- uniform sampler2D normalTex;
- uniform sampler2D positionTex;
- uniform sampler2D diffuseTex;
- uniform vec4 lightColor;
- uniform float shininess;
- uniform vec3 lightPos;
- uniform float lightRadius;
- uniform float lightFalloff;
- uniform vec2 invViewport;
- const int MATERIALFLAG_NOLIGHT = 1;
- // Decodes normal from 0_1 to -1_1
- vec3 decodeNormal(vec3 n) {
- return vec3((2.0 * n) - 1.0);
- }
- void main (void)
- {
- vec2 texcoord = vec2(gl_FragCoord.x * invViewport.x, gl_FragCoord.y * invViewport.y);
- vec4 pos = texture2D(positionTex, texcoord);
- // Skip no lighting fragments
- int materialValue = int(pos.w);
- if ((materialValue & MATERIALFLAG_NOLIGHT) == MATERIALFLAG_NOLIGHT) {
- discard;
- }
- // Skip non-geometry fragments
- vec3 vertex = pos.xyz;
- if (vertex.x < -9999.0) {
- discard;
- }
- vec3 normal = decodeNormal(texture2D(normalTex, texcoord).xyz);
- vec3 lightDir = lightPos - pos.xyz;
- float distance = length(lightDir);
- float attenuation = clamp(1.0 - distance / lightRadius, 0.0, 1.0);
- float diffuse = dot(lightDir / distance, normal);
- float specular = 0.0;
- if (diffuse > 0.0 && shininess > 0.0) {
- vec3 posEye = -pos.xyz;
- vec3 viewEye = normalize(-posEye);
- vec3 halfVec = normalize(lightDir + viewEye);
- specular = pow(max(0.0, dot(normal, halfVec)), shininess);
- }
- gl_FragData[3] = (vec4(lightColor.xyz, 1.0) * (diffuse + specular) * attenuation) * lightColor.w;
- }