Removed ClearCoatNormal RT from the pipeline and shaders.

Changed stencil bits to use 0x3 for the IBL Specular pass and 0x80 for the DiffuseGI pass.
main
dmcdiar 5 years ago
parent cc6393b074
commit a4fe1bc8db

@ -311,7 +311,6 @@ ForwardPassOutputWithDepth EnhancedPbr_ForwardPassPS(VSOutput IN, bool isFrontFa
OUT.m_specularF0 = lightingOutput.m_specularF0;
OUT.m_albedo = lightingOutput.m_albedo;
OUT.m_normal = lightingOutput.m_normal;
OUT.m_clearCoatNormal = lightingOutput.m_clearCoatNormal;
OUT.m_scatterDistance = lightingOutput.m_scatterDistance;
OUT.m_depth = depth;
return OUT;
@ -330,7 +329,6 @@ ForwardPassOutput EnhancedPbr_ForwardPassPS_EDS(VSOutput IN, bool isFrontFace :
OUT.m_specularF0 = lightingOutput.m_specularF0;
OUT.m_albedo = lightingOutput.m_albedo;
OUT.m_normal = lightingOutput.m_normal;
OUT.m_clearCoatNormal = lightingOutput.m_clearCoatNormal;
OUT.m_scatterDistance = lightingOutput.m_scatterDistance;
return OUT;

@ -333,7 +333,6 @@ ForwardPassOutput SkinPS(VSOutput IN)
OUT.m_specularF0 = lightingOutput.m_specularF0;
OUT.m_albedo = lightingOutput.m_albedo;
OUT.m_normal = lightingOutput.m_normal;
OUT.m_clearCoatNormal = lightingOutput.m_clearCoatNormal;
OUT.m_scatterDistance = lightingOutput.m_scatterDistance;
return OUT;

@ -389,7 +389,6 @@ ForwardPassOutputWithDepth ForwardPassPS(VSOutput IN, bool isFrontFace : SV_IsFr
OUT.m_specularF0 = lightingOutput.m_specularF0;
OUT.m_albedo = lightingOutput.m_albedo;
OUT.m_normal = lightingOutput.m_normal;
OUT.m_clearCoatNormal = lightingOutput.m_clearCoatNormal;
OUT.m_scatterDistance = lightingOutput.m_scatterDistance;
OUT.m_depth = depth;
return OUT;
@ -408,7 +407,6 @@ ForwardPassOutput ForwardPassPS_EDS(VSOutput IN, bool isFrontFace : SV_IsFrontFa
OUT.m_specularF0 = lightingOutput.m_specularF0;
OUT.m_albedo = lightingOutput.m_albedo;
OUT.m_normal = lightingOutput.m_normal;
OUT.m_clearCoatNormal = lightingOutput.m_clearCoatNormal;
OUT.m_scatterDistance = lightingOutput.m_scatterDistance;
return OUT;

@ -312,7 +312,6 @@ ForwardPassOutputWithDepth StandardPbr_ForwardPassPS(VSOutput IN, bool isFrontFa
OUT.m_specularF0 = lightingOutput.m_specularF0;
OUT.m_albedo = lightingOutput.m_albedo;
OUT.m_normal = lightingOutput.m_normal;
OUT.m_clearCoatNormal = lightingOutput.m_clearCoatNormal;
OUT.m_scatterDistance = lightingOutput.m_scatterDistance;
OUT.m_depth = depth;
return OUT;
@ -331,7 +330,6 @@ ForwardPassOutput StandardPbr_ForwardPassPS_EDS(VSOutput IN, bool isFrontFace :
OUT.m_specularF0 = lightingOutput.m_specularF0;
OUT.m_albedo = lightingOutput.m_albedo;
OUT.m_normal = lightingOutput.m_normal;
OUT.m_clearCoatNormal = lightingOutput.m_clearCoatNormal;
OUT.m_scatterDistance = lightingOutput.m_scatterDistance;
return OUT;

@ -68,7 +68,7 @@
"ShaderAsset": {
"FilePath": "Shaders/DiffuseGlobalIllumination/DiffuseComposite.shader"
},
"StencilRef": 1,
"StencilRef": 128, // See RenderCommon.h and DiffuseComposite.shader
"PipelineViewTag": "MainCamera"
}
}

@ -48,7 +48,7 @@
"ShaderAsset": {
"FilePath": "Shaders/DiffuseGlobalIllumination/DiffuseGlobalFullscreen.shader"
},
"StencilRef": 1,
"StencilRef": 128, // See RenderCommon.h and DiffuseGlobalFullscreen.shader
"PipelineViewTag": "MainCamera"
}
}

@ -43,7 +43,7 @@
"ShaderAsset": {
"FilePath": "Shaders/DiffuseGlobalIllumination/DiffuseGlobalFullscreen_nomsaa.shader"
},
"StencilRef": 1,
"StencilRef": 128, // See RenderCommon.h and DiffuseGlobalFullscreen.shader
"PipelineViewTag": "MainCamera"
}
}

