【问题标题】:how can i make a cube with a grid in three.js我如何在three.js中制作一个带有网格的立方体
【发布时间】:2022-01-26 04:35:12
【问题描述】:

Cube

我想做一个完全一样的东西,但是我可以用一个变量来改变网格中立方体的数量。(我不知道如何开始)

【问题讨论】:

标签: javascript html three.js 3d


【解决方案1】:

您需要将立方体添加到 Group,然后将 Group 添加到场景中,然后将 Group 居中

这是执行此操作的一种方法:

const grid = new THREE.Group();

const cubeSize = 0.25;
const rows = 4;
const cols = 4;
const gap = 0.01;

for (let row = 0; row < rows; row++) {
    for (let col = 0; col < cols; col++) {
        for (let z = 0; z < rows; z++) {
            const cube = createCube(cubeSize);
            const pos = ((cubeSize / 2) * rows) / 2 + gap;
            const x = pos * row;
            const y = pos * col;
            cube.position.set(x, y, pos * z);
            grid.add(cube);
        }
    }
}

scene.add(grid);

请注意,添加的多维数据集越多,这将无法很好地扩展。由于对象的总数将是(rows + cols) ^ 3,这将产生大量的对象。鉴于此,您可以使用InstancedMeshmesh,我在下面展示了一个演示。

演示:

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

canvas {
  display: block;
}
<script type="module">
  import * as THREE from "https://cdn.jsdelivr.net/npm/three@0.121.1/build/three.module.js";
  import { OrbitControls } from "https://cdn.jsdelivr.net/npm/three@0.121.1/examples/jsm/controls/OrbitControls.js";

  const renderer = new THREE.WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

  const scene = new THREE.Scene();
  const camera = new THREE.PerspectiveCamera(
    75,
    window.innerWidth / window.innerHeight,
    0.1,
    1000
  );
  const controls = new OrbitControls(camera, renderer.domElement);

  const grid = new THREE.Group();

  const cubeSize = 0.25;
  const size = 20;
  const gap = 0.01;

  const geometry = new THREE.BoxBufferGeometry(
    cubeSize,
    cubeSize,
    cubeSize
  );
  const material = new THREE.MeshNormalMaterial();
  const cubes = new THREE.InstancedMesh(
    geometry,
    material,
    Math.pow(size, 3)
  );
  cubes.instanceMatrix.setUsage(THREE.DynamicDrawUsage);

  grid.add(cubes);
  scene.add(grid);

  const cube = new THREE.Object3D();
  const center = (size + gap * (size - 1)) * -0.5;

  grid.position.set(center, center, center);

  camera.position.z = size * 1.5;

  (function animate() {
    requestAnimationFrame(animate);

    let i = 0;
    for (let x = 0; x < size; x++) {
      for (let y = 0; y < size; y++) {
        for (let z = 0; z < size; z++) {
          cube.position.set(x, y, z);
          cube.updateMatrix();
          cubes.setMatrixAt(i, cube.matrix);
          i++;
        }
      }
    }

    cubes.instanceMatrix.needsUpdate = true;

    controls.update();
    renderer.render(scene, camera);
  })();
</script>

【讨论】:

  • 可行,但我不能使用该代码放置 126 个立方体,我想做的是输入一个以 3d 形式显示在立方体中的数字。
  • rowscols 之和的平方根需要是整数。 126 的平方根是 11.224972160321824 不是整数,这意味着网格不会是正方形
  • 126 也太多了,无法使用此方法进行渲染。您将需要使用实例化来实现这一点。在“输入”中输入的任何数字都会被立方,126^3 超过 200 万立方
  • 是的,我明白这一点,但是有没有一种方法可以不用行或列,只需输入一个数字,该数字就会显示在立方体中,就像中心有一个立方体,所有其他立方体都是根据他的立场?
  • 我现在正在更新我的答案以包含 InstancedMesh 示例
猜你喜欢
  • 1970-01-01
  • 2021-10-12
  • 2012-10-11
  • 1970-01-01
  • 2020-02-07
  • 1970-01-01
  • 1970-01-01
  • 2016-02-08
  • 2012-09-14
相关资源
最近更新 更多