<@include gpu/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 DeferredBufferRead.slh@> //Everything about deferred lighting <@include DeferredLighting.slh@> // Everything about light <@include model/Light.slh@> in vec4 _texCoord0; out vec4 _fragColor; void main(void) { DeferredTransform deferredTransform = getDeferredTransform(); // Grab the fragment data from the uv vec2 texCoord = _texCoord0.st / _texCoord0.q; DeferredFragment frag = unpackDeferredFragment(deferredTransform, texCoord); if (frag.mode == FRAG_MODE_UNLIT) { discard; } mat4 invViewMat = deferredTransform.viewInverse; // 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 fragPos = invViewMat * frag.position; vec3 fragLightVec = getLightPosition(light) - fragPos.xyz; // Kill if too far from the light center if (dot(fragLightVec, fragLightVec) > getLightCutoffSquareRadius(light)) { discard; } // Allright we re valid in the volume float fragLightDistance = length(fragLightVec); vec3 fragLightDir = fragLightVec / fragLightDistance; // Kill if not in the spot light (ah ah !) vec3 lightSpotDir = getLightDirection(light); float cosSpotAngle = max(-dot(fragLightDir, lightSpotDir), 0.0); if (cosSpotAngle < getLightSpotAngleCos(light)) { discard; } // Eval shading vec3 fragNormal = vec3(frag.normal); vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0); vec3 fragEyeDir = normalize(fragEyeVector.xyz); vec4 shading = evalFragShading(fragNormal, fragLightDir, fragEyeDir, frag.metallic, frag.specular, frag.roughness); // Eval attenuation float radialAttenuation = evalLightAttenuation(light, fragLightDistance); float angularAttenuation = evalLightSpotAttenuation(light, cosSpotAngle); // Final Lighting color vec3 fragColor = (shading.w * frag.diffuse + shading.xyz); _fragColor = vec4(fragColor * angularAttenuation * radialAttenuation * getLightColor(light) * getLightIntensity(light) * frag.obscurance, 0.0); if (getLightShowContour(light) > 0.0) { // Show edges float edgeDistR = (getLightRadius(light) - fragLightDistance); float edgeDistS = dot(fragLightDistance * vec2(cosSpotAngle, sqrt(1.0 - cosSpotAngle * cosSpotAngle)), -getLightSpotOutsideNormal2(light)); float edgeDist = min(edgeDistR, edgeDistS); float edge = abs(2.0 * (edgeDist / (0.1)) - 1.0); if (edge < 1) { float edgeCoord = exp2(-8.0*edge*edge); _fragColor = vec4(edgeCoord * edgeCoord * getLightColor(light), 0.0); } } }