varying vec3 N; varying vec3 v; uniform int nLights; uniform float scaling; uniform vec3 light_positions[8]; uniform vec4 light_colours_ambient[8]; uniform vec4 light_colours_specular[8]; uniform vec4 light_colours_diffuse[8]; varying vec4 E; varying vec4 theVert; varying float size; uniform bool shadowsOn; uniform int shadowQuality; uniform sampler2D ShadowMap; uniform float xPixelOffset; uniform float yPixelOffset; uniform bool ssaoOn; uniform sampler2D SSAOMap; uniform float screenWidth; uniform float screenHeight; float lookup(vec2 offSet, float zoffset) { vec4 theVert2 = theVert; vec4 tCoord = vec4(0.0,0.0,1.0,0.0); tCoord = gl_ModelViewMatrixInverse * (tCoord); theVert2 += zoffset*tCoord; theVert2.w = 1.0; vec4 shadowCoord = gl_TextureMatrix[2]*theVert2; vec4 coord = shadowCoord + vec4(offSet.x * xPixelOffset * shadowCoord.w, offSet.y * yPixelOffset * shadowCoord.w, 0.0005, 0.0); float depth = texture2D(ShadowMap, coord.xy ).z; float R = coord.p / coord.q; return (R <= depth) ? 1.0 : 0.0; } void main(void) { vec4 color = vec4(gl_Color); vec3 L; vec3 E2; vec3 R; vec4 Iamb =vec4(0.0,0.0,0.0,0.0); vec4 Idiff=vec4(0.0,0.0,0.0,0.0); vec4 Ispec=vec4(0.0,0.0,0.0,0.0); int i; float x = gl_TexCoord[0].x; float y = gl_TexCoord[0].y; float zz = 1.0 - x*x - y*y; float z = sqrt(zz); if(zz <= 0.06) discard; vec4 pos = E; pos.z += z*scaling*size; mat4 projMat = gl_ProjectionMatrix; pos = projMat * pos; gl_FragDepth = (pos.z / pos.w + 1.0) / 2.0; vec3 norm = vec3(x,y,z); E2 = normalize(-v); for (i = 0; i<8; i++) { if(i < nLights){ L = normalize(light_positions[i].xyz); R = normalize(-reflect(L,norm)); //calculate Ambient Term: Iamb += light_colours_ambient[i]; //calculate Diffuse Term: Idiff += light_colours_diffuse[i] * max(dot(norm,L), 0.0); // calculate Specular Term: if(gl_FrontFacing){ float y = max(max(light_colours_specular[i].r,light_colours_specular[i].g),light_colours_specular[i].b); Ispec += light_colours_specular[i] * pow(max(dot(R,E2),0.0),0.3*gl_FrontMaterial.shininess); Ispec.a *= y; } } } float shadow = 0.0; if(!shadowsOn){ shadow = 1.0; }else{ if(shadowQuality==0){ // Quick jaggy-shadows shadow += lookup(vec2(0,0),z*scaling*size); shadow += 0.2; }else if(shadowQuality==1){ // PCF soft-shadows if(shadowsOn){ float x,y; for (y = -1.5 ; y <=1.5 ; y+=1.0) for (x = -1.5 ; x <=1.5 ; x+=1.0) shadow += lookup(vec2(x*0.5,y*0.5),z*scaling*size); shadow /= 16.0 ; shadow += 0.2; } }else{ // PCF softer-shadows if(shadowsOn){ float x,y; for (y = -3.5 ; y <=3.5 ; y+=1.0) for (x = -3.5 ; x <=3.5 ; x+=1.0) shadow += lookup(vec2(x*0.5,y*0.5),z*scaling*size); shadow /= 64.0 ; shadow += 0.2; } } shadow = clamp(shadow,0.0,1.0); } float att=1.0; if(ssaoOn){ vec2 texCoord = vec2(gl_FragCoord.x/screenWidth, gl_FragCoord.y/screenHeight); att = texture2D(SSAOMap, texCoord).r; } color = (gl_FrontMaterial.emission + 1.5*color* Iamb + 1.2*color* Idiff*shadow*att); if(shadow>0.5) color += Ispec; float fogFactor = (gl_Fog.end - gl_FogFragCoord+z*scaling*size)*gl_Fog.scale; fogFactor = clamp(fogFactor,0.0,1.0); gl_FragColor = mix(gl_Fog.color, color, fogFactor ); }