@ -146,22 +146,6 @@
"LoadAction": "Clear"
}
},
{
"Name": "ClearCoatNormalOutput",
"SlotType": "Output",
"ScopeAttachmentUsage": "RenderTarget",
"LoadStoreAction": {
"ClearValue": {
"Value": [
0.0,
0.0,
0.0,
0.0
]
},
"LoadAction": "Clear"
}
},
{
"Name": "ScatterDistanceOutput",
"SlotType": "Output",
@ -271,23 +255,6 @@
"FilePath": "Textures/BRDFTexture.attimage"
}
},
{
"Name": "ClearCoatNormalImage",
"SizeSource": {
"Source": {
"Pass": "Parent",
"Attachment": "Output"
}
},
"MultisampleSource": {
"Pass": "This",
"Attachment": "DepthStencilInputOutput"
},
"ImageDescriptor": {
"Format": "R16G16B16A16_FLOAT",
"SharedQueueMask": "Graphics"
}
},
{
"Name": "ScatterDistanceImage",
"SizeSource": {
@ -349,13 +316,6 @@
"Attachment": "BRDFTexture"
}
},
{
"LocalSlot": "ClearCoatNormalOutput",
"AttachmentRef": {
"Pass": "This",
"Attachment": "ClearCoatNormalImage"
}
},
{
"LocalSlot": "ScatterDistanceOutput",
"AttachmentRef": {

@ -372,7 +372,7 @@
"ShaderAsset": {
"FilePath": "Shaders/Reflections/ReflectionComposite.shader"
},
"StencilRef": 1
"StencilRef": 1 // See RenderCommon.h and ReflectionComposite.shader
}
},
{

@ -149,22 +149,6 @@
"LoadAction": "Clear"
}
},
{
"Name": "ClearCoatNormalOutput",
"SlotType": "Output",
"ScopeAttachmentUsage": "RenderTarget",
"LoadStoreAction": {
"ClearValue": {
"Value": [
0.0,
0.0,
0.0,
0.0
]
},
"LoadAction": "Clear"
}
},
{
"Name": "ScatterDistanceOutput",
"SlotType": "Output",
@ -255,19 +239,6 @@
"FilePath": "Textures/BRDFTexture.attimage"
}
},
{
"Name": "ClearCoatNormalImage",
"SizeSource": {
"Source": {
"Pass": "Parent",
"Attachment": "SwapChainOutput"
}
},
"ImageDescriptor": {
"Format": "R16G16B16A16_FLOAT",
"SharedQueueMask": "Graphics"
}
},
{
"Name": "ScatterDistanceImage",
"SizeSource": {
@ -325,13 +296,6 @@
"Attachment": "BRDFTexture"
}
},
{
"LocalSlot": "ClearCoatNormalOutput",
"AttachmentRef": {
"Pass": "This",
"Attachment": "ClearCoatNormalImage"
}
},
{
"LocalSlot": "ScatterDistanceOutput",
"AttachmentRef": {

@ -106,14 +106,6 @@
"LoadAction": "Clear"
}
},
{
"Name": "ClearCoatNormalOutput",
"SlotType": "Output",
"ScopeAttachmentUsage": "RenderTarget",
"LoadStoreAction": {
"LoadAction": "Clear"
}
},
{
"Name": "ScatterDistanceOutput",
"SlotType": "Output",
@ -226,22 +218,6 @@
"AssetRef": {
"FilePath": "Textures/BRDFTexture.attimage"
}
},
{
"Name": "ClearCoatNormalImage",
"SizeSource": {
"Source": {
"Pass": "Parent",
"Attachment": "SwapChainOutput"
}
},
"ImageDescriptor": {
"Format": "R16G16B16A16_FLOAT",
"MultisampleState": {
"samples": 2
},
"SharedQueueMask": "Graphics"
}
}
],
"Connections": [
@ -293,13 +269,6 @@
"Pass": "This",
"Attachment": "BRDFTexture"
}
},
{
"LocalSlot": "ClearCoatNormalOutput",
"AttachmentRef": {
"Pass": "This",
"Attachment": "ClearCoatNormalImage"
}
}
]
}

@ -149,22 +149,6 @@
"LoadAction": "Clear"
}
},
{
"Name": "ClearCoatNormalOutput",
"SlotType": "Output",
"ScopeAttachmentUsage": "RenderTarget",
"LoadStoreAction": {
"ClearValue": {
"Value": [
0.0,
0.0,
0.0,
0.0
]
},
"LoadAction": "Clear"
}
},
{
"Name": "ScatterDistanceOutput",
"SlotType": "Output",
@ -275,23 +259,6 @@
"FilePath": "Textures/BRDFTexture.attimage"
}
},
{
"Name": "ClearCoatNormalImage",
"SizeSource": {
"Source": {
"Pass": "Parent",
"Attachment": "SwapChainOutput"
}
},
"MultisampleSource": {
"Pass": "This",
"Attachment": "DepthStencilInputOutput"
},
"ImageDescriptor": {
"Format": "R16G16B16A16_FLOAT",
"SharedQueueMask": "Graphics"
}
},
{
"Name": "ScatterDistanceImage",
"SizeSource": {
@ -353,13 +320,6 @@
"Attachment": "BRDFTexture"
}
},
{
"LocalSlot": "ClearCoatNormalOutput",
"AttachmentRef": {
"Pass": "This",
"Attachment": "ClearCoatNormalImage"
}
},
{
"LocalSlot": "ScatterDistanceOutput",
"AttachmentRef": {

@ -180,13 +180,6 @@
"Attachment": "SpecularF0Output"
}
},
{
"LocalSlot": "ClearCoatNormalInput",
"AttachmentRef": {
"Pass": "ForwardMSAAPass",
"Attachment": "ClearCoatNormalOutput"
}
},
{
"LocalSlot": "DepthStencilInputOutput",
"AttachmentRef": {
@ -262,7 +255,7 @@
"ShaderAsset": {
"FilePath": "Shaders/Reflections/ReflectionComposite.shader"
},
"StencilRef": 1,
"StencilRef": 1, // See RenderCommon.h and ReflectionComposite.shader
"PipelineViewTag": "MainCamera"
}
},

