Skip to content

Commit 4bfa851

Browse files
GLTF Viewer: use surface properties to apply SSR
1 parent 4ceffc5 commit 4bfa851

File tree

3 files changed

+94
-45
lines changed

3 files changed

+94
-45
lines changed

Samples/GLTFViewer/assets/shaders/ApplyPostEffects.psh

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "BasicStructures.fxh"
44
#include "PBR_Structures.fxh"
55
#include "RenderPBR_Structures.fxh"
6+
#include "PBR_Shading.fxh"
67
#include "ToneMapping.fxh"
78
#include "SRGBUtilities.fxh"
89

@@ -11,31 +12,60 @@ cbuffer cbFrameAttribs
1112
PBRFrameAttribs g_Frame;
1213
}
1314

14-
Texture2D<float4> g_tex2DColor;
15+
Texture2D<float4> g_tex2DRadiance;
16+
Texture2D<float4> g_tex2DNormal;
1517
Texture2D<float4> g_tex2DSSR;
1618
Texture2D<float4> g_tex2DIBL;
19+
Texture2D<float4> g_tex2DMaterialData;
20+
Texture2D<float4> g_tex2DBaseColor;
21+
22+
Texture2D<float4> g_tex2DPreintegratedGGX;
23+
SamplerState g_tex2DPreintegratedGGX_sampler;
1724

1825
float4 main(in FullScreenTriangleVSOutput VSOut) : SV_Target
1926
{
20-
float4 Color = g_tex2DColor.Load(int3(VSOut.f4PixelPos.xy, 0));
21-
float4 SSR = g_tex2DSSR.Load(int3(VSOut.f4PixelPos.xy, 0));
22-
float4 IBL = g_tex2DIBL.Load(int3(VSOut.f4PixelPos.xy, 0));
27+
float4 OutColor = g_tex2DRadiance.Load(int3(VSOut.f4PixelPos.xy, 0));
28+
float3 Normal = g_tex2DNormal.Load(int3(VSOut.f4PixelPos.xy, 0)).xyz;
29+
float4 SSRRadiance = g_tex2DSSR.Load(int3(VSOut.f4PixelPos.xy, 0));
30+
float4 IBL = g_tex2DIBL.Load(int3(VSOut.f4PixelPos.xy, 0));
31+
float4 BaseColor = g_tex2DBaseColor.Load(int3(VSOut.f4PixelPos.xy, 0));
32+
float4 Material = g_tex2DMaterialData.Load(int3(VSOut.f4PixelPos.xy, 0));
2333

2434
float SSRScale = g_Frame.PrevCamera.f4ExtraData[0].x;
2535
float DebugMode = g_Frame.PrevCamera.f4ExtraData[0].y;
36+
37+
float Roughness = Material.x;
38+
float Metallic = Material.y;
39+
SurfaceReflectanceInfo SrfInfo = GetSurfaceReflectanceMR(BaseColor.rgb, Metallic, Roughness);
40+
41+
float4 WorldPos = mul(float4(VSOut.f2NormalizedXY, DepthToNormalizedDeviceZ(0.5), 1.0), g_Frame.Camera.mViewProjInv);
42+
float3 ViewDir = normalize(WorldPos.xyz / WorldPos.w - g_Frame.Camera.f4Position.xyz);
43+
44+
IBLSamplingInfo IBLInfo = GetIBLSamplingInfo(SrfInfo,
45+
g_tex2DPreintegratedGGX,
46+
g_tex2DPreintegratedGGX_sampler,
47+
Normal,
48+
ViewDir);
49+
50+
float3 SSR = GetSpecularIBL_GGX(SrfInfo, IBLInfo, SSRRadiance.rgb);
51+
2652
if (DebugMode == 0.0)
2753
{
28-
Color.rgb += (SSR.rgb - IBL.rgb) * SSR.w * Color.a * SSRScale;
54+
OutColor.rgb += (SSR.rgb - IBL.rgb) * SSRRadiance.w * OutColor.a * SSRScale;
2955
}
3056
else if (DebugMode == 1.0)
3157
{
32-
Color.rgb = SSR.rgb;
58+
OutColor.rgb = SSRRadiance.rgb;
3359
}
3460
else if (DebugMode == 2.0)
3561
{
36-
Color.rgb = float3(SSR.w, SSR.w, SSR.w);
62+
OutColor.rgb = SSR.rgb;
3763
}
38-
64+
else if (DebugMode == 3.0)
65+
{
66+
OutColor.rgb = float3(SSRRadiance.w, SSRRadiance.w, SSRRadiance.w);
67+
}
68+
3969
{
4070
// Perform tone mapping
4171
ToneMappingAttribs TMAttribs;
@@ -45,15 +75,15 @@ float4 main(in FullScreenTriangleVSOutput VSOut) : SV_Target
4575
TMAttribs.bLightAdaptation = false;
4676
TMAttribs.fWhitePoint = g_Frame.Renderer.WhitePoint;
4777
TMAttribs.fLuminanceSaturation = 1.0;
48-
Color.rgb = ToneMap(Color.rgb, TMAttribs, g_Frame.Renderer.AverageLogLum);
78+
OutColor.rgb = ToneMap(OutColor.rgb, TMAttribs, g_Frame.Renderer.AverageLogLum);
4979
}
5080

5181
#if CONVERT_OUTPUT_TO_SRGB
5282
{
53-
Color.rgb = FastLinearToSRGB(Color.rgb);
83+
OutColor.rgb = FastLinearToSRGB(OutColor.rgb);
5484
}
5585
#endif
5686

57-
Color.a = 1.0;
58-
return Color;
87+
OutColor.a = 1.0;
88+
return OutColor;
5989
}

