aboutsummaryrefslogtreecommitdiff
path: root/shaders/textured.frag
blob: 0ba7c48f17c8e10967edeb848f3a61dc112719cb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
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(2.0,2.0,2.0,2.0), sin(time/10.0+cmp.a*27.3) ) ;
        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 ;
}