3 * @brief Medium quality battlescape 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
15 uniform int SPECULARMAP;
16 /*uniform float SPECULAR; specular exponent divided by 512 */
17 /*uniform float HARDNESS; specular component brightness (0 - no specular) */
20 /** Diffuse texture.*/
21 uniform sampler2D SAMPLER_DIFFUSE;
23 uniform sampler2D SAMPLER_SPECULAR;
25 uniform sampler2D SAMPLER_LIGHTMAP;
27 uniform sampler2D SAMPLER_DELUXEMAP;
29 uniform sampler2D SAMPLER_NORMALMAP;
31 #define R_DYNAMIC_LIGHTS #replace r_dynamic_lights
33 in_qualifier vec3 lightDirs[R_DYNAMIC_LIGHTS];
34 uniform vec4 LIGHTPARAMS[R_DYNAMIC_LIGHTS];
37 #include "light_fs.glsl"
38 #include "bump_fs.glsl"
39 #include "fog_fs.glsl"
40 #include "world_devtools_fs.glsl"
41 #include "write_fragment_fs.glsl"
43 in_qualifier vec4 blendColor;
49 vec4 finalColor = vec4(0.0);
50 vec3 light = vec3(0.0);
53 /* normalmap should be declared in this scope for developer tools to work */
54 vec4 normalmap = vec4(0.0, 0.0, 1.0, 0.5);
55 vec4 specularmap = vec4(HARDNESS, HARDNESS, HARDNESS, SPECULAR);
57 vec2 offset = vec2(0.0);
59 /* lightmap contains pre-computed incoming light color */
60 light = texture2D(SAMPLER_LIGHTMAP, gl_TexCoord[1].st).rgb;
62 /* deluxemap contains pre-computed incoming light vectors in object tangent space */
63 deluxemap = texture2D(SAMPLER_DELUXEMAP, gl_TexCoord[1].st).rgb;
64 deluxemap = normalize(deluxemap * 2.0 - 1.0);
68 /* Sample normalmap.*/
69 normalmap = texture2D(SAMPLER_NORMALMAP, gl_TexCoord[0].st);
70 normalmap.rgb = normalize(normalmap.rgb * 2.0 - 1.0);
72 /* Resolve parallax offset */
73 offset = BumpTexcoord(normalmap.a);
77 /* Modulate incoming light by cos(angle_of_incidence); should be done even bump mapping is disabled, to avoid having flat shading as a result.*/
78 light *= clamp(dot(deluxemap, vec3(normalmap.x * BUMP, normalmap.y * BUMP, normalmap.z)), 0.0, 1.0);
80 /* Sample the diffuse texture, honoring the parallax offset.*/
81 vec4 diffusemap = texture2D(SAMPLER_DIFFUSE, gl_TexCoord[0].st + offset);
83 /* Sample specularity map, if any */
84 if (SPECULARMAP > 0) {
85 specularmap = texture2D(SAMPLER_SPECULAR, gl_TexCoord[0].st + offset);
88 /* Calculate specular component via Phong model */
89 vec3 V = reflect(-normalize(eyedir), normalmap.rgb);
90 float LdotV = dot(V, deluxemap);
91 specular = clamp(light - AMBIENT, 0.0, 1.0) * specularmap.rgb * pow(max(LdotV, 0.0), specularmap.a * 512.0);
93 /* Calculate dynamic lights (if any) */
94 light = clamp(light + LightFragment(normalmap.rgb), 0.0, 2.0);
96 finalColor.rgb = diffusemap.rgb * light + specular;
97 finalColor.a = diffusemap.a;
99 finalColor *= blendColor;
103 finalColor = FogFragment(finalColor);
106 /* Developer tools, if enabled */
107 finalColor = ApplyDeveloperTools(finalColor, normalmap.rgb, light, deluxemap);
109 writeFragment(finalColor);