diff options
Diffstat (limited to 'shaders/textured.frag')
-rw-r--r-- | shaders/textured.frag | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/shaders/textured.frag b/shaders/textured.frag new file mode 100644 index 0000000..266bf31 --- /dev/null +++ b/shaders/textured.frag @@ -0,0 +1,156 @@ +#version 150 +uniform sampler2D texture ; +uniform sampler2D earth ; +uniform sampler2D clouds ; +uniform sampler2D lights ; +uniform sampler2D random ; +uniform sampler2D winter ; + +uniform float time ; +uniform vec3 light ; +uniform float dX ; +uniform float dY ; + +in vec2 texCoord ; +in vec3 trueNormal ; +in vec4 location ; +in vec3 light2 ; +in mat3 normalMat ; + +out vec4 frag_color ; +in vec2 texMapping ; + + +float cloudMotion = -time / 1100.0 ; +float earthMotion = -time / 1400.0 ; + +vec3 lighting( vec3 norm, vec3 lightPos ) { + vec3 diff = normalize(vec3(location) - lightPos) ; + float tmp = dot(diff, normalize( norm )) + 0.3 ; + + if( tmp < 0.0 ) return vec3(0) ; + return vec3( + pow(tmp / length(diff),0.3), + pow(tmp / length(diff),0.8), + pow(tmp / length(diff),1.0) + ); +} + +vec4 sample(sampler2D tex, float xc,float yc) { + return texture2D(texture,texMapping + vec2(earthMotion,0.0) + vec2(xc,yc)); +} + +float f( float x ) { + return x * (x - 1.0) ; +} + +vec3 calNormChange( sampler2D tex, vec3 norm, vec3 down, vec3 right ) { + float x00 = length(sample(tex,-dX, dY)) ; + float x01 = length(sample(tex, 0, dY)) ; + float x02 = length(sample(tex, dX, dY)) ; + + float x10 = length(sample(tex,-dX, 0)) ; + float x11 = length(sample(tex, 0, 0)) ; + float x12 = length(sample(tex, dX, 0)) ; + + float x20 = length(sample(tex,-dX,-dY)) ; + float x21 = length(sample(tex, 0,-dY)) ; + float x22 = length(sample(tex, dX,-dY)) ; + + down = ((x11 - x00) + (x11 - x01) + (x11 - x02) - (x11 - x20) - (x11 - x21) - (x11 - x22)) * down ; + right = ((x11 - x00) + (x11 - x10) + (x11 - x20) - (x11 - x02) - (x11 - x12) - (x11 - x22)) * right ; + + return (right + down + norm) / 3.0 ; +} + +vec4 sampleBlur( sampler2D tex ) { + return + texture2D(texture,texMapping + vec2(earthMotion,0.0) + vec2( dX, dY)) / 9.0 + + texture2D(texture,texMapping + vec2(earthMotion,0.0) + vec2( 0, dY)) / 9.0 + + texture2D(texture,texMapping + vec2(earthMotion,0.0) + vec2(-dX, dY)) / 9.0 + + texture2D(texture,texMapping + vec2(earthMotion,0.0) + vec2( dX, 0)) / 9.0 + + texture2D(texture,texMapping + vec2(earthMotion,0.0) + vec2( 0, 0)) / 9.0 + + texture2D(texture,texMapping + vec2(earthMotion,0.0) + vec2(-dX, 0)) / 9.0 + + texture2D(texture,texMapping + vec2(earthMotion,0.0) + vec2( dX,-dY)) / 9.0 + + texture2D(texture,texMapping + vec2(earthMotion,0.0) + vec2( 0,-dY)) / 9.0 + + texture2D(texture,texMapping + vec2(earthMotion,0.0) + vec2(-dX,-dY)) / 9.0; +} + +void main() { + vec3 down = vec3( 0, -1, 0 ) ; + vec3 right = normalize(cross( trueNormal, down )) ; + down = normalize(cross( trueNormal, right ) ); + + /* Calculate the new normal using bump mapping */ + vec3 newNorm = calNormChange( texture, trueNormal, down, right ) ; + + /* Calculate the shadow casted by the clouds. Blur it a litte for + * realism */ + vec4 shadow = (texture2D(clouds, texMapping+vec2(cloudMotion-0.005,-0.005))+ + texture2D(clouds, texMapping+vec2(cloudMotion-0.01,-0.01))+ + texture2D(clouds, texMapping+vec2(cloudMotion-0.01,-0.005))+ + texture2D(clouds, texMapping+vec2(cloudMotion-0.005,-0.01))) / 8.0 ; + + /* The color of the clouds at the position */ + vec4 cloudsColor = texture2D(clouds, texMapping+vec2(cloudMotion,0.0)) ; + + /* Mix the colors of the earth in the summer and earth in the winter with + * as a function of the sin of the time */ + vec4 color = mix( + texture2D(earth, texMapping+vec2(earthMotion,0.0)), + texture2D(winter, texMapping+vec2(earthMotion,0.0)), (sin(time / 400.0) + 1.0) / 2.0 + /* Add the clouds an subtract the shadows */ + ) + cloudsColor - shadow ; + + /* Calulate the light intensity using the new norrmal */ + vec3 light = lighting(newNorm, light2) + vec3(0.05); + vec4 tmpcolor = vec4(color.x*light.x, color.y*light.y, color.z*light.z, 1.0); + + /* Get a couple of random values from the noise texture */ + vec4 cmp = texture2D(random, texMapping+vec2(earthMotion,0.0)) ; + vec4 cmp2 = texture2D(random, texMapping+vec2(earthMotion,0.1)) ; + + /* Get the texture for the city lights */ + vec4 cityLights = texture2D(lights, texMapping+vec2(earthMotion,0.0)) ; + + if ( pow(length(cmp),2) > pow(length(tmpcolor)*1.3,2) && length(cityLights) > 1.0) { + /* if the random value is larger than the current color and there is a light + * in this position, turn it on. This is to simulate lights in regions + * under the shadow of a cloud */ + tmpcolor += vec4(1.0,1.0,0.5,1.0) * cityLights ; + } + + if (0.1 > light.x) { + /* It is night time all overt the place, so include the night texture + * and subtract out the clouds. Mix between two reddish-yellow colors as + * a function of time to simulate twinkling */ + tmpcolor *= mix( + vec4(cmp.r*2.0,min(cmp.g,cmp.r)*1.5,min(cmp.b,cmp.r),1.0), + vec4(cmp2.r*2.0,min(cmp2.g,cmp2.r)*1.5,min(cmp2.b,cmp2.r),1.0), (sin(time*cmp2.a+cmp.a)+1.0)/2.0 ) ; + tmpcolor -= cloudsColor; + } + + /* Draw the atmosphere of the earth. The blue ring at the edge of the + * Earth*/ + float blue = max( + pow(1.0-dot(vec3(0,0,-1), normalize(trueNormal)),3.0), + 0.0); + tmpcolor += vec4(0.0,0.0,blue*length(light),0.0) ; + + /* Calculate the Sun's reflection off of the water on the Earth. + * Get a blurred sample from the earth to check for blue */ + vec4 sample = sampleBlur(earth); + + /* calculate the coefficient of the specular dot based on + * the amount of blue in the sample */ + float lightlen = pow(max(length(light)-0.8,0.0),5.0) * (sample.b/(sample.r+sample.g)) * (1-length(shadow)); + tmpcolor += vec4(0.3,0.2,0.15,0.0) * + max( + pow(dot(reflect(normalize(vec3(location) - light2), normalize(trueNormal)), + - normalize(vec3(location))),1.0) * + lightlen, 0.0) ; + frag_color = tmpcolor ; +} + + + |