3 * @brief Geoscape fragment shader.
8 * Indicates that gl_FragData is written to, not gl_FragColor.
9 * #extension needs to be placed before all non preprocessor code.
11 #extension GL_ARB_draw_buffers : enable
16in_qualifier vec4 ambientLight;
17in_qualifier vec4 diffuseLight;
18in_qualifier vec4 specularLight;
19in_qualifier vec4 diffuseLight2;
21in_qualifier vec3 lightVec;
22in_qualifier vec3 lightVec2;
23in_qualifier vec3 eyeVec;
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];
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;
36uniform sampler2D SAMPLER_DIFFUSE;
38uniform sampler2D SAMPLER_BLEND;
40uniform sampler2D SAMPLER_NORMALMAP;
42uniform float BLENDSCALE;
43uniform float GLOWSCALE;
44uniform vec4 DEFAULTCOLOR;
45uniform vec4 CITYLIGHTCOLOR;
47const float specularExp = 32.0;
49/* index of refraction for water */
51const float n2 = 1.333;
52const float eta = n1 / n2;
55 * @brief Calculate reflection component of Frenel's equations.
57float 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);
66 /* blend textures smoothly */
67 vec3 diffuseColorA = texture2D(SAMPLER_DIFFUSE, tex).rgb;
68 vec3 diffuseColorB = texture2D(SAMPLER_BLEND, tex).rgb;
70 diffuseColor.rgb = ((1.0 - BLENDSCALE) * diffuseColorA) + (BLENDSCALE * diffuseColorB);
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;
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.
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;
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;
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);
101 /* calculate final color */
103 gl_FragData[0] = color;
104 gl_FragData[1] = hdrColor;
106 gl_FragColor.rgb = color.rgb + hdrColor.rgb;
107 gl_FragColor.a = color.a;