<@include Config.slh@> <$VERSION_HEADER$> // Generated on <$_SCRIBE_DATE$> // // spot_light.frag // fragment shader // // Created by Andrzej Kapolka on 9/18/14. // Copyright 2014 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // // Everything about deferred buffer <@include DeferredBuffer.slh@> // Everything about light <@include Light.slh@> // The view Matrix uniform mat4 invViewMat; void main(void) { // get the depth and exit early if it doesn't pass the test vec2 texCoord = gl_TexCoord[0].st / gl_TexCoord[0].q; DeferredFragment frag = unpackDeferredFragment(texCoord); // Kill if in front of the light volume float depth = frag.depthVal; if (depth < gl_FragCoord.z) { discard; } // Need the light now Light light = getLight(); // Make the Light vector going from fragment to light center in world space vec4 wPos; wPos = invViewMat * frag.position; vec3 lightVector = wPos.xyz - getLightPosition(light); // Kill if too far from the light center if (dot(lightVector, lightVector) > getLightSquareRadius(light)) { discard; } // Allright we re valid in the volume float lightDistance = length(lightVector); float lightAttenuation = evalLightAttenuation(light, lightDistance); vec3 lightDir = lightVector / lightDistance; gl_FragColor = vec4(getLightColor(light), 0.0); // Kill if not in the spot light (ah ah !) vec3 lightSpotDir = getLightDirection(light); float cosSpotAngle = max(-dot(lightDir, lightSpotDir), 0.0); if (cosSpotAngle < getLightSpotAngleCos(light)) { // discard; gl_FragColor = vec4(vec3(1.0, 0.0, 0.0), 0.0); } /* vec4 wNor = invViewMat * vec4(frag.normal, 0.0); vec4 wEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0); vec3 eyeDir = normalize(wEyeVector.xyz); vec3 wHalfDir = normalize(eyeDir + lightDir); // Diffuse Lighting float diffuseDot = dot(wNor.xyz, lightDir); float facingLight = step(0.0, diffuseDot); vec3 diffuseColor = frag.diffuse * diffuseDot * facingLight; // compute the specular multiplier (sans exponent) float specularPower = facingLight * max(0.0, dot(eyeDir, wHalfDir)); vec3 specularColor = pow(specularPower, frag.gloss * 128.0) * frag.specular; // add specular contribution /* float ring = (lightAttenuation / (0.2 * getLightAttenuationCutoff(light))) - 1; if (ring < 1) { gl_FragColor = vec4(ring * ring * getLightColor(light), 0.0); } else { gl_FragColor = vec4((diffuseColor + specularColor) * lightAttenuation * getLightColor(light) * getLightIntensity(light), 0.0); }*/ } /* float attenuation = step(lightDistance, radius) * step(gl_LightSource[1].spotCosCutoff, cosSpotAngle) * pow(cosSpotAngle, gl_LightSource[1].spotExponent) / dot(vec3(gl_LightSource[1].constantAttenuation, gl_LightSource[1].linearAttenuation, gl_LightSource[1].quadraticAttenuation), vec3(1.0, lightDistance, lightDistance * lightDistance)); float lightAttenuation = evalLightAttenuation(light, lightDistance); vec4 wNor = invViewMat * vec4(frag.normal, 0.0); vec4 wEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0); vec3 eyeDir = normalize(wEyeVector.xyz); vec3 wHalfDir = normalize(eyeDir + lightDir); // Diffuse Lighting float diffuseDot = dot(wNor.xyz, lightDir); float facingLight = step(0.0, diffuseDot); vec3 diffuseColor = frag.diffuse * diffuseDot * facingLight; // compute the specular multiplier (sans exponent) float specularPower = facingLight * max(0.0, dot(eyeDir, wHalfDir)); vec3 specularColor = pow(specularPower, frag.gloss * 128.0) * frag.specular; // add specular contribution gl_FragColor = vec4((diffuseColor + specularColor) * lightAttenuation * getLightColor(light) * getLightIntensity(light), 0.0); */ // gl_FragColor = vec4(frag.normal, 0.0); //} /* // the radius (hard cutoff) of the light effect uniform float radius; void main(void) { vec2 texCoord = gl_TexCoord[0].st / gl_TexCoord[0].q; DeferredFragment frag = unpackDeferredFragment(texCoord); // get the depth and exit early if it doesn't pass the test float depth = frag.depthVal; if (depth < gl_FragCoord.z) { discard; } // compute the view space position using the depth float z = near / (depth * depthScale - 1.0); vec4 position = vec4((depthTexCoordOffset + texCoord * depthTexCoordScale) * z, z, 1.0); // get the normal from the map vec4 normal = texture2D(normalMap, texCoord); vec4 normalizedNormal = normalize(normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0)); // compute the base color based on OpenGL lighting model vec4 lightVector = gl_LightSource[1].position - position; float lightDistance = length(lightVector); lightVector = lightVector / lightDistance; float diffuse = dot(normalizedNormal, lightVector); float facingLight = step(0.0, diffuse); vec4 baseColor = texture2D(diffuseMap, texCoord) * (gl_FrontLightProduct[1].ambient + gl_FrontLightProduct[1].diffuse * (diffuse * facingLight)); // compute attenuation based on spot angle, distance, etc. float cosSpotAngle = max(-dot(lightVector.xyz, gl_LightSource[1].spotDirection), 0.0); float attenuation = step(lightDistance, radius) * step(gl_LightSource[1].spotCosCutoff, cosSpotAngle) * pow(cosSpotAngle, gl_LightSource[1].spotExponent) / dot(vec3(gl_LightSource[1].constantAttenuation, gl_LightSource[1].linearAttenuation, gl_LightSource[1].quadraticAttenuation), vec3(1.0, lightDistance, lightDistance * lightDistance)); // add base to specular, modulate by attenuation float specular = facingLight * max(0.0, dot(normalize(lightVector - normalize(vec4(position.xyz, 0.0))), normalizedNormal)); vec4 specularColor = texture2D(specularMap, texCoord); gl_FragColor = vec4((baseColor.rgb + pow(specular, specularColor.a * 128.0) * specularColor.rgb) * attenuation, 0.0); gl_FragColor = vec4(frag.normal, 0.0); } */