overte-HifiExperiments/libraries/render-utils/src/DeferredGlobalLight.slh

146 lines
5.8 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 model/Light.slh@>
<@include DeferredLighting.slh@>
<@func declareSkyboxMap()@>
// declareSkyboxMap
uniform samplerCube skyboxMap;
vec4 evalSkyboxLight(vec3 direction, float lod) {
// textureQueryLevels is not available until #430, so we require explicit lod
// float mipmapLevel = lod * textureQueryLevels(skyboxMap);
return textureLod(skyboxMap, direction, lod);
}
<@endfunc@>
<@func prepareGlobalLight()@>
// prepareGlobalLight
// Transform directions to worldspace
vec3 fragNormal = vec3(invViewMat * vec4(normal, 0.0));
// vec3 fragEyeVector = vec3(invViewMat * vec4(-position, 0.0));
vec3 fragEyeVector = vec3(invViewMat * vec4(-normalize(position), 0.0));
vec3 fragEyeDir = normalize(fragEyeVector);
// Get light
Light light = getLight();
vec3 fresnel = vec3(0.03); // Default Di-electric fresnel value
if (metallic > 0.5) {
fresnel = albedo;
metallic = 1.0;
}
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, metallic, fresnel, roughness);
vec3 color = vec3(albedo * shading.w + shading.rgb) * min(shadowAttenuation, obscurance) * getLightColor(light) * getLightIntensity(light);
color += emissive;
<@endfunc@>
<@func declareAmbientFresnel()@>
vec3 fresnelSchlickAmbient(vec3 fresnelColor, vec3 lightDir, vec3 halfDir, float gloss) {
return fresnelColor + (max(vec3(gloss), fresnelColor) - fresnelColor) * pow(1.0 - clamp(dot(lightDir, halfDir), 0.0, 1.0), 5);
}
<@endfunc@>
<@func declareEvalAmbientGlobalColor()@>
vec3 evalAmbientGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) {
<$prepareGlobalLight()$>
color += albedo * getLightColor(light) * obscurance * getLightAmbientIntensity(light);
return color;
}
<@endfunc@>
<@func declareEvalAmbientSphereGlobalColor()@>
<$declareAmbientFresnel()$>
vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) {
<$prepareGlobalLight()$>
// Diffuse from ambient
color += (1 - metallic) * albedo * evalSphericalLight(getLightAmbientSphere(light), fragNormal).xyz * obscurance * getLightAmbientIntensity(light);
// Specular highlight from ambient
vec3 direction = -reflect(fragEyeDir, fragNormal);
vec3 skyboxLight = evalSphericalLight(getLightAmbientSphere(light), direction).xyz;
vec3 ambientFresnel = fresnelSchlickAmbient(fresnel, fragEyeDir, fragNormal, 1 - roughness);
color += ambientFresnel * skyboxLight.rgb * obscurance * getLightAmbientIntensity(light);
return color;
}
<@endfunc@>
<@func declareEvalSkyboxGlobalColor()@>
<$declareSkyboxMap()$>
<$declareAmbientFresnel()$>
vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) {
<$prepareGlobalLight()$>
// Diffuse from ambient
color += (1 - metallic) * albedo * evalSphericalLight(getLightAmbientSphere(light), fragNormal).xyz * obscurance * getLightAmbientIntensity(light);
// Specular highlight from ambient
//vec3 direction = -reflect(fragEyeDir, fragNormal);
// -normalize(position)
vec3 direction = -reflect(-normalize(position), normal);
// vec3 direction = normal;
// if (gl_FragCoord.x > 1000) {
float angleY = fract(asin(direction.y)/ 0.314);
float angleX = fract(acos(normalize(direction.xz).x)/ 0.314);
float stripeY = step(0.05,abs(angleY));
float stripeX = step(0.05,abs(angleX));
float grid = max(stripeY, stripeX);
return mix( 0.5 * direction + vec3(0.5), mix(vec3(0.0, 1.0, 0.0), vec3(1.0, 0.0, 0.0), stripeY), grid);
// }
float levels = getLightAmbientMapNumMips(light);
float lod = min(floor((roughness) * levels), levels);
// vec4 skyboxLight = evalSkyboxLight(direction, lod);
vec4 skyboxLight = evalSkyboxLight(direction, levels * 0.5);
return skyboxLight.xyz;
//vec3 ambientFresnel = fresnelSchlickAmbient(fresnel, fragEyeDir, fragNormal, 1 - roughness);
//color += ambientFresnel * skyboxLight.rgb * obscurance * getLightAmbientIntensity(light);
//return color;
}
<@endfunc@>
<@func declareEvalLightmappedColor()@>
vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 normal, vec3 albedo, vec3 lightmap) {
Light light = getLight();
// 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 - 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 - lightAttenuation) * lightmap * getLightAmbientIntensity(light);
return obscurance * albedo * (diffuseLight + ambientLight);
}
<@endfunc@>
<@endif@>