Making room for specular cavity occlusion support in the buffer. We can pre-multiply the diffuseAmbientOcclusion into the albedo term output from the forward pass, instead of multiplying it in the diffuse GI passes. The difference due to precision is negligable. This can be seen in the corresponding changes in AtomSampleViewer baseline screenshots.

ATOM-14040 Add Support for Cavity Maps
This commit is contained in:
Chris Santora
2021-04-20 00:12:53 -07:00
parent 0c10e769c5
commit f5cb6f438b
5 changed files with 18 additions and 34 deletions
@@ -79,6 +79,7 @@ void PbrVsHelper(in VSInput IN, inout VSOutput OUT, float3 worldPosition, bool s
struct PbrLightingOutput
{
// Note some of these use special encodings, which are identical to struct ForwardPassOutput
float4 m_diffuseColor;
float4 m_specularColor;
float4 m_albedo;
@@ -98,7 +99,7 @@ PbrLightingOutput PbrLighting( in VSOutput IN,
float3 vtxBitangent,
float2 anisotropy, // angle and factor
float3 emissive,
float occlusion,
float diffuseAmbientOcclusion,
float4 transmissionTintThickness,
float4 transmissionParams,
float clearCoatFactor,
@@ -213,7 +214,7 @@ PbrLightingOutput PbrLighting( in VSOutput IN,
}
// Apply ambient occlusion to indirect diffuse
iblDiffuse *= occlusion;
iblDiffuse *= diffuseAmbientOcclusion;
// Adjust IBL lighting by exposure.
float iblExposureFactor = pow(2.0, SceneSrg::m_iblExposure);
@@ -259,8 +260,7 @@ PbrLightingOutput PbrLighting( in VSOutput IN,
// albedo, specularF0, roughness, and normals for later passes (specular IBL, Diffuse GI, SSR, AO, etc)
lightingOutput.m_specularF0 = float4(specularF0, roughness);
lightingOutput.m_albedo.rgb = surface.albedo * diffuseResponse;
lightingOutput.m_albedo.a = occlusion;
lightingOutput.m_albedo.rgb = surface.albedo * diffuseResponse * diffuseAmbientOcclusion;
lightingOutput.m_normal.rgb = EncodeNormalSignedOctahedron(normal);
lightingOutput.m_normal.a = o_specularF0_enableMultiScatterCompensation ? 1.0f : 0.0f;
@@ -24,7 +24,7 @@ ShaderResourceGroup PassSrg : SRG_PerPass
Texture2DMS<float4> m_downsampledProbeIrradiance;
Texture2DMS<float> m_downsampledDepth;
Texture2DMS<float4> m_downsampledNormal;
Texture2DMS<float4> m_albedo; // RGB8 = Albedo, A = Occlusion
Texture2DMS<float4> m_albedo; // RGB8 = Albedo with pre-multiplied factors, A = Unused here
Texture2DMS<float4> m_normal; // RGB10 = Normal (Encoded), A2 = Flags
Texture2DMS<float> m_depth;
@@ -118,7 +118,7 @@ float3 SampleProbeIrradiance(uint sampleIndex, uint2 probeIrradianceCoords, floa
}
// retrieve irradiance from the global IBL diffuse cubemap
float3 SampleGlobalIBL(uint sampleIndex, uint2 screenCoords, float depth, float3 normal, float3 albedo)
float3 SampleGlobalIBL(uint sampleIndex, uint2 screenCoords, float depth, float3 normal)
{
uint2 dimensions;
uint samples;
@@ -160,23 +160,19 @@ PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex)
float4 encodedNormal = PassSrg::m_normal.Load(screenCoords, sampleIndex);
float3 normal = DecodeNormalSignedOctahedron(encodedNormal.rgb);
float4 albedo = PassSrg::m_albedo.Load(screenCoords, sampleIndex);
float occlusion = albedo.a;
float useProbeIrradiance = PassSrg::m_downsampledProbeIrradiance.Load(probeIrradianceCoords, sampleIndex).a;
float3 diffuse = float3(0.0f, 0.0f, 0.0f);
if (useProbeIrradiance > 0.0f)
{
float3 irradiance = SampleProbeIrradiance(sampleIndex, probeIrradianceCoords, depth, normal, albedo, ImageScale);
diffuse = (albedo.rgb / PI) * irradiance * occlusion;
diffuse = (albedo.rgb / PI) * irradiance;
}
else
{
float3 irradiance = SampleGlobalIBL(sampleIndex, screenCoords, depth, normal, albedo);
float3 irradiance = SampleGlobalIBL(sampleIndex, screenCoords, depth, normal);
diffuse = albedo * irradiance;
// apply ambient occlusion to indirect diffuse
diffuse *= occlusion;
// adjust IBL lighting by exposure.
float iblExposureFactor = pow(2.0, SceneSrg::m_iblExposure);
diffuse *= iblExposureFactor;
@@ -27,7 +27,7 @@ ShaderResourceGroup PassSrg : SRG_PerPass
Texture2D<float4> m_downsampledProbeIrradiance;
Texture2D<float> m_downsampledDepth;
Texture2D<float4> m_downsampledNormal;
Texture2D<float4> m_albedo; // RGB8 = Albedo, A = Occlusion
Texture2D<float4> m_albedo; // RGB8 = Albedo with pre-multiplied factors, A = Unused here
Texture2D<float4> m_normal; // RGB10 = Normal (Encoded), A2 = Flags
Texture2D<float> m_depth;
@@ -121,7 +121,7 @@ float3 SampleProbeIrradiance(uint2 probeIrradianceCoords, float depth, float3 no
}
// retrieve irradiance from the global IBL diffuse cubemap
float3 SampleGlobalIBL(uint2 screenCoords, float depth, float3 normal, float3 albedo)
float3 SampleGlobalIBL(uint2 screenCoords, float depth, float3 normal)
{
uint2 dimensions;
PassSrg::m_depth.GetDimensions(dimensions.x, dimensions.y);
@@ -162,23 +162,19 @@ PSOutput MainPS(VSOutput IN)
float4 encodedNormal = PassSrg::m_normal.Load(int3(screenCoords, 0));
float3 normal = DecodeNormalSignedOctahedron(encodedNormal.rgb);
float4 albedo = PassSrg::m_albedo.Load(int3(screenCoords, 0));
float occlusion = albedo.a;
float useProbeIrradiance = PassSrg::m_downsampledProbeIrradiance.Load(int3(probeIrradianceCoords,0)).a;
float3 diffuse = float3(0.0f, 0.0f, 0.0f);
if (useProbeIrradiance > 0.0f)
{
float3 irradiance = SampleProbeIrradiance(probeIrradianceCoords, depth, normal, albedo, ImageScale);
diffuse = (albedo.rgb / PI) * irradiance * occlusion;
diffuse = (albedo.rgb / PI) * irradiance;
}
else
{
float3 irradiance = SampleGlobalIBL(screenCoords, depth, normal, albedo);
float3 irradiance = SampleGlobalIBL(screenCoords, depth, normal);
diffuse = albedo * irradiance;
// apply ambient occlusion to indirect diffuse
diffuse *= occlusion;
// adjust IBL lighting by exposure.
float iblExposureFactor = pow(2.0, SceneSrg::m_iblExposure);
diffuse *= iblExposureFactor;
@@ -21,7 +21,7 @@
ShaderResourceGroup PassSrg : SRG_PerPass
{
Texture2DMS<float4> m_albedo; // RGB8 = Albedo, A = Occlusion
Texture2DMS<float4> m_albedo; // RGB8 = Albedo with pre-multiplied factors, A = Unused here
Texture2DMS<float4> m_normal; // RGB10 = Normal (Encoded), A2 = Flags
Texture2DMS<float> m_depth;
}
@@ -41,7 +41,7 @@ VSOutput MainVS(VSInput input)
}
// retrieve irradiance from the global IBL diffuse cubemap
float3 SampleGlobalIBL(uint sampleIndex, uint2 screenCoords, float depth, float3 normal, float3 albedo)
float3 SampleGlobalIBL(uint sampleIndex, uint2 screenCoords, float depth, float3 normal)
{
uint2 dimensions;
uint samples;
@@ -76,14 +76,10 @@ PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex)
float4 encodedNormal = PassSrg::m_normal.Load(screenCoords, sampleIndex);
float3 normal = DecodeNormalSignedOctahedron(encodedNormal.rgb);
float4 albedo = PassSrg::m_albedo.Load(screenCoords, sampleIndex);
float occlusion = albedo.a;
float3 irradiance = SampleGlobalIBL(sampleIndex, screenCoords, depth, normal, albedo);
float3 irradiance = SampleGlobalIBL(sampleIndex, screenCoords, depth, normal);
float3 diffuse = albedo * irradiance;
// apply ambient occlusion to indirect diffuse
diffuse *= occlusion;
// adjust IBL lighting by exposure.
float iblExposureFactor = pow(2.0, SceneSrg::m_iblExposure);
diffuse *= iblExposureFactor;
@@ -24,7 +24,7 @@
ShaderResourceGroup PassSrg : SRG_PerPass
{
Texture2D<float4> m_albedo; // RGB8 = Albedo, A = Occlusion
Texture2D<float4> m_albedo; // RGB8 = Albedo with pre-multiplied factors, A = Unused here
Texture2D<float4> m_normal; // RGB10 = Normal (Encoded), A2 = Flags
Texture2D<float> m_depth;
}
@@ -44,7 +44,7 @@ VSOutput MainVS(VSInput input)
}
// retrieve irradiance from the global IBL diffuse cubemap
float3 SampleGlobalIBL(uint sampleIndex, uint2 screenCoords, float depth, float3 normal, float3 albedo)
float3 SampleGlobalIBL(uint sampleIndex, uint2 screenCoords, float depth, float3 normal)
{
uint2 dimensions;
PassSrg::m_depth.GetDimensions(dimensions.x, dimensions.y);
@@ -78,14 +78,10 @@ PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex)
float4 encodedNormal = PassSrg::m_normal.Load(int3(screenCoords, 0));
float3 normal = DecodeNormalSignedOctahedron(encodedNormal.rgb);
float4 albedo = PassSrg::m_albedo.Load(int3(screenCoords, 0));
float occlusion = albedo.a;
float3 irradiance = SampleGlobalIBL(sampleIndex, screenCoords, depth, normal, albedo);
float3 irradiance = SampleGlobalIBL(sampleIndex, screenCoords, depth, normal);
float3 diffuse = albedo * irradiance;
// apply ambient occlusion to indirect diffuse
diffuse *= occlusion;
// adjust IBL lighting by exposure.
float iblExposureFactor = pow(2.0, SceneSrg::m_iblExposure);
diffuse *= iblExposureFactor;