You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Three.js立方体填充不全问题:cubeIndices设置异常求助

Three.js手动构建棱柱仅显示一半的问题解决

你的问题确实出在cubeIndices的设置上——当前的索引数组里充满了重复的顶点索引,生成的是无效三角形(三个顶点重复或共线的面不会被WebGL渲染),所以只显示了部分图形。

下面是修正后的索引逻辑,同时补上上下底面的三角化(你之前仅处理了侧面且逻辑错误):

function createCube() {
  const radiusBottom = 2;
  const radiusTop = 2;
  const height = 2;
  const cubeVertices = new Float32Array((segments + 1) * 6);
  for (let i = 0; i <= segments; i++) {
    const angle = (i / segments) * Math.PI * 2;
    const x = Math.cos(angle);
    const z = Math.sin(angle);

    const topX = x * radiusTop;
    const topZ = z * radiusTop;
    const topY = height / 2;

    const bottomX = x * radiusBottom;
    const bottomZ = z * radiusBottom;
    const bottomY = -height / 2;

    const baseOffset = i * 6;
    cubeVertices[baseOffset] = topX;
    cubeVertices[baseOffset + 1] = topY;
    cubeVertices[baseOffset + 2] = topZ;

    cubeVertices[baseOffset + 3] = bottomX;
    cubeVertices[baseOffset + 4] = bottomY;
    cubeVertices[baseOffset + 5] = bottomZ;
  }

  // 重新计算索引:侧面每个面2个三角,上下底面各segments-1个三角
  const faceCount = segments * 2 + (segments - 1) * 2;
  const cubeIndices = new Uint16Array(faceCount * 3);
  let indexOffset = 0;

  // 1. 处理侧面的三角面
  for (let i = 0; i < segments; i++) {
    const currentTop = i * 2;
    const nextTop = (i + 1) * 2;
    const currentBottom = i * 2 + 1;
    const nextBottom = (i + 1) * 2 + 1;

    // 第一个三角形:currentTop -> nextTop -> currentBottom
    cubeIndices[indexOffset++] = currentTop;
    cubeIndices[indexOffset++] = nextTop;
    cubeIndices[indexOffset++] = currentBottom;

    // 第二个三角形:nextTop -> nextBottom -> currentBottom
    cubeIndices[indexOffset++] = nextTop;
    cubeIndices[indexOffset++] = nextBottom;
    cubeIndices[indexOffset++] = currentBottom;
  }

  // 2. 处理上底面(扇形三角化,以第一个顶部顶点为中心)
  const topCenterIndex = 0;
  for (let i = 1; i < segments; i++) {
    cubeIndices[indexOffset++] = topCenterIndex;
    cubeIndices[indexOffset++] = i * 2;
    cubeIndices[indexOffset++] = (i + 1) * 2;
  }

  // 3. 处理下底面(扇形三角化,以第一个底部顶点为中心)
  const bottomCenterIndex = 1;
  for (let i = 1; i < segments; i++) {
    cubeIndices[indexOffset++] = bottomCenterIndex;
    cubeIndices[indexOffset++] = (i + 1) * 2 + 1;
    cubeIndices[indexOffset++] = i * 2 + 1;
  }

  cubeGeometry = new THREE.BufferGeometry();
  cubeGeometry.setIndex(new THREE.BufferAttribute(cubeIndices, 1));
  cubeGeometry.setAttribute('position', new THREE.BufferAttribute(cubeVertices, 3));

  const cubeMaterial = new THREE.MeshBasicMaterial({
    color: 'blue'
  });
  cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
  scene.add(cube);
}

关键修正点:

  • 侧面三角化:每个侧面由两个不重复的三角形组成,顶点顺序符合WebGL默认的正面剔除规则(逆时针为正面)。
  • 上下底面填充:通过扇形三角化,用中心顶点连接周围顶点,生成完整的闭合底面。
  • 移除无效索引:删除了原代码中重复顶点的索引,避免生成WebGL无法渲染的无效三角形。

如果要得到立方体,只需将segments设置为4即可——正四棱柱就是标准立方体。

内容的提问来源于stack exchange,提问作者duxa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 12:33:16