Skip to content

Commit e257811

Browse files
GLTF Viewer: improved mixing SSR with IBL
1 parent e2c6686 commit e257811

File tree

3 files changed

+46
-11
lines changed

3 files changed

+46
-11
lines changed

Samples/GLTFViewer/assets/shaders/ApplyPostEffects.psh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@ cbuffer cbFrameAttribs
1313

1414
Texture2D<float4> g_tex2DColor;
1515
Texture2D<float4> g_tex2DSSR;
16-
16+
Texture2D<float4> g_tex2DIBL;
1717

1818
float4 main(in FullScreenTriangleVSOutput VSOut) : SV_Target
1919
{
2020
float4 Color = g_tex2DColor.Load(int3(VSOut.f4PixelPos.xy, 0));
2121
float4 SSR = g_tex2DSSR.Load(int3(VSOut.f4PixelPos.xy, 0));
22-
Color.rgb += SSR.rgb * SSR.w;
22+
float4 IBL = g_tex2DIBL.Load(int3(VSOut.f4PixelPos.xy, 0));
23+
24+
Color.rgb += (SSR.rgb - IBL.rgb) * SSR.w;
2325

2426
{
2527
// Perform tone mapping

Samples/GLTFViewer/src/GLTFViewer.cpp

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ enum GBUFFER_RT : Uint32
104104
GBUFFER_RT_NORMAL,
105105
GBUFFER_RT_MATERIAL_DATA,
106106
GBUFFER_RT_MOTION_VECTORS,
107+
GBUFFER_RT_SPECULAR_IBL,
107108
GBUFFER_RT_DEPTH,
108109
GBUFFER_RT_COUNT
109110
};
@@ -114,6 +115,7 @@ enum GBUFFER_RT_FLAG : Uint32
114115
GBUFFER_RT_FLAG_NORMAL = 1u << GBUFFER_RT_NORMAL,
115116
GBUFFER_RT_FLAG_MATERIAL_DATA = 1u << GBUFFER_RT_MATERIAL_DATA,
116117
GBUFFER_RT_FLAG_MOTION_VECTORS = 1u << GBUFFER_RT_MOTION_VECTORS,
118+
GBUFFER_RT_FLAG_SPECULAR_IBL = 1u << GBUFFER_RT_SPECULAR_IBL,
117119
GBUFFER_RT_FLAG_DEPTH = 1u << GBUFFER_RT_DEPTH,
118120
GBUFFER_RT_FLAG_LAST = GBUFFER_RT_FLAG_DEPTH,
119121
GBUFFER_RT_FLAG_ALL = (GBUFFER_RT_FLAG_LAST << 1u) - 1u,
@@ -349,6 +351,7 @@ struct PSOutput
349351
float4 Normal : SV_Target1;
350352
float4 MaterialData : SV_Target2;
351353
float4 MotionVec : SV_Target3;
354+
float4 IBL : SV_Target4;
352355
};
353356
)";
354357

@@ -360,17 +363,40 @@ struct PSOutput
360363
PSOut.Color = OutColor;
361364
#endif
362365
363-
PSOut.Normal = float4(Shading.BaseLayer.Normal, 1.0);
364-
PSOut.MaterialData = float4(Shading.BaseLayer.Srf.PerceptualRoughness, Shading.BaseLayer.Metallic, 0.0, 1.0);
366+
PSOut.Normal.xyz = Shading.BaseLayer.Normal.xyz;
367+
PSOut.MaterialData.xyz = float3(Shading.BaseLayer.Srf.PerceptualRoughness, Shading.BaseLayer.Metallic, 0.0);
368+
PSOut.IBL.xyz = GetBaseLayerIBL(Shading, SrfLighting);
365369
366370
# if ENABLE_CLEAR_COAT
367371
{
372+
// We clearly can't do SSR for both base layer and clear coat, so we
373+
// blend the base layer properties with the clearcoat using the clearcoat factor.
374+
// This way when the factor is 0.0, we get the base layer, when it is 1.0,
375+
// we get the clear coat, and something in between otherwise.
376+
368377
PSOut.Normal.xyz = lerp(PSOut.Normal.xyz, Shading.Clearcoat.Normal, Shading.Clearcoat.Factor);
369-
PSOut.MaterialData.xy = lerp(PSOut.MaterialData.xy, float2(0.0, Shading.Clearcoat.Srf.PerceptualRoughness), Shading.Clearcoat.Factor);
370-
}
378+
PSOut.MaterialData.xy = lerp(PSOut.MaterialData.xy, float2(Shading.Clearcoat.Srf.PerceptualRoughness, 0.0), Shading.Clearcoat.Factor);
379+
380+
// Note that the base layer IBL is weighted by (1.0 - Shading.Clearcoat.Factor * ClearcoatFresnel).
381+
// Here we are weighting it by (1.0 - Shading.Clearcoat.Factor), which is always smaller,
382+
// so when we subtract the IBL, it can never be negative.
383+
PSOut.IBL.xyz = lerp(
384+
PSOut.IBL.xyz,
385+
GetClearcoatIBL(Shading, SrfLighting),
386+
Shading.Clearcoat.Factor);
387+
}
371388
# endif
372-
389+
390+
// Blend material data and IBL with background
391+
PSOut.MaterialData = float4(PSOut.MaterialData.xyz * BaseColor.a, BaseColor.a);
392+
PSOut.IBL = float4(PSOut.IBL.xyz * BaseColor.a, BaseColor.a);
393+
394+
// Do not blend motion vectors as it does not make sense
373395
PSOut.MotionVec = float4(MotionVector, 0.0, 1.0);
396+
397+
// Also do not blend normal - we want normal of the top layer
398+
PSOut.Normal.a = 1.0;
399+
374400
return PSOut;
375401
)";
376402

