mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-06-17 16:08:49 +02:00
290 lines
10 KiB
Text
290 lines
10 KiB
Text
<!
|
|
// DeferredGlobalLight.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 DEFERRED_GLOBAL_LIGHT_SLH@>
|
|
<@def DEFERRED_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 Haze.slh@>
|
|
|
|
<@func declareEvalSkyboxGlobalColor(supportScattering)@>
|
|
|
|
<$declareLightingAmbient(_SCRIBE_NULL, 1, _SCRIBE_NULL, $supportScattering$)$>
|
|
<$declareLightingDirectional($supportScattering$)$>
|
|
|
|
<@if supportScattering@>
|
|
<$declareDeferredCurvature()$>
|
|
<@endif@>
|
|
|
|
vec3 evalSkyboxGlobalColor(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;
|
|
|
|
vec3 directionalDiffuse;
|
|
vec3 directionalSpecular;
|
|
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surfaceWS, metallic, fresnel, albedo, shadowAttenuation
|
|
<@if supportScattering@>
|
|
,scattering, midNormalCurvature, lowNormalCurvature
|
|
<@endif@>
|
|
);
|
|
color += directionalDiffuse;
|
|
color += directionalSpecular;
|
|
|
|
// Attenuate the light if haze effect selected
|
|
if ((isHazeEnabled() > 0.0) && (hazeParams.hazeMode & HAZE_MODE_IS_KEYLIGHT_ATTENUATED) == HAZE_MODE_IS_KEYLIGHT_ATTENUATED) {
|
|
color = computeHazeColorKeyLightAttenuation(color, lightDirection, fragPositionWS);
|
|
}
|
|
|
|
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 position, vec3 normal, vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity, vec3 prevLighting) {
|
|
<$prepareGlobalLight(position, normal)$>
|
|
|
|
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragEyeDirWS);
|
|
|
|
color = prevLighting;
|
|
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);
|
|
|
|
return color;
|
|
}
|
|
<@endfunc@>
|
|
|
|
<@func declareEvalGlobalLightingAlphaBlendedWithHaze()@>
|
|
|
|
<$declareLightingAmbient(1, 1, 1)$>
|
|
<$declareLightingDirectional()$>
|
|
|
|
vec3 evalGlobalLightingAlphaBlendedWithHaze(
|
|
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) && (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 evalGlobalLightingAlphaBlendedWithHaze(
|
|
mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 positionES, vec3 positionWS,
|
|
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) && (hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE) {
|
|
vec4 hazeColor = computeHazeColor(
|
|
positionES, // fragment position in eye coordinates
|
|
positionWS, // fragment position in world coordinates
|
|
invViewMat[3].xyz, // eye position in world coordinates
|
|
lightDirection // keylight direction vector
|
|
);
|
|
|
|
color = mix(color.rgb, hazeColor.rgb, hazeColor.a);
|
|
}
|
|
|
|
return color;
|
|
}
|
|
<@endfunc@>
|
|
|
|
|
|
<@endif@>
|