Add and expose distance attenuation to compensate low-res shadow maps

Signed-off-by: Santi Paprika <santi.gonzalez.cs@gmail.com>
This commit is contained in:
Santi Paprika
2021-12-10 13:57:04 +01:00
parent 78aa73e3fd
commit 90bf2520be
10 changed files with 60 additions and 6 deletions
@@ -1239,7 +1239,7 @@
{
"name": "angleOffset",
"displayName": " Angle Offset",
"description": "Angle to accept below (N . L = 0) in scattering through thin objects",
"description": "cosine of angle to extend below (N . L = 0) in scattering through thin objects",
"type": "float",
"defaultValue": 0.1,
"min": -1.0,
@@ -1249,6 +1249,19 @@
"name": "m_angleOffset"
}
},
{
"name": "distanceAttenuation",
"displayName": " Distance Attenuation",
"description": "Attenuation applied to hide artifacts due to low-res shadow maps (e.g. objects far to the camera when using directional lights or objects far to the light when using sphere/disk lights",
"type": "float",
"defaultValue": 4.0,
"min": 0.0,
"softMax": 10.0,
"connection": {
"type": "ShaderInput",
"name": "m_distanceAttenuation"
}
},
{
"name": "transmissionScale",
"displayName": " Scale",
@@ -102,6 +102,7 @@ ShaderResourceGroup MaterialSrg : SRG_PerMaterial
uint m_transmissionThicknessMapUvIndex;
float m_shrinkFactor;
float m_angleOffset;
float m_distanceAttenuation;
}
// Callback function for ParallaxMapping.azsli
@@ -283,6 +283,9 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
// Shrink (absolute) offset towards the normal opposite direction to ensure correct shadow map projection
lightingData.shrinkFactor = MaterialSrg::m_shrinkFactor;
// Attenuation applied to hide artifacts due to low-res shadow maps
lightingData.distanceAttenuation = MaterialSrg::m_distanceAttenuation;
// ------- Clearcoat -------
// [GFX TODO][ATOM-14603]: Clean up the double uses of these clear coat flags
@@ -349,6 +349,9 @@ PbrLightingOutput SkinPS_Common(VSOutput IN)
// Shrink (absolute) offset towards the normal opposite direction to ensure correct shadow map projection
lightingData.shrinkFactor = MaterialSrg::m_shrinkFactor;
// Attenuation applied to hide artifacts due to low-res shadow maps
lightingData.distanceAttenuation = MaterialSrg::m_distanceAttenuation;
// ------- Occlusion -------
lightingData.diffuseAmbientOcclusion = GetOcclusionInput(MaterialSrg::m_diffuseOcclusionMap, MaterialSrg::m_sampler, IN.m_uv[MaterialSrg::m_diffuseOcclusionMapUvIndex], MaterialSrg::m_diffuseOcclusionFactor, o_diffuseOcclusion_useTexture);
@@ -653,7 +653,7 @@
{
"name": "angleOffset",
"displayName": " Angle Offset",
"description": "Angle to accept below (N . L = 0) in scattering through thin objects",
"description": "cosine of angle to extend below (N . L = 0) in scattering through thin objects",
"type": "float",
"defaultValue": 0.1,
"min": -1.0,
@@ -663,6 +663,19 @@
"name": "m_angleOffset"
}
},
{
"name": "distanceAttenuation",
"displayName": " Distance Attenuation",
"description": "Attenuation applied to hide artifacts due to low-res shadow maps (e.g. objects far to the camera when using directional lights or objects far to the light when using sphere/disk lights",
"type": "float",
"defaultValue": 4.0,
"min": 0.0,
"softMax": 10.0,
"connection": {
"type": "ShaderInput",
"name": "m_distanceAttenuation"
}
},
{
"name": "transmissionScale",
"displayName": " Scale",
@@ -73,6 +73,7 @@ ShaderResourceGroup MaterialSrg : SRG_PerMaterial
uint m_transmissionThicknessMapUvIndex;
float m_shrinkFactor;
float m_angleOffset;
float m_distanceAttenuation;
Texture2D m_wrinkle_baseColor_texture1;
Texture2D m_wrinkle_baseColor_texture2;
@@ -37,6 +37,9 @@ class LightingData
// 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;
@@ -18,7 +18,7 @@ void ApplyDirectionalLights(Surface surface, inout LightingData lightingData)
// Shadowed check
const uint shadowIndex = ViewSrg::m_shadowIndexDirectionalLight;
float litRatio = 1.0f;
float camToSurfDist = distance(ViewSrg::m_worldPosition, surface.position);
// Transmission distance inside object
float transmissionDistance = 0.0f;
@@ -84,7 +84,13 @@ void ApplyDirectionalLights(Surface surface, inout LightingData lightingData)
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, currentTransmissionDistance);
float3 backLighting = GetBackLighting(surface, lightingData, light.m_rgbIntensityLux, dirToLight, currentTransmissionDistance);
// Attenuation applied to hide artifacts due to low-res shadow maps (might need some work in the future)
float attenuation = 1.0 / pow(max(1.0, camToSurfDist/2.0), lightingData.distanceAttenuation + 1.0);
lightingData.translucentBackLighting += backLighting * attenuation;
}
// Add debug coloring for directional light shadow
@@ -114,8 +114,13 @@ 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, transmissionDistance);
float3 backLighting = GetBackLighting(surface, lightingData, lightIntensity, posToLightDir, transmissionDistance);
// Attenuation applied to hide artifacts due to low-res shadow maps (might need some work in the future)
float attenuation = 1.0 / pow(max(1.0, sqrt(distanceToLight2)), lightingData.distanceAttenuation + 1.0);
lightingData.translucentBackLighting += backLighting * attenuation;
// Adjust the light direction for specular based on disk size
// Calculate the reflection off the normal from the view direction
@@ -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;
@@ -112,7 +113,12 @@ 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), transmissionDistance);
float3 backLighting = GetBackLighting(surface, lightingData, lightIntensity, normalize(posToLight), transmissionDistance);
// Attenuation applied to hide artifacts due to low-res shadow maps (might need some work in the future)
float attenuation = 1.0 / pow(max(1.0, posToLightDist), lightingData.distanceAttenuation + 1.0);
lightingData.translucentBackLighting += backLighting * attenuation;
// Adjust the light direcion for specular based on bulb size