I create a earth planet use the MeshStandardMaterial, i want to use the night map on the earth dark side.
So i use dot(normal, vec3(1.0, 0.0, 0.0))
, if the result is less then 0, i will use the night map, if the result is greater than 0, i will use the color map.
But when i rotate the camera i got a odd effect.
Does it look better if you transform this vector with the viewMatrix
?
2 Likes
AFAIK, the engine transforms light’s vector parameters with viewMatrix
: three.js/WebGLLights.js at f0e2b3453f1412b53389beb04add414e3a80023c · mrdoob/three.js · GitHub
So, it’s possible to use values from structures in shaders (geometry
and directionalLights
), to compute dot-product
:
An example of code for .onBeforeCompile
:
let m = new THREE.MeshStandardMaterial({
map: loader.load("https://threejs.org/examples/textures/uv_grid_opengl.jpg"),
onBeforeCompile: shader => {
shader.uniforms.darkSideTex = {value: loader.load("https://threejs.org/examples/textures/758px-Canestra_di_frutta_(Caravaggio).jpg")};
shader.fragmentShader = `
#define ss(a, b, c) smoothstep(a, b, c)
uniform sampler2D darkSideTex;
${shader.fragmentShader}
`.replace(
`#include <dithering_fragment>`,
`#include <dithering_fragment>
float d = max(dot(geometry.normal, directionalLights[0].direction), 0.);
vec4 dst = texture(darkSideTex, vUv);
gl_FragColor = mix(dst, gl_FragColor, ss(0., 0.15, d));
`
);
}
})
1 Like
When use the directionalLights[0].direction
, the normal
works fine.
Thanks! works now.
I do not understand why need transform the light direction with the viewMatrix
.