varying vec4 ambientGlobal/*,ambientA[8],diffuseA[8]*/; varying vec4 pixelpos; uniform sampler2D tex; varying vec3 normal/*,lightDirA[8],halfVectorA[8]*/; /*varying float distA[8];*/ vec4 overlay_blend(vec4 base, vec4 blend) { vec4 lumCoeff = vec4(0.2125, 0.7154, 0.0721, 1.0); vec4 white = vec4(1.0, 1.0, 1.0, 1.0); vec4 result; float luminance = dot(base, lumCoeff); if (luminance < 0.45) result = 2.0 * blend * base; else if (luminance > 0.55) result = white - 2.0 * (white - blend) * (white - base); else { vec4 result1 = 2.0 * blend * base; vec4 result2 = white - 2.0 * (white - blend) * (white - base); result = mix(result1, result2, (luminance - 0.45) * 10.0); } return result; } vec4 process_lightsource(gl_LightSourceParameters light, vec4 incolor) { vec3 n,halfV,viewV,lightDir,halfVector; float NdotL,NdotHV,dist; vec4 color = vec4(0.0, 0.0, 0.0, 1.0); vec4 spec = vec4(0.0, 0.0, 0.0, 1.0); vec4 white = vec4(1.0, 1.0, 1.0, 1.0); float att; /* a fragment shader can't write a varying variable, hence we need a new variable to store the normalized interpolated normal */ n = normalize(normal); vec3 aux, ldir; vec4 d,a; if (light.position[3] == 1.0) { aux = vec3(light.position-pixelpos); ldir = normalize(aux); dist = length(aux); } else { ldir = normalize(vec3(light.position)); dist = 0.0; } halfVector = normalize(light.halfVector.xyz); /* Compute the diffuse, ambient and globalAmbient terms */ d = gl_FrontMaterial.diffuse * light.diffuse; /* The ambient terms have been separated since one of them */ /* suffers attenuation */ a = gl_FrontMaterial.ambient * light.ambient; /* compute the dot product between normal and normalized lightdir */ NdotL = dot(n,ldir); #define SHADOW_FUZZ 0.1 if (NdotL > 0.0) { NdotL = ((1.0 - SHADOW_FUZZ) * NdotL) + SHADOW_FUZZ; att = 1.0 / (light.constantAttenuation + light.linearAttenuation * dist + light.quadraticAttenuation * dist * dist); color = att * (d * NdotL + a); halfV = normalize(halfVector); NdotHV = max(dot(n,halfV),0.0); //spec = att * gl_FrontMaterial.specular * light.specular * pow(NdotHV,gl_FrontMaterial.shininess); spec = att * white * light.specular * pow(NdotHV,10.0); } else if (NdotL > (-1.0 * SHADOW_FUZZ)) { float fraction; NdotL = (NdotL+SHADOW_FUZZ); fraction = NdotL / SHADOW_FUZZ; att = 1.0 / (light.constantAttenuation + light.linearAttenuation * dist + light.quadraticAttenuation * dist * dist); color = att * fraction * (d * NdotL + a); halfV = normalize(halfVector); NdotHV = max(dot(n,halfV),0.0); //spec = att * fraction * gl_FrontMaterial.specular * light.specular * pow(NdotHV,gl_FrontMaterial.shininess); spec = att * white * light.specular * pow(NdotHV,10.0); } // blend mode SCREEN color = white - ((white - color) * (white - incolor)); // blend mode AVG //color = (color + incolor) * 0.5; // blend mode LIGHTEN //color = max(color, incolor); // blend mode OVERLAY //color = overlay_blend(incolor, color); // blend mode DODGE //color = incolor / (white - color); // blend mode MULTIPLY //color = color * incolor; color += clamp(spec, 0.0, 1.0); return clamp(color, 0.0, 1.0); } void main() { vec4 color = ambientGlobal; vec4 white = vec4(1.0, 1.0, 1.0, 1.0); //color = white; color = process_lightsource(gl_LightSource[0], color); color = process_lightsource(gl_LightSource[1], color); color = process_lightsource(gl_LightSource[2], color); color = process_lightsource(gl_LightSource[3], color); color = process_lightsource(gl_LightSource[4], color); color = process_lightsource(gl_LightSource[5], color); color = process_lightsource(gl_LightSource[6], color); color = process_lightsource(gl_LightSource[7], color); vec4 texcolor = texture2D(tex, gl_TexCoord[0].st); gl_FragColor = clamp(texcolor * color, 0.0, 1.0); // gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); }