@ -27,11 +27,6 @@
"SlotType": "Input",
"ScopeAttachmentUsage": "Shader"
},
{
"Name": "ClearCoatNormalInput",
"SlotType": "Input",
"ScopeAttachmentUsage": "Shader"
},
{
"Name": "ReflectionBlendWeightInput",
"SlotType": "Input",

@ -27,11 +27,6 @@
"SlotType": "Input",
"ScopeAttachmentUsage": "Shader"
},
{
"Name": "ClearCoatNormalInput",
"SlotType": "Input",
"ScopeAttachmentUsage": "Shader"
},
{
"Name": "ReflectionBlendWeightInput",
"SlotType": "Input",

@ -27,11 +27,6 @@
"SlotType": "Input",
"ScopeAttachmentUsage": "Shader"
},
{
"Name": "ClearCoatNormalInput",
"SlotType": "Input",
"ScopeAttachmentUsage": "Shader"
},
{
"Name": "BRDFTextureInput",
"ShaderInputName": "m_brdfMap",

@ -27,11 +27,6 @@
"SlotType": "Input",
"ScopeAttachmentUsage": "Shader"
},
{
"Name": "ClearCoatNormalInput",
"SlotType": "Input",
"ScopeAttachmentUsage": "Shader"
},
{
"Name": "ReflectionBlendWeightInput",
"SlotType": "Input",

@ -17,11 +17,6 @@
"SlotType": "Input",
"ScopeAttachmentUsage": "Shader"
},
{
"Name": "ClearCoatNormalInput",
"SlotType": "Input",
"ScopeAttachmentUsage": "Shader"
},
{
"Name": "DepthStencilInputOutput",
"SlotType": "InputOutput",
@ -127,13 +122,6 @@
"Attachment": "SpecularF0Input"
}
},
{
"LocalSlot": "ClearCoatNormalInput",
"AttachmentRef": {
"Pass": "Parent",
"Attachment": "ClearCoatNormalInput"
}
},
{
"LocalSlot": "ReflectionBlendWeightInput",
"AttachmentRef": {
@ -147,7 +135,7 @@
"ShaderAsset": {
"FilePath": "Shaders/Reflections/ReflectionGlobalFullscreen.shader"
},
"StencilRef": 15,
"StencilRef": 3, // See RenderCommon.h and ReflectionGlobalFullscreen.shader
"PipelineViewTag": "MainCamera"
}
},
@ -191,13 +179,6 @@
"Attachment": "SpecularF0Input"
}
},
{
"LocalSlot": "ClearCoatNormalInput",
"AttachmentRef": {
"Pass": "Parent",
"Attachment": "ClearCoatNormalInput"
}
},
{
"LocalSlot": "ReflectionBlendWeightInput",
"AttachmentRef": {
@ -254,13 +235,6 @@
"Pass": "Parent",
"Attachment": "SpecularF0Input"
}
},
{
"LocalSlot": "ClearCoatNormalInput",
"AttachmentRef": {
"Pass": "Parent",
"Attachment": "ClearCoatNormalInput"
}
}
],
"PassData": {

@ -17,11 +17,6 @@
"SlotType": "Input",
"ScopeAttachmentUsage": "Shader"
},
{
"Name": "ClearCoatNormalInput",
"SlotType": "Input",
"ScopeAttachmentUsage": "Shader"
},
{
"Name": "DepthStencilInputOutput",
"SlotType": "InputOutput",
@ -127,13 +122,6 @@
"Attachment": "SpecularF0Input"
}
},
{
"LocalSlot": "ClearCoatNormalInput",
"AttachmentRef": {
"Pass": "Parent",
"Attachment": "ClearCoatNormalInput"
}
},
{
"LocalSlot": "ReflectionBlendWeightInput",
"AttachmentRef": {
@ -147,7 +135,7 @@
"ShaderAsset": {
"FilePath": "Shaders/Reflections/ReflectionGlobalFullscreen_nomsaa.shader"
},
"StencilRef": 15,
"StencilRef": 3, // See RenderCommon.h and ReflectionGlobalFullscreen_nomsaa.shader
"PipelineViewTag": "MainCamera"
}
},
@ -191,13 +179,6 @@
"Attachment": "SpecularF0Input"
}
},
{
"LocalSlot": "ClearCoatNormalInput",
"AttachmentRef": {
"Pass": "Parent",
"Attachment": "ClearCoatNormalInput"
}
},
{
"LocalSlot": "ReflectionBlendWeightInput",
"AttachmentRef": {
@ -254,13 +235,6 @@
"Pass": "Parent",
"Attachment": "SpecularF0Input"
}
},
{
"LocalSlot": "ClearCoatNormalInput",
"AttachmentRef": {
"Pass": "Parent",
"Attachment": "ClearCoatNormalInput"
}
}
],
"PassData": {

@ -18,8 +18,7 @@ struct ForwardPassOutput
float4 m_albedo : SV_Target2;
float4 m_specularF0 : SV_Target3;
float4 m_normal : SV_Target4;
float4 m_clearCoatNormal : SV_Target5;
float3 m_scatterDistance : SV_Target6;
float3 m_scatterDistance : SV_Target5;
};
struct ForwardPassOutputWithDepth
@ -30,7 +29,6 @@ struct ForwardPassOutputWithDepth
float4 m_albedo : SV_Target2;
float4 m_specularF0 : SV_Target3;
float4 m_normal : SV_Target4;
float4 m_clearCoatNormal : SV_Target5;
float3 m_scatterDistance : SV_Target6;
float3 m_scatterDistance : SV_Target5;
float m_depth : SV_Depth;
};

