I currently have a custom shader draw a gradient on a skydome and would like to have a sun/moon in front of the skydome (from users perspective). The easiest way to do this is to have sprites for the sun and moon but the problem that arises is that the sprites get lodged within the skydome (sprite is partway in front and partway in back of the skydome). I have attempted to solve this with polygonoffset, but that doesn't seem to work on sprite objects.
So my question is, how can I setup a sun/moon on top of skydome without having to modify my custom skydome shader to add sun/moon texture with the gradient (which could end up being very difficult)?
Below is the code for my sky shader for the 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")
});
Make sure your skydome is drawn before any other object and disable the
depthWrite
/depthTest
flags on the material (depthWrite
being the important thing here):where
skydome
is the mesh on which you have appliedyourmaterial
.