Three.js着色器实现网格几何体Z轴方向Alpha渐变需求问询
实现立方体沿Z轴渐变透明度的着色方案
核心思路
不用UV,直接用顶点的局部空间坐标计算Z轴位置占总长度的比例,以此控制片元的alpha值。UV是单一面的纹理坐标,无法对应整个立方体的全局Z轴位置;而局部坐标是物体自身坐标系下的位置,能准确反映每个顶点/片元在Z轴上的相对位置。
具体实现步骤
- 传递局部坐标到片元着色器:在顶点着色器中,把Three.js内置的局部空间顶点坐标
position作为varying变量传给片元着色器,让每个片元都能拿到自身对应的局部Z坐标。 - 传入立方体Z轴长度(灵活适配尺寸):通过uniform变量把立方体的Z轴长度(比如
BoxGeometry的第三个参数)传给着色器,避免硬编码,适配不同尺寸的立方体。 - 计算归一化比例控制alpha:把局部Z坐标从
[-sizeZ/2, sizeZ/2]映射到[0,1]范围,用这个值作为alpha系数,实现沿Z轴的渐变效果。
完整代码示例
顶点着色器
varying vec3 vPosition; void main() { vPosition = position; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); }
片元着色器
varying vec3 vPosition; uniform float uSizeZ; uniform vec3 uColor; void main() { // 将Z轴坐标映射为0-1的比例:从Z=-sizeZ/2(0)到Z=sizeZ/2(1) float zRatio = (vPosition.z + uSizeZ / 2.0) / uSizeZ; // 反转比例可实现反向渐变:zRatio = 1.0 - zRatio; gl_FragColor = vec4(uColor, zRatio); }
Three.js使用关键代码
// 创建Z轴长度为5的立方体几何体 const geometry = new THREE.BoxGeometry(2, 2, 5); // 着色器材质配置 const material = new THREE.ShaderMaterial({ uniforms: { uSizeZ: { value: 5 }, // 对应几何体Z轴长度 uColor: { value: new THREE.Color(0x00ff00) } }, vertexShader: document.getElementById('vertexShader').textContent, fragmentShader: document.getElementById('fragmentShader').textContent, transparent: true, // 必须开启透明 side: THREE.DoubleSide // 可选,让立方体内部也显示渐变 }); // 创建网格并加入场景 const cube = new THREE.Mesh(geometry, material); scene.add(cube);
关键细节
- 局部空间的优势:用局部坐标而非世界坐标,避免物体缩放、旋转后渐变方向偏离自身Z轴。
- 透明渲染设置:必须开启
transparent: true,alpha值才会生效;若需更准确的透明层级,可调整depthWrite或depthTest参数。
内容的提问来源于stack exchange,提问作者Johannes Klauß
相关产品推荐
相关产品推荐