@@ -383,14 +409,16 @@ void main(in float4 Pos : SV_Position,
383409
out float4 Color : SV_Target0,
384410
out float4 Normal : SV_Target1,
385411
out float4 MaterialData : SV_Target2,
386-
out float4 MotionVec : SV_Target3)
412+
out float4 MotionVec : SV_Target3,
413+
out float4 IBL : SV_Target4)
387414
{
388415
Color.rgb = SampleEnvMap(ClipPos);
389416
Color.a = 1.0;
390417
391418
Normal = float4(0.0, 0.0, 0.0, 0.0);
392419
MaterialData = float4(0.0, 0.0, 0.0, 0.0);
393420
MotionVec = float4(0.0, 0.0, 0.0, 0.0);
421+
IBL = float4(0.0, 0.0, 0.0, 0.0);
394422
}
395423
)";
396424

@@ -528,8 +556,9 @@ void GLTFViewer::Initialize(const SampleInitInfo& InitInfo)
528556
GBufferElems[GBUFFER_RT_NORMAL] = {TEX_FORMAT_RGBA16_FLOAT};
529557
GBufferElems[GBUFFER_RT_MATERIAL_DATA] = {TEX_FORMAT_RG8_UNORM};
530558
GBufferElems[GBUFFER_RT_MOTION_VECTORS] = {TEX_FORMAT_RG16_FLOAT};
559+
GBufferElems[GBUFFER_RT_SPECULAR_IBL] = {TEX_FORMAT_RGBA16_FLOAT};
531560
GBufferElems[GBUFFER_RT_DEPTH] = {TEX_FORMAT_D32_FLOAT};
532-
static_assert(GBUFFER_RT_COUNT == 5, "Not all G-buffer elements are initialized");
561+
static_assert(GBUFFER_RT_COUNT == 6, "Not all G-buffer elements are initialized");
533562

534563
m_GBuffer = std::make_unique<GBuffer>(GBufferElems, _countof(GBufferElems));
535564
}
@@ -648,6 +677,8 @@ void GLTFViewer::ApplyPosteffects::Initialize(IRenderDevice* pDevice, TEXTURE_FO
648677
VERIFY_EXPR(ptex2DColorVar != nullptr);
649678
ptex2DSSR = pSRB->GetVariableByName(SHADER_TYPE_PIXEL, "g_tex2DSSR");
650679
VERIFY_EXPR(ptex2DSSR != nullptr);
680+
ptex2DPecularIBL = pSRB->GetVariableByName(SHADER_TYPE_PIXEL, "g_tex2DIBL");
681+
VERIFY_EXPR(ptex2DPecularIBL != nullptr);
651682
}
652683

653684
void GLTFViewer::UpdateUI()
@@ -1164,6 +1195,7 @@ void GLTFViewer::Render()
11641195
m_pImmediateContext->SetPipelineState(m_ApplyPostFX.pPSO);
11651196
m_ApplyPostFX.ptex2DColorVar->Set(m_GBuffer->GetBuffer(GBUFFER_RT_COLOR)->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE));
11661197
m_ApplyPostFX.ptex2DSSR->Set(m_SSR->GetSSRRadianceSRV());
1198+
m_ApplyPostFX.ptex2DPecularIBL->Set(m_GBuffer->GetBuffer(GBUFFER_RT_SPECULAR_IBL)->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE));
11671199
m_pImmediateContext->CommitShaderResources(m_ApplyPostFX.pSRB, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
11681200
m_pImmediateContext->Draw({3, DRAW_FLAG_VERIFY_ALL});
11691201

Samples/GLTFViewer/src/GLTFViewer.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,9 @@ class GLTFViewer final : public SampleBase
148148
RefCntAutoPtr<IPipelineState> pPSO;
149149
RefCntAutoPtr<IShaderResourceBinding> pSRB;
150150

151-
IShaderResourceVariable* ptex2DColorVar = nullptr;
152-
IShaderResourceVariable* ptex2DSSR = nullptr;
151+
IShaderResourceVariable* ptex2DColorVar = nullptr;
152+
IShaderResourceVariable* ptex2DSSR = nullptr;
153+
IShaderResourceVariable* ptex2DPecularIBL = nullptr;
153154

154155
void Initialize(IRenderDevice* pDevice, TEXTURE_FORMAT RTVFormat, IBuffer* pFrameAttribsCB);
155156
operator bool() const { return pPSO != nullptr; }

0 commit comments

Comments
 (0)