mirror of
https://github.com/overte-org/overte.git
synced 2025-07-09 20:00:28 +02:00
163 lines
5.7 KiB
Text
Executable file
163 lines
5.7 KiB
Text
Executable file
<!
|
|
// 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 DeferredLighting.slh@>
|
|
|
|
<@func declareSkyboxMap()@>
|
|
|
|
uniform samplerCube skyboxMap;
|
|
|
|
vec4 evalSkyboxLight(vec3 direction, float lod) {
|
|
// FIXME
|
|
//vec4 skytexel = textureLod(skyboxMap, direction, lod * textureQueryLevels(skyboxMap));
|
|
vec4 skytexel = texture(skyboxMap, direction);
|
|
return skytexel;
|
|
}
|
|
|
|
<@endfunc@>
|
|
|
|
<@func declareSphericalHarmonics()@>
|
|
struct SphericalHarmonics {
|
|
vec4 L00;
|
|
vec4 L1m1;
|
|
vec4 L10;
|
|
vec4 L11;
|
|
vec4 L2m2;
|
|
vec4 L2m1;
|
|
vec4 L20;
|
|
vec4 L21;
|
|
vec4 L22;
|
|
};
|
|
|
|
vec4 evalSphericalLight(SphericalHarmonics sh, vec3 direction ) {
|
|
|
|
vec3 dir = direction.xzy; // we don;t understand why yet but we need to use z as vertical axis?
|
|
|
|
const float C1 = 0.429043;
|
|
const float C2 = 0.511664;
|
|
const float C3 = 0.743125;
|
|
const float C4 = 0.886227;
|
|
const float C5 = 0.247708;
|
|
|
|
vec4 value = C1 * sh.L22 * (dir.x * dir.x - dir.y * dir.y) +
|
|
C3 * sh.L20 * dir.z * dir.z +
|
|
C4 * sh.L00 - C5 * sh.L20 +
|
|
2.0 * C1 * ( sh.L2m2 * dir.x * dir.y +
|
|
sh.L21 * dir.x * dir.z +
|
|
sh.L2m1 * dir.y * dir.z ) +
|
|
2.0 * C2 * ( sh.L11 * dir.x +
|
|
sh.L1m1 * dir.y +
|
|
sh.L10 * dir.z ) ;
|
|
return value;
|
|
}
|
|
|
|
// Need one SH
|
|
uniform SphericalHarmonics ambientSphere;
|
|
|
|
<@endfunc@>
|
|
|
|
// Everything about light
|
|
<@include model/Light.slh@>
|
|
|
|
<@func declareEvalAmbientGlobalColor()@>
|
|
vec3 evalAmbientGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) {
|
|
|
|
// Need the light now
|
|
Light light = getLight();
|
|
|
|
vec3 fragNormal = vec3(invViewMat * vec4(normal, 0.0));
|
|
vec4 fragEyeVector = invViewMat * vec4(-position, 0.0);
|
|
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
|
|
|
|
vec3 color = diffuse.rgb * getLightColor(light) * obscurance * getLightAmbientIntensity(light);
|
|
|
|
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss);
|
|
|
|
color += vec3(diffuse * shading.w + shading.rgb) * min(shadowAttenuation, obscurance) * getLightColor(light) * getLightIntensity(light);
|
|
|
|
return color;
|
|
}
|
|
<@endfunc@>
|
|
|
|
<@func declareEvalAmbientSphereGlobalColor()@>
|
|
|
|
<$declareSphericalHarmonics()$>
|
|
|
|
vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) {
|
|
// Need the light now
|
|
Light light = getLight();
|
|
|
|
vec3 fragNormal = normalize(vec3(invViewMat * vec4(normal, 0.0)));
|
|
vec4 fragEyeVector = invViewMat * vec4(-position, 0.0);
|
|
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
|
|
|
|
vec3 ambientNormal = fragNormal.xyz;
|
|
vec3 color = diffuse.rgb * evalSphericalLight(ambientSphere, ambientNormal).xyz * obscurance * getLightAmbientIntensity(light);
|
|
|
|
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss);
|
|
|
|
color += vec3(diffuse * shading.w + shading.rgb) * min(shadowAttenuation, obscurance) * getLightColor(light) * getLightIntensity(light);
|
|
|
|
return color;
|
|
}
|
|
<@endfunc@>
|
|
|
|
<@func declareEvalSkyboxGlobalColor()@>
|
|
|
|
<$declareSkyboxMap()$>
|
|
<$declareSphericalHarmonics()$>
|
|
|
|
vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) {
|
|
// Need the light now
|
|
Light light = getLight();
|
|
|
|
vec3 fragNormal = normalize(vec3(invViewMat * vec4(normal, 0.0)));
|
|
vec4 fragEyeVector = invViewMat * vec4(-position, 0.0);
|
|
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
|
|
|
|
vec3 color = diffuse.rgb * evalSphericalLight(ambientSphere, fragNormal).xyz * obscurance * getLightAmbientIntensity(light);
|
|
|
|
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss);
|
|
|
|
color += vec3(diffuse * shading.w + shading.rgb) * min(shadowAttenuation, obscurance) * getLightColor(light) * getLightIntensity(light);
|
|
|
|
return color;
|
|
}
|
|
<@endfunc@>
|
|
|
|
<@func declareEvalLightmappedColor()@>
|
|
vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 normal, vec3 diffuse, vec3 lightmap) {
|
|
|
|
Light light = getLight();
|
|
|
|
vec3 fragNormal = vec3(invViewMat * vec4(normal, 0.0));
|
|
float diffuseDot = dot(fragNormal, -getLightDirection(light));
|
|
|
|
// need to catch normals perpendicular to the projection plane hence the magic number for the threshold
|
|
// it should be just 0, but we have innacurracy so we need to overshoot
|
|
const float PERPENDICULAR_THRESHOLD = -0.005;
|
|
float facingLight = step(PERPENDICULAR_THRESHOLD, diffuseDot);
|
|
//float facingLight = step(PERPENDICULAR_THRESHOLD, diffuseDot);
|
|
// evaluate the shadow test but only relevant for light facing fragments
|
|
float lightAttenuation = (1 - facingLight) + facingLight * shadowAttenuation;
|
|
// diffuse light is the lightmap dimmed by shadow
|
|
vec3 diffuseLight = lightAttenuation * lightmap;
|
|
|
|
// ambient is a tiny percentage of the lightmap and only when in the shadow
|
|
vec3 ambientLight = (1 - lightAttenuation) * lightmap * getLightAmbientIntensity(light);
|
|
|
|
return obscurance * diffuse * (ambientLight + diffuseLight);
|
|
}
|
|
<@endfunc@>
|
|
|
|
<@endif@>
|