diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR.materialtype b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR.materialtype index d4b5882f21..846c3d0f34 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR.materialtype +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR.materialtype @@ -1154,7 +1154,7 @@ { "name": "thickness", "displayName": " Thickness", - "description": "Normalized global thickness, the maxima between this value (multiplied by thickness map if enabled) and thickness from shadow map (if applicable) will be used as final thickness of pixel", + "description": "In thick transmission mode: Normalized global thickness, the maxima between this value (multiplied by thickness map if enabled) and thickness from shadow map (if applicable) will be used as final thickness of pixel\n\nIn thin transmission mode: This value modulates the distance traversed by light inside an object.", "type": "float", "defaultValue": 0.5, "min": 0.0, @@ -1223,14 +1223,41 @@ "min": 0.0, "softMax": 20.0 }, + { + "name": "shrinkFactor", + "displayName": " Shrink Factor", + "description": "Shrink (absolute) offset towards the normal opposite direction to ensure correct shadow map projection", + "type": "float", + "defaultValue": 0.005, + "min": 0.0, + "softMax": 0.05 + }, + { + "name": "transmissionNdLBias", + "displayName": " Angle Bias", + "description": "cosine of angle to extend below (N . L = 0) in scattering through thin objects", + "type": "float", + "defaultValue": 0.1, + "min": -1.0, + "softMax": 1.0 + }, + { + "name": "distanceAttenuation", + "displayName": " Distance Attenuation", + "description": "Attenuation of the transmission effect, used to hide artifacts due to low-res shadow maps\nFor directional lights: attenuation proportional to the distance from the object to the camera.\nFor other light sources: attenuation proportional to the distance from the object to the light source.", + "type": "float", + "defaultValue": 0.5, + "min": 0.0, + "softMax": 4.0 + }, { "name": "transmissionScale", "displayName": " Scale", "description": "Strength of transmission", "type": "float", - "defaultValue": 3.0, + "defaultValue": 1.0, "min": 0.0, - "softMax": 20.0 + "softMax": 5.0 } ], "detailLayerGroup": [ @@ -1555,6 +1582,9 @@ "power": "subsurfaceScattering.transmissionPower", "distortion": "subsurfaceScattering.transmissionDistortion", "attenuation": "subsurfaceScattering.transmissionAttenuation", + "shrinkFactor": "subsurfaceScattering.shrinkFactor", + "transmissionNdLBias": "subsurfaceScattering.transmissionNdLBias", + "distanceAttenuation": "subsurfaceScattering.distanceAttenuation", "tintColor": "subsurfaceScattering.transmissionTint", "thickness": "subsurfaceScattering.thickness", "enabled": "subsurfaceScattering.enableSubsurfaceScattering", diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_Common.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_Common.azsli index 3c35ca65be..786b0db4d7 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_Common.azsli +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_Common.azsli @@ -93,7 +93,7 @@ ShaderResourceGroup MaterialSrg : SRG_PerMaterial // Elements of m_transmissionParams: // Thick object mode: (attenuation coefficient, power, distortion, scale) - // Thin object mode: (float3 scatter distance, scale) + // Thin object mode: (shrinkFactor, transmissionNdLBias, distanceAttenuation, scale) float4 m_transmissionParams; // (float3 TintColor, thickness) diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl index 4b37f67930..8458ca11a2 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl @@ -243,6 +243,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float surface.transmission.tint = transmissionTintThickness.rgb; surface.transmission.thickness = transmissionTintThickness.w; surface.transmission.transmissionParams = MaterialSrg::m_transmissionParams; + surface.transmission.scatterDistance = MaterialSrg::m_scatterDistance; // ------- Anisotropy ------- @@ -275,6 +276,17 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float lightingData.diffuseAmbientOcclusion = GetOcclusionInput(MaterialSrg::m_diffuseOcclusionMap, MaterialSrg::m_sampler, IN.m_uv[MaterialSrg::m_diffuseOcclusionMapUvIndex], MaterialSrg::m_diffuseOcclusionFactor, o_diffuseOcclusion_useTexture); lightingData.specularOcclusion = GetOcclusionInput(MaterialSrg::m_specularOcclusionMap, MaterialSrg::m_sampler, IN.m_uv[MaterialSrg::m_specularOcclusionMapUvIndex], MaterialSrg::m_specularOcclusionFactor, o_specularOcclusion_useTexture); + // ------- Thin Object Light Transmission ------- + + // Shrink (absolute) offset towards the normal opposite direction to ensure correct shadow map projection + lightingData.shrinkFactor = surface.transmission.transmissionParams.x; + + // Angle offset for subsurface scattering through thin objects + lightingData.transmissionNdLBias = surface.transmission.transmissionParams.y; + + // Attenuation applied to hide artifacts due to low-res shadow maps + lightingData.distanceAttenuation = surface.transmission.transmissionParams.z; + // ------- Clearcoat ------- // [GFX TODO][ATOM-14603]: Clean up the double uses of these clear coat flags diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_SubsurfaceState.lua b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_SubsurfaceState.lua index e705d7867a..1f1979e3a9 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_SubsurfaceState.lua +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_SubsurfaceState.lua @@ -92,23 +92,34 @@ function ProcessEditor(context) -- Update visibility for transmission... - local transmissionEnabled = TransmissionMode_None ~= context:GetMaterialPropertyValue_enum("subsurfaceScattering.transmissionMode") - - local commonTrasmissionVisibility - if(transmissionEnabled) then + local thickTransmissionEnabled = TransmissionMode_ThickObject == context:GetMaterialPropertyValue_enum("subsurfaceScattering.transmissionMode") + local thinTransmissionEnabled = TransmissionMode_ThinObject == context:GetMaterialPropertyValue_enum("subsurfaceScattering.transmissionMode") + + local commonTrasmissionVisibility = MaterialPropertyVisibility_Hidden + local thickTransmissionVisibility = MaterialPropertyVisibility_Hidden + local thinTransmissionVisibility = MaterialPropertyVisibility_Hidden + if (thickTransmissionEnabled or thinTransmissionEnabled) then commonTrasmissionVisibility = MaterialPropertyVisibility_Enabled - else - commonTrasmissionVisibility = MaterialPropertyVisibility_Hidden + + if(thickTransmissionEnabled) then + thickTransmissionVisibility = MaterialPropertyVisibility_Enabled + else -- thin transmission enabled + thinTransmissionVisibility = MaterialPropertyVisibility_Enabled + end end context:SetMaterialPropertyVisibility("subsurfaceScattering.thickness", commonTrasmissionVisibility) context:SetMaterialPropertyVisibility("subsurfaceScattering.thicknessMap", commonTrasmissionVisibility) context:SetMaterialPropertyVisibility("subsurfaceScattering.transmissionTint", commonTrasmissionVisibility) - context:SetMaterialPropertyVisibility("subsurfaceScattering.transmissionPower", commonTrasmissionVisibility) - context:SetMaterialPropertyVisibility("subsurfaceScattering.transmissionDistortion", commonTrasmissionVisibility) - context:SetMaterialPropertyVisibility("subsurfaceScattering.transmissionAttenuation", commonTrasmissionVisibility) + context:SetMaterialPropertyVisibility("subsurfaceScattering.transmissionPower", thickTransmissionVisibility) + context:SetMaterialPropertyVisibility("subsurfaceScattering.transmissionDistortion", thickTransmissionVisibility) + context:SetMaterialPropertyVisibility("subsurfaceScattering.transmissionAttenuation", thickTransmissionVisibility) + context:SetMaterialPropertyVisibility("subsurfaceScattering.shrinkFactor", thinTransmissionVisibility) + context:SetMaterialPropertyVisibility("subsurfaceScattering.transmissionNdLBias", thinTransmissionVisibility) + context:SetMaterialPropertyVisibility("subsurfaceScattering.distanceAttenuation", thinTransmissionVisibility) context:SetMaterialPropertyVisibility("subsurfaceScattering.transmissionScale", commonTrasmissionVisibility) - UpdateTextureDependentPropertyVisibility(context, transmissionEnabled, "subsurfaceScattering.thicknessMap", "subsurfaceScattering.useThicknessMap", "subsurfaceScattering.thicknessMapUv") + + UpdateTextureDependentPropertyVisibility(context, thickTransmissionEnabled or thinTransmissionEnabled, "subsurfaceScattering.thicknessMap", "subsurfaceScattering.useThicknessMap", "subsurfaceScattering.thicknessMapUv") end diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl index 00dee50c93..27df159583 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl @@ -325,6 +325,7 @@ PbrLightingOutput SkinPS_Common(VSOutput IN) surface.transmission.tint = transmissionTintThickness.rgb; surface.transmission.thickness = transmissionTintThickness.w; surface.transmission.transmissionParams = MaterialSrg::m_transmissionParams; + surface.transmission.scatterDistance = MaterialSrg::m_scatterDistance; // ------- Lighting Data ------- @@ -341,6 +342,17 @@ PbrLightingOutput SkinPS_Common(VSOutput IN) lightingData.specularResponse = FresnelSchlickWithRoughness(lightingData.NdotV, surface.specularF0, surface.roughnessLinear); lightingData.diffuseResponse = 1.0 - lightingData.specularResponse; + // ------- Thin Object Light Transmission ------- + + // Shrink (absolute) offset towards the normal opposite direction to ensure correct shadow map projection + lightingData.shrinkFactor = surface.transmission.transmissionParams.x; + + // Angle offset for subsurface scattering through thin objects + lightingData.transmissionNdLBias = surface.transmission.transmissionParams.y; + + // Attenuation applied to hide artifacts due to low-res shadow maps + lightingData.distanceAttenuation = surface.transmission.transmissionParams.z; + // ------- Occlusion ------- lightingData.diffuseAmbientOcclusion = GetOcclusionInput(MaterialSrg::m_diffuseOcclusionMap, MaterialSrg::m_sampler, IN.m_uv[MaterialSrg::m_diffuseOcclusionMapUvIndex], MaterialSrg::m_diffuseOcclusionFactor, o_diffuseOcclusion_useTexture); diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.materialtype b/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.materialtype index a49eba7975..1edbd7e505 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.materialtype +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.materialtype @@ -568,7 +568,7 @@ { "name": "thickness", "displayName": " Thickness", - "description": "Normalized global thickness, the maxima between this value (multiplied by thickness map if enabled) and thickness from shadow map (if applicable) will be used as final thickness of pixel", + "description": "In thick transmission mode: Normalized global thickness, the maxima between this value (multiplied by thickness map if enabled) and thickness from shadow map (if applicable) will be used as final thickness of pixel\n\nIn thin transmission mode: This value modulates the distance traversed by light inside an object.", "type": "float", "defaultValue": 0.5, "min": 0.0, @@ -637,14 +637,41 @@ "min": 0.0, "softMax": 20.0 }, + { + "name": "shrinkFactor", + "displayName": " Shrink Factor", + "description": "Shrink (absolute) offset towards the normal opposite direction to ensure correct shadow map projection", + "type": "float", + "defaultValue": 0.005, + "min": 0.0, + "softMax": 0.05 + }, + { + "name": "transmissionNdLBias", + "displayName": " Angle Bias", + "description": "cosine of angle to extend below (N . L = 0) in scattering through thin objects", + "type": "float", + "defaultValue": 0.1, + "min": -1.0, + "softMax": 1.0 + }, + { + "name": "distanceAttenuation", + "displayName": " Distance Attenuation", + "description": "Attenuation of the transmission effect, used to hide artifacts due to low-res shadow maps\nFor directional lights: attenuation proportional to the distance from the object to the camera.\nFor other light sources: attenuation proportional to the distance from the object to the light source.", + "type": "float", + "defaultValue": 0.5, + "min": 0.0, + "softMax": 4.0 + }, { "name": "transmissionScale", "displayName": " Scale", "description": "Strength of transmission", "type": "float", - "defaultValue": 3.0, + "defaultValue": 1.0, "min": 0.0, - "softMax": 20.0 + "softMax": 5.0 } ], "wrinkleLayers": [ @@ -1011,6 +1038,9 @@ "power": "subsurfaceScattering.transmissionPower", "distortion": "subsurfaceScattering.transmissionDistortion", "attenuation": "subsurfaceScattering.transmissionAttenuation", + "shrinkFactor": "subsurfaceScattering.shrinkFactor", + "transmissionNdLBias": "subsurfaceScattering.transmissionNdLBias", + "distanceAttenuation": "subsurfaceScattering.distanceAttenuation", "tintColor": "subsurfaceScattering.transmissionTint", "thickness": "subsurfaceScattering.thickness", "enabled": "subsurfaceScattering.enableSubsurfaceScattering", diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin_Common.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin_Common.azsli index a94f203b23..9b3c29e96d 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin_Common.azsli +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin_Common.azsli @@ -22,6 +22,10 @@ #include "MaterialInputs/UvSetCount.azsli" #include "MaterialInputs/DetailMapsInput.azsli" +// Use human skin profile for thin object transmission (if enabled) +// Remove this line to use a custom profile based on the scatter color +#define USE_HUMAN_SKIN_PROFILE + ShaderResourceGroup MaterialSrg : SRG_PerMaterial { // Auto-generate material SRG fields for common inputs @@ -64,7 +68,7 @@ ShaderResourceGroup MaterialSrg : SRG_PerMaterial // Elements of m_transmissionParams: // Thick object mode: (attenuation coefficient, power, distortion, scale) - // Thin object mode: (float3 scatter distance, scale) + // Thin object mode: (shrinkFactor, transmissionNdLBias, distanceAttenuation, scale) float4 m_transmissionParams; // (float3 TintColor, thickness) diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/BackLighting.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/BackLighting.azsli index d33780641d..68bc60a8dd 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/BackLighting.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/BackLighting.azsli @@ -16,24 +16,28 @@ #include // Analytical integation (approximation) of diffusion profile over radius, could be replaced by other pre integrated kernels -// such as sum of Gaussian +// such as sum of Gaussian (see T(s)) float3 TransmissionKernel(float t, float3 s) { float3 exponent = s * t; return 0.25 * (1.0 / exp(exponent) + 3.0 / exp(exponent / 3.0)); } -float ThinObjectFalloff(const float3 surfaceNormal, const float3 dirToLight) +// [specific profile for human skin] +// Analytical integation (approximation) of diffusion profile over radius, could be precomputed in a LUT +// From d'Eon and Luebke (https://developer.nvidia.com/gpugems/gpugems3/part-iii-rendering/chapter-14-advanced-techniques-realistic-real-time-skin, section 14.4.7) +float3 T(float s) { - const float ndl = saturate(dot(-surfaceNormal, dirToLight)); - - // ndl works decently well but it can produce a harsh discontinuity in the area just before - // the shadow starts appearing on objects like cylinder and tubes. - // Smoothing out ndl does a decent enough job of removing this artifact. - return smoothstep(0, 1, ndl * ndl); + // dipoles and multipoles are approximated with sums of a small number of Gaussians with variable weights and variances + return float3(0.233, 0.455, 0.649) * exp(-s*s/0.0064) + + float3(0.1, 0.336, 0.344) * exp(-s*s/0.0484) + + float3(0.118, 0.198, 0.0) * exp(-s*s/0.187) + + float3(0.113, 0.007, 0.007) * exp(-s*s/0.567) + + float3(0.358, 0.004, 0.0) * exp(-s*s/1.99) + + float3(0.078, 0.0, 0.0) * exp(-s*s/7.41); } -float3 GetBackLighting(Surface surface, LightingData lightingData, float3 lightIntensity, float3 dirToLight, float shadowRatio) +float3 GetBackLighting(Surface surface, LightingData lightingData, float3 lightIntensity, float3 dirToLight, float transmissionDistance, float attenuationDistance) { float3 result = float3(0.0, 0.0, 0.0); @@ -52,7 +56,7 @@ float3 GetBackLighting(Surface surface, LightingData lightingData, float3 lightI // https://colinbarrebrisebois.com/2011/03/07/gdc-2011-approximating-translucency-for-a-fast-cheap-and-convincing-subsurface-scattering-look/ { - thickness = max(shadowRatio, surface.transmission.thickness); + thickness = max(transmissionDistance, surface.transmission.thickness); float transmittance = pow( saturate( dot( lightingData.dirToCamera, -normalize( dirToLight + surface.normal * transmissionParams.z ) ) ), transmissionParams.y ) * transmissionParams.w; float lamberAttenuation = exp(-thickness * transmissionParams.x) * saturate(1.0 - thickness); result = transmittance * lamberAttenuation * lightIntensity; @@ -60,18 +64,39 @@ float3 GetBackLighting(Surface surface, LightingData lightingData, float3 lightI break; case TransmissionMode::ThinObject: - // Thin object mode, using thin-film assumption proposed by Jimenez J. et al, 2010, "Real-Time Realistic Skin Translucency" + // Thin object mode, based on Jimenez J. et al, 2010, "Real-Time Realistic Skin Translucency" // http://www.iryoku.com/translucency/downloads/Real-Time-Realistic-Skin-Translucency.pdf - - float litRatio = 1.0 - shadowRatio; - if (litRatio) + { - const float thickness = surface.transmission.thickness * transmissionParams.w; - const float3 invScattering = rcp(transmissionParams.xyz); - const float falloff = ThinObjectFalloff(surface.normal, dirToLight); - result = TransmissionKernel(thickness, invScattering) * falloff * lightIntensity * litRatio; - } + // transmissionDistance < 0.0f means shadows are not enabled --> avoid unnecessary computation + if (transmissionDistance < 0.0f) + { + break; + } + + // Irradiance arround surface point. + // Albedo at front (surface point) is used to approximate irradiance at the back of the object (observation 4 in [Jimenez J. et al, 2010]) + // Increase angle of influence to smooth transition regions + float3 E = surface.albedo * saturate(lightingData.transmissionNdLBias + dot(-surface.normal, dirToLight)); + + // Transmission distance modulated by hardcoded constant C and the thickness exposed parameter (in this case modulating the distance traversed by the light inside the object) + const float C = 300.0f; + float s = transmissionDistance * C * surface.transmission.thickness; + + // Use scattering color to weight thin object transmission color + const float3 invScattering = rcp(max(surface.transmission.scatterDistance, float(0.00001))); + +#ifndef USE_HUMAN_SKIN_PROFILE + // Generic profile based on scatter color + result = TransmissionKernel(s, invScattering) * lightIntensity * E * transmissionParams.w; +#else // USE_HUMAN_SKIN_PROFILE + // Profile specific to human skin + result = T(s) * lightIntensity * E * transmissionParams.w; +#endif + // Distance attenuation applied to hide artifacts due to low-res projected areas onto shadowmaps (might need some work in the future) + result /= max(1.0, attenuationDistance * attenuationDistance * lightingData.distanceAttenuation); + } break; } diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lighting/LightingData.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lighting/LightingData.azsli index 721c9e13cc..7fe5f278da 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lighting/LightingData.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lighting/LightingData.azsli @@ -28,6 +28,15 @@ class LightingData // Direction light shadow coordinates float3 shadowCoords[ViewSrg::MaxCascadeCount]; + // (N . L) to accept below (N . L = 0) in scattering through thin objects + float transmissionNdLBias; + + // Shrink (absolute) offset towards the normal opposite direction to ensure correct shadow map projection + float shrinkFactor; + + // Attenuation applied to hide artifacts due to low-res shadow maps + float distanceAttenuation; + // Normalized direction from surface to camera float3 dirToCamera; diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/CapsuleLight.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/CapsuleLight.azsli index 733ea2dbea..17fd27849d 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/CapsuleLight.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/CapsuleLight.azsli @@ -135,8 +135,15 @@ void ApplyCapsuleLight(ViewSrg::CapsuleLight light, Surface surface, inout Light float3 closestIntersectionPoint = startPoint + closestT * startToEnd; float3 posToLight = closestIntersectionPoint - surface.position; - // Tranmission contribution - lightingData.translucentBackLighting += GetBackLighting(surface, lightingData, lightIntensity, normalize(posToLight), 0.0); + // Transmission contribution + // We cannot compute the actual transmission distance so we want to: + // - If transmission mode is thick object -> use transmission thickness parameter instead + // - If transmission mode is thin object -> ignore back lighting + // To detect and apply this behavior in the GetBackLighting function, we need to use a negative transmissionDistance + const float transmissionDistance = -1.0f; + // If the transmissionDistance is ignored then the attenuation distance (only used on thin objects) does not have any influence + const float attenuationDistance = 0.0f; + lightingData.translucentBackLighting += GetBackLighting(surface, lightingData, lightIntensity, normalize(posToLight), transmissionDistance, attenuationDistance); // Calculate the offset from the nearest point on the reflection vector to the nearest point on the capsule light float3 posToClosestPointAlongReflection = dot(posToLight, reflectionDir) * reflectionDir; diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/DirectionalLight.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/DirectionalLight.azsli index 7cf10f13a3..03c48b6232 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/DirectionalLight.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/DirectionalLight.azsli @@ -18,7 +18,13 @@ void ApplyDirectionalLights(Surface surface, inout LightingData lightingData) // Shadowed check const uint shadowIndex = ViewSrg::m_shadowIndexDirectionalLight; float litRatio = 1.0f; - float backShadowRatio = 0.0f; + float camToSurfDist = distance(ViewSrg::m_worldPosition, surface.position); + + // Distance travelled by the light inside the object. If not redefined to a non-negative value, it will take the following behavior: + // - If transmission mode is thick object -> use transmission thickness parameter instead + // - If transmission mode is thin object -> ignore back lighting + float transmissionDistance = -1.0f; + if (o_enableShadows && shadowIndex < SceneSrg::m_directionalLightCount) { litRatio = DirectionalLightShadow::GetVisibility( @@ -30,7 +36,19 @@ void ApplyDirectionalLights(Surface surface, inout LightingData lightingData) #if ENABLE_TRANSMISSION if (o_transmission_mode == TransmissionMode::ThickObject) { - backShadowRatio = DirectionalLightShadow::GetThickness(shadowIndex, lightingData.shadowCoords); + transmissionDistance = DirectionalLightShadow::GetThickness(shadowIndex, lightingData.shadowCoords); + } + else if (o_transmission_mode == TransmissionMode::ThinObject) + { + // Fetch and use shrinked positions for thin object transmission to ensure they fall onto the object when querying + DirectionalLightShadow::GetShadowCoords( + shadowIndex, + surface.position - lightingData.shrinkFactor * surface.vertexNormal, + surface.normal, + lightingData.shadowCoords); + + // the depth from the shadow map + transmissionDistance = DirectionalLightShadow::GetThickness(shadowIndex, lightingData.shadowCoords); } #endif } @@ -52,23 +70,20 @@ void ApplyDirectionalLights(Surface surface, inout LightingData lightingData) // [GFX TODO][ATOM-2012] care of multiple directional light // Currently shadow check is done only for index == shadowIndex. float currentLitRatio = 1.0f; - float currentBackShadowRatio = 1.0f; - if (o_enableShadows) + float currentTransmissionDistance = -1.0f; + + if (o_enableShadows && index == shadowIndex) { - currentLitRatio = (index == shadowIndex) ? litRatio : 1.; - - currentBackShadowRatio = 1.0 - currentLitRatio; -#if ENABLE_TRANSMISSION - if (o_transmission_mode == TransmissionMode::ThickObject) - { - currentBackShadowRatio = (index == shadowIndex) ? backShadowRatio : 0.; - } -#endif + // Add contribution only if current directional light is the active one for shadows + currentLitRatio = litRatio; + currentTransmissionDistance = transmissionDistance; } + + // Transmission contribution + lightingData.translucentBackLighting += GetBackLighting(surface, lightingData, light.m_rgbIntensityLux, dirToLight, currentTransmissionDistance, camToSurfDist); lightingData.diffuseLighting += GetDiffuseLighting(surface, lightingData, light.m_rgbIntensityLux, dirToLight) * currentLitRatio; lightingData.specularLighting += GetSpecularLighting(surface, lightingData, light.m_rgbIntensityLux, dirToLight) * currentLitRatio; - lightingData.translucentBackLighting += GetBackLighting(surface, lightingData, light.m_rgbIntensityLux, dirToLight, currentBackShadowRatio); } // Add debug coloring for directional light shadow diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/DiskLight.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/DiskLight.azsli index 79b377c568..fff37c5d4c 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/DiskLight.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/DiskLight.azsli @@ -76,9 +76,12 @@ void ApplyDiskLight(ViewSrg::DiskLight light, Surface surface, inout LightingDat // shadow float litRatio = 1.0; - - // How much is back face shadowed, it's set to the reverse of litRatio to share the same default value with thickness, which should be 0 if no shadow map available - float backShadowRatio = 0.0; + + // Distance travelled by the light inside the object. If not redefined to a non-negative value, it will take the following behavior: + // - If transmission mode is thick object -> use transmission thickness parameter instead + // - If transmission mode is thin object -> ignore back lighting + float transmissionDistance = -1.0f; + if (o_enableShadows) { litRatio = ProjectedShadow::GetVisibility( @@ -88,14 +91,16 @@ void ApplyDiskLight(ViewSrg::DiskLight light, Surface surface, inout LightingDat -dirToConeTip, surface.vertexNormal); - // Use backShadowRatio to carry thickness from shadow map for thick mode - backShadowRatio = 1.0 - litRatio; + + // o_transmission_mode == NONE is not taken into account because GetBackLighting already ignores this case #if ENABLE_TRANSMISSION if (o_transmission_mode == TransmissionMode::ThickObject) { - backShadowRatio = ProjectedShadow::GetThickness( - light.m_shadowIndex, - surface.position); + transmissionDistance = ProjectedShadow::GetThickness(light.m_shadowIndex, surface.position); + } + else if (o_transmission_mode == TransmissionMode::ThinObject) + { + transmissionDistance = ProjectedShadow::GetThickness(light.m_shadowIndex, surface.position - lightingData.shrinkFactor * surface.vertexNormal); } #endif } @@ -115,8 +120,8 @@ void ApplyDiskLight(ViewSrg::DiskLight light, Surface surface, inout LightingDat lightingData.diffuseLighting += GetDiffuseLighting(surface, lightingData, lightIntensity, posToLightDir) * litRatio; // Transmission contribution - lightingData.translucentBackLighting += GetBackLighting(surface, lightingData, lightIntensity, posToLightDir, backShadowRatio); - + lightingData.translucentBackLighting += GetBackLighting(surface, lightingData, lightIntensity, posToLightDir, transmissionDistance, distanceToLight2); + // Adjust the light direction for specular based on disk size // Calculate the reflection off the normal from the view direction diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/LightTypesCommon.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/LightTypesCommon.azsli index 16adbba280..5eeec270f9 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/LightTypesCommon.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/LightTypesCommon.azsli @@ -46,6 +46,16 @@ void AddSampleContribution( float3 intensityRgb = float3(intensity, intensity, intensity); diffuseAcc += GetDiffuseLighting(surface, lightingData, intensityRgb, posToLightSampleDir); - translucentAcc += GetBackLighting(surface, lightingData, intensityRgb, posToLightSampleDir, 0.0); + + // Transmission contribution + // We cannot compute the actual transmission distance so we want to: + // - If transmission mode is thick object -> use transmission thickness parameter instead + // - If transmission mode is thin object -> ignore back lighting + // To detect and apply this behavior in the GetBackLighting function, we need to use a negative transmissionDistance + const float transmissionDistance = -1.0f; + // If the transmissionDistance is ignored then the attenuation distance (only used on thin objects) does not have any influence + const float attenuationDistance = 0.0f; + translucentAcc += GetBackLighting(surface, lightingData, intensityRgb, posToLightSampleDir, transmissionDistance, attenuationDistance); + specularAcc += GetSpecularLighting(surface, lightingData, intensityRgb, posToLightSampleDir); } diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli index 883d86af48..2429ec1542 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli @@ -67,6 +67,7 @@ uint ComputeShadowIndex(const ViewSrg::PointLight light, const Surface surface) void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingData lightingData) { float3 posToLight = light.m_position - surface.position; + float posToLightDist = length(posToLight); float d2 = dot(posToLight, posToLight); // light distance squared float falloff = d2 * light.m_invAttenuationRadiusSquared; @@ -84,8 +85,11 @@ void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingD // shadow float litRatio = 1.0; - // How much is back face shadowed, it's set to the reverse of litRatio to share the same default value with thickness, which should be 0 if no shadow map available - float backShadowRatio = 0.0; + // Distance travelled by the light inside the object. If not redefined to a non-negative value, it will take the following behavior: + // - If transmission mode is thick object -> use transmission thickness parameter instead + // - If transmission mode is thin object -> ignore back lighting + float transmissionDistance = -1.0f; + if (o_enableShadows) { const float3 lightDir = normalize(light.m_position - surface.position); @@ -96,16 +100,17 @@ void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingD surface.position, lightDir, surface.vertexNormal); - - // Use backShadowRatio to carry thickness from shadow map for thick mode - backShadowRatio = 1.0 - litRatio; + #if ENABLE_TRANSMISSION + // o_transmission_mode == NONE is not taken into account because GetBackLighting already ignores this case if (o_transmission_mode == TransmissionMode::ThickObject) { - backShadowRatio = ProjectedShadow::GetThickness( - shadowIndex, - surface.position); - } + transmissionDistance = ProjectedShadow::GetThickness(shadowIndex, surface.position); + } + else if (o_transmission_mode == TransmissionMode::ThinObject) + { + transmissionDistance = ProjectedShadow::GetThickness(shadowIndex, surface.position - lightingData.shrinkFactor * surface.vertexNormal); + } #endif } @@ -113,7 +118,7 @@ void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingD lightingData.diffuseLighting += GetDiffuseLighting(surface, lightingData, lightIntensity, normalize(posToLight)) * litRatio; // Transmission contribution - lightingData.translucentBackLighting += GetBackLighting(surface, lightingData, lightIntensity, normalize(posToLight), backShadowRatio); + lightingData.translucentBackLighting += GetBackLighting(surface, lightingData, lightIntensity, normalize(posToLight), transmissionDistance, posToLightDist); // Adjust the light direcion for specular based on bulb size diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/QuadLight.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/QuadLight.azsli index a705e663c2..a2bf7cccf1 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/QuadLight.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/QuadLight.azsli @@ -148,13 +148,21 @@ void ApplyQuadLight(ViewSrg::QuadLight light, Surface surface, inout LightingDat GetDiffuseLighting(surface, lightingData, intensity, dirToLightCenter) ); + // Transmission contribution + // We cannot compute the actual transmission distance so we want to: + // - If transmission mode is thick object -> use transmission thickness parameter instead + // - If transmission mode is thin object -> ignore back lighting + // To detect and apply this behavior in the GetBackLighting function, we need to use a negative transmissionDistance + const float transmissionDistance = -1.0f; + // If the transmissionDistance is ignored then the attenuation distance (only used on thin objects) does not have any influence + const float attenuationDistance = 0.0f; lightingData.translucentBackLighting += ( - GetBackLighting(surface, lightingData, intensity, p0, 0.0) + - GetBackLighting(surface, lightingData, intensity, p1, 0.0) + - GetBackLighting(surface, lightingData, intensity, p2, 0.0) + - GetBackLighting(surface, lightingData, intensity, p3, 0.0) + - GetBackLighting(surface, lightingData, intensity, dirToLightCenter, 0.0) + GetBackLighting(surface, lightingData, intensity, p0, transmissionDistance, attenuationDistance) + + GetBackLighting(surface, lightingData, intensity, p1, transmissionDistance, attenuationDistance) + + GetBackLighting(surface, lightingData, intensity, p2, transmissionDistance, attenuationDistance) + + GetBackLighting(surface, lightingData, intensity, p3, transmissionDistance, attenuationDistance) + + GetBackLighting(surface, lightingData, intensity, dirToLightCenter, transmissionDistance, attenuationDistance) ); // Calculate specular by choosing a single representative point on the light's surface based on the reflection ray diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/TransmissionSurfaceData.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/TransmissionSurfaceData.azsli index dda62d85e5..a31b347960 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/TransmissionSurfaceData.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Surfaces/TransmissionSurfaceData.azsli @@ -14,7 +14,8 @@ class TransmissionSurfaceData { float3 tint; float thickness; //!< pre baked local thickness, used for transmission - float4 transmissionParams; //!< parameters: thick mode->(attenuation coefficient, power, distortion, scale), thin mode: (float3 scatter distance, scale) + float4 transmissionParams; //!< parameters: thick mode->(attenuation coefficient, power, distortion, scale), thin mode: (shrinkFactor, transmissionNdLBias, distanceAttenuation, scale) + float3 scatterDistance; //!< scatter distance (same as in MaterialSrg) > void InitializeToZero(); }; @@ -24,6 +25,7 @@ void TransmissionSurfaceData::InitializeToZero() tint = float3(0.0f, 0.0f, 0.0f); thickness = 0.0f; transmissionParams = float4(0.0f, 0.0f, 0.0f, 0.0f); + scatterDistance = float3(0.0f, 0.0f, 0.0f); } #endif diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Shadow/DirectionalLightShadow.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Shadow/DirectionalLightShadow.azsli index 870bebdf4b..f44b4e422b 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Shadow/DirectionalLightShadow.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Shadow/DirectionalLightShadow.azsli @@ -161,7 +161,10 @@ float DirectionalLightShadow::GetThickness(uint lightIndex, float3 shadowCoords[ shadowCoord.y >= 0. && shadowCoord.y * size < size - PixelMargin && shadowCoord.z < (1. - DepthMargin)) { const float depthBufferValue = shadowmap.Sample(PassSrg::LinearSampler, float3(shadowCoord.xy, indexOfCascade)).r; - const float deltaDepth = abs(shadowCoord.z - depthBufferValue); + + // Normalized thickness (avoid negative values given by precision errors or shrinking offsets) + const float deltaDepth = max(shadowCoord.z - depthBufferValue,0.0); + const float viewSpaceThickness = ViewSrg::m_directionalLightShadows[lightIndex].m_far_minus_near * deltaDepth; return viewSpaceThickness; } diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Shadow/ProjectedShadow.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Shadow/ProjectedShadow.azsli index 98ec9ea8bc..e6bdc13293 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Shadow/ProjectedShadow.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Shadow/ProjectedShadow.azsli @@ -274,8 +274,9 @@ float ProjectedShadow::GetThickness() float3(atlasPosition.xy * invAtlasSize, atlasPosition.z), /*LOD=*/0 ).r; - - const float viewSpaceThickness = abs(UnprojectDepth(m_shadowIndex, m_shadowPosition.z) - UnprojectDepth(m_shadowIndex, depthValue)); + + // Denormalized thickness (avoid negative values given by precision errors or shrinking offsets) + const float viewSpaceThickness = max(UnprojectDepth(m_shadowIndex, depthValue) - UnprojectDepth(m_shadowIndex, m_shadowPosition.z), 0.0); return viewSpaceThickness; } diff --git a/Gems/Atom/Feature/Common/Code/Source/Material/SubsurfaceTransmissionParameterFunctor.cpp b/Gems/Atom/Feature/Common/Code/Source/Material/SubsurfaceTransmissionParameterFunctor.cpp index 8c42160fff..b5d38e25fc 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Material/SubsurfaceTransmissionParameterFunctor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Material/SubsurfaceTransmissionParameterFunctor.cpp @@ -26,6 +26,9 @@ namespace AZ ->Field("m_power", &SubsurfaceTransmissionParameterFunctor::m_power) ->Field("m_distortion", &SubsurfaceTransmissionParameterFunctor::m_distortion) ->Field("m_attenuation", &SubsurfaceTransmissionParameterFunctor::m_attenuation) + ->Field("m_shrinkFactor", &SubsurfaceTransmissionParameterFunctor::m_shrinkFactor) + ->Field("m_transmissionNdLBias", &SubsurfaceTransmissionParameterFunctor::m_transmissionNdLBias) + ->Field("m_distanceAttenuation", &SubsurfaceTransmissionParameterFunctor::m_distanceAttenuation) ->Field("m_tintColor", &SubsurfaceTransmissionParameterFunctor::m_tintColor) ->Field("m_thickness", &SubsurfaceTransmissionParameterFunctor::m_thickness) ->Field("m_enabled", &SubsurfaceTransmissionParameterFunctor::m_enabled) @@ -50,6 +53,9 @@ namespace AZ auto power = context.GetMaterialPropertyValue(m_power); auto distortion = context.GetMaterialPropertyValue(m_distortion); auto attenuation = context.GetMaterialPropertyValue(m_attenuation); + auto shrinkFactor = context.GetMaterialPropertyValue(m_shrinkFactor); + auto transmissionNdLBias = context.GetMaterialPropertyValue(m_transmissionNdLBias); + auto distanceAttenuation = context.GetMaterialPropertyValue(m_distanceAttenuation); auto tintColor = context.GetMaterialPropertyValue(m_tintColor); auto thickness = context.GetMaterialPropertyValue(m_thickness); auto scatterDistanceColor = context.GetMaterialPropertyValue(m_scatterDistanceColor); @@ -67,7 +73,9 @@ namespace AZ } else { - transmissionParams.Set(scatterDistance); + transmissionParams.SetX(shrinkFactor); + transmissionParams.SetY(transmissionNdLBias); + transmissionParams.SetZ(distanceAttenuation); transmissionParams.SetW(scale); } diff --git a/Gems/Atom/Feature/Common/Code/Source/Material/SubsurfaceTransmissionParameterFunctor.h b/Gems/Atom/Feature/Common/Code/Source/Material/SubsurfaceTransmissionParameterFunctor.h index e412687947..17096e71a5 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Material/SubsurfaceTransmissionParameterFunctor.h +++ b/Gems/Atom/Feature/Common/Code/Source/Material/SubsurfaceTransmissionParameterFunctor.h @@ -37,6 +37,9 @@ namespace AZ RPI::MaterialPropertyIndex m_power; RPI::MaterialPropertyIndex m_distortion; RPI::MaterialPropertyIndex m_attenuation; + RPI::MaterialPropertyIndex m_shrinkFactor; + RPI::MaterialPropertyIndex m_transmissionNdLBias; + RPI::MaterialPropertyIndex m_distanceAttenuation; RPI::MaterialPropertyIndex m_tintColor; RPI::MaterialPropertyIndex m_thickness; RPI::MaterialPropertyIndex m_enabled; diff --git a/Gems/Atom/Feature/Common/Code/Source/Material/SubsurfaceTransmissionParameterFunctorSourceData.cpp b/Gems/Atom/Feature/Common/Code/Source/Material/SubsurfaceTransmissionParameterFunctorSourceData.cpp index a8ba40fb7f..140dfe8c6b 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Material/SubsurfaceTransmissionParameterFunctorSourceData.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Material/SubsurfaceTransmissionParameterFunctorSourceData.cpp @@ -25,6 +25,9 @@ namespace AZ ->Field("power", &SubsurfaceTransmissionParameterFunctorSourceData::m_power) ->Field("distortion", &SubsurfaceTransmissionParameterFunctorSourceData::m_distortion) ->Field("attenuation", &SubsurfaceTransmissionParameterFunctorSourceData::m_attenuation) + ->Field("shrinkFactor", &SubsurfaceTransmissionParameterFunctorSourceData::m_shrinkFactor) + ->Field("transmissionNdLBias", &SubsurfaceTransmissionParameterFunctorSourceData::m_transmissionNdLBias) + ->Field("distanceAttenuation", &SubsurfaceTransmissionParameterFunctorSourceData::m_distanceAttenuation) ->Field("tintColor", &SubsurfaceTransmissionParameterFunctorSourceData::m_tintColor) ->Field("thickness", &SubsurfaceTransmissionParameterFunctorSourceData::m_thickness) ->Field("enabled", &SubsurfaceTransmissionParameterFunctorSourceData::m_enabled) @@ -48,6 +51,9 @@ namespace AZ functor->m_power = context.FindMaterialPropertyIndex(Name{ m_power }); functor->m_distortion = context.FindMaterialPropertyIndex(Name{ m_distortion }); functor->m_attenuation = context.FindMaterialPropertyIndex(Name{ m_attenuation }); + functor->m_shrinkFactor = context.FindMaterialPropertyIndex(Name{ m_shrinkFactor }); + functor->m_transmissionNdLBias = context.FindMaterialPropertyIndex(Name{ m_transmissionNdLBias }); + functor->m_distanceAttenuation = context.FindMaterialPropertyIndex(Name{ m_distanceAttenuation }); functor->m_tintColor = context.FindMaterialPropertyIndex(Name{ m_tintColor }); functor->m_thickness = context.FindMaterialPropertyIndex(Name{ m_thickness }); functor->m_enabled = context.FindMaterialPropertyIndex(Name{ m_enabled }); @@ -56,7 +62,8 @@ namespace AZ if (functor->m_mode.IsNull() || functor->m_scale.IsNull() || functor->m_power.IsNull() || functor->m_distortion.IsNull() || functor->m_tintColor.IsNull() || functor->m_thickness.IsNull() || functor->m_enabled.IsNull() || functor->m_attenuation.IsNull() || functor->m_scatterDistanceColor.IsNull() || - functor->m_scatterDistanceIntensity.IsNull()) + functor->m_scatterDistanceIntensity.IsNull() || functor->m_shrinkFactor.IsNull() || functor->m_transmissionNdLBias.IsNull() || + functor->m_distanceAttenuation.IsNull()) { return Failure(); } @@ -66,6 +73,9 @@ namespace AZ AddMaterialPropertyDependency(functor, functor->m_power); AddMaterialPropertyDependency(functor, functor->m_distortion); AddMaterialPropertyDependency(functor, functor->m_attenuation); + AddMaterialPropertyDependency(functor, functor->m_shrinkFactor); + AddMaterialPropertyDependency(functor, functor->m_transmissionNdLBias); + AddMaterialPropertyDependency(functor, functor->m_distanceAttenuation); AddMaterialPropertyDependency(functor, functor->m_tintColor); AddMaterialPropertyDependency(functor, functor->m_thickness); AddMaterialPropertyDependency(functor, functor->m_enabled); diff --git a/Gems/Atom/Feature/Common/Code/Source/Material/SubsurfaceTransmissionParameterFunctorSourceData.h b/Gems/Atom/Feature/Common/Code/Source/Material/SubsurfaceTransmissionParameterFunctorSourceData.h index 9d074551c3..8d058243fa 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Material/SubsurfaceTransmissionParameterFunctorSourceData.h +++ b/Gems/Atom/Feature/Common/Code/Source/Material/SubsurfaceTransmissionParameterFunctorSourceData.h @@ -36,6 +36,9 @@ namespace AZ AZStd::string m_power; //!< material property for thick transmission power AZStd::string m_distortion; //!< material property for thick transmission distortion towards surface normal AZStd::string m_attenuation; //!< material property for thick transmission volume absorption + AZStd::string m_shrinkFactor; //!< material property for thin transmission position shrink factor towards surface normal + AZStd::string m_transmissionNdLBias; //!< material property for thin transmission bias of the NdL value + AZStd::string m_distanceAttenuation; //!< material property for thin transmission attenuation with distance AZStd::string m_tintColor; //!< material property for transmission tint AZStd::string m_thickness; //!< material property for normalized object thickness AZStd::string m_enabled; //!< material property for subsurface scattering feature switch (enabled or disabled)