I'm looking for this kind of effect MINUS the lights and snow (Another problem).
- It needs to change depending on the time of year.
- Doesn't need snow or city lights.
Now I'm pretty new to shaders (learnt them yesterday in my spare time) but so far I have achieved:
This moves across the screen display light on both sides.
Now I'm completely lost, as to how I can make it seem like a light map I.E. it needs to be more square/sharper (As it's going off the edges) & have the bottom and top times of year.. I though maybe I could pass sphere mesh to the vertex? Or do something with the map-normal. Or maybe use blending with two textures but I've looked around and it looks extremely difficult.
Code I have so far:
Fragment / Pixel shader:
//attributes from vertex shader
varying vec4 vColor;
varying vec2 vTexCoord;
//our texture samplers
uniform sampler2D u_texture; //diffuse map
uniform sampler2D u_normals; //normal map
//values used for shading algorithm...
uniform vec2 Resolution; //resolution of screen
uniform vec3 LightPos; //light position, normalized
uniform vec4 LightColor; //light RGBA -- alpha is intensity
uniform vec4 AmbientColor; //ambient RGBA -- alpha is intensity
uniform vec3 Falloff; //attenuation coefficients
uniform float lightX; //X Position of light. Can also feed Y for times of the year.
void main()
{
//RGBA of our diffuse color
vec4 DiffuseColor = texture2D(u_texture, vTexCoord);
//RGB of our normal map
vec3 NormalMap = texture2D(u_normals, vTexCoord).rgb;
int numberOfLights = 3;
vec3 lightPoses[3];
vec3 lightDirections[3];
//LightX goes to 0, then back to 1.
lightPoses[0] = vec3(lightX - 1.0, LightPos.y, LightPos.z);
lightPoses[1] = vec3(lightX, LightPos.y, LightPos.z);
lightPoses[2] = vec3(lightX + 1.0, LightPos.y, LightPos.z);
//TODO Introduce one extra light for top and bottom. OR Figure out how to squash the Y.
//TODO Needs to be sharper light.
vec3 Sum = vec3(0.0);
//Go though both lights.
for(int index=0; index < numberOfLights; index++)
{
//The delta position of light
vec3 LightDir = vec3(lightPoses[index].xy - (gl_FragCoord.xy / Resolution.xy), LightPos.z);
//Correct for aspect ratio
LightDir.x = LightDir.x * (Resolution.x / Resolution.y);
//Make it bigger. (smaller the value the bigger.)
LightDir *= vec3(0.55, 0.4, 1.0);
//Determine distance (used for attenuation) BEFORE we normalize our LightDir
float D = length(LightDir);
//normalize our vectors
vec3 N = normalize(NormalMap * 2.0 - 1.0);
vec3 L = normalize(LightDir);
//Pre-multiply light color with intensity
//Then perform "N dot L" to determine our diffuse term
vec3 Diffuse = (LightColor.rgb * LightColor.a) * max(dot(N, L), 0.0);
//pre-multiply ambient color with intensity
vec3 Ambient = AmbientColor.rgb * AmbientColor.a;
//Because there are more lights, take off total ambient power.
Ambient *= vec3(1.0 / float(numberOfLights));
//Calculate attenuation (The amount of fade the light has.)
float Attenuation = 1.0 / (Falloff.x + (Falloff.y*D) + (Falloff.z*D*D));
//the calculation which brings it all together
vec3 Intensity = Ambient + Diffuse * Attenuation;
vec3 FinalColor = DiffuseColor.rgb * Intensity;
Sum += FinalColor;
}
gl_FragColor = vec4(Sum, DiffuseColor.a);
}
Vertex Shader:
//combined projection and view matrix
uniform mat4 u_projTrans;
//"in" attributes from our SpriteBatch
attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoord0;
//"out" varyings to our fragment shader
varying vec4 vColor;
varying vec2 vTexCoord;
void main() {
vColor = a_color;
vTexCoord = a_texCoord0;
gl_Position = u_projTrans * a_position;
}