强制sprite对象始终位于THREE.js中的skydome对象前面

Fre*_*yer 1 javascript shader sprite three.js

我目前有一个自定义着色器在天幕上绘制渐变,并希望在天幕前面有一个太阳/月亮(从用户的角度来看).最简单的方法就是拥有太阳和月亮的精灵,但出现的问题是精灵会被留在天幕内(精灵位于天幕的前方和中间位置).我试图用polygonoffset解决这个问题,但这似乎不适用于精灵对象.

所以我的问题是,如何在天空之上设置太阳/月亮而不必修改我的自定义天幕着色器以添加渐变的太阳/月亮纹理(这可能最终会非常困难)?

下面是我的天空着色器的代码.

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")
});
Run Code Online (Sandbox Code Playgroud)

Pop*_*pov 5

确保你的天幕是在任何其他对象之前绘制的,并禁用材质上的depthWrite/ depthTestflags(depthWrite这里重要的是):

yourmaterial = new THREE.ShaderMaterial({...});
yourmaterial.depthWrite = false;
yourmaterial.depthTest = false;
skydome.renderDepth = 1e20;
Run Code Online (Sandbox Code Playgroud)

skydome您应用的网格在哪里yourmaterial.