强制一个精灵对象始终在THREE.js中的天体对象前面
问题描述:
我目前有一个自定义着色器在天穹上画一个渐变,并希望在天蝎座前面有一个太阳/月亮(从用户角度来看) 。最简单的方法是为太阳和月亮拍摄精灵,但问题在于精灵会在天体中出现(精灵在前方和后方的中间部分)。我试图用polygonoffset来解决这个问题,但是这似乎不适用于精灵对象。强制一个精灵对象始终在THREE.js中的天体对象前面
所以我的问题是,我如何在skydome上设置太阳/月亮,而不必修改我自定义的skydome着色器来添加渐变(最终会变得非常困难)太阳/月亮纹理?
以下是天球着色器的代码。
new THREE.ShaderMaterial({
uniforms: {
glow: {
type: "t",
value: THREE.ImageUtils.loadTexture(DEFAULT_PATH+"glow2.png")
},
color: {
type: "t",
value: THREE.ImageUtils.loadTexture(DEFAULT_PATH+"sky2.png")
},
lightDir: {
type: "v3",
value: self.lightPos
}
},
vertexShader: [
"varying vec3 vWorldPosition;",
"varying vec3 vPosition;",
"void main() {",
"vec4 worldPosition = modelMatrix * vec4(position, 1.0);",
"vWorldPosition = worldPosition.xyz;",
"vPosition = position;",
"gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);",
"}"
].join("\n"),
fragmentShader: [
"uniform sampler2D glow;",
"uniform sampler2D color;",
"uniform vec3 lightDir;",
"varying vec3 vWorldPosition;",
"varying vec3 vPosition;",
"void main() {",
"vec3 V = normalize(vWorldPosition.xzy);",
"vec3 L = normalize(lightDir.xzy);",
"float vl = dot(V, L);",
"vec4 Kc = texture2D(color, vec2((L.y + 1.0)/2.0, V.y));",
"vec4 Kg = texture2D(glow, vec2((L.y + 1.0)/2.0, vl));",
"gl_FragColor = vec4(Kc.rgb + Kg.rgb * Kg.a/2.0, Kc.a);",
"}",
].join("\n")
});
答
确保您的体育馆被任何其他对象之前绘制和材料禁用depthWrite
/depthTest
标志(depthWrite
是这里最重要的):
yourmaterial = new THREE.ShaderMaterial({...});
yourmaterial.depthWrite = false;
yourmaterial.depthTest = false;
skydome.renderDepth = 1e20;
其中skydome
是网格上您已申请yourmaterial
。