UFO: Alien Invasion
geoscape_fs.glsl
Go to the documentation of this file.
1 /**
2  * @file
3  * @brief Geoscape fragment shader.
4  */
5 
6 #if r_postprocess
7  /*
8  * Indicates that gl_FragData is written to, not gl_FragColor.
9  * #extension needs to be placed before all non preprocessor code.
10  */
11  #extension GL_ARB_draw_buffers : enable
12 #endif
13 
14 in_qualifier vec2 tex;
15 
16 in_qualifier vec4 ambientLight;
17 in_qualifier vec4 diffuseLight;
18 in_qualifier vec4 specularLight;
19 in_qualifier vec4 diffuseLight2;
20 
21 in_qualifier vec3 lightVec;
22 in_qualifier vec3 lightVec2;
23 in_qualifier vec3 eyeVec;
24 
25 #ifndef glsl110
26  #if r_postprocess
27  /** After glsl1110 this need to be explicitly declared; used by fixed functionality at the end of the OpenGL pipeline.*/
28  out vec4 gl_FragData[2];
29  #else
30  /** After glsl1110 this need to be explicitly declared; used by fixed functionality at the end of the OpenGL pipeline.*/
31  out vec4 gl_FragColor;
32  #endif
33 #endif
34 
35 /** Diffuse.*/
36 uniform sampler2D SAMPLER_DIFFUSE;
37 /** Blend.*/
38 uniform sampler2D SAMPLER_BLEND;
39 /** Normalmap.*/
40 uniform sampler2D SAMPLER_NORMALMAP;
41 
42 uniform float BLENDSCALE;
43 uniform float GLOWSCALE;
44 uniform vec4 DEFAULTCOLOR;
45 uniform vec4 CITYLIGHTCOLOR;
46 
47 const float specularExp = 32.0;
48 
49 /* index of refraction for water */
50 const float n1 = 1.0;
51 const float n2 = 1.333;
52 const float eta = n1 / n2;
53 
54 /**
55  * @brief Calculate reflection component of Frenel's equations.
56  */
57 float fresnelReflect(in float cos_a) {
58  float cos_b = sqrt(1.0 - ((eta * eta) * ( 1.0 - (cos_a * cos_a))));
59  float rs = (n1 * cos_a - n2 * cos_b ) / (n1 * cos_a + n2 * cos_b);
60  float rp = (n1 * cos_b - n2 * cos_a ) / (n1 * cos_b + n2 * cos_a);
61  return ((rs * rs + rp * rp) / 2.0);
62 }
63 
64 
65 void main(void) {
66  /* blend textures smoothly */
67  vec3 diffuseColorA = texture2D(SAMPLER_DIFFUSE, tex).rgb;
68  vec3 diffuseColorB = texture2D(SAMPLER_BLEND, tex).rgb;
69  vec4 diffuseColor;
70  diffuseColor.rgb = ((1.0 - BLENDSCALE) * diffuseColorA) + (BLENDSCALE * diffuseColorB);
71  diffuseColor.a = 1.0;
72 
73  /* calculate diffuse reflections */
74  vec3 V = normalize(eyeVec);
75  vec3 L = normalize(lightVec);
76  vec3 N = normalize(texture2D(SAMPLER_NORMALMAP, tex).rgb * 2.0 - 1.0);
77  float NdotL = clamp(dot(N, L), 0.0, 1.0);
78  vec4 reflectColor = diffuseColor * diffuseLight * NdotL;
79 
80  /* calculate specular reflections */
81  float RdotL = clamp(dot(reflect(-L, N), V), 0.0, 1.0);
82  float gloss = texture2D(SAMPLER_NORMALMAP, tex).a;
83  /* NOTE: this "d" here is a hack to compensate for the fact
84  * that we're using orthographic projection.
85  */
86  float d = clamp(pow(1.0 + dot(V, L), 0.4), 0.0, 1.0);
87  float fresnel = 2.0 * fresnelReflect(NdotL);
88  vec4 specularColor = (d * d * fresnel * fresnel) * gloss * pow(RdotL, specularExp) * specularLight;
89 
90  /* calculate night illumination */
91  float diffuseNightColor = texture2D(SAMPLER_DIFFUSE, tex).a;
92  float NdotL2 = clamp(dot(N, normalize(lightVec2)), 0.0, 1.0);
93  vec4 nightColor = diffuseLight2 * CITYLIGHTCOLOR * diffuseNightColor * NdotL2;
94 
95  vec4 color = DEFAULTCOLOR + (ambientLight * diffuseColor) + reflectColor + (0.0 * specularColor) + nightColor;
96  vec4 hdrColor = GLOWSCALE *
97  ( clamp((reflectColor - vec4(0.9, 0.9, 0.9, 0)), 0.0, GLOWSCALE) +
98  1.0 * specularColor + nightColor);
99  hdrColor.a = 1.0;
100 
101  /* calculate final color */
102 #if r_postprocess
103  gl_FragData[0] = color;
104  gl_FragData[1] = hdrColor;
105 #else
106  gl_FragColor.rgb = color.rgb + hdrColor.rgb;
107  gl_FragColor.a = color.a;
108 #endif
109 }