Samples/GLTFViewer/src/GLTFViewer.cpp

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,9 @@ const std::pair<const char*, const char*> DefaultGLTFModels[] =
101101

102102
enum GBUFFER_RT : Uint32
103103
{
104-
GBUFFER_RT_COLOR,
104+
GBUFFER_RT_RADIANCE,
105105
GBUFFER_RT_NORMAL,
106+
GBUFFER_RT_BASE_COLOR,
106107
GBUFFER_RT_MATERIAL_DATA,
107108
GBUFFER_RT_MOTION_VECTORS,
108109
GBUFFER_RT_SPECULAR_IBL,
@@ -112,8 +113,9 @@ enum GBUFFER_RT : Uint32
112113

113114
enum GBUFFER_RT_FLAG : Uint32
114115
{
115-
GBUFFER_RT_FLAG_COLOR = 1u << GBUFFER_RT_COLOR,
116+
GBUFFER_RT_FLAG_COLOR = 1u << GBUFFER_RT_RADIANCE,
116117
GBUFFER_RT_FLAG_NORMAL = 1u << GBUFFER_RT_NORMAL,
118+
GBUFFER_RT_FLAG_BASE_COLOR = 1u << GBUFFER_RT_BASE_COLOR,
117119
GBUFFER_RT_FLAG_MATERIAL_DATA = 1u << GBUFFER_RT_MATERIAL_DATA,
118120
GBUFFER_RT_FLAG_MOTION_VECTORS = 1u << GBUFFER_RT_MOTION_VECTORS,
119121
GBUFFER_RT_FLAG_SPECULAR_IBL = 1u << GBUFFER_RT_SPECULAR_IBL,
@@ -350,9 +352,10 @@ struct PSOutput
350352
{
351353
float4 Color : SV_Target0;
352354
float4 Normal : SV_Target1;
353-
float4 MaterialData : SV_Target2;
354-
float4 MotionVec : SV_Target3;
355-
float4 IBL : SV_Target4;
355+
float4 BaseColor : SV_Target2;
356+
float4 MaterialData : SV_Target3;
357+
float4 MotionVec : SV_Target4;
358+
float4 IBL : SV_Target5;
356359
};
357360
)";
358361

@@ -366,6 +369,7 @@ struct PSOutput
366369
367370
PSOut.Normal.xyz = Shading.BaseLayer.Normal.xyz;
368371
PSOut.MaterialData.xyz = float3(Shading.BaseLayer.Srf.PerceptualRoughness, Shading.BaseLayer.Metallic, 0.0);
372+
PSOut.BaseColor.xyz = BaseColor.xyz;
369373
PSOut.IBL.xyz = GetBaseLayerIBL(Shading, SrfLighting);
370374
371375
# if ENABLE_CLEAR_COAT
@@ -377,6 +381,7 @@ struct PSOutput
377381
378382
PSOut.Normal.xyz = lerp(PSOut.Normal.xyz, Shading.Clearcoat.Normal, Shading.Clearcoat.Factor);
379383
PSOut.MaterialData.xy = lerp(PSOut.MaterialData.xy, float2(Shading.Clearcoat.Srf.PerceptualRoughness, 0.0), Shading.Clearcoat.Factor);
384+
PSOut.BaseColor.xyz = lerp(PSOut.BaseColor.xyz, float3(1.0, 1.0, 1.0), Shading.Clearcoat.Factor);
380385
381386
// Note that the base layer IBL is weighted by (1.0 - Shading.Clearcoat.Factor * ClearcoatFresnel).
382387
// Here we are weighting it by (1.0 - Shading.Clearcoat.Factor), which is always smaller,
@@ -389,6 +394,7 @@ struct PSOutput
389394
# endif
390395
391396
// Blend material data and IBL with background
397+
PSOut.BaseColor = float4(PSOut.BaseColor.xyz * BaseColor.a, BaseColor.a);
392398
PSOut.MaterialData = float4(PSOut.MaterialData.xyz * BaseColor.a, BaseColor.a);
393399
PSOut.IBL = float4(PSOut.IBL.xyz * BaseColor.a, BaseColor.a);
394400
@@ -409,13 +415,15 @@ void main(in float4 Pos : SV_Position,
409415
in float4 ClipPos : CLIP_POS,
410416
out float4 Color : SV_Target0,
411417
out float4 Normal : SV_Target1,
412-
out float4 MaterialData : SV_Target2,
413-
out float4 MotionVec : SV_Target3,
414-
out float4 IBL : SV_Target4)
418+
out float4 BaseColor : SV_Target2,
419+
out float4 MaterialData : SV_Target3,
420+
out float4 MotionVec : SV_Target4,
421+
out float4 IBL : SV_Target5)
415422
{
416423
Color = SampleEnvMap(ClipPos);
417424
418425
Normal = float4(0.0, 0.0, 0.0, 0.0);
426+
BaseColor = float4(0.0, 0.0, 0.0, 0.0);
419427
MaterialData = float4(0.0, 0.0, 0.0, 0.0);
420428
MotionVec = float4(0.0, 0.0, 0.0, 0.0);
421429
IBL = float4(0.0, 0.0, 0.0, 0.0);
@@ -552,13 +560,14 @@ void GLTFViewer::Initialize(const SampleInitInfo& InitInfo)
552560

553561
{
554562
GBuffer::ElementDesc GBufferElems[GBUFFER_RT_COUNT];
555-
GBufferElems[GBUFFER_RT_COLOR] = {TEX_FORMAT_RGBA16_FLOAT};
563+
GBufferElems[GBUFFER_RT_RADIANCE] = {TEX_FORMAT_RGBA16_FLOAT};
556564
GBufferElems[GBUFFER_RT_NORMAL] = {TEX_FORMAT_RGBA16_FLOAT};
565+
GBufferElems[GBUFFER_RT_BASE_COLOR] = {TEX_FORMAT_RGBA8_UNORM};
557566
GBufferElems[GBUFFER_RT_MATERIAL_DATA] = {TEX_FORMAT_RG8_UNORM};
558567
GBufferElems[GBUFFER_RT_MOTION_VECTORS] = {TEX_FORMAT_RG16_FLOAT};
559568
GBufferElems[GBUFFER_RT_SPECULAR_IBL] = {TEX_FORMAT_RGBA16_FLOAT};
560569
GBufferElems[GBUFFER_RT_DEPTH] = {TEX_FORMAT_D32_FLOAT};
561-
static_assert(GBUFFER_RT_COUNT == 6, "Not all G-buffer elements are initialized");
570+
static_assert(GBUFFER_RT_COUNT == 7, "Not all G-buffer elements are initialized");
562571

563572
m_GBuffer = std::make_unique<GBuffer>(GBufferElems, _countof(GBufferElems));
564573
}
@@ -656,7 +665,8 @@ void GLTFViewer::ApplyPosteffects::Initialize(IRenderDevice* pDevice, TEXTURE_FO
656665
PipelineResourceLayoutDescX ResourceLauout;
657666
ResourceLauout
658667
.SetDefaultVariableType(SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC)
659-
.AddVariable(SHADER_TYPE_PIXEL, "cbFrameAttribs", SHADER_RESOURCE_VARIABLE_TYPE_STATIC);
668+
.AddVariable(SHADER_TYPE_PIXEL, "cbFrameAttribs", SHADER_RESOURCE_VARIABLE_TYPE_STATIC)
669+
.AddImmutableSampler(SHADER_TYPE_PIXEL, "g_tex2DPreintegratedGGX", Sam_LinearClamp);
660670

661671
GraphicsPipelineStateCreateInfoX PsoCI{"Apply Post Effects"};
662672
PsoCI
@@ -673,12 +683,19 @@ void GLTFViewer::ApplyPosteffects::Initialize(IRenderDevice* pDevice, TEXTURE_FO
673683
pPSO->GetStaticVariableByName(SHADER_TYPE_PIXEL, "cbFrameAttribs")->Set(pFrameAttribsCB);
674684

675685
pPSO->CreateShaderResourceBinding(&pSRB, true);
676-
ptex2DColorVar = pSRB->GetVariableByName(SHADER_TYPE_PIXEL, "g_tex2DColor");
677-
VERIFY_EXPR(ptex2DColorVar != nullptr);
678-
ptex2DSSR = pSRB->GetVariableByName(SHADER_TYPE_PIXEL, "g_tex2DSSR");
679-
VERIFY_EXPR(ptex2DSSR != nullptr);
680-
ptex2DPecularIBL = pSRB->GetVariableByName(SHADER_TYPE_PIXEL, "g_tex2DIBL");
681-
VERIFY_EXPR(ptex2DPecularIBL != nullptr);
686+
687+
auto GetVariable = [&](const char* Name) {
688+
IShaderResourceVariable* pVar = pSRB->GetVariableByName(SHADER_TYPE_PIXEL, Name);
689+
VERIFY_EXPR(pVar != nullptr);
690+
return pVar;
691+
};
692+
ptex2DRadianceVar = GetVariable("g_tex2DRadiance");
693+
ptex2DNormalVar = GetVariable("g_tex2DNormal");
694+
ptex2DSSR = GetVariable("g_tex2DSSR");
695+
ptex2DPecularIBL = GetVariable("g_tex2DIBL");
696+
ptex2DBaseColorVar = GetVariable("g_tex2DBaseColor");
697+
ptex2DMaterialDataVar = GetVariable("g_tex2DMaterialData");
698+
ptex2DPreintegratedGGXVar = GetVariable("g_tex2DPreintegratedGGX");
682699
}
683700

684701
void GLTFViewer::UpdateUI()
@@ -961,9 +978,10 @@ void GLTFViewer::UpdateUI()
961978

962979
ImGui::SliderFloat("SSR scale", &m_ShaderAttribs.SSRScale, 0.f, 1.f);
963980

964-
ImGui::Combo("SSR Debug View", reinterpret_cast<int*>(&m_ShaderAttribs.SSRDebugMode),
981+
ImGui::Combo("SSR Debug View", &m_ShaderAttribs.SSRDebugMode,
965982
"None\0"
966-
"SSR\0"
983+
"Radiance\0"
984+
"Reflection\0"
967985
"Confidence\0\0");
968986

969987
ImGui::TreePop();
@@ -1190,7 +1208,7 @@ void GLTFViewer::Render()
11901208
ScreenSpaceReflection::RenderAttributes SSRRenderAttribs{};
11911209
SSRRenderAttribs.pDevice = m_pDevice;
11921210
SSRRenderAttribs.pDeviceContext = m_pImmediateContext;
1193-
SSRRenderAttribs.pColorBufferSRV = m_GBuffer->GetBuffer(GBUFFER_RT_COLOR)->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE);
1211+
SSRRenderAttribs.pColorBufferSRV = m_GBuffer->GetBuffer(GBUFFER_RT_RADIANCE)->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE);
11941212
SSRRenderAttribs.pDepthBufferSRV = m_GBuffer->GetBuffer(GBUFFER_RT_DEPTH)->GetDefaultView(TEXTURE_VIEW_DEPTH_STENCIL);
11951213
SSRRenderAttribs.pNormalBufferSRV = m_GBuffer->GetBuffer(GBUFFER_RT_NORMAL)->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE);
11961214
SSRRenderAttribs.pMaterialBufferSRV = m_GBuffer->GetBuffer(GBUFFER_RT_MATERIAL_DATA)->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE);
@@ -1223,9 +1241,13 @@ void GLTFViewer::Render()
12231241
m_pImmediateContext->ClearRenderTarget(pRTV, ClearColor, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
12241242

12251243
m_pImmediateContext->SetPipelineState(m_ApplyPostFX.pPSO);
1226-
m_ApplyPostFX.ptex2DColorVar->Set(m_GBuffer->GetBuffer(GBUFFER_RT_COLOR)->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE));
1244+
m_ApplyPostFX.ptex2DRadianceVar->Set(m_GBuffer->GetBuffer(GBUFFER_RT_RADIANCE)->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE));
1245+
m_ApplyPostFX.ptex2DNormalVar->Set(m_GBuffer->GetBuffer(GBUFFER_RT_NORMAL)->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE));
12271246
m_ApplyPostFX.ptex2DSSR->Set(m_SSR->GetSSRRadianceSRV());
12281247
m_ApplyPostFX.ptex2DPecularIBL->Set(m_GBuffer->GetBuffer(GBUFFER_RT_SPECULAR_IBL)->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE));
1248+
m_ApplyPostFX.ptex2DBaseColorVar->Set(m_GBuffer->GetBuffer(GBUFFER_RT_BASE_COLOR)->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE));
1249+
m_ApplyPostFX.ptex2DMaterialDataVar->Set(m_GBuffer->GetBuffer(GBUFFER_RT_MATERIAL_DATA)->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE));
1250+
m_ApplyPostFX.ptex2DPreintegratedGGXVar->Set(m_GLTFRenderer->GetPreintegratedGGX_SRV());
12291251
m_pImmediateContext->CommitShaderResources(m_ApplyPostFX.pSRB, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
12301252
m_pImmediateContext->Draw({3, DRAW_FLAG_VERIFY_ALL});
12311253

Samples/GLTFViewer/src/GLTFViewer.hpp

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,6 @@ class GLTFViewer final : public SampleBase
8787

8888
GLTF_PBR_Renderer::RenderInfo m_RenderParams;
8989

90-
enum class SSRDebugViewMode : int
91-
{
92-
None,
93-
SSR,
94-
Confidence
95-
};
96-
9790
struct ShaderParams
9891
{
9992
float OcclusionStrength = 1;
@@ -106,8 +99,8 @@ class GLTFViewer final : public SampleBase
10699
float4 HighlightColor = float4{0, 0, 0, 0};
107100
float4 WireframeColor = float4{0.8f, 0.7f, 0.5f, 1.0f};
108101

109-
float SSRScale = 1;
110-
SSRDebugViewMode SSRDebugMode = SSRDebugViewMode::None;
102+
float SSRScale = 1;
103+
int SSRDebugMode = 0;
111104
};
112105
ShaderParams m_ShaderAttribs;
113106

@@ -158,9 +151,13 @@ class GLTFViewer final : public SampleBase
158151
RefCntAutoPtr<IPipelineState> pPSO;
159152
RefCntAutoPtr<IShaderResourceBinding> pSRB;
160153

161-
IShaderResourceVariable* ptex2DColorVar = nullptr;
162-
IShaderResourceVariable* ptex2DSSR = nullptr;
163-
IShaderResourceVariable* ptex2DPecularIBL = nullptr;
154+
IShaderResourceVariable* ptex2DRadianceVar = nullptr;
155+
IShaderResourceVariable* ptex2DNormalVar = nullptr;
156+
IShaderResourceVariable* ptex2DSSR = nullptr;
157+
IShaderResourceVariable* ptex2DPecularIBL = nullptr;
158+
IShaderResourceVariable* ptex2DBaseColorVar = nullptr;
159+
IShaderResourceVariable* ptex2DMaterialDataVar = nullptr;
160+
IShaderResourceVariable* ptex2DPreintegratedGGXVar = nullptr;
164161

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

0 commit comments

Comments
 (0)