I am trying to do an earth simulation in OpenGL with GLSL shaders, and so far it's been going decent. Although I am stuck with a slightly small problem. Right now I have 3 spheres, one for ground level (earth), one for clouds and the third for the atmosphere (scattering effects). The earth sphere handles with most of the textures.
The cloud sphere is a slightly bigger sphere than the earth sphere, and is mapped with a cloud texture and normal mapped using one created with the photoshop plugin. One more thing to point out is, the rotation speed of the cloud sphere is slightly greater than the rotation speed of the earth sphere.
This is where things get confusing for me. I am trying to cast the shadow of the clouds onto the ground (earth) sphere by passing the cloud texture into the earth sphere's shader and subtracting the cloud's color from earth's color. But since the rotation speeds of the two sphere's are different, I figured if I multiplied the rotation matrix of the cloud sphere with the uv coordinates for the cloud texture, that should solve the problem. But sadly, the shadows and the clouds do not seem to rotate in sync. I was hoping if anyone can help me figure out the math to make the shadows and the cloud rotate in sync with each other, no matter how different the rotation speeds of the two sphere are.
Here is my fragment shader for the earth where I'm calculating the cloud's shadow:
#version 400 core
uniform sampler2D day;
uniform sampler2D bumpMap;
uniform sampler2D night;
uniform sampler2D specMap;
uniform sampler2D clouds;
uniform mat4 cloudRotation;
in vec3 vPos;
in vec3 lightVec;
in vec3 eyeVec;
in vec3 halfVec;
in vec2 texCoord;
out vec4 frag_color;
void main()
{
vec3 normal = 2.0 * texture(bumpMap, texCoord).rgb - 1.0;
//normal.z = 1 - normal.x * normal.x - normal.y * normal.y;
normal = normalize ( normal );
vec4 spec = vec4(1.0, 0.941, 0.898, 1.0);
vec4 specMapColor = texture2D(specMap, texCoord);
vec3 L = lightVec;
vec3 N = normal;
vec3 Emissive = normalize(-vPos);
vec3 R = reflect(-L, N);
float dotProd = max(dot(R, Emissive), 0.0);
vec4 specColor = spec * pow(dotProd,6.0) * 0.5;
float diffuse = max(dot(N, L), 0.0);
vec2 cloudTexCoord = vec2(cloudRotation * vec4(texCoord, 0.0, 1.0));
vec3 cloud_color = texture2D( clouds, cloudTexCoord).rgb;
vec3 day_color = texture2D( day, texCoord ).rgb * diffuse + specColor.rgb * specMapColor.g - cloud_color * 0.25;// * (1 - cloud_color.r) + cloud_color.r * diffuse;
vec3 night_color = texture2D( night, texCoord ).rgb * 0.5;// * (1 - cloud_color.r) * 0.5;
vec3 color = day_color;
if(dot(N, L) < 0.1)
color = mix(night_color, day_color, (diffuse + 0.1) * 5.0);
frag_color = vec4(color, 1.0);
}
Here's a sample output as a result of the above shader. Note that the shadows start out at the correct position, but the due to the wrong rotation speed, they tend to move ahead of the rotation of the cloud sphere.
Again, it would be really helpful if anyone can help me figure out the math behind keep the shadow and the clouds in sync
Thanks in advance