Three.js:为细分迭代顶点添加颜色区分及解决额外顶点问题
解决方案
1. 解决几何体原始顶点重复问题
Three.js的部分内置几何体(如CylinderGeometry、SphereGeometry)为实现正确的法线、UV映射,会对拓扑上的同一顶点创建多个副本(每个副本对应不同的面或法线方向),这就是你看到“额外顶点”的原因。处理方式如下:
- 使用
BufferGeometryUtils.mergeVertices()合并重复顶点,该方法会移除位置、法线、UV等属性完全一致的重复顶点,得到拓扑上唯一的原始顶点集合。 - 代码示例:
注意:去重后若需保留平滑着色效果,可调用import { BufferGeometryUtils } from 'three/addons/utils/BufferGeometryUtils.js'; // 创建原始几何体后立即去重 const originalGeo = new THREE.CylinderGeometry(1, 1, 2, 8); const deduplicatedGeo = BufferGeometryUtils.mergeVertices(originalGeo);deduplicatedGeo.computeVertexNormals()重新计算法线;若不需要平滑效果,创建几何体时可设置smoothShading: false。
2. 实现细分层级顶点的颜色区分
要区分不同细分层级的顶点,需在细分流程中给每个顶点添加自定义属性记录生成层级,再通过着色器映射颜色:
步骤1:给原始顶点添加层级属性
在去重后的原始几何体中,添加customIteration属性,将原始顶点的层级设为0:
// 初始化层级数组,所有原始顶点层级为0 const iterationArray = new Float32Array(deduplicatedGeo.attributes.position.count).fill(0); deduplicatedGeo.setAttribute('customIteration', new THREE.BufferAttribute(iterationArray, 1));
步骤2:细分时标记新顶点的层级
无论你使用自定义细分算法还是第三方工具,在生成新顶点(如边中点、面内顶点)时,将其customIteration设为当前细分层级(1到5):
- 示例(以边中点生成为例):
若使用// currentLevel为当前细分层级(从1开始) const midPoint = new THREE.Vector3().lerpVectors(v1, v2, 0.5); // v1、v2为边的两个端点 // 将新顶点的层级加入数组 iterationArray.push(currentLevel);THREE.SubdivisionModifier,需修改其源码逻辑,确保在生成新顶点时同步复制或添加customIteration属性。
步骤3:着色器中根据层级分配颜色
在顶点着色器中读取customIteration属性,映射为对应颜色,片元着色器直接使用该颜色:
// 顶点着色器 attribute float customIteration; varying vec3 vColor; void main() { // 按层级定义颜色 if (customIteration == 0.0) vColor = vec3(1.0, 0.0, 0.0); // 原始顶点:红色 else if (customIteration == 1.0) vColor = vec3(0.0, 1.0, 0.0); // 第1级细分:绿色 else if (customIteration == 2.0) vColor = vec3(0.0, 0.0, 1.0); // 第2级细分:蓝色 else if (customIteration == 3.0) vColor = vec3(1.0, 1.0, 0.0); // 第3级细分:黄色 else if (customIteration == 4.0) vColor = vec3(1.0, 0.0, 1.0); // 第4级细分:品红 else vColor = vec3(0.0, 1.0, 1.0); // 第5级细分:青色 gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); }
// 片元着色器 varying vec3 vColor; void main() { gl_FragColor = vec4(vColor, 1.0); }
额外提示
- 调整
mergeVertices的精度参数(默认0.0001)可控制顶点合并的严格程度,避免误合并位置接近的不同顶点。 - 若细分后几何体的属性出现异常,需确保所有自定义属性在细分过程中都被正确复制或更新。
内容的提问来源于stack exchange,提问作者Vyxxen
相关产品推荐
相关产品推荐

