I have a 3D scene with only one sphere in it and I have two textures - one for the night, and one for the day of this planet. In addition I have the a lightSource at (15,15,15) in my scene. For each vertex on the sphere I also have the normal.
Now I want to blend between the two texture so that the fading between day and night seems to be realistic. Therefore I calculate the angle between the normal and the light using dot-product, but with this approach I get hard crossover if I check if the angle is > 0 (which will be the dayside). I need to mix the textures based on the angle, that it is a soft crossover.
Can anyone help me how I can mix the textures? My code so far:
float angle = dot(L,N);
vec4 texture = texture2D(day, textureCoord);
texture = texture2D(night,textureCoord) * (1-angle) + texture * angle;
vec4 light = vec4(ambientTerm + diffuseTerm + specularTerm , 1);
if(angle > 0) {
color = light * texture;
} else if(angle >= -0.25) {
color = texture2D(night,textureCoord)*(angle-1) + texture * (angle);
} else if( angle < -0.25) {
color = texture2D(night,textureCoord);
}
You can use the smoothstep
function to turn a continous value into a 0/1 decision with a small smooth transition in between. So basically you define a range where the transisition is, let's just take [-0.25,0.25], which would be an angle range from about 75 to 105 degrees (take larger values for a larger transistion area, but try to make it symmetrical, thus centered around 90 degrees, since people switch on their lights at dusk already ;)). Then we transform our [-1,1] monotonic cosine using
angle = smoothstep(-0.25, 0.25, angle)
which will result in angle
(though that name is a bit unfortunately chosen, given that it isn't an angle and behaves inverse to the actual angle) being 0
if it was < -0.25
, 1
if it was > 0.25
and a smooth transition if in between. And the whole texturing would look like (cleaned from the strange if and making use of the builtin mix
function):
float angle = dot(N, L);
vec4 nightColor = texture2D(night, textureCoord);
vec4 dayColor = texture2D(day, textureCoord);
color = light * mix(nightColor, dayColor, smoothstep(-0.25, 0.25, angle));
Or, for the fun and sake of completeness the more streamlined
color = light * mix(texture2D(night, textureCoord),
texture2D(day, textureCoord),
smoothstep(-0.25, 0.25, dot(N, L)));