mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-06-24 20:38:47 +02:00
141 lines
5.3 KiB
Text
141 lines
5.3 KiB
Text
// Generated on <$_SCRIBE_DATE$>
|
|
//
|
|
// Created by Sam Gateau on 7/5/16.
|
|
// Copyright 2016 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
|
|
|
|
<@include render-utils/ShaderConstants.h@>
|
|
<@func declareSkyboxMap()@>
|
|
// declareSkyboxMap
|
|
LAYOUT(binding=RENDER_UTILS_TEXTURE_SKYBOX) 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);
|
|
|
|
#if !defined(GL_ES)
|
|
float filterLod = textureQueryLod(skyboxMap, direction).x;
|
|
// Keep texture filtering LOD as limit to prevent aliasing on specular reflection, but add
|
|
// a bias to limit overblurring with convolved maps
|
|
lod = max(lod, filterLod-2);
|
|
#endif
|
|
|
|
return textureLod(skyboxMap, direction, lod);
|
|
}
|
|
<@endfunc@>
|
|
|
|
<@func declareEvalAmbientSpecularIrradiance(supportAmbientSphere, supportAmbientMap, supportIfAmbientMapElseAmbientSphere)@>
|
|
LAYOUT(binding=RENDER_UTILS_TEXTURE_AMBIENT_FRESNEL) uniform sampler2D ambientFresnelLUT;
|
|
|
|
vec3 fresnelSchlickAmbient(vec3 fresnelColor, float ndotd, float roughness) {
|
|
#if RENDER_UTILS_ENABLE_AMBIENT_FRESNEL_LUT
|
|
vec2 ambientFresnel = texture(ambientFresnelLUT, vec2(roughness, ndotd)).xy;
|
|
return fresnelColor * ambientFresnel.x + vec3(ambientFresnel.y);
|
|
#else
|
|
float gloss = 1.0-roughness;
|
|
float f = pow(1.0 - ndotd, 5.0);
|
|
return fresnelColor + (max(vec3(gloss), fresnelColor) - fresnelColor) * f;
|
|
#endif
|
|
}
|
|
|
|
<@if supportAmbientMap@>
|
|
<$declareSkyboxMap()$>
|
|
<@endif@>
|
|
|
|
float getMipLevelFromRoughness(float roughness, float lodCount) {
|
|
// This should match the value in the CubeMap::convolveForGGX method (CubeMap.cpp)
|
|
float ROUGHNESS_1_MIP_RESOLUTION = 1.5;
|
|
float deltaLod = lodCount - ROUGHNESS_1_MIP_RESOLUTION;
|
|
return deltaLod * (sqrt(1.0+24.0*roughness)-1.0) / 4.0;
|
|
}
|
|
|
|
vec3 evalAmbientSpecularIrradiance(LightAmbient ambient, SurfaceData surface, vec3 lightDir) {
|
|
vec3 specularLight;
|
|
<@if supportIfAmbientMapElseAmbientSphere@>
|
|
if (getLightHasAmbientMap(ambient))
|
|
<@endif@>
|
|
<@if supportAmbientMap@>
|
|
{
|
|
float levelCount = getLightAmbientMapNumMips(ambient);
|
|
float lod = getMipLevelFromRoughness(surface.roughness, levelCount);
|
|
lod = max(lod, 0.0);
|
|
|
|
specularLight = evalSkyboxLight(lightDir, lod).xyz;
|
|
}
|
|
<@endif@>
|
|
<@if supportIfAmbientMapElseAmbientSphere@>
|
|
else
|
|
<@endif@>
|
|
<@if supportAmbientSphere@>
|
|
{
|
|
specularLight = sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(ambient), lightDir).xyz;
|
|
}
|
|
<@endif@>
|
|
|
|
return specularLight;
|
|
}
|
|
<@endfunc@>
|
|
|
|
<@func declareLightingAmbient(supportAmbientSphere, supportAmbientMap, supportIfAmbientMapElseAmbientSphere, supportScattering)@>
|
|
|
|
<$declareEvalAmbientSpecularIrradiance($supportAmbientSphere$, $supportAmbientMap$, $supportIfAmbientMapElseAmbientSphere$)$>
|
|
|
|
<@if supportScattering@>
|
|
float curvatureAO(in float k) {
|
|
return 1.0f - (0.0022f * k * k) + (0.0776f * k) + 0.7369f;
|
|
}
|
|
<@endif@>
|
|
|
|
void evalLightingAmbient(out vec3 diffuse, out vec3 specular, LightAmbient ambient, SurfaceData surface,
|
|
float metallic, vec3 fresnelF0, vec3 albedo, float obscurance
|
|
<@if supportScattering@>
|
|
, float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature
|
|
<@endif@>
|
|
) {
|
|
|
|
// Rotate surface normal and eye direction
|
|
vec3 ambientSpaceSurfaceNormal = (ambient.transform * vec4(surface.normal, 0.0)).xyz;
|
|
vec3 ambientSpaceSurfaceEyeDir = (ambient.transform * vec4(surface.eyeDir, 0.0)).xyz;
|
|
<@if supportScattering@>
|
|
vec3 ambientSpaceLowNormal = (ambient.transform * vec4(lowNormalCurvature.xyz, 0.0)).xyz;
|
|
<@endif@>
|
|
|
|
vec3 ambientFresnel = fresnelSchlickAmbient(fresnelF0, surface.ndotv, surface.roughness);
|
|
|
|
diffuse = (1.0 - metallic) * (vec3(1.0) - ambientFresnel) *
|
|
sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(ambient), ambientSpaceSurfaceNormal).xyz;
|
|
|
|
// Specular highlight from ambient
|
|
vec3 ambientSpaceLightDir = -reflect(ambientSpaceSurfaceEyeDir, ambientSpaceSurfaceNormal);
|
|
specular = evalAmbientSpecularIrradiance(ambient, surface, ambientSpaceLightDir) * ambientFresnel;
|
|
|
|
<@if supportScattering@>
|
|
if (scattering * isScatteringEnabled() > 0.0) {
|
|
float ambientOcclusion = curvatureAO(lowNormalCurvature.w * 20.0f) * 0.5f;
|
|
float ambientOcclusionHF = curvatureAO(midNormalCurvature.w * 8.0f) * 0.5f;
|
|
ambientOcclusion = min(ambientOcclusion, ambientOcclusionHF);
|
|
|
|
obscurance = min(obscurance, ambientOcclusion);
|
|
|
|
// Diffuse from ambient
|
|
diffuse = sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(ambient), ambientSpaceLowNormal).xyz;
|
|
|
|
// Scattering ambient specular is the same as non scattering for now
|
|
// TODO: we should use the same specular answer as for direct lighting
|
|
}
|
|
<@endif@>
|
|
|
|
obscurance = mix(1.0, obscurance, isObscuranceEnabled());
|
|
|
|
float lightEnergy = obscurance * getLightAmbientIntensity(ambient);
|
|
|
|
diffuse *= mix(vec3(1), albedo, isAlbedoEnabled());
|
|
|
|
lightEnergy *= isAmbientEnabled();
|
|
diffuse *= lightEnergy * isDiffuseEnabled();
|
|
specular *= lightEnergy * isSpecularEnabled();
|
|
}
|
|
|
|
<@endfunc@>
|