overte-AleziaKurdis/libraries/render-utils/src/GlobalLight.slh
2019-07-10 23:52:50 -07:00

290 lines
10 KiB
Text

<!
// GlobalLight.slh
// libraries/render-utils/src
//
// Created by Sam Gateau on 2/5/15.
// Copyright 2013 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
!>
<@if not GLOBAL_LIGHT_SLH@>
<@def GLOBAL_LIGHT_SLH@>
<@include graphics/Light.slh@>
<@include LightingModel.slh@>
<$declareLightBuffer()$>
<$declareLightAmbientBuffer()$>
<@include LightAmbient.slh@>
<@include LightDirectional.slh@>
<@func fetchGlobalLight()@>
// Get light
Light light = getKeyLight();
LightAmbient lightAmbient = getLightAmbient();
vec3 lightDirection = getLightDirection(light);
vec3 lightIrradiance = getLightIrradiance(light);
vec3 color = vec3(0.0);
<@endfunc@>
<@func prepareGlobalLight(positionES, normalWS)@>
// prepareGlobalLight
// Transform directions to worldspace
vec3 fragNormalWS = vec3(<$normalWS$>);
vec3 fragPositionWS = vec3(invViewMat * vec4(<$positionES$>, 1.0));
vec3 fragEyeVectorWS = invViewMat[3].xyz - fragPositionWS;
vec3 fragEyeDirWS = normalize(fragEyeVectorWS);
<$fetchGlobalLight()$>
<@endfunc@>
<@func declareEvalAmbientGlobalColor()@>
vec3 evalAmbientGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, vec3 fresnel, float metallic, float roughness) {
<$prepareGlobalLight(position, normal)$>
color += albedo * getLightColor(light) * obscurance * getLightAmbientIntensity(lightAmbient);
return color;
}
<@endfunc@>
<@func declareEvalAmbientSphereGlobalColor(supportScattering)@>
<$declareLightingAmbient(1, _SCRIBE_NULL, _SCRIBE_NULL, $supportScattering$)$>
<$declareLightingDirectional($supportScattering$)$>
<@if supportScattering@>
<$declareDeferredCurvature()$>
<@endif@>
vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal,
vec3 albedo, vec3 fresnel, float metallic, float roughness
<@if supportScattering@>
, float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature
<@endif@>
) {
<$prepareGlobalLight(position, normal)$>
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragEyeDirWS);
// Ambient
vec3 ambientDiffuse;
vec3 ambientSpecular;
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surfaceWS, metallic, fresnel, albedo, obscurance
<@if supportScattering@>
, scattering, midNormalCurvature, lowNormalCurvature
<@endif@>
);
color += ambientDiffuse;
color += ambientSpecular;
// Directional
vec3 directionalDiffuse;
vec3 directionalSpecular;
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surfaceWS, metallic, fresnel, albedo, shadowAttenuation
<@if supportScattering@>
, scattering, midNormalCurvature, lowNormalCurvature
<@endif@>
);
color += directionalDiffuse;
color += directionalSpecular;
return color;
}
<@endfunc@>
<@include graphics/Haze.slh@>
<@func declareEvalSkyboxGlobalColor(supportScattering, computeHaze)@>
<$declareLightingAmbient(_SCRIBE_NULL, 1, _SCRIBE_NULL, $supportScattering$)$>
<$declareLightingDirectional($supportScattering$)$>
<@if supportScattering@>
<$declareDeferredCurvature()$>
<@endif@>
vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 positionES, vec3 normalWS,
vec3 albedo, vec3 fresnel, float metallic, float roughness
<@if supportScattering@>
, float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature
<@endif@>
) {
<$prepareGlobalLight(positionES, normalWS)$>
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragEyeDirWS);
// Ambient
vec3 ambientDiffuse;
vec3 ambientSpecular;
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surfaceWS, metallic, fresnel, albedo, obscurance
<@if supportScattering@>
, scattering, midNormalCurvature, lowNormalCurvature
<@endif@>
);
color += ambientDiffuse;
color += ambientSpecular;
// Directional
vec3 directionalDiffuse;
vec3 directionalSpecular;
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surfaceWS, metallic, fresnel, albedo, shadowAttenuation
<@if supportScattering@>
, scattering, midNormalCurvature, lowNormalCurvature
<@endif@>
);
color += directionalDiffuse;
color += directionalSpecular;
// Haze
if (isHazeEnabled() > 0.0) {
if ((hazeParams.hazeMode & HAZE_MODE_IS_KEYLIGHT_ATTENUATED) == HAZE_MODE_IS_KEYLIGHT_ATTENUATED) {
color = computeHazeColorKeyLightAttenuation(color, lightDirection, fragPositionWS);
}
<@if computeHaze@>
if ((hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE) {
vec4 hazeColor = computeHazeColor(
positionES, // fragment position in eye coordinates
fragPositionWS, // fragment position in world coordinates
invViewMat[3].xyz, // eye position in world coordinates
lightDirection // keylight direction vector in world coordinates
);
color = mix(color.rgb, hazeColor.rgb, hazeColor.a);
}
<@endif@>
}
return color;
}
<@endfunc@>
<@func declareEvalLightmappedColor()@>
vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 normal, vec3 albedo, vec3 lightmap) {
Light light = getKeyLight();
LightAmbient ambient = getLightAmbient();
// Catch normals perpendicular to the projection plane, hence the magic number for the threshold
// It should be just 0, but we have inaccuracy so we overshoot
const float PERPENDICULAR_THRESHOLD = -0.005;
vec3 fragNormal = vec3(invViewMat * vec4(normal, 0.0)); // transform to worldspace
float diffuseDot = dot(fragNormal, -getLightDirection(light));
float facingLight = step(PERPENDICULAR_THRESHOLD, diffuseDot);
// Reevaluate the shadow attenuation for light facing fragments
float lightAttenuation = (1.0 - facingLight) + facingLight * shadowAttenuation;
// Diffuse light is the lightmap dimmed by shadow
vec3 diffuseLight = lightAttenuation * lightmap;
// Ambient light is the lightmap when in shadow
vec3 ambientLight = (1.0 - lightAttenuation) * lightmap * getLightAmbientIntensity(ambient);
return isLightmapEnabled() * obscurance * albedo * (diffuseLight + ambientLight);
}
<@endfunc@>
<@func declareEvalGlobalLightingAlphaBlended()@>
<$declareLightingAmbient(1, 1, 1)$>
<$declareLightingDirectional()$>
vec3 evalGlobalLightingAlphaBlended(
mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 positionES, vec3 normalWS,
vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity)
{
<$prepareGlobalLight(positionES, normalWS)$>
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragEyeDirWS);
color += emissive * isEmissiveEnabled();
// Ambient
vec3 ambientDiffuse;
vec3 ambientSpecular;
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surfaceWS, metallic, fresnel, albedo, obscurance);
color += ambientDiffuse;
// Directional
vec3 directionalDiffuse;
vec3 directionalSpecular;
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surfaceWS, metallic, fresnel, albedo, shadowAttenuation);
color += directionalDiffuse;
color += evalSpecularWithOpacity(ambientSpecular + directionalSpecular, opacity);
// Haze
if (isHazeEnabled() > 0.0) {
if ((hazeParams.hazeMode & HAZE_MODE_IS_KEYLIGHT_ATTENUATED) == HAZE_MODE_IS_KEYLIGHT_ATTENUATED) {
color = computeHazeColorKeyLightAttenuation(color, lightDirection, fragPositionWS);
}
if ((hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE) {
vec4 hazeColor = computeHazeColor(
positionES, // fragment position in eye coordinates
fragPositionWS, // fragment position in world coordinates
invViewMat[3].xyz, // eye position in world coordinates
lightDirection // keylight direction vector in world coordinates
);
color = mix(color.rgb, hazeColor.rgb, hazeColor.a);
}
}
return color;
}
vec3 evalGlobalLightingAlphaBlended(
mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 positionES, vec3 normalWS,
vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, SurfaceData surface, float opacity, vec3 prevLighting)
{
<$fetchGlobalLight()$>
color = prevLighting;
color += emissive * isEmissiveEnabled();
// Ambient
vec3 ambientDiffuse;
vec3 ambientSpecular;
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance);
// Directional
vec3 directionalDiffuse;
vec3 directionalSpecular;
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation);
color += ambientDiffuse + directionalDiffuse;
color += evalSpecularWithOpacity(ambientSpecular + directionalSpecular, opacity);
// Haze
if (isHazeEnabled() > 0.0) {
vec3 fragPositionWS = vec3(invViewMat * vec4(positionES, 1.0));
if ((hazeParams.hazeMode & HAZE_MODE_IS_KEYLIGHT_ATTENUATED) == HAZE_MODE_IS_KEYLIGHT_ATTENUATED) {
color = computeHazeColorKeyLightAttenuation(color, lightDirection, fragPositionWS);
}
if ((hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE) {
vec4 hazeColor = computeHazeColor(
positionES, // fragment position in eye coordinates
fragPositionWS, // fragment position in world coordinates
invViewMat[3].xyz, // eye position in world coordinates
lightDirection // keylight direction vector in world coordinates
);
color = mix(color.rgb, hazeColor.rgb, hazeColor.a);
}
}
return color;
}
<@endfunc@>
<@endif@>