@@ -41,7 +41,6 @@ TEXTURE2D_X(_GBufferTexture4); // VTFeedbakc or Light layer or shadow mask
41
41
TEXTURE2D_X (_GBufferTexture5); // Light layer or shadow mask
42
42
TEXTURE2D_X (_GBufferTexture6); // shadow mask
43
43
44
-
45
44
TEXTURE2D_X (_LightLayersTexture);
46
45
#ifdef SHADOWS_SHADOWMASK
47
46
TEXTURE2D_X (_ShadowMaskTexture); // Alias for shadow mask, so we don't need to know which gbuffer is used for shadow mask
@@ -63,11 +62,11 @@ TEXTURE2D_X(_ShadowMaskTexture); // Alias for shadow mask, so we don't need to k
63
62
#define OUT_GBUFFER_OPTIONAL_SLOT_2 outGBuffer5
64
63
#endif
65
64
66
- #if defined (LIGHT_LAYERS) && defined (SHADOWS_SHADOWMASK)
67
- #define OUT_GBUFFER_LIGHT_LAYERS OUT_GBUFFER_OPTIONAL_SLOT_1
65
+ #if ( defined (LIGHT_LAYERS) || (SHADEROPTIONS_PROBE_VOLUMES_EVALUATION_MODE == PROBEVOLUMESEVALUATIONMODES_LIGHT_LOOP) ) && defined (SHADOWS_SHADOWMASK)
66
+ #define OUT_GBUFFER_LIGHT_LAYERS_AND_AO_AND_UNITIALIZED_GI OUT_GBUFFER_OPTIONAL_SLOT_1
68
67
#define OUT_GBUFFER_SHADOWMASK OUT_GBUFFER_OPTIONAL_SLOT_2
69
- #elif defined (LIGHT_LAYERS)
70
- #define OUT_GBUFFER_LIGHT_LAYERS OUT_GBUFFER_OPTIONAL_SLOT_1
68
+ #elif ( defined (LIGHT_LAYERS) || (SHADEROPTIONS_PROBE_VOLUMES_EVALUATION_MODE == PROBEVOLUMESEVALUATIONMODES_LIGHT_LOOP) )
69
+ #define OUT_GBUFFER_LIGHT_LAYERS_AND_AO_AND_UNITIALIZED_GI OUT_GBUFFER_OPTIONAL_SLOT_1
71
70
#elif defined (SHADOWS_SHADOWMASK)
72
71
#define OUT_GBUFFER_SHADOWMASK OUT_GBUFFER_OPTIONAL_SLOT_1
73
72
#endif
@@ -194,7 +193,7 @@ float3 GetNormalForShadowBias(BSDFData bsdfData)
194
193
float GetAmbientOcclusionForMicroShadowing (BSDFData bsdfData)
195
194
{
196
195
float sourceAO;
197
- #if (SHADERPASS == SHADERPASS_DEFERRED_LIGHTING)
196
+ #if (SHADERPASS == SHADERPASS_DEFERRED_LIGHTING) && ! defined (OUT_GBUFFER_LIGHT_LAYERS_AND_AO_AND_UNITIALIZED_GI)
198
197
// Note: In deferred pass we don't have space in GBuffer to store ambientOcclusion so we use specularOcclusion instead
199
198
sourceAO = bsdfData.specularOcclusion;
200
199
#else
@@ -462,6 +461,28 @@ BSDFData ConvertSurfaceDataToBSDFData(uint2 positionSS, SurfaceData surfaceData)
462
461
return bsdfData;
463
462
}
464
463
464
+ // Store a 7-bit unorm payload, with a 1-bit isUninitializedGI flag.
465
+ float EncodeIsUninitializedGIAndAO (bool isUninitializedGI, float ao)
466
+ {
467
+ // TODO: Could add dither while discretizing to 7-bit to break up any potential banding.
468
+ float encoded = floor (saturate (ao) * 127.0 + 0.5 );
469
+ encoded += isUninitializedGI ? 128.0 : 0.0 ;
470
+ encoded *= (1.0 / 255.0 );
471
+
472
+ return encoded;
473
+ }
474
+
475
+ bool DecodeIsUninitializedGIAndAO (float encoded, out float ao)
476
+ {
477
+ ao = encoded * 255.0 ;
478
+ bool isUninitializedGI = ao > 127.5 ;
479
+ ao -= isUninitializedGI ? 128.0 : 0.0 ;
480
+ ao *= (1.0 / 127.0 );
481
+ ao = saturate (ao); // For precision.
482
+
483
+ return isUninitializedGI;
484
+ }
485
+
465
486
//-----------------------------------------------------------------------------
466
487
// conversion function for deferred
467
488
//-----------------------------------------------------------------------------
@@ -666,7 +687,7 @@ void EncodeIntoGBuffer( SurfaceData surfaceData
666
687
if (_DebugLightingMode == DEBUGLIGHTINGMODE_EMISSIVE_LIGHTING)
667
688
{
668
689
#if SHADEROPTIONS_PROBE_VOLUMES_EVALUATION_MODE == PROBEVOLUMESEVALUATIONMODES_LIGHT_LOOP
669
- if (!IsUninitializedGI (builtinData.bakeDiffuseLighting ))
690
+ if (!IsUninitializedGI (builtinData))
670
691
#endif
671
692
{
672
693
builtinData.bakeDiffuseLighting = real3 (0.0 , 0.0 , 0.0 );
@@ -679,33 +700,34 @@ void EncodeIntoGBuffer( SurfaceData surfaceData
679
700
}
680
701
#endif
681
702
682
- // RT3 - 11f:11f:10f
683
- // In deferred we encode emissive color with bakeDiffuseLighting. We don't have the room to store emissiveColor.
684
- // It mean that any futher process that affect bakeDiffuseLighting will also affect emissiveColor, like SSAO for example.
685
- #if SHADEROPTIONS_PROBE_VOLUMES_EVALUATION_MODE == PROBEVOLUMESEVALUATIONMODES_LIGHT_LOOP
703
+ outGBuffer3 = float4 (builtinData.emissiveColor * GetCurrentExposureMultiplier (), 0.0 );
686
704
687
- if (IsUninitializedGI (builtinData.bakeDiffuseLighting))
688
- {
689
- // builtinData.bakeDiffuseLighting contain uninitializedGI sentinel value.
690
-
691
- // This means probe volumes will not get applied to this pixel, only emissiveColor will.
692
- // When length(emissiveColor) is much greater than length(probeVolumeOutgoingRadiance), this will visually look reasonable.
693
- // Unfortunately this will break down when emissiveColor is faded out (result will pop).
694
- // TODO: If evaluating probe volumes in lightloop, only write out sentinel value here, and re-render emissive surfaces.
695
- // Pre-expose lighting buffer
696
- outGBuffer3 = float4 (all (builtinData.emissiveColor == 0.0 ) ? builtinData.bakeDiffuseLighting : builtinData.emissiveColor * GetCurrentExposureMultiplier (), 0.0 );
697
- }
698
- else
705
+ #if SHADEROPTIONS_PROBE_VOLUMES_EVALUATION_MODE == PROBEVOLUMESEVALUATIONMODES_LIGHT_LOOP
706
+ bool isUninitializedGI = IsUninitializedGI (builtinData);
707
+ #else
708
+ bool isUninitializedGI = false ;
699
709
#endif
710
+ if (!isUninitializedGI)
700
711
{
701
- outGBuffer3 = float4 (builtinData.bakeDiffuseLighting * surfaceData.ambientOcclusion + builtinData.emissiveColor, 0.0 );
702
- // Pre-expose lighting buffer
703
- outGBuffer3.rgb *= GetCurrentExposureMultiplier ();
712
+ // RT3 - 11f:11f:10f
713
+ // In deferred we encode emissive color with bakeDiffuseLighting. We don't have the room to store emissiveColor.
714
+ // It mean that any futher process that affect bakeDiffuseLighting will also affect emissiveColor, like SSAO for example.
715
+ outGBuffer3.rgb += builtinData.bakeDiffuseLighting * (surfaceData.ambientOcclusion * GetCurrentExposureMultiplier ());
704
716
}
705
717
706
- #ifdef LIGHT_LAYERS
718
+ #if defined (LIGHT_LAYERS) || (SHADEROPTIONS_PROBE_VOLUMES_EVALUATION_MODE == PROBEVOLUMESEVALUATIONMODES_LIGHT_LOOP)
719
+ float4 lightLayersAndAOAndUnitializedGI = 0.0 ;
720
+
721
+ #if defined (LIGHT_LAYERS)
707
722
// Note: we need to mask out only 8bits of the layer mask before encoding it as otherwise any value > 255 will map to all layers active
708
- OUT_GBUFFER_LIGHT_LAYERS = float4 (0.0 , 0.0 , 0.0 , (builtinData.renderingLayers & 0x000000FF ) / 255.0 );
723
+ lightLayersAndAOAndUnitializedGI.w = (builtinData.renderingLayers & 0x000000FF ) / 255.0 ;
724
+ #endif
725
+
726
+ #if SHADEROPTIONS_PROBE_VOLUMES_EVALUATION_MODE == PROBEVOLUMESEVALUATIONMODES_LIGHT_LOOP
727
+ lightLayersAndAOAndUnitializedGI.x = EncodeIsUninitializedGIAndAO (isUninitializedGI, surfaceData.ambientOcclusion);
728
+ #endif
729
+
730
+ OUT_GBUFFER_LIGHT_LAYERS_AND_AO_AND_UNITIALIZED_GI = lightLayersAndAOAndUnitializedGI;
709
731
#endif
710
732
711
733
#ifdef SHADOWS_SHADOWMASK
@@ -739,31 +761,44 @@ uint DecodeFromGBuffer(uint2 positionSS, uint tileFeatureFlags, out BSDFData bsd
739
761
GBufferType1 inGBuffer1 = LOAD_TEXTURE2D_X (_GBufferTexture1, positionSS);
740
762
GBufferType2 inGBuffer2 = LOAD_TEXTURE2D_X (_GBufferTexture2, positionSS);
741
763
742
- // BuiltinData
743
- builtinData.bakeDiffuseLighting = LOAD_TEXTURE2D_X (_GBufferTexture3, positionSS).rgb; // This also contain emissive (and * AO if no lightlayers)
744
-
745
- #if SHADEROPTIONS_PROBE_VOLUMES_EVALUATION_MODE == PROBEVOLUMESEVALUATIONMODES_LIGHT_LOOP
746
- if (!IsUninitializedGI (builtinData.bakeDiffuseLighting))
747
- #endif
748
- {
749
- // Inverse pre-exposure
750
- builtinData.bakeDiffuseLighting *= GetInverseCurrentExposureMultiplier (); // zero-div guard
751
- }
752
-
753
764
// In deferred ambient occlusion isn't available and is already apply on bakeDiffuseLighting for the GI part.
754
765
// Caution: even if we store it in the GBuffer we need to apply it on GI and not on emissive color, so AO must be 1.0 in deferred
755
766
bsdfData.ambientOcclusion = 1.0 ;
756
767
768
+ // BuiltinData
769
+ builtinData.bakeDiffuseLighting = LOAD_TEXTURE2D_X (_GBufferTexture3, positionSS).rgb;
770
+
771
+ float4 inGBufferLightLayersAndAOAndUnitializedGI = 0.0 ;
772
+
773
+ #if SHADEROPTIONS_PROBE_VOLUMES_EVALUATION_MODE != PROBEVOLUMESEVALUATIONMODES_LIGHT_LOOP
757
774
// Avoid to introduce a new variant for light layer as it is already long to compile
758
775
if (_EnableLightLayers)
776
+ #else
759
777
{
760
- float4 inGBuffer4 = LOAD_TEXTURE2D_X (_LightLayersTexture, positionSS);
761
- builtinData.renderingLayers = uint (inGBuffer4.w * 255.5 );
778
+ inGBufferLightLayersAndAOAndUnitializedGI = LOAD_TEXTURE2D_X (_LightLayersTexture, positionSS);
762
779
}
780
+ #endif
781
+
782
+ #if SHADEROPTIONS_PROBE_VOLUMES_EVALUATION_MODE == PROBEVOLUMESEVALUATIONMODES_LIGHT_LOOP
783
+ if (DecodeIsUninitializedGIAndAO (inGBufferLightLayersAndAOAndUnitializedGI.x, bsdfData.ambientOcclusion))
784
+ {
785
+ // In this context the bakeDiffuseLighting RT stores only emissiveColor.
786
+ // Inverse pre-exposure
787
+ builtinData.emissiveColor = builtinData.bakeDiffuseLighting * GetInverseCurrentExposureMultiplier (); // zero-div guard
788
+ builtinData.bakeDiffuseLighting = UNINITIALIZED_GI;
789
+ }
763
790
else
764
791
{
765
- builtinData.renderingLayers = DEFAULT_LIGHT_LAYERS;
792
+ #else
793
+ // In this context, the bakeDiffuseLighting RT stores emissive + lightmapBakedLighting * ao.
794
+ // Inverse pre-exposure
795
+ builtinData.bakeDiffuseLighting *= GetInverseCurrentExposureMultiplier (); // zero-div guard
796
+ #endif
797
+ #if SHADEROPTIONS_PROBE_VOLUMES_EVALUATION_MODE == PROBEVOLUMESEVALUATIONMODES_LIGHT_LOOP
766
798
}
799
+ #endif
800
+
801
+ builtinData.renderingLayers = _EnableLightLayers ? uint (inGBufferLightLayersAndAOAndUnitializedGI.w * 255.5 ) : DEFAULT_LIGHT_LAYERS;
767
802
768
803
// We know the GBufferType no need to use abstraction
769
804
#ifdef SHADOWS_SHADOWMASK
0 commit comments