diff --git a/libraries/model/src/model/Light.slh b/libraries/model/src/model/Light.slh index 80804e3cf5..7cc4691d63 100644 --- a/libraries/model/src/model/Light.slh +++ b/libraries/model/src/model/Light.slh @@ -109,10 +109,15 @@ SphericalHarmonics getLightAmbientSphere(Light l) { return l._ambientSphere; } +bool getLightHasAmbientMap(Light l) { + return l._control.x > 0; +} + float getLightAmbientMapNumMips(Light l) { return l._control.x; } + <@if GPU_FEATURE_PROFILE == GPU_CORE @> uniform lightBuffer { Light light; diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh index 04c9df9bc5..7608c8ae08 100755 --- a/libraries/render-utils/src/DeferredGlobalLight.slh +++ b/libraries/render-utils/src/DeferredGlobalLight.slh @@ -25,6 +25,43 @@ vec4 evalSkyboxLight(vec3 direction, float lod) { } <@endfunc@> +<@func declareEvalGlobalSpecularIrradiance(supportAmbientSphere, supportAmbientMap, supportIfAmbientMapElseAmbientSphere)@> + +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); +} + +<@if supportAmbientMap@> + <$declareSkyboxMap()$> +<@endif@> + +vec3 evalGlobalSpecularIrradiance(Light light, vec3 fragEyeDir, vec3 fragNormal, float roughness, vec3 fresnel, float obscurance) { + vec3 direction = -reflect(fragEyeDir, fragNormal); + vec3 ambientFresnel = fresnelSchlickAmbient(fresnel, fragEyeDir, fragNormal, 1 - roughness); + vec3 specularLight; + <@if supportIfAmbientMapElseAmbientSphere@> + if (getLightHasAmbientMap(light)) + <@endif@> + <@if supportAmbientMap@> + { + float levels = getLightAmbientMapNumMips(light); + float lod = min(floor((roughness) * levels), levels); + specularLight = evalSkyboxLight(direction, lod).xyz; + } + <@endif@> + <@if supportIfAmbientMapElseAmbientSphere@> + else + <@endif@> + <@if supportAmbientSphere@> + { + specularLight = evalSphericalLight(getLightAmbientSphere(light), direction).xyz; + } + <@endif@> + + return specularLight * ambientFresnel * getLightAmbientIntensity(light); +} +<@endfunc@> + <@func prepareGlobalLight()@> // prepareGlobalLight @@ -45,11 +82,6 @@ vec4 evalSkyboxLight(vec3 direction, float lod) { 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) { @@ -60,7 +92,8 @@ vec3 evalAmbientGlobalColor(mat4 invViewMat, float shadowAttenuation, float obsc <@endfunc@> <@func declareEvalAmbientSphereGlobalColor()@> -<$declareAmbientFresnel()$> +<$declareEvalGlobalSpecularIrradiance(1, 0, 0)$> + vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) { <$prepareGlobalLight()$> @@ -69,18 +102,15 @@ vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, floa 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); + vec3 specularLighting = evalGlobalSpecularIrradiance(light, fragEyeDir, fragNormal, roughness, fresnel, obscurance); + color += specularLighting; return color; } <@endfunc@> <@func declareEvalSkyboxGlobalColor()@> -<$declareSkyboxMap()$> -<$declareAmbientFresnel()$> +<$declareEvalGlobalSpecularIrradiance(0, 1, 0)$> vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) { <$prepareGlobalLight()$> @@ -89,13 +119,8 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu color += (1 - metallic) * albedo * evalSphericalLight(getLightAmbientSphere(light), fragNormal).xyz * obscurance * getLightAmbientIntensity(light); // Specular highlight from ambient - vec3 direction = -reflect(fragEyeDir, fragNormal); - - float levels = getLightAmbientMapNumMips(light); - float lod = min(floor((roughness) * levels), levels); - vec4 skyboxLight = evalSkyboxLight(direction, lod); - vec3 ambientFresnel = fresnelSchlickAmbient(fresnel, fragEyeDir, fragNormal, 1 - roughness); - color += ambientFresnel * skyboxLight.rgb * obscurance * getLightAmbientIntensity(light); + vec3 specularLighting = evalGlobalSpecularIrradiance(light, fragEyeDir, fragNormal, roughness, fresnel, obscurance); + color += specularLighting; return color; } @@ -127,32 +152,23 @@ vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscur -<@func declareEvalGlobalLightColor()@> +<@func declareEvalGlobalLightingAlphaBlended()@> -<$declareSkyboxMap()$> -<$declareAmbientFresnel()$> +<$declareEvalGlobalSpecularIrradiance(1, 1, 1)$> -vec3 evalSkyboxGlobalColorAlpha(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness, float opacity) { +vec3 evalGlobalLightingAlphaBlended(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness, float opacity) { <$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); - - float levels = getLightAmbientMapNumMips(light); - float lod = min(floor((roughness) * levels), levels); - vec4 skyboxLight = evalSkyboxLight(direction, lod); - vec3 ambientFresnel = fresnelSchlickAmbient(fresnel, fragEyeDir, fragNormal, 1 - roughness); - color += ambientFresnel * skyboxLight.rgb * obscurance * getLightAmbientIntensity(light) / opacity; + vec3 specularLighting = evalGlobalSpecularIrradiance(light, fragEyeDir, fragNormal, roughness, fresnel, obscurance); + color += specularLighting / opacity; return color; } -vec3 evalGlobalLightColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness, float opacity) { - return evalSkyboxGlobalColorAlpha(invViewMat, shadowAttenuation, obscurance, position, normal, albedo, metallic, emissive, roughness, opacity); -} <@endfunc@> diff --git a/libraries/render-utils/src/model_translucent.slf b/libraries/render-utils/src/model_translucent.slf index 2bd49345ee..1a807c5703 100755 --- a/libraries/render-utils/src/model_translucent.slf +++ b/libraries/render-utils/src/model_translucent.slf @@ -16,7 +16,7 @@ <@include DeferredGlobalLight.slh@> -<$declareEvalGlobalLightColor()$> +<$declareEvalGlobalLightingAlphaBlended()$> <@include gpu/Transform.slh@> <$declareStandardCameraTransform()$> @@ -59,7 +59,7 @@ void main(void) { TransformCamera cam = getTransformCamera(); - _fragColor = vec4(evalGlobalLightColor( + _fragColor = vec4(evalGlobalLightingAlphaBlended( cam._viewInverse, 1.0, 1.0,