three实现4000个三维小行星球体压缩在立方体内旋转动画效果代码
代码语言:html
所属分类:三维
代码描述:three实现4000个三维小行星球体压缩在立方体内旋转动画效果代码
代码标签: three 三维 小行星 球体 压缩 立方体 旋转 动画
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> html, body { margin: 0; height: 100%; background: #1a1a1a; } #log { position: absolute; bottom: 0; right: 0; padding: 0.5em 0.75em; font-size: 12px; font-family: monospace; white-space: pre-line; text-align: right; color: grey; } </style> </head> <body translate="no"> <div id="log">packing 4000 spheres...</div> <canvas id="canvas"></canvas> <script type="module"> import { Color, DirectionalLight, HemisphereLight, InstancedMesh, MeshLambertMaterial, Object3D, OrthographicCamera, PCFSoftShadowMap, Quaternion, Scene, SphereGeometry, Vector3, WebGLRenderer } from "//repo.bfw.wiki/bfwrepo/js/module/three/build/169/three.module.js"; const N = 4000; const MIN_R = 0.005; const MAX_R = 0.5; const min = Math.min; const abs = Math.abs; //////// SETUP const scene = new Scene(); scene.background = new Color(0.01, 0.01, 0.01); let asp = innerWidth / innerHeight; const camera = new OrthographicCamera(-asp, asp, 1, -1, -1, 1); const renderer = new WebGLRenderer({ canvas }); renderer.setSize(innerWidth, innerHeight); renderer.setPixelRatio(min(2, devicePixelRatio)); renderer.shadowMap.enabled = true; renderer.shadowMap.type = PCFSoftShadowMap; //////// LIGHT const ambient = new HemisphereLight(new Color(1, 0.6, 0.2), new Color(0.2, 0.6, 1), 2); scene.add(ambient); const light = new DirectionalLight(new Color(1, 0.9, 0.8), 2); light.position.set(-1, 1, 1); scene.add(light); light.castShadow = true; light.shadow.mapSize.width = 1024; light.shadow.mapSize.height = 1024; light.shadow.camera.near = 0; light.shadow.camera.far = 4; light.shadow.camera.left = -1; light.shadow.camera.right = 1; light.shadow.camera.top = -1; light.shadow.camera.bottom = 1; light.shadow.bias = -0.001; //////// INTSTANCED SPHERES const mat = new MeshLambertMaterial(); const new_spheres = (ws, hs) => { const geom = new SphereGeometry(1, ws, hs); const spheres = new InstancedMesh(geom, mat, N); spheres.castShadow = true; spheres.receiveShadow = true; return spheres; }; const spheres = [ // small spheres { num: 0, mesh: new_spheres(9, 6) }, // medium spheres { num: 0, mesh: new_spheres(21, 14) }, // large spheres { num: 0, mesh: new_spheres(72, 48) }, ]; //////// PACKING const dummy = new Object3D(); const packed = new Float32Array(N * 4); const start = performance.now(); const MAX_TRIES = 1e3; let checks_num = 0; for (let i = 0; i < N; i++) { let x = 0, y = 0, z = 0, r = 0, k = 0; while (r === 0 && k < MAX_TRIES) { x = random(-1, 1); y = random(-1, 1); z = random(-1, 1); r = get_radius(x, y, z, i); k++; } if (k === MAX_TRIES && r === 0) { continue; } dummy.position.set(x, y, z); dummy.scale.set(r, r, r); dummy.updateMatrix(); const size_id = r > 0.03 ? r > 0.1 ? 2 : 1 : 0; const inst = spheres[size_id]; inst.mesh.setMatrixAt(inst.num, dummy.matrix); inst.mesh.setColorAt(inst.num, new Color(random(0.4, 1.0), random(0.3, 0.9), random(0.2, 0.8))); inst.num++; const j = i * 4; packed[j + 0] = x; packed[j + 1] = y; packed[j + 2] = z; packed.........完整代码请登录后点击上方下载按钮下载查看
网友评论0