Three.js如何实现BoxGeometry单个顶点的透明效果
需求可行性结论
完全可行。
先纠正一个概念偏差:标准立方体拓扑的BoxGeometry最少需要8个顶点,不存在仅包含2个顶点的合法Box几何体,你提到的2顶点版本应该是通过两个空间对角点坐标生成的自定义薄盒/类平面盒体。
Three.js内置的基础材质默认只支持材质级、面级的透明度控制,没有开放逐顶点透明度的配置入口,所以直接用默认材质没法实现单顶点透明效果,只要通过自定义顶点属性+着色器逻辑扩展,就能实现你参考图里的单顶点渐隐透明效果。
具体实现步骤
- 给几何体新增逐顶点透明度属性
拿到你的Box几何体实例后,新增一个自定义顶点属性存储每个顶点的透明度值:你需要完全透明的目标顶点对应值设为0,其余顶点对应值设为1即可。
参考代码:// 替换为你自己的BoxGeometry实例 const boxGeo = yourBoxGeometry; const vertexTotal = boxGeo.attributes.position.count; // 初始化所有顶点透明度为1(完全不透明) const opacityValueList = new Float32Array(vertexTotal).fill(1); // 替换targetVertexIndex为你要透明的那个顶点的索引值,设为0(完全透明) opacityValueList[targetVertexIndex] = 0; // 把透明度数组挂到几何体属性上,属性名自定义为aOpacity boxGeo.setAttribute('aOpacity', new THREE.BufferAttribute(opacityValueList, 1)); - 扩展内置材质支持顶点透明度插值
不需要从零手写ShaderMaterial,直接对常用的MeshStandardMaterial/MeshBasicMaterial做注入扩展即可,记得开启透明开关,避免渲染排序异常:const boxMat = new THREE.MeshStandardMaterial({ color: 0x3b82f6, transparent: true, side: THREE.DoubleSide, depthWrite: false // 透明材质建议关闭深度写入,减少渲染穿模问题 }); // 注入自定义着色器逻辑 boxMat.onBeforeCompile = (shader) => { // 顶点着色器注入:接收顶点透明度属性,通过varying变量传给片元 shader.vertexShader = shader.vertexShader.replace( '#include <common>', ` #include <common> attribute float aOpacity; varying float vOpacity; ` ); shader.vertexShader = shader.vertexShader.replace( '#include <begin_vertex>', ` #include <begin_vertex> vOpacity = aOpacity; ` ); // 片元着色器注入:接收插值后的透明度值,应用到最终片元颜色上 shader.fragmentShader = shader.fragmentShader.replace( '#include <common>', ` #include <common> varying float vOpacity; ` ); shader.fragmentShader = shader.fragmentShader.replace( '#include <output_fragment>', ` #include <output_fragment> gl_FragColor.a *= vOpacity; ` ); }; - 生成网格加入场景
用处理好的几何体和材质创建Mesh实例加入场景,渲染后会自动在透明顶点和相邻不透明顶点之间做透明度线性插值,得到你参考图里的角部渐隐效果。

补充说明:如果你不需要渐变过渡,想要硬边裁切的透明效果,只需要在片元着色器里加一行判断,透明度低于阈值直接丢弃片元即可:
if(vOpacity < 0.5) discard;。
内容的提问来源于stack exchange,提问作者user13762985
相关产品推荐
相关产品推荐