@ -18,7 +18,11 @@
#include <Atom/Features/PBR/Lights/LightTypesCommon.azsli>
#include <Atom/Features/PBR/LightingUtils.azsli>
void ApplyIblDiffuse(float3 normal, float3 albedo, float3 diffuseResponse, out float3 outDiffuse)
void ApplyIblDiffuse(
float3 normal,
float3 albedo,
float3 diffuseResponse,
out float3 outDiffuse)
{
float3 irradianceDir = MultiplyVectorQuaternion(normal, SceneSrg::m_iblOrientation);
float3 diffuseSample = SceneSrg::m_diffuseEnvMap.Sample(SceneSrg::m_samplerEnv, GetCubemapCoords(irradianceDir)).rgb;
@ -26,10 +30,18 @@ void ApplyIblDiffuse(float3 normal, float3 albedo, float3 diffuseResponse, out f
outDiffuse = diffuseResponse * albedo * diffuseSample;
}
void ApplyIblSpecular(float3 position, float3 normal, float3 specularF0, float roughnessLinear, float3 specularResponse, float3 dirToCamera, float2 brdf, out float3 outSpecular)
void ApplyIblSpecular(
float3 position,
float3 normal,
float3 specularF0,
float roughnessLinear,
float3 dirToCamera,
float2 brdf,
out float3 outSpecular)
{
float3 reflectDir = reflect(-dirToCamera, normal);
reflectDir = MultiplyVectorQuaternion(reflectDir, SceneSrg::m_iblOrientation);
// global
outSpecular = SceneSrg::m_specularEnvMap.SampleLevel(SceneSrg::m_samplerEnv, GetCubemapCoords(reflectDir), GetRoughnessMip(roughnessLinear)).rgb;
outSpecular *= (specularF0 * brdf.x + brdf.y);
@ -70,9 +82,21 @@ void ApplyIBL(Surface surface, inout LightingData lightingData)
if (o_enableIBL)
{
float3 iblDiffuse = 0.0f;
ApplyIblDiffuse(
surface.normal,
surface.albedo,
lightingData.diffuseResponse,
iblDiffuse);
float3 iblSpecular = 0.0f;
ApplyIblDiffuse(surface.normal, surface.albedo, lightingData.diffuseResponse, iblDiffuse);
ApplyIblSpecular(surface.position, surface.normal, surface.specularF0, surface.roughnessLinear, lightingData.specularResponse, lightingData.dirToCamera, lightingData.brdf, iblSpecular);
ApplyIblSpecular(
surface.position,
surface.normal,
surface.specularF0,
surface.roughnessLinear,
lightingData.dirToCamera,
lightingData.brdf,
iblSpecular);
// Adjust IBL lighting by exposure.
float iblExposureFactor = pow(2.0, SceneSrg::m_iblExposure);
@ -85,7 +109,47 @@ void ApplyIBL(Surface surface, inout LightingData lightingData)
if (o_enableIBL)
{
float3 iblSpecular = 0.0f;
ApplyIblSpecular(surface.position, surface.normal, surface.specularF0, surface.roughnessLinear, lightingData.specularResponse, lightingData.dirToCamera, lightingData.brdf, iblSpecular);
ApplyIblSpecular(
surface.position,
surface.normal,
surface.specularF0,
surface.roughnessLinear,
lightingData.dirToCamera,
lightingData.brdf,
iblSpecular);
iblSpecular *= lightingData.multiScatterCompensation;
if (o_clearCoat_feature_enabled)
{
if (surface.clearCoat.factor > 0.0f)
{
float clearCoatNdotV = saturate(dot(surface.clearCoat.normal, lightingData.dirToCamera));
clearCoatNdotV = max(clearCoatNdotV, 0.01f); // [GFX TODO][ATOM-4466] This is a current band-aid for specular noise at grazing angles.
float2 clearCoatBrdf = PassSrg::m_brdfMap.Sample(PassSrg::LinearSampler, GetBRDFTexCoords(surface.clearCoat.roughness, clearCoatNdotV)).rg;
// clear coat uses fixed IOR = 1.5 represents polyurethane which is the most common material for gloss clear coat
// coat layer assumed to be dielectric thus don't need multiple scattering compensation
float3 clearCoatSpecularF0 = float3(0.04f, 0.04f, 0.04f);
float3 clearCoatIblSpecular = 0.0f;
ApplyIblSpecular(
surface.position,
surface.clearCoat.normal,
clearCoatSpecularF0,
surface.clearCoat.roughness,
lightingData.dirToCamera,
clearCoatBrdf,
clearCoatIblSpecular);
clearCoatIblSpecular *= surface.clearCoat.factor;
// attenuate base layer energy
float3 clearCoatResponse = FresnelSchlickWithRoughness(clearCoatNdotV, clearCoatSpecularF0, surface.clearCoat.roughness) * surface.clearCoat.factor;
iblSpecular = iblSpecular * (1.0 - clearCoatResponse) * (1.0 - clearCoatResponse) + clearCoatIblSpecular;
}
}
float iblExposureFactor = pow(2.0f, SceneSrg::m_iblExposure);
lightingData.specularLighting += (iblSpecular * iblExposureFactor);

@ -15,11 +15,11 @@
"Stencil" :
{
"Enable" : true,
"ReadMask" : "0xFF",
"ReadMask" : "0x80",
"WriteMask" : "0x00",
"FrontFace" :
{
"Func" : "LessEqual",
"Func" : "Equal",
"DepthFailOp" : "Keep",
"FailOp" : "Keep",
"PassOp" : "Keep"

@ -15,11 +15,11 @@
"Stencil" :
{
"Enable" : true,
"ReadMask" : "0xFF",
"ReadMask" : "0x80",
"WriteMask" : "0x00",
"FrontFace" :
{
"Func" : "LessEqual",
"Func" : "Equal",
"DepthFailOp" : "Keep",
"FailOp" : "Keep",
"PassOp" : "Keep"

@ -15,11 +15,11 @@
"Stencil" :
{
"Enable" : true,
"ReadMask" : "0xFF",
"ReadMask" : "0x80",
"WriteMask" : "0x00",
"FrontFace" :
{
"Func" : "LessEqual",
"Func" : "Equal",
"DepthFailOp" : "Keep",
"FailOp" : "Keep",
"PassOp" : "Keep"

@ -15,11 +15,11 @@
"Stencil" :
{
"Enable" : true,
"ReadMask" : "0xFF",
"ReadMask" : "0x80",
"WriteMask" : "0x00",
"FrontFace" :
{
"Func" : "LessEqual",
"Func" : "Equal",
"DepthFailOp" : "Keep",
"FailOp" : "Keep",
"PassOp" : "Keep"

@ -17,7 +17,7 @@
"Stencil" :
{
"Enable" : true,
"ReadMask" : "0xFF",
"ReadMask" : "0x7F",
"WriteMask" : "0x00",
"FrontFace" :
{

@ -45,7 +45,6 @@ ShaderResourceGroup PassSrg : SRG_PerPass
Texture2DMS<float> m_depth;
Texture2DMS<float4> m_normal; // RGB10 = Normal (Encoded), A2 = Flags
Texture2DMS<float4> m_specularF0; // RGB8 = SpecularF0, A8 = Roughness
Texture2DMS<float4> m_clearCoatNormal; // R16G16 = Normal (Packed), B16A16 = (factor, perceptual roughness)
Texture2DMS<float> m_blendWeight;
Texture2D<float2> m_brdfMap;
@ -105,34 +104,6 @@ PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex)
float3 multiScatterCompensation = GetMultiScatterCompensation(specularF0, brdf, multiScatterCompensationEnabled);
float3 specular = blendWeight * globalSpecular * multiScatterCompensation * (specularF0 * brdf.x + brdf.y);
float4 encodedClearCoatNormal = PassSrg::m_clearCoatNormal.Load(IN.m_position.xy, sampleIndex);
if(encodedClearCoatNormal.z > 0.0)
{
float3 clearCoatNormal = DecodedNormalSphereMap(encodedClearCoatNormal.xy);
float factor = encodedClearCoatNormal.z;
float roughness = encodedClearCoatNormal.w;
// recompute reflection direction based on coat's normal
float3 reflectDir = reflect(-dirToCamera, clearCoatNormal);
reflectDir = MultiplyVectorQuaternion(reflectDir, SceneSrg::m_iblOrientation);
float NdotV = saturate(dot(clearCoatNormal, dirToCamera));
NdotV = max(NdotV, 0.01f); // [GFX TODO][ATOM-4466] This is a current band-aid for specular noise at grazing angles.
float3 coatGlobalSpecular = SceneSrg::m_specularEnvMap.SampleLevel(SceneSrg::m_samplerEnv, GetCubemapCoords(reflectDir), GetRoughnessMip(roughness)).rgb;
float2 coatBrdf = PassSrg::m_brdfMap.Sample(PassSrg::LinearSampler, GetBRDFTexCoords(roughness, NdotV)).rg;
// clear coat uses fixed IOR = 1.5 represents polyurethane which is the most common material for gloss clear coat
// coat layer assumed to be dielectric thus don't need multiple scattering compensation
float3 clearCoat = blendWeight * coatGlobalSpecular * (float3(0.04, 0.04, 0.04) * coatBrdf.x + coatBrdf.y) * factor;
// attenuate base layer energy
float3 coatResponse = FresnelSchlickWithRoughness(NdotV, float3(0.04, 0.04, 0.04), roughness) * factor;
specular = specular * (1.0 - coatResponse) * (1.0 - coatResponse) + clearCoat;
}
// apply exposure setting
specular *= pow(2.0, SceneSrg::m_iblExposure);

@ -15,7 +15,7 @@
"Stencil" :
{
"Enable" : true,
"ReadMask" : "0xFF",
"ReadMask" : "0x7F",
"WriteMask" : "0x00",
"FrontFace" :
{

@ -49,7 +49,6 @@ ShaderResourceGroup PassSrg : SRG_PerPass
Texture2D<float> m_depth;
Texture2D<float4> m_normal; // RGB10 = Normal (Encoded), A2 = Flags
Texture2D<float4> m_specularF0; // RGB8 = SpecularF0, A8 = Roughness
Texture2D<float4> m_clearCoatNormal; // R16G16 = Normal (Packed), B16A16 = (factor, perceptual roughness)
Texture2D<float> m_blendWeight;
Texture2D<float2> m_brdfMap;
@ -126,34 +125,6 @@ PSOutput MainPS(VSOutput IN)
float3 multiScatterCompensation = GetMultiScatterCompensation(specularF0, brdf, multiScatterCompensationEnabled);
float3 specular = blendWeight * globalSpecular * multiScatterCompensation * (specularF0 * brdf.x + brdf.y);
float4 encodedClearCoatNormal = PassSrg::m_clearCoatNormal.Load(int3(IN.m_position.xy, 0));
if(encodedClearCoatNormal.z > 0.0)
{
float3 clearCoatNormal = DecodedNormalSphereMap(encodedClearCoatNormal.xy);
float factor = encodedClearCoatNormal.z;
float roughness = encodedClearCoatNormal.w;
// recompute reflection direction based on coat's normal
float3 reflectDir = reflect(-dirToCamera, clearCoatNormal);
reflectDir = MultiplyVectorQuaternion(reflectDir, SceneSrg::m_iblOrientation);
float NdotV = saturate(dot(clearCoatNormal, dirToCamera));
NdotV = max(NdotV, 0.01f); // [GFX TODO][ATOM-4466] This is a current band-aid for specular noise at grazing angles.
float3 coatGlobalSpecular = SceneSrg::m_specularEnvMap.SampleLevel(SceneSrg::m_samplerEnv, GetCubemapCoords(reflectDir), GetRoughnessMip(roughness)).rgb;
float2 coatBrdf = PassSrg::m_brdfMap.Sample(PassSrg::LinearSampler, GetBRDFTexCoords(roughness, NdotV)).rg;
// clear coat uses fixed IOR = 1.5 represents polyurethane which is the most common material for gloss clear coat
// coat layer assumed to be dielectric thus don't need multiple scattering compensation
float3 clearCoat = blendWeight * coatGlobalSpecular * (float3(0.04, 0.04, 0.04) * coatBrdf.x + coatBrdf.y) * factor;
// attenuate base layer energy
float3 coatResponse = FresnelSchlickWithRoughness(NdotV, float3(0.04, 0.04, 0.04), roughness) * factor;
specular = specular * (1.0 - coatResponse) * (1.0 - coatResponse) + clearCoat;
}
// apply exposure setting
specular *= pow(2.0, SceneSrg::m_iblExposure);

@ -15,7 +15,7 @@
"Stencil" :
{
"Enable" : true,
"ReadMask" : "0xFF",
"ReadMask" : "0x7F",
"WriteMask" : "0x00",
"BackFace" :
{

@ -61,40 +61,5 @@ bool ComputeProbeSpecular(float2 screenCoords, float3 positionWS, float3 aabbMin
float3 multiScatterCompensation = GetMultiScatterCompensation(specularF0, brdf, multiScatterCompensationEnabled);
specular = probeSpecular * multiScatterCompensation * (specularF0.xyz * brdf.x + brdf.y);
// compute clear coat specular amount
float4 encodedClearCoatNormal = PassSrg::m_clearCoatNormal.Load(screenCoords, sampleIndex);
if(encodedClearCoatNormal.z > 0.0)
{
float3 clearCoatNormal = DecodedNormalSphereMap(encodedClearCoatNormal.xy);
float factor = encodedClearCoatNormal.z;
float roughness = encodedClearCoatNormal.w;
// recompute reflection direction based on coat's normal
float3 reflectDir = reflect(-dirToCamera, clearCoatNormal);
// compute parallax corrected reflection vector, if necessary
// clear coat uses different normal from bottom layer, so reflection direction should be recalculated
float3 localReflectDir = reflectDir;
if (ObjectSrg::m_useParallaxCorrection)
{
localReflectDir = ApplyParallaxCorrection(ObjectSrg::m_outerAabbMin, ObjectSrg::m_outerAabbMax, ObjectSrg::m_aabbPos, positionWS, reflectDir);
}
float NdotV = saturate(dot(clearCoatNormal, dirToCamera));
NdotV = max(NdotV, 0.01f); // [GFX TODO][ATOM-4466] This is a current band-aid for specular noise at grazing angles.
float3 coatProbeSpecular = ObjectSrg::m_reflectionCubeMap.SampleLevel(SceneSrg::m_samplerEnv, GetCubemapCoords(localReflectDir), GetRoughnessMip(roughness)).rgb;
float2 coatBrdf = PassSrg::m_brdfMap.Sample(PassSrg::LinearSampler, GetBRDFTexCoords(roughness, NdotV)).rg;
// clear coat uses fixed IOR = 1.5 represents polyurethane which is the most common material for gloss clear coat
// coat layer assumed to be dielectric thus don't need multiple scattering compensation
float3 clearCoat = coatProbeSpecular * (float3(0.04, 0.04, 0.04) * coatBrdf.x + coatBrdf.y) * factor;
// attenuate base layer energy
float3 coatResponse = FresnelSchlickWithRoughness(NdotV, float3(0.04, 0.04, 0.04), roughness) * factor;
specular = specular * (1.0 - coatResponse) * (1.0 - coatResponse) + clearCoat;
}
return true;
}

@ -28,7 +28,6 @@ ShaderResourceGroup PassSrg : SRG_PerPass
Texture2DMS<float> m_depth;
Texture2DMS<float4> m_normal;
Texture2DMS<float4> m_specularF0;
Texture2DMS<float4> m_clearCoatNormal;
Texture2D<float2> m_brdfMap;
Sampler LinearSampler

@ -15,7 +15,7 @@
"Stencil" :
{
"Enable" : true,
"ReadMask" : "0xFF",
"ReadMask" : "0x7F",
"WriteMask" : "0x00",
"BackFace" :
{

@ -30,7 +30,6 @@ ShaderResourceGroup PassSrg : SRG_PerPass
Texture2DMS<float> m_depth;
Texture2DMS<float4> m_normal;
Texture2DMS<float4> m_specularF0;
Texture2DMS<float4> m_clearCoatNormal;
Texture2DMS<float> m_blendWeight;
Texture2D<float2> m_brdfMap;

@ -15,7 +15,7 @@
"Stencil" :
{
"Enable" : true,
"ReadMask" : "0xFF",
"ReadMask" : "0x7F",
"WriteMask" : "0x00",
"BackFace" :
{

@ -17,8 +17,8 @@
// This shader stencils the pixels covered by inner probe volumes. This will
// exclude them from blending operations in the later passes since inner volumes
// always blend at 100%. Note that this shader only considers pixels that were
// stenciled with the UseSpecularIBLPass value when they were rendered in the forward pass.
// It increases the stencil value if they are in an inner volume (i.e., makes their stencil > 1).
// stenciled with the UseIBLSpecularPass value when they were rendered in the forward pass.
// It increases the stencil value if they are in an inner volume.
#include <viewsrg.srgi>

@ -17,8 +17,8 @@
"Stencil" :
{
"Enable" : true,
"ReadMask" : "0xFF",
"WriteMask" : "0xFF",
"ReadMask" : "0x7F",
"WriteMask" : "0x7F",
"FrontFace" :
{
"Func" : "Less",

@ -99,6 +99,7 @@ namespace AZ
bool m_rayTracingEnabled = true;
bool m_visible = true;
bool m_useForwardPassIblSpecular = false;
bool m_hasForwardPassIblSpecularMaterial = false;
};
//! This feature processor handles static and dynamic non-skinned meshes.

@ -240,6 +240,8 @@ namespace AZ
{
meshHandle->m_materialAssignments = materials;
}
meshHandle->m_objectSrgNeedsUpdate = true;
}
}
@ -547,6 +549,8 @@ namespace AZ
drawPacketListOut.clear();
drawPacketListOut.reserve(meshCount);
m_hasForwardPassIblSpecularMaterial = false;
for (size_t meshIndex = 0; meshIndex < meshCount; ++meshIndex)
{
Data::Instance<RPI::Material> material = modelLod.GetMeshes()[meshIndex].m_material;
@ -602,7 +606,16 @@ namespace AZ
AZ_Warning("MeshDrawPacket", false, "Failed to set o_meshUseForwardPassIBLSpecular on mesh draw packet");
}
drawPacket.SetStencilRef(m_useForwardPassIblSpecular || MaterialRequiresForwardPassIblSpecular(material) ? Render::StencilRefs::None : Render::StencilRefs::UseIBLSpecularPass);
bool materialRequiresForwardPassIblSpecular = MaterialRequiresForwardPassIblSpecular(material);
// track whether any materials in this mesh require ForwardPassIblSpecular, we need this information when the ObjectSrg is updated
m_hasForwardPassIblSpecularMaterial |= materialRequiresForwardPassIblSpecular;
// stencil bits
uint8_t stencilRef = m_useForwardPassIblSpecular || materialRequiresForwardPassIblSpecular ? Render::StencilRefs::None : Render::StencilRefs::UseIBLSpecularPass;
stencilRef |= Render::StencilRefs::UseDiffuseGIPass;
drawPacket.SetStencilRef(stencilRef);
drawPacket.SetSortKey(m_sortKey);
drawPacket.Update(*m_scene, false);
drawPacketListOut.emplace_back(AZStd::move(drawPacket));
@ -891,7 +904,9 @@ namespace AZ
return;
}
if (m_useForwardPassIblSpecular)
ReflectionProbeFeatureProcessor* reflectionProbeFeatureProcessor = m_scene->GetFeatureProcessor<ReflectionProbeFeatureProcessor>();
if (reflectionProbeFeatureProcessor && (m_useForwardPassIblSpecular || m_hasForwardPassIblSpecularMaterial))
{
// retrieve probe constant indices
AZ::RHI::ShaderInputConstantIndex posConstantIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name("m_reflectionProbeData.m_aabbPos"));
@ -924,7 +939,6 @@ namespace AZ
TransformServiceFeatureProcessor* transformServiceFeatureProcessor = m_scene->GetFeatureProcessor<TransformServiceFeatureProcessor>();
Transform transform = transformServiceFeatureProcessor->GetTransformForId(m_objectId);
ReflectionProbeFeatureProcessor* reflectionProbeFeatureProcessor = m_scene->GetFeatureProcessor<ReflectionProbeFeatureProcessor>();
ReflectionProbeFeatureProcessor::ReflectionProbeVector reflectionProbes;
reflectionProbeFeatureProcessor->FindReflectionProbes(transform.GetTranslation(), reflectionProbes);

@ -22,13 +22,30 @@ namespace AZ
{
const uint32_t None = 0x00;
// The MeshFeatureProcessor sets this stencil bit on any geometry that should receive IBL specular in the reflections pass,
// otherwise IBL specular is rendered in the Forward pass.
// The Reflections pass only renders to areas with this stencil bit set.
// UseIBLSpecularPass
//
// Pass Range: Forward -> Reflections.
// Note: The Reflections pass may also overwrite other bits in the stencil buffer.
const uint32_t UseIBLSpecularPass = 0xF;
// The MeshFeatureProcessor sets this stencil bit on any geometry that should receive IBL Specular in the Reflections pass,
// otherwise IBL specular is rendered in the Forward pass. The Reflections pass only renders to areas with these stencil bits set.
//
// Used in pass range: Forward -> Reflections
//
// Notes:
// - Two bits are needed here (0x3) so that the ReflectionProbeStencilPass can use "Less" on its stencil test to
// properly handle the DecrSat on the FrontFace stencil operation depth-fail.
// - The ReflectionProbeStencilPass pass may overwrite other bits in the stencil buffer, depending on the amount of
// reflection probe volume nesting in the content.
// - New stencil bits for other purposes should be added to the most signficant bits and masked out of the Reflection passes. This is
// necessary to allow the most amount of bits to be used by the ReflectionProbeStencilPass for nested probe volumes.
// - The Reflection passes currently use 0x7F for the ReadMask and WriteMask to exclude the UseDiffuseGIPass stencil bit (see below). If
// other stencil bits are added then these masks will need to be updated.
const uint32_t UseIBLSpecularPass = 0x3;
// UseDiffuseGIPass
//
// The MeshFeatureProcessor sets this stencil bit on any geometry that should receive Diffuse GI in the DiffuseGlobalIllumination pass.
//
// Used in pass range: Forward -> DiffuseGlobalIllumination
const uint32_t UseDiffuseGIPass = 0x80;
}
}
}

@ -187,7 +187,6 @@ ForwardPassOutput AutoBrick_ForwardPassPS(VSOutput IN)
OUT.m_specularF0 = lightingOutput.m_specularF0;
OUT.m_albedo = lightingOutput.m_albedo;
OUT.m_normal = lightingOutput.m_normal;
OUT.m_clearCoatNormal = lightingOutput.m_clearCoatNormal;
OUT.m_scatterDistance = float3(0,0,0);
return OUT;

@ -85,7 +85,6 @@ ForwardPassOutput MinimalPBR_MainPassPS(VSOutput IN)
OUT.m_specularF0 = lightingOutput.m_specularF0;
OUT.m_albedo = lightingOutput.m_albedo;
OUT.m_normal = lightingOutput.m_normal;
OUT.m_clearCoatNormal = lightingOutput.m_clearCoatNormal;
OUT.m_scatterDistance = float3(0,0,0);
return OUT;

Loading…
Cancel
Save