mirror of
https://github.com/overte-org/overte.git
synced 2025-08-14 02:26:51 +02:00
96 lines
3.1 KiB
Text
96 lines
3.1 KiB
Text
<@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);
|
|
}
|
|
}
|
|
}
|
|
|