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