// 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 // <@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 declareEvalAmbientSpecularIrradiance(supportAmbientSphere, supportAmbientMap, supportIfAmbientMapElseAmbientSphere)@> vec3 fresnelSchlickAmbient(vec3 fresnelColor, vec3 lightDir, vec3 halfDir, float gloss) { float f = pow(1.0 - clamp(dot(lightDir, halfDir), 0.0, 1.0), 5.0); return fresnelColor + (max(vec3(gloss), fresnelColor) - fresnelColor) * f; // return mix(fresnelColor, vec3(1.0), f); } <@if supportAmbientMap@> <$declareSkyboxMap()$> <@endif@> vec3 evalAmbientSpecularIrradiance(LightAmbient ambient, vec3 fragEyeDir, vec3 fragNormal, float roughness) { vec3 lightDir = -reflect(fragEyeDir, fragNormal); vec3 specularLight; <@if supportIfAmbientMapElseAmbientSphere@> if (getLightHasAmbientMap(ambient)) <@endif@> <@if supportAmbientMap@> { float levels = getLightAmbientMapNumMips(ambient); float lod = min(((roughness)* levels), levels); specularLight = evalSkyboxLight(lightDir, lod).xyz; // We multiply specular by Pi to match specular / diffuse normalization in // LightingModel.slh where diffuse and specular arent divided by Pi (when they should, rigourously // speaking, based on physical equations). The spherical harmonics evaluation, on // the other hand, seems to be Pi times stronger than usual. So all in all, everything // should be at the right level now. specularLight *= 3.1415926; } <@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, vec3 eyeDir, vec3 normal, float roughness, float metallic, vec3 fresnelF0, vec3 albedo, float obscurance <@if supportScattering@> , float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature <@endif@> ) { // Fresnel vec3 ambientFresnel = fresnelSchlickAmbient(fresnelF0, eyeDir, normal, 1.0 - roughness); // Diffuse from ambient diffuse = (1.0 - metallic) * (vec3(1.0) - ambientFresnel) * sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(ambient), normal).xyz; // Specular highlight from ambient specular = evalAmbientSpecularIrradiance(ambient, eyeDir, normal, roughness) * 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), lowNormalCurvature.xyz).xyz; specular = vec3(0.0); } <@endif@> if (!(isObscuranceEnabled() > 0.0)) { obscurance = 1.0; } float lightEnergy = obscurance * getLightAmbientIntensity(ambient); if (isAlbedoEnabled() > 0.0) { diffuse *= albedo; } lightEnergy *= isAmbientEnabled(); diffuse *= lightEnergy * isDiffuseEnabled(); specular *= lightEnergy * isSpecularEnabled(); } <@endfunc@>