Refactor thin transmission factor variable packing and visibility + use thickness to modulate transmission distance

Signed-off-by: Santi Paprika <santi.gonzalez.cs@gmail.com>
This commit is contained in:
Santi Paprika
2022-01-10 18:19:39 +01:00
parent 0f766d92d3
commit d0bb222ce6
13 changed files with 89 additions and 74 deletions
@@ -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,
@@ -1230,24 +1230,16 @@
"type": "float",
"defaultValue": 0.005,
"min": 0.0,
"softMax": 0.05,
"connection": {
"type": "ShaderInput",
"name": "m_shrinkFactor"
}
"softMax": 0.05
},
{
"name": "transmissionAngleBias",
"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,
"connection": {
"type": "ShaderInput",
"name": "m_transmissionNdLBias"
}
"softMax": 1.0
},
{
"name": "distanceAttenuation",
@@ -1256,20 +1248,16 @@
"type": "float",
"defaultValue": 0.5,
"min": 0.0,
"softMax": 4.0,
"connection": {
"type": "ShaderInput",
"name": "m_distanceAttenuation"
}
"softMax": 4.0
},
{
"name": "transmissionScale",
"displayName": " Scale",
"description": "Strength of transmission",
"type": "float",
"defaultValue": 0.01,
"defaultValue": 1.0,
"min": 0.0,
"softMax": 1.0
"softMax": 5.0
}
],
"detailLayerGroup": [
@@ -1594,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",
@@ -93,16 +93,13 @@ 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)
float4 m_transmissionTintThickness;
Texture2D m_transmissionThicknessMap;
uint m_transmissionThicknessMapUvIndex;
float m_shrinkFactor;
float m_transmissionNdLBias;
float m_distanceAttenuation;
}
// Callback function for ParallaxMapping.azsli
@@ -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 -------
@@ -277,14 +278,14 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
// ------- Thin Object Light Transmission -------
// Angle offset for subsurface scattering through thin objects
lightingData.transmissionNdLBias = MaterialSrg::m_transmissionNdLBias;
// Shrink (absolute) offset towards the normal opposite direction to ensure correct shadow map projection
lightingData.shrinkFactor = MaterialSrg::m_shrinkFactor;
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 = MaterialSrg::m_distanceAttenuation;
lightingData.distanceAttenuation = surface.transmission.transmissionParams.z;
// ------- Clearcoat -------
@@ -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
@@ -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 -------
@@ -343,14 +344,14 @@ PbrLightingOutput SkinPS_Common(VSOutput IN)
// ------- Thin Object Light Transmission -------
// Angle offset for subsurface scattering through thin objects
lightingData.transmissionNdLBias = MaterialSrg::m_transmissionNdLBias;
// Shrink (absolute) offset towards the normal opposite direction to ensure correct shadow map projection
lightingData.shrinkFactor = MaterialSrg::m_shrinkFactor;
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 = MaterialSrg::m_distanceAttenuation;
lightingData.distanceAttenuation = surface.transmission.transmissionParams.z;
// ------- Occlusion -------
@@ -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,
@@ -644,24 +644,16 @@
"type": "float",
"defaultValue": 0.005,
"min": 0.0,
"softMax": 0.05,
"connection": {
"type": "ShaderInput",
"name": "m_shrinkFactor"
}
"softMax": 0.05
},
{
"name": "transmissionAngleBias",
"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,
"connection": {
"type": "ShaderInput",
"name": "m_transmissionNdLBias"
}
"softMax": 1.0
},
{
"name": "distanceAttenuation",
@@ -670,20 +662,16 @@
"type": "float",
"defaultValue": 0.5,
"min": 0.0,
"softMax": 4.0,
"connection": {
"type": "ShaderInput",
"name": "m_distanceAttenuation"
}
"softMax": 4.0
},
{
"name": "transmissionScale",
"displayName": " Scale",
"description": "Strength of transmission",
"type": "float",
"defaultValue": 0.01,
"defaultValue": 1.0,
"min": 0.0,
"softMax": 1.0
"softMax": 5.0
}
],
"wrinkleLayers": [
@@ -1050,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",
@@ -64,16 +64,13 @@ 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)
float4 m_transmissionTintThickness;
Texture2D m_transmissionThicknessMap;
uint m_transmissionThicknessMapUvIndex;
float m_shrinkFactor;
float m_transmissionNdLBias;
float m_distanceAttenuation;
Texture2D m_wrinkle_baseColor_texture1;
Texture2D m_wrinkle_baseColor_texture2;
@@ -75,19 +75,19 @@ float3 GetBackLighting(Surface surface, LightingData lightingData, float3 lightI
// Increase angle of influence (angle(N,L) -> angle(N,L) + acos(transmissionNdLBias)) to smooth transition regions
float3 E = surface.albedo * saturate(lightingData.transmissionNdLBias + dot(-surface.normal, dirToLight));
// Transmission distance modulated by hardcoded constant C (could be exposed as a weight of scattering distance for transmission)
const float C = 100.0f;
float s = transmissionDistance * C;
// 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(transmissionParams.xyz);
const float3 invScattering = rcp(max(surface.transmission.scatterDistance, float(0.00001)));
// Albedo at front (surface point) is used to approximate irradiance at the back of the object
// See observation 4 in [Jimenez J. et al, 2010]
result = TransmissionKernel(s, invScattering) * lightIntensity * E * transmissionParams.w;
// Alternative specific to skin translucency
// result = T(s) * lightIntensity * surface.albedo * E * transmissionParams.w;
// result = T(s) * lightIntensity * E * transmissionParams.w;
// 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);
@@ -12,7 +12,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();
};
@@ -22,4 +23,5 @@ 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);
}
@@ -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<float>(m_power);
auto distortion = context.GetMaterialPropertyValue<float>(m_distortion);
auto attenuation = context.GetMaterialPropertyValue<float>(m_attenuation);
auto shrinkFactor = context.GetMaterialPropertyValue<float>(m_shrinkFactor);
auto transmissionNdLBias = context.GetMaterialPropertyValue<float>(m_transmissionNdLBias);
auto distanceAttenuation = context.GetMaterialPropertyValue<float>(m_distanceAttenuation);
auto tintColor = context.GetMaterialPropertyValue<Color>(m_tintColor);
auto thickness = context.GetMaterialPropertyValue<float>(m_thickness);
auto scatterDistanceColor = context.GetMaterialPropertyValue<Color>(m_scatterDistanceColor);
@@ -67,7 +73,9 @@ namespace AZ
}
else
{
transmissionParams.Set(scatterDistance);
transmissionParams.SetX(shrinkFactor);
transmissionParams.SetY(transmissionNdLBias);
transmissionParams.SetZ(distanceAttenuation);
transmissionParams.SetW(scale);
}
@@ -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;
@@ -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);
@@ -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)