From 66b65391a46502d6186533f57b946108c7cf7cb4 Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 5 Jul 2016 18:21:49 -0700 Subject: [PATCH] Cleaning up the lighting equations --- .../render-utils/src/DeferredGlobalLight.slh | 380 ++++++------------ libraries/render-utils/src/LightAmbient.slh | 111 +++++ .../render-utils/src/LightDirectional.slh | 73 ++++ .../render-utils/src/SubsurfaceScattering.slh | 33 +- .../src/directional_ambient_light.slf | 7 +- .../src/directional_skybox_light.slf | 7 +- .../subsurfaceScattering_drawScattering.slf | 29 +- 7 files changed, 355 insertions(+), 285 deletions(-) create mode 100644 libraries/render-utils/src/LightAmbient.slh create mode 100644 libraries/render-utils/src/LightDirectional.slh diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh index 6791a90829..d76c333206 100755 --- a/libraries/render-utils/src/DeferredGlobalLight.slh +++ b/libraries/render-utils/src/DeferredGlobalLight.slh @@ -17,74 +17,34 @@ <@include LightingModel.slh@> <$declareLightingModel()$> -<@func declareSkyboxMap()@> -// declareSkyboxMap -uniform samplerCube skyboxMap; +<@include LightAmbient.slh@> +<@include LightDirectional.slh@> -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 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()@> +<@func prepareGlobalLight(isScattering)@> // prepareGlobalLight - // Transform directions to worldspace - // vec3 fragNormal = vec3(invViewMat * vec4(normal, 0.0)); vec3 fragNormal = vec3((normal)); vec3 fragEyeVector = vec3(invViewMat * vec4(-position, 0.0)); vec3 fragEyeDir = normalize(fragEyeVector); // Get light Light light = getLight(); + + vec3 color = vec3(0.0); + +<@if isScattering@> + vec3 fresnel = vec3(0.028); // Default Di-electric fresnel value for skin + float metallic = 0.0; +<@else@> 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(0.0); - color += vec3(albedo * shading.w * isDiffuseEnabled() + shading.rgb * isSpecularEnabled()) * min(shadowAttenuation, obscurance) * getLightColor(light) * getLightIntensity(light) * isDirectionalEnabled(); color += emissive * isEmissiveEnabled(); +<@endif@> + <@endfunc@> @@ -96,131 +56,138 @@ vec3 evalAmbientGlobalColor(mat4 invViewMat, float shadowAttenuation, float obsc } <@endfunc@> -<@func declareEvalAmbientSphereGlobalColor()@> -<$declareEvalGlobalSpecularIrradiance(1, 0, 0)$> +<@func declareEvalAmbientSphereGlobalColor(supportScattering)@> +<$declareLightingAmbient(1, 0, 0, supportScattering)$> +<$declareLightingDirectional(supportScattering)$> 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); + // Ambient + vec3 ambientDiffuse; + vec3 ambientSpecular; + evalLightingAmbient(ambientDiffuse, ambientSpecular, light, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, obscurance); + color += ambientDiffuse * isDiffuseEnabled() * isAmbientEnabled(); + color += ambientSpecular * isSpecularEnabled() * isAmbientEnabled(); - // Specular highlight from ambient - vec3 specularLighting = evalGlobalSpecularIrradiance(light, fragEyeDir, fragNormal, roughness, fresnel, obscurance); - color += specularLighting; + + // Directional + vec3 directionalDiffuse; + vec3 directionalSpecular; + evalLightingDirectional(directionalDiffuse, directionalSpecular, light, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, shadowAttenuation); + color += directionalDiffuse * isDiffuseEnabled() * isDirectionalEnabled(); + color += directionalSpecular * isSpecularEnabled() * isDirectionalEnabled(); return color; } -<@endfunc@> -<@func declareEvalAmbientSphereGlobalColorScattering()@> +<@if supportScattering@> <$declareDeferredCurvature()$> -<@include SubsurfaceScattering.slh@> -<$declareSubsurfaceScatteringResource()$> -!> -<$declareSkinSpecularLighting()$> +vec3 evalAmbientSphereGlobalColorScattering(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float roughness, float scattering, vec4 blurredCurvature, vec4 diffusedCurvature) { -vec3 evalAmbientSphereGlobalColorScattering(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float scattering, vec4 blurredCurvature, vec4 diffusedCurvature, float roughness) { - // prepareGlobalLight + <$prepareGlobalLight(1)$> - // Transform directions to worldspace - vec3 fragNormal = vec3((normal)); - vec3 fragEyeVector = vec3(invViewMat * vec4(-position, 0.0)); - vec3 fragEyeDir = normalize(fragEyeVector); - - // Get light - Light light = getLight(); - vec3 fresnel = vec3(0.028); // Default Di-electric fresnel value for skin - float metallic = 0.0; - - vec3 fragLightDir = -normalize(getLightDirection(light)); - - vec3 midNormal = normalize((blurredCurvature.xyz - 0.5f) * 2.0f); + vec3 midNormal = normalize((blurredCurvature.xyz - 0.5f) * 2.0f); vec3 lowNormal = normalize((diffusedCurvature.xyz - 0.5f) * 2.0f); - float curvature = unpackCurvature(diffusedCurvature.w); + float highCurvature = unpackCurvature(blurredCurvature.w); + float lowCurvature = unpackCurvature(diffusedCurvature.w); - if (showDiffusedNormal()) { - return diffusedCurvature.xyz; - return lowNormal * 0.5 + vec3(0.5); - } - if (showCurvature()) { - float curvatureSigned = unpackCurvatureSigned(diffusedCurvature.w); - return (curvatureSigned > 0 ? vec3(curvatureSigned, 0.0, 0.0) : vec3(0.0, 0.0, -curvatureSigned)); - } - - vec3 bentNdotL = evalScatteringBentNdotL(fragNormal, midNormal, lowNormal, fragLightDir); - - vec3 brdf = fetchBRDFSpectrum(bentNdotL, curvature); - - // The position of the pixel fragment in Eye space then in world space - - float scatteringLevel = getScatteringLevel(); - - vec4 shading; - float standardDiffuse = clamp(dot(normal, fragLightDir), 0.0, 1.0); - { // Key Sun Lighting - // Diffuse Lighting - //float diffuse = clamp(dot(normal, fragLightDir), 0.0, 1.0); - - // Specular Lighting - vec3 halfDir = normalize(fragEyeDir + fragLightDir); - - float specular = skinSpecular(fragNormal, fragLightDir, fragEyeDir, roughness, 1.0); - - vec3 fresnelColor = fresnelSchlick(fresnel, fragLightDir, halfDir); - float power = specularDistribution(roughness, fragNormal, halfDir); - //vec3 specular = power * fresnelColor * standardDiffuse; - - shading = vec4(vec3(specular), (1 - fresnelColor.x)); - } + // Ambient + vec3 ambientDiffuse; + vec3 ambientSpecular; + evalLightingAmbientScattering(ambientDiffuse, ambientSpecular, light, + fragEyeDir, fragNormal, roughness, + metallic, fresnel, albedo, obscurance, + isScatteringEnabled() * scattering, lowNormal, highCurvature, lowCurvature); + color += ambientDiffuse * isDiffuseEnabled() * isAmbientEnabled(); + color += ambientSpecular * isSpecularEnabled() * isAmbientEnabled(); - if (scatteringLevel < 0.1) { - brdf = vec3(standardDiffuse); - } - brdf = mix(vec3(standardDiffuse), brdf, scatteringLevel * scattering); + // Directional + vec3 directionalDiffuse; + vec3 directionalSpecular; + evalLightingDirectionalScattering(directionalDiffuse, directionalSpecular, light, + fragEyeDir, fragNormal, roughness, + metallic, fresnel, albedo, shadowAttenuation, + isScatteringEnabled() * scattering, midNormal, lowNormal, lowCurvature); + color += directionalDiffuse * isDiffuseEnabled() * isDirectionalEnabled(); + color += directionalSpecular * isSpecularEnabled() * isDirectionalEnabled(); - - vec3 color = vec3(albedo * vec3(brdf.xyz) * isDiffuseEnabled() * shading.w + shading.rgb * isSpecularEnabled()) * getLightColor(light) * getLightIntensity(light) * isDirectionalEnabled(); - - - // Diffuse from ambient - // color += albedo * evalSphericalLight(getLightAmbientSphere(light), bentNormalHigh).xyz *getLightAmbientIntensity(light); - - // Specular highlight from ambient - vec3 specularLighting = evalGlobalSpecularIrradiance(light, fragEyeDir, fragNormal, roughness, fresnel, 1.0); - // color += specularLighting; - - if (showBRDF()) - return brdf; - - //vec3 debugNdotL = 0.5 * (NdotLSpectrum + vec3(1.0)); - //return vec3(debugNdotL.z, curvature, 0.0 ); - - return vec3(color); + return color; } + +<@endif@> + <@endfunc@> +<@func declareEvalSkyboxGlobalColor(supportScattering)@> -<@func declareEvalSkyboxGlobalColor()@> -<$declareEvalGlobalSpecularIrradiance(0, 1, 0)$> +<$declareLightingAmbient(0, 1, 0, supportScattering)$> +<$declareLightingDirectional(supportScattering)$> 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); + // Ambient + vec3 ambientDiffuse; + vec3 ambientSpecular; + evalLightingAmbient(ambientDiffuse, ambientSpecular, light, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, obscurance); + color += ambientDiffuse * isDiffuseEnabled() * isAmbientEnabled(); + color += ambientSpecular * isSpecularEnabled() * isAmbientEnabled(); - // Specular highlight from ambient - vec3 specularLighting = evalGlobalSpecularIrradiance(light, fragEyeDir, fragNormal, roughness, fresnel, obscurance); - color += specularLighting; + + // Directional + vec3 directionalDiffuse; + vec3 directionalSpecular; + evalLightingDirectional(directionalDiffuse, directionalSpecular, light, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, shadowAttenuation); + color += directionalDiffuse * isDiffuseEnabled() * isDirectionalEnabled(); + color += directionalSpecular * isSpecularEnabled() * isDirectionalEnabled(); return color; } + +<@if supportScattering@> + +<$declareDeferredCurvature()$> + +vec3 evalSkyboxGlobalColorScattering(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float roughness, float scattering, vec4 blurredCurvature, vec4 diffusedCurvature) { + <$prepareGlobalLight(1)$> + + vec3 midNormal = normalize((blurredCurvature.xyz - 0.5f) * 2.0f); + vec3 lowNormal = normalize((diffusedCurvature.xyz - 0.5f) * 2.0f); + float highCurvature = unpackCurvature(blurredCurvature.w); + float lowCurvature = unpackCurvature(diffusedCurvature.w); + + // Ambient + vec3 ambientDiffuse; + vec3 ambientSpecular; + evalLightingAmbientScattering(ambientDiffuse, ambientSpecular, light, + fragEyeDir, fragNormal, roughness, + metallic, fresnel, albedo, obscurance, + isScatteringEnabled() * scattering, lowNormal, highCurvature, lowCurvature); + color += ambientDiffuse * isDiffuseEnabled() * isAmbientEnabled(); + color += ambientSpecular * isSpecularEnabled() * isAmbientEnabled(); + + // Directional + vec3 directionalDiffuse; + vec3 directionalSpecular; + evalLightingDirectionalScattering(directionalDiffuse, directionalSpecular, light, + fragEyeDir, fragNormal, roughness, + metallic, fresnel, albedo, shadowAttenuation, + isScatteringEnabled() * scattering, midNormal, lowNormal, lowCurvature); + color += directionalDiffuse * isDiffuseEnabled() * isDirectionalEnabled(); + color += directionalSpecular * isSpecularEnabled() * isDirectionalEnabled(); + + return vec3(color); +} + +<@endif@> + <@endfunc@> <@func declareEvalLightmappedColor()@> @@ -243,128 +210,35 @@ vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscur // Ambient light is the lightmap when in shadow vec3 ambientLight = (1 - lightAttenuation) * lightmap * getLightAmbientIntensity(light); - return obscurance * albedo * (diffuseLight + ambientLight); + return isLightmapEnabled() * obscurance * albedo * (diffuseLight + ambientLight); } <@endfunc@> -<@func declareEvalSkyboxGlobalColorScattering()@> - -<$declareDeferredCurvature()$> -<@include SubsurfaceScattering.slh@> -<$declareSubsurfaceScatteringResource()$> -!> - -<$declareSkinSpecularLighting()$> - -float curvatureAO(in float k) { - return 1.0f - (0.0022f * k * k) + (0.0776f * k) + 0.7369; -} -vec3 evalSkyboxGlobalColorScattering(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float scattering, vec4 blurredCurvature, vec4 diffusedCurvature, float roughness) { - // prepareGlobalLight - - // Transform directions to worldspace - vec3 fragNormal = vec3((normal)); - vec3 fragEyeVector = vec3(invViewMat * vec4(-position, 0.0)); - vec3 fragEyeDir = normalize(fragEyeVector); - - // Get light - Light light = getLight(); - vec3 fresnel = vec3(0.028); // Default Di-electric fresnel value for skin - float metallic = 0.0; - - vec3 fragLightDir = -normalize(getLightDirection(light)); - - vec3 midNormal = normalize((blurredCurvature.xyz - 0.5f) * 2.0f); - vec3 lowNormal = normalize((diffusedCurvature.xyz - 0.5f) * 2.0f); - float curvature = unpackCurvature(diffusedCurvature.w); - - if (showDiffusedNormal()) { - return diffusedCurvature.xyz; - return lowNormal * 0.5 + vec3(0.5); - } - /* if (showCurvature()) { - float curvatureSigned = unpackCurvatureSigned(diffusedCurvature.w); - return (curvatureSigned > 0 ? vec3(curvatureSigned, 0.0, 0.0) : vec3(0.0, 0.0, -curvatureSigned)); - }*/ - - vec3 bentNdotL = evalScatteringBentNdotL(fragNormal, midNormal, lowNormal, fragLightDir); - - vec3 brdf = fetchBRDFSpectrum(bentNdotL, curvature); - - // The position of the pixel fragment in Eye space then in world space - - float scatteringLevel = getScatteringLevel(); - - vec4 shading; - float standardDiffuse = clamp(dot(normal, fragLightDir), 0.0, 1.0); - { // Key Sun Lighting - // Diffuse Lighting - //float diffuse = clamp(dot(normal, fragLightDir), 0.0, 1.0); - - // Specular Lighting - vec3 halfDir = normalize(fragEyeDir + fragLightDir); - - float specular = skinSpecular(fragNormal, fragLightDir, fragEyeDir, roughness, 1.0); - - vec3 fresnelColor = fresnelSchlick(fresnel, fragLightDir, halfDir); - float power = specularDistribution(roughness, fragNormal, halfDir); - //vec3 specular = power * fresnelColor * standardDiffuse; - - shading = vec4(vec3(specular), (1 - fresnelColor.x)); - - // shading = vec4(specular, (1 - fresnelColor.x)); - } - - if (scatteringLevel < 0.1) { - brdf = vec3(standardDiffuse); - } - - brdf = mix(vec3(standardDiffuse), brdf, scatteringLevel * scattering); - vec3 color = vec3(albedo * vec3(brdf.xyz) * shading.w + shading.rgb) * getLightColor(light) * getLightIntensity(light); - - //vec3 color = vec3(shading.rgb) * getLightColor(light) * getLightIntensity(light); - - float ambientOcclusion = curvatureAO((diffusedCurvature.w * 2 - 1) * 20.0f) * 0.5f; - float ambientOcclusionHF = curvatureAO((diffusedCurvature.w * 2 - 1) * 8.0f) * 0.5f; - ambientOcclusion = min(ambientOcclusion, ambientOcclusionHF); - - if (showCurvature()) { - return vec3(ambientOcclusion); - } - - - // Diffuse from ambient - color += ambientOcclusion * albedo * evalSphericalLight(getLightAmbientSphere(light), lowNormal).xyz *getLightAmbientIntensity(light); - - // Specular highlight from ambient - // vec3 specularLighting = evalGlobalSpecularIrradiance(light, fragEyeDir, fragNormal, roughness, fresnel, 1.0); - // color += specularLighting; - - if ( showBRDF()) - return brdf; - - //vec3 debugNdotL = 0.5 * (NdotLSpectrum + vec3(1.0)); - //return vec3(debugNdotL.z, curvature, 0.0 ); - - return vec3(color); -} -<@endfunc@> <@func declareEvalGlobalLightingAlphaBlended()@> -<$declareEvalGlobalSpecularIrradiance(1, 1, 1)$> +<$declareLightingAmbient(1, 1, 1)$> +<$declareLightingDirectional()$> 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); + // Ambient + vec3 ambientDiffuse; + vec3 ambientSpecular; + evalLightingAmbient(ambientDiffuse, ambientSpecular, light, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, obscurance); + color += ambientDiffuse * isDiffuseEnabled() * isAmbientEnabled(); + color += ambientSpecular * isSpecularEnabled() * isAmbientEnabled() / opacity; - // Specular highlight from ambient - vec3 specularLighting = evalGlobalSpecularIrradiance(light, fragEyeDir, fragNormal, roughness, fresnel, obscurance); - color += specularLighting / opacity; + + // Directional + vec3 directionalDiffuse; + vec3 directionalSpecular; + evalLightingDirectional(directionalDiffuse, directionalSpecular, light, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, shadowAttenuation); + color += directionalDiffuse * isDiffuseEnabled() * isDirectionalEnabled(); + color += directionalSpecular * isSpecularEnabled() * isDirectionalEnabled() / opacity; return color; } diff --git a/libraries/render-utils/src/LightAmbient.slh b/libraries/render-utils/src/LightAmbient.slh new file mode 100644 index 0000000000..e677eac6f8 --- /dev/null +++ b/libraries/render-utils/src/LightAmbient.slh @@ -0,0 +1,111 @@ +// 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) { + return fresnelColor + (max(vec3(gloss), fresnelColor) - fresnelColor) * pow(1.0 - clamp(dot(lightDir, halfDir), 0.0, 1.0), 5); +} + +<@if supportAmbientMap@> +<$declareSkyboxMap()$> +<@endif@> + +vec3 evalAmbientSpecularIrradiance(Light light, vec3 fragEyeDir, vec3 fragNormal, float roughness, vec3 fresnel) { + 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; +} +<@endfunc@> + +<@func declareLightingAmbient(supportAmbientSphere, supportAmbientMap, supportIfAmbientMapElseAmbientSphere, supportScattering)@> + +<$declareEvalAmbientSpecularIrradiance(supportAmbientSphere, supportAmbientMap, supportIfAmbientMapElseAmbientSphere)$> + +void evalLightingAmbient(out vec3 diffuse, out vec3 specular, Light light, vec3 eyeDir, vec3 normal, float roughness, float metallic, vec3 fresnel, vec3 albedo, float obscurance) { + // Diffuse from ambient + diffuse = (1 - metallic) * albedo * evalSphericalLight(getLightAmbientSphere(light), normal).xyz * obscurance * getLightAmbientIntensity(light); + + // Specular highlight from ambient + specular = evalAmbientSpecularIrradiance(light, eyeDir, normal, roughness, fresnel) * obscurance * getLightAmbientIntensity(light); +} + +<@if supportScattering@> + +!> + +float curvatureAO(in float k) { + return 1.0f - (0.0022f * k * k) + (0.0776f * k) + 0.7369; +} + +void evalLightingAmbientScattering(out vec3 diffuse, out vec3 specular, Light light, + vec3 eyeDir, vec3 normal, float roughness, + float metallic, vec3 fresnel, vec3 albedo, float obscurance, + float scatttering, vec3 lowNormal, float highCurvature, float lowCurvature) { + + float ambientOcclusion = curvatureAO(lowCurvature * 20.0f) * 0.5f; + float ambientOcclusionHF = curvatureAO(highCurvature * 8.0f) * 0.5f; + ambientOcclusion = min(ambientOcclusion, ambientOcclusionHF); + + /* if (showCurvature()) { + diffuse = vec3(ambientOcclusion); + specular = vec3(0.0); + return; + }*/ + + + // Diffuse from ambient + diffuse = ambientOcclusion * albedo * evalSphericalLight(getLightAmbientSphere(light), lowNormal).xyz *getLightAmbientIntensity(light); + + // Specular highlight from ambient + // vec3 specularLighting = evalGlobalSpecularIrradiance(light, fragEyeDir, fragNormal, roughness, fresnel); + // color += specularLighting; + + + // Specular highlight from ambient +// specular = evalAmbientSpecularIrradiance(light, eyeDir, normal, roughness, fresnel) * obscurance * getLightAmbientIntensity(light); + specular = vec3(0.0); +} + +<@endif@> + +<@endfunc@> diff --git a/libraries/render-utils/src/LightDirectional.slh b/libraries/render-utils/src/LightDirectional.slh new file mode 100644 index 0000000000..63ee8b3eda --- /dev/null +++ b/libraries/render-utils/src/LightDirectional.slh @@ -0,0 +1,73 @@ +// 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 declareLightingDirectional(supportScattering)@> +<@include DeferredLighting.slh@> + +void evalLightingDirectional(out vec3 diffuse, out vec3 specular, Light light, + vec3 eyeDir, vec3 normal, float roughness, + float metallic, vec3 fresnel, vec3 albedo, float shadow) { + + vec4 shading = evalFragShading(normal, -getLightDirection(light), eyeDir, metallic, fresnel, roughness); + + diffuse = albedo * shading.w * shadow * getLightColor(light) * getLightIntensity(light); + + specular = shading.rgb * shadow * getLightColor(light) * getLightIntensity(light); +} + +<@if supportScattering@> + +<@include SubsurfaceScattering.slh@> +<$declareSubsurfaceScatteringBRDF()$> +<$declareSkinSpecularLighting()$> + +void evalLightingDirectionalScattering(out vec3 diffuse, out vec3 specular, Light light, + vec3 eyeDir, vec3 normal, float roughness, + float metallic, vec3 fresnel, vec3 albedo, float shadow, + float scattering, vec3 midNormal, vec3 lowNormal, float curvature) { + + vec3 fragLightDir = -normalize(getLightDirection(light)); + vec3 brdf = evalSkinBRDF(fragLightDir, normal, midNormal, lowNormal, curvature); + float scatteringLevel = getScatteringLevel(); + vec4 shading; + float standardDiffuse = clamp(dot(normal, fragLightDir), 0.0, 1.0); + { // Key Sun Lighting + // Diffuse Lighting + //float diffuse = clamp(dot(normal, fragLightDir), 0.0, 1.0); + + // Specular Lighting + vec3 halfDir = normalize(eyeDir + fragLightDir); + + float specular = skinSpecular(normal, fragLightDir, eyeDir, roughness, 1.0); + + vec3 fresnelColor = fresnelSchlick(fresnel, fragLightDir, halfDir); + float power = specularDistribution(roughness, normal, halfDir); + //vec3 specular = power * fresnelColor * standardDiffuse; + + shading = vec4(vec3(specular), (1 - fresnelColor.x)); + } + + + if (scatteringLevel < 0.1) { + brdf = vec3(standardDiffuse); + } + brdf = mix(vec3(standardDiffuse), brdf, scatteringLevel * scattering); + + + diffuse = albedo * brdf.xyz * shadow * getLightColor(light) * getLightIntensity(light); + + specular = shading.rgb * shadow * getLightColor(light) * getLightIntensity(light); +} + +<@endif@> + +<@endfunc@> + diff --git a/libraries/render-utils/src/SubsurfaceScattering.slh b/libraries/render-utils/src/SubsurfaceScattering.slh index 8b801427df..6d5dd01d8f 100644 --- a/libraries/render-utils/src/SubsurfaceScattering.slh +++ b/libraries/render-utils/src/SubsurfaceScattering.slh @@ -6,6 +6,8 @@ // 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 SUBSURFACE_SCATTERING_SLH@> +<@def SUBSURFACE_SCATTERING_SLH@> <@func declareSubsurfaceScatteringProfileSource()@> @@ -174,12 +176,14 @@ bool showCurvature() { bool showDiffusedNormal() { return parameters.debugFlags.y > 0.0; } -float unpackCurvatureSigned(float packedCurvature) { - return (packedCurvature * 2 - 1) * parameters.curvatureInfo.y + parameters.curvatureInfo.x; + + +float tuneCurvatureUnsigned(float curvature) { + return abs(curvature) * parameters.curvatureInfo.y + parameters.curvatureInfo.x; } float unpackCurvature(float packedCurvature) { - return abs(packedCurvature * 2 - 1) * parameters.curvatureInfo.y + parameters.curvatureInfo.x; + return (packedCurvature * 2 - 1); } vec3 evalScatteringBentNdotL(vec3 normal, vec3 midNormal, vec3 lowNormal, vec3 lightDir) { @@ -197,3 +201,26 @@ vec3 evalScatteringBentNdotL(vec3 normal, vec3 midNormal, vec3 lowNormal, vec3 l <@endfunc@> + +<@func declareSubsurfaceScatteringBRDF()@> +<$declareSubsurfaceScatteringResource()$> + +vec3 evalSkinBRDF(vec3 lightDir, vec3 normal, vec3 midNormal, vec3 lowNormal, float curvature) { + if (showDiffusedNormal()) { + return lowNormal * 0.5 + vec3(0.5); + } + if (showCurvature()) { + return (curvature > 0 ? vec3(curvature, 0.0, 0.0) : vec3(0.0, 0.0, -curvature)); + } + + vec3 bentNdotL = evalScatteringBentNdotL(normal, midNormal, lowNormal, lightDir); + + float tunedCurvature = tuneCurvatureUnsigned(curvature); + + vec3 brdf = fetchBRDFSpectrum(bentNdotL, tunedCurvature); + return brdf; +} + +<@endfunc@> + +<@endif@> \ No newline at end of file diff --git a/libraries/render-utils/src/directional_ambient_light.slf b/libraries/render-utils/src/directional_ambient_light.slf index 156ff44f69..89663dbfa4 100755 --- a/libraries/render-utils/src/directional_ambient_light.slf +++ b/libraries/render-utils/src/directional_ambient_light.slf @@ -16,8 +16,7 @@ <@include DeferredGlobalLight.slh@> <$declareEvalLightmappedColor()$> -<$declareEvalAmbientSphereGlobalColor()$> -<$declareEvalAmbientSphereGlobalColorScattering()$> +<$declareEvalAmbientSphereGlobalColor(supportScattering)$> in vec2 _texCoord0; @@ -52,10 +51,10 @@ void main(void) { frag.position.xyz, frag.normal, frag.diffuse, + frag.roughness, frag.scattering, blurredCurvature, - diffusedCurvature, - frag.roughness); + diffusedCurvature); _fragColor = vec4(color, 1.0); } else { vec3 color = evalAmbientSphereGlobalColor( diff --git a/libraries/render-utils/src/directional_skybox_light.slf b/libraries/render-utils/src/directional_skybox_light.slf index d019e29866..e2183887a5 100755 --- a/libraries/render-utils/src/directional_skybox_light.slf +++ b/libraries/render-utils/src/directional_skybox_light.slf @@ -16,8 +16,7 @@ <@include DeferredGlobalLight.slh@> <$declareEvalLightmappedColor()$> -<$declareEvalSkyboxGlobalColor()$> -<$declareEvalSkyboxGlobalColorScattering()$> +<$declareEvalSkyboxGlobalColor(supportScattering)$> in vec2 _texCoord0; out vec4 _fragColor; @@ -52,10 +51,10 @@ void main(void) { frag.position.xyz, frag.normal, frag.diffuse, + frag.roughness, frag.scattering, blurredCurvature, - diffusedCurvature, - frag.roughness); + diffusedCurvature); _fragColor = vec4(color, 1.0); } else { vec3 color = evalSkyboxGlobalColor( diff --git a/libraries/render-utils/src/subsurfaceScattering_drawScattering.slf b/libraries/render-utils/src/subsurfaceScattering_drawScattering.slf index 0b881e8e29..7ee65e27e3 100644 --- a/libraries/render-utils/src/subsurfaceScattering_drawScattering.slf +++ b/libraries/render-utils/src/subsurfaceScattering_drawScattering.slf @@ -17,7 +17,7 @@ <$declareDeferredCurvature()$> <@include SubsurfaceScattering.slh@> -<$declareSubsurfaceScatteringResource()$> +<$declareSubsurfaceScatteringBRDF()$> in vec2 varTexCoord0; out vec4 _fragColor; @@ -32,6 +32,9 @@ vec3 evalScatteringBRDF(vec2 texcoord) { vec3 normal = fragment.normal; // .getWorldNormal(varTexCoord0); vec4 blurredCurvature = fetchCurvature(texcoord); vec4 diffusedCurvature = fetchDiffusedCurvature(texcoord); + vec3 midNormal = normalize((blurredCurvature.xyz - 0.5f) * 2.0f); + vec3 lowNormal = normalize((diffusedCurvature.xyz - 0.5f) * 2.0f); + float curvature = unpackCurvature(diffusedCurvature.w); // Transform directions to worldspace @@ -44,22 +47,8 @@ vec3 evalScatteringBRDF(vec2 texcoord) { vec3 fragLightDir = -normalize(getLightDirection(light)); - vec3 midNormal = normalize((blurredCurvature.xyz - 0.5f) * 2.0f); - vec3 lowNormal = normalize((diffusedCurvature.xyz - 0.5f) * 2.0f); - float curvature = unpackCurvature(diffusedCurvature.w); - if (showDiffusedNormal()) { - return diffusedCurvature.xyz; - return lowNormal * 0.5 + vec3(0.5); - } - if (showCurvature()) { - float curvatureSigned = unpackCurvatureSigned(diffusedCurvature.w); - return (curvatureSigned > 0 ? vec3(curvatureSigned, 0.0, 0.0) : vec3(0.0, 0.0, -curvatureSigned)); - } - - vec3 bentNdotL = evalScatteringBentNdotL(fragNormal, midNormal, lowNormal, fragLightDir); - - vec3 brdf = fetchBRDFSpectrum(bentNdotL, curvature); + vec3 brdf = evalSkinBRDF(fragLightDir, fragNormal, midNormal, lowNormal, curvature); return brdf; } @@ -70,7 +59,9 @@ vec3 drawScatteringTableUV(vec2 cursor, vec2 texcoord) { vec3 normal = fragment.normal; // .getWorldNormal(varTexCoord0); vec4 blurredCurvature = fetchCurvature(cursor); vec4 diffusedCurvature = fetchDiffusedCurvature(cursor); - + vec3 midNormal = normalize((blurredCurvature.xyz - 0.5f) * 2.0f); + vec3 lowNormal = normalize((diffusedCurvature.xyz - 0.5f) * 2.0f); + float curvature = unpackCurvature(diffusedCurvature.w); // Get light Light light = getLight(); @@ -78,10 +69,6 @@ vec3 drawScatteringTableUV(vec2 cursor, vec2 texcoord) { vec3 fragLightDir = -normalize(getLightDirection(light)); - vec3 midNormal = normalize((blurredCurvature.xyz - 0.5f) * 2.0f); - vec3 lowNormal = normalize((diffusedCurvature.xyz - 0.5f) * 2.0f); - float curvature = unpackCurvature(diffusedCurvature.w); - vec3 bentNdotL = evalScatteringBentNdotL(normal, midNormal, lowNormal, fragLightDir); // return clamp(bentNdotL * 0.5 + 0.5, 0.0, 1.0);