@@ -104,6 +104,7 @@ enum GBUFFER_RT : Uint32
104
104
GBUFFER_RT_NORMAL,
105
105
GBUFFER_RT_MATERIAL_DATA,
106
106
GBUFFER_RT_MOTION_VECTORS,
107
+ GBUFFER_RT_SPECULAR_IBL,
107
108
GBUFFER_RT_DEPTH,
108
109
GBUFFER_RT_COUNT
109
110
};
@@ -114,6 +115,7 @@ enum GBUFFER_RT_FLAG : Uint32
114
115
GBUFFER_RT_FLAG_NORMAL = 1u << GBUFFER_RT_NORMAL,
115
116
GBUFFER_RT_FLAG_MATERIAL_DATA = 1u << GBUFFER_RT_MATERIAL_DATA,
116
117
GBUFFER_RT_FLAG_MOTION_VECTORS = 1u << GBUFFER_RT_MOTION_VECTORS,
118
+ GBUFFER_RT_FLAG_SPECULAR_IBL = 1u << GBUFFER_RT_SPECULAR_IBL,
117
119
GBUFFER_RT_FLAG_DEPTH = 1u << GBUFFER_RT_DEPTH,
118
120
GBUFFER_RT_FLAG_LAST = GBUFFER_RT_FLAG_DEPTH,
119
121
GBUFFER_RT_FLAG_ALL = (GBUFFER_RT_FLAG_LAST << 1u ) - 1u ,
@@ -349,6 +351,7 @@ struct PSOutput
349
351
float4 Normal : SV_Target1;
350
352
float4 MaterialData : SV_Target2;
351
353
float4 MotionVec : SV_Target3;
354
+ float4 IBL : SV_Target4;
352
355
};
353
356
)" ;
354
357
@@ -360,17 +363,40 @@ struct PSOutput
360
363
PSOut.Color = OutColor;
361
364
#endif
362
365
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);
365
369
366
370
# if ENABLE_CLEAR_COAT
367
371
{
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
+
368
377
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
+ }
371
388
# 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
373
395
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
+
374
400
return PSOut;
375
401
)" ;
376
402
@@ -383,14 +409,16 @@ void main(in float4 Pos : SV_Position,
383
409
out float4 Color : SV_Target0,
384
410
out float4 Normal : SV_Target1,
385
411
out float4 MaterialData : SV_Target2,
386
- out float4 MotionVec : SV_Target3)
412
+ out float4 MotionVec : SV_Target3,
413
+ out float4 IBL : SV_Target4)
387
414
{
388
415
Color.rgb = SampleEnvMap(ClipPos);
389
416
Color.a = 1.0;
390
417
391
418
Normal = float4(0.0, 0.0, 0.0, 0.0);
392
419
MaterialData = float4(0.0, 0.0, 0.0, 0.0);
393
420
MotionVec = float4(0.0, 0.0, 0.0, 0.0);
421
+ IBL = float4(0.0, 0.0, 0.0, 0.0);
394
422
}
395
423
)" ;
396
424
@@ -528,8 +556,9 @@ void GLTFViewer::Initialize(const SampleInitInfo& InitInfo)
528
556
GBufferElems[GBUFFER_RT_NORMAL] = {TEX_FORMAT_RGBA16_FLOAT};
529
557
GBufferElems[GBUFFER_RT_MATERIAL_DATA] = {TEX_FORMAT_RG8_UNORM};
530
558
GBufferElems[GBUFFER_RT_MOTION_VECTORS] = {TEX_FORMAT_RG16_FLOAT};
559
+ GBufferElems[GBUFFER_RT_SPECULAR_IBL] = {TEX_FORMAT_RGBA16_FLOAT};
531
560
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" );
533
562
534
563
m_GBuffer = std::make_unique<GBuffer>(GBufferElems, _countof (GBufferElems));
535
564
}
@@ -648,6 +677,8 @@ void GLTFViewer::ApplyPosteffects::Initialize(IRenderDevice* pDevice, TEXTURE_FO
648
677
VERIFY_EXPR (ptex2DColorVar != nullptr );
649
678
ptex2DSSR = pSRB->GetVariableByName (SHADER_TYPE_PIXEL, " g_tex2DSSR" );
650
679
VERIFY_EXPR (ptex2DSSR != nullptr );
680
+ ptex2DPecularIBL = pSRB->GetVariableByName (SHADER_TYPE_PIXEL, " g_tex2DIBL" );
681
+ VERIFY_EXPR (ptex2DPecularIBL != nullptr );
651
682
}
652
683
653
684
void GLTFViewer::UpdateUI ()
@@ -1164,6 +1195,7 @@ void GLTFViewer::Render()
1164
1195
m_pImmediateContext->SetPipelineState (m_ApplyPostFX.pPSO );
1165
1196
m_ApplyPostFX.ptex2DColorVar ->Set (m_GBuffer->GetBuffer (GBUFFER_RT_COLOR)->GetDefaultView (TEXTURE_VIEW_SHADER_RESOURCE));
1166
1197
m_ApplyPostFX.ptex2DSSR ->Set (m_SSR->GetSSRRadianceSRV ());
1198
+ m_ApplyPostFX.ptex2DPecularIBL ->Set (m_GBuffer->GetBuffer (GBUFFER_RT_SPECULAR_IBL)->GetDefaultView (TEXTURE_VIEW_SHADER_RESOURCE));
1167
1199
m_pImmediateContext->CommitShaderResources (m_ApplyPostFX.pSRB , RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
1168
1200
m_pImmediateContext->Draw ({3 , DRAW_FLAG_VERIFY_ALL});
1169
1201
0 commit comments