diff --git a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/1000_RaytracingQualityKeyword_Indirect.png.meta b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/1000_RaytracingQualityKeyword_Indirect.png.meta
index db1a4457192..e74b5b1391f 100644
--- a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/1000_RaytracingQualityKeyword_Indirect.png.meta
+++ b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/1000_RaytracingQualityKeyword_Indirect.png.meta
@@ -6,7 +6,7 @@ TextureImporter:
serializedVersion: 11
mipmaps:
mipMapMode: 0
- enableMipMap: 1
+ enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
@@ -20,7 +20,7 @@ TextureImporter:
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
- isReadable: 0
+ isReadable: 1
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
@@ -38,7 +38,7 @@ TextureImporter:
wrapU: -1
wrapV: -1
wrapW: -1
- nPOTScale: 1
+ nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 0
@@ -68,7 +68,7 @@ TextureImporter:
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
- textureCompression: 1
+ textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
diff --git a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/101_ReflectionsPerfFullRes.png b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/101_ReflectionsPerfFullRes.png
index 5d822e278e9..d0731c7952f 100644
--- a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/101_ReflectionsPerfFullRes.png
+++ b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/101_ReflectionsPerfFullRes.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:05c8df6e8c4e6fca5eab5a9171bed258311926d5121a728ae6cc6496098aee43
-size 81606
+oid sha256:4c4d07b56f7b76cb8af60dbdc4f522b70894dae08eeef994473c6c46e51fab68
+size 69365
diff --git a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/102_ReflectionsPerfHalfRes.png b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/102_ReflectionsPerfHalfRes.png
index 332e8ab9ebf..21eab6a60fa 100644
--- a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/102_ReflectionsPerfHalfRes.png
+++ b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/102_ReflectionsPerfHalfRes.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:137dc73ae4b5267944b8dc9c69b3bd408dfdfeeecefa9d9c5981a1b77d50fd97
-size 98841
+oid sha256:5446efe8d72ae658c054a930cf106acb6c6b1e0465b672a8c6df3b741c7e396e
+size 77317
diff --git a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/105_ReflectionsAndGlobalIlluminationCollision.png b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/105_ReflectionsAndGlobalIlluminationCollision.png
index abda429c6bd..e1047d1f74b 100644
--- a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/105_ReflectionsAndGlobalIlluminationCollision.png
+++ b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/105_ReflectionsAndGlobalIlluminationCollision.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:8e02db0c8d32628cb124178fd670d2fa5d800662efed74fe8cfaca9229b728a6
-size 392210
+oid sha256:51bac42f7daa095863513587b0a3d5ec9a24c51a474ad3466bf03e3889adfdc9
+size 379013
diff --git a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/105_ReflectionsDenoised.png b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/105_ReflectionsDenoised.png
index 20a76aeaa94..b89384229a9 100644
--- a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/105_ReflectionsDenoised.png
+++ b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/105_ReflectionsDenoised.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:302453a292ff9ea710dd605bfae9b5d2cc93d84c687e29913a4ffa381df32244
-size 225149
+oid sha256:1a44b9302413feea3c35858cf451b677e876975da0baec8d1f2680d58a96ef99
+size 205596
diff --git a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/105_ReflectionsDenoised2.png b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/105_ReflectionsDenoised2.png
index a180c811985..d776c2b0b9b 100644
--- a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/105_ReflectionsDenoised2.png
+++ b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/105_ReflectionsDenoised2.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:81fe973af52b29bdf0bae74163a52133c9f7bc63a5dbdb867891c2a4fbbd04e6
-size 183003
+oid sha256:0a4735ce6744354e19f40cb46e15fd28ec769aac7bf3a580a49a9f0b1eeafb87
+size 178762
diff --git a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/302_GlobalIlluminationPerfHalf.png b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/302_GlobalIlluminationPerfHalf.png
index 690a5369a46..d63cd3700a6 100644
--- a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/302_GlobalIlluminationPerfHalf.png
+++ b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/302_GlobalIlluminationPerfHalf.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:74298880138515566b58e2c951e38b3c9ecb1a80fd99d9be954948fb506000fa
-size 657078
+oid sha256:d3e935806942f1b54b3dfa030253c3c8b439434b594011c31ca6ce23c230ffdc
+size 657220
diff --git a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/304_GlobalIlluminationDenoised1.png b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/304_GlobalIlluminationDenoised1.png
index 3bfdb20f459..ae191206ddc 100644
--- a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/304_GlobalIlluminationDenoised1.png
+++ b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/304_GlobalIlluminationDenoised1.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:b35f8eb7a154adc6599f015c68f91a9357104e84be201d27613760f787ea89c9
-size 599123
+oid sha256:85fed6f3c924666634a011e160a44ff694ce6f61ad351bcb04c3ca8aa7dbca87
+size 599168
diff --git a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/305_GlobalIlluminationDenoisedHalf1.png b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/305_GlobalIlluminationDenoisedHalf1.png
index d2044826119..3d919bfe544 100644
--- a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/305_GlobalIlluminationDenoisedHalf1.png
+++ b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/305_GlobalIlluminationDenoisedHalf1.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:db80c6dc860cf7fad358d6a7790948bca3fc0fad729731dce683a8e3458dfc42
-size 297947
+oid sha256:50e7ee059bfd51a9d284ab318cba06f5b2c01479d39ea1342a8dce8ba366384a
+size 297860
diff --git a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/306_GlobalIlluminationDenoised2.png b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/306_GlobalIlluminationDenoised2.png
index a0c6fa4371a..d887031e06c 100644
--- a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/306_GlobalIlluminationDenoised2.png
+++ b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/306_GlobalIlluminationDenoised2.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:afa3a35c56a1400702b5a2dec68fa9a2db573305e1dfe77d6d137f3328e0ebac
-size 496947
+oid sha256:f16dae35ccbf6e7a4e2f9856bf741ad59d7b6ee1495b4d8bad37d3c2015213d1
+size 497090
diff --git a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/307_GlobalIlluminationFog.png b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/307_GlobalIlluminationFog.png
index a44b7c69487..b427e7509fd 100644
--- a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/307_GlobalIlluminationFog.png
+++ b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/307_GlobalIlluminationFog.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:522d7a2b5cbe517e81e86a56bced1d170bd59868bc41163c68f349e907cf7b56
-size 462357
+oid sha256:0c9ec967fdffccb853be2c6bcdb672bcbc4f6166934b4a916d12becbfff5664c
+size 462373
diff --git a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/6000_VertexFormats.png b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/6000_VertexFormats.png
index 7d004ea8e5d..4ea7ef968c9 100644
--- a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/6000_VertexFormats.png
+++ b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/6000_VertexFormats.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:62b32bcd52371008dcf0d46541473d60d8b5031cc824ff4cc2dc4851739bb558
-size 73352
+oid sha256:18fce23722bf3cd6aa9839b665285f68adbcedc9ed56d434e2d0bfa359ecf509
+size 59399
diff --git a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/7000_QuadChannelTexCoord.png b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/7000_QuadChannelTexCoord.png
index a8285a1e7b7..a0b2cb65f00 100644
--- a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/7000_QuadChannelTexCoord.png
+++ b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/7000_QuadChannelTexCoord.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:350e0657a4f616b26168079b57a2ebadcb09dad403b964f766026e52fd0c01a0
-size 91947
+oid sha256:9d17dd6f2f3a7ce05914afec2ce442af576c27b62504a6e85423a883674f4bc9
+size 72869
diff --git a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/902_Materials_SG_Variants_Lit.png b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/902_Materials_SG_Variants_Lit.png
index 23bdb436d1a..524e4906bb3 100644
--- a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/902_Materials_SG_Variants_Lit.png
+++ b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/902_Materials_SG_Variants_Lit.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:678caa023a92f87be0ff1fb683444f819c0ba8c72aef341cde5bd479c56f3e25
-size 187779
+oid sha256:2423916043f6d18052859393aae1a14020a3389c61fa46b6815449580971a9a8
+size 187113
diff --git a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/902_Materials_SG_Variants_StackLit.png b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/902_Materials_SG_Variants_StackLit.png
index d54c4d9f391..bf3bfe20298 100644
--- a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/902_Materials_SG_Variants_StackLit.png
+++ b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/902_Materials_SG_Variants_StackLit.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:88a755fb7e76106bcb30895bf7808cd4a04b2599624cf535ba4fa926f041866f
-size 197516
+oid sha256:b6ca7a4959b1229e84a2b8d0df86fa0592721c7e39d9638febbe11b79660d55b
+size 196919
diff --git a/TestProjects/HDRP_DXR_Tests/Assets/Scenes/902_Materials_SG_Variants/902_Materials_SG_Variants.asset b/TestProjects/HDRP_DXR_Tests/Assets/Scenes/902_Materials_SG_Variants/902_Materials_SG_Variants.asset
index 4c70b10ee2f..71bea00cc61 100644
--- a/TestProjects/HDRP_DXR_Tests/Assets/Scenes/902_Materials_SG_Variants/902_Materials_SG_Variants.asset
+++ b/TestProjects/HDRP_DXR_Tests/Assets/Scenes/902_Materials_SG_Variants/902_Materials_SG_Variants.asset
@@ -31,7 +31,6 @@ MonoBehaviour:
m_OverrideState: 1
m_Value: 50
min: 0
- max: 50
minSmoothness:
m_OverrideState: 0
m_Value: 0.5
@@ -462,16 +461,10 @@ MonoBehaviour:
m_EditorClassIdentifier:
active: 1
m_AdvancedMode: 0
- maxNumLightsPercell:
- m_OverrideState: 0
- m_Value: 10
- min: 0
- max: 24
cameraClusterRange:
m_OverrideState: 1
m_Value: 50
min: 0.001
- max: 50
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -553,6 +546,58 @@ MonoBehaviour:
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
+ limitMinCurveMap:
+ m_OverrideState: 0
+ m_Value:
+ serializedVersion: 2
+ m_Curve:
+ - serializedVersion: 3
+ time: -10
+ value: -12
+ inSlope: 0
+ outSlope: 1
+ tangentMode: 0
+ weightedMode: 0
+ inWeight: 0
+ outWeight: 0
+ - serializedVersion: 3
+ time: 20
+ value: 18
+ inSlope: 1
+ outSlope: 0
+ tangentMode: 0
+ weightedMode: 0
+ inWeight: 0
+ outWeight: 0
+ m_PreInfinity: 2
+ m_PostInfinity: 2
+ m_RotationOrder: 4
+ limitMaxCurveMap:
+ m_OverrideState: 0
+ m_Value:
+ serializedVersion: 2
+ m_Curve:
+ - serializedVersion: 3
+ time: -10
+ value: -8
+ inSlope: 0
+ outSlope: 1
+ tangentMode: 0
+ weightedMode: 0
+ inWeight: 0
+ outWeight: 0
+ - serializedVersion: 3
+ time: 20
+ value: 22
+ inSlope: 1
+ outSlope: 0
+ tangentMode: 0
+ weightedMode: 0
+ inWeight: 0
+ outWeight: 0
+ m_PreInfinity: 2
+ m_PostInfinity: 2
+ m_RotationOrder: 4
adaptationMode:
m_OverrideState: 0
m_Value: 1
@@ -575,6 +620,28 @@ MonoBehaviour:
histogramUseCurveRemapping:
m_OverrideState: 0
m_Value: 0
+ targetMidGray:
+ m_OverrideState: 0
+ m_Value: 0
+ centerAroundExposureTarget:
+ m_OverrideState: 0
+ m_Value: 0
+ proceduralCenter:
+ m_OverrideState: 0
+ m_Value: {x: 0.5, y: 0.5}
+ proceduralRadii:
+ m_OverrideState: 0
+ m_Value: {x: 0.3, y: 0.3}
+ maskMinIntensity:
+ m_OverrideState: 0
+ m_Value: -30
+ maskMaxIntensity:
+ m_OverrideState: 0
+ m_Value: 30
+ proceduralSoftness:
+ m_OverrideState: 0
+ m_Value: 0.5
+ min: 0
--- !u!114 &3564700782616824417
MonoBehaviour:
m_ObjectHideFlags: 3
@@ -591,23 +658,16 @@ MonoBehaviour:
m_AdvancedMode: 0
quality:
m_OverrideState: 0
- m_Value: 1
+ m_Value: 3
enabled:
m_OverrideState: 1
m_Value: 1
+ usedAlgorithm:
+ m_OverrideState: 0
+ m_Value: 0
rayTracing:
m_OverrideState: 1
m_Value: 1
- minSmoothness:
- m_OverrideState: 1
- m_Value: 0
- min: 0
- max: 1
- smoothnessFadeStart:
- m_OverrideState: 1
- m_Value: 0.5
- min: 0
- max: 1
reflectSky:
m_OverrideState: 1
m_Value: 1
@@ -621,38 +681,19 @@ MonoBehaviour:
m_Value: 0.1
min: 0
max: 1
+ accumulationFactor:
+ m_OverrideState: 0
+ m_Value: 0.75
+ min: 0
+ max: 1
layerMask:
m_OverrideState: 0
m_Value:
serializedVersion: 2
m_Bits: 4294967295
- rayLength:
- m_OverrideState: 1
- m_Value: 50
- min: 0.001
- max: 50
- clampValue:
- m_OverrideState: 1
- m_Value: 1
- min: 0.001
- max: 10
- denoise:
- m_OverrideState: 1
- m_Value: 1
- denoiserRadius:
- m_OverrideState: 1
- m_Value: 16
- min: 1
- max: 32
mode:
m_OverrideState: 1
m_Value: 2
- upscaleRadius:
- m_OverrideState: 1
- m_Value: 2
- fullResolution:
- m_OverrideState: 1
- m_Value: 1
sampleCount:
m_OverrideState: 1
m_Value: 8
@@ -663,9 +704,42 @@ MonoBehaviour:
m_Value: 1
min: 1
max: 31
+ m_MinSmoothness:
+ m_OverrideState: 1
+ m_Value: 0
+ min: 0
+ max: 1
+ m_SmoothnessFadeStart:
+ m_OverrideState: 1
+ m_Value: 0.5
+ min: 0
+ max: 1
m_RayMaxIterations:
m_OverrideState: 0
m_Value: 32
+ m_RayLength:
+ m_OverrideState: 1
+ m_Value: 50
+ min: 0.001
+ m_ClampValue:
+ m_OverrideState: 1
+ m_Value: 1
+ min: 0.001
+ max: 10
+ m_FullResolution:
+ m_OverrideState: 1
+ m_Value: 1
+ m_Denoise:
+ m_OverrideState: 1
+ m_Value: 1
+ m_DenoiserRadius:
+ m_OverrideState: 1
+ m_Value: 16
+ min: 1
+ max: 32
+ m_AffectSmoothSurfaces:
+ m_OverrideState: 0
+ m_Value: 0
--- !u!114 &8436036751141806562
MonoBehaviour:
m_ObjectHideFlags: 3
diff --git a/TestProjects/HDRP_DXR_Tests/Assets/Scenes/RayTracedReflectionsData/ReflectionsAndGlobalIlluminationCollision.asset b/TestProjects/HDRP_DXR_Tests/Assets/Scenes/RayTracedReflectionsData/ReflectionsAndGlobalIlluminationCollision.asset
index 29e0380d1d8..1cd903c492e 100644
--- a/TestProjects/HDRP_DXR_Tests/Assets/Scenes/RayTracedReflectionsData/ReflectionsAndGlobalIlluminationCollision.asset
+++ b/TestProjects/HDRP_DXR_Tests/Assets/Scenes/RayTracedReflectionsData/ReflectionsAndGlobalIlluminationCollision.asset
@@ -192,19 +192,9 @@ MonoBehaviour:
m_Value: 24
min: 16
max: 128
- m_MaximalRadius:
- m_OverrideState: 0
- m_Value: 2
- min: 0.01
- max: 50
m_FullResolutionSS:
m_OverrideState: 0
m_Value: 1
- m_ClampValueSS:
- m_OverrideState: 0
- m_Value: 2
- min: 0.01
- max: 10
m_FilterRadius:
m_OverrideState: 0
m_Value: 2
@@ -235,7 +225,6 @@ MonoBehaviour:
m_OverrideState: 0
m_Value: 50
min: 0
- max: 50
m_ClampValue:
m_OverrideState: 0
m_Value: 1
@@ -279,10 +268,13 @@ MonoBehaviour:
m_AdvancedMode: 0
quality:
m_OverrideState: 0
- m_Value: 1
+ m_Value: 3
enabled:
m_OverrideState: 1
m_Value: 1
+ usedAlgorithm:
+ m_OverrideState: 0
+ m_Value: 0
rayTracing:
m_OverrideState: 1
m_Value: 1
@@ -299,13 +291,18 @@ MonoBehaviour:
m_Value: 0.1
min: 0
max: 1
+ accumulationFactor:
+ m_OverrideState: 0
+ m_Value: 0.75
+ min: 0
+ max: 1
layerMask:
m_OverrideState: 0
m_Value:
serializedVersion: 2
m_Bits: 4294967295
mode:
- m_OverrideState: 0
+ m_OverrideState: 1
m_Value: 2
sampleCount:
m_OverrideState: 0
@@ -318,13 +315,13 @@ MonoBehaviour:
min: 1
max: 31
m_MinSmoothness:
- m_OverrideState: 0
- m_Value: 0.9
+ m_OverrideState: 1
+ m_Value: 0.5
min: 0
max: 1
m_SmoothnessFadeStart:
- m_OverrideState: 0
- m_Value: 0.9
+ m_OverrideState: 1
+ m_Value: 0.7
min: 0
max: 1
m_RayMaxIterations:
@@ -334,17 +331,11 @@ MonoBehaviour:
m_OverrideState: 0
m_Value: 50
min: 0
- max: 50
m_ClampValue:
m_OverrideState: 0
m_Value: 1
min: 0.001
max: 10
- m_UpscaleRadius:
- m_OverrideState: 0
- m_Value: 2
- min: 2
- max: 6
m_FullResolution:
m_OverrideState: 0
m_Value: 0
@@ -356,3 +347,6 @@ MonoBehaviour:
m_Value: 8
min: 1
max: 32
+ m_AffectSmoothSurfaces:
+ m_OverrideState: 0
+ m_Value: 0
diff --git a/com.unity.render-pipelines.high-definition/CHANGELOG.md b/com.unity.render-pipelines.high-definition/CHANGELOG.md
index 2a21cbdbe23..c0b6a78000a 100644
--- a/com.unity.render-pipelines.high-definition/CHANGELOG.md
+++ b/com.unity.render-pipelines.high-definition/CHANGELOG.md
@@ -12,10 +12,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Added support for nested volume components to volume system.
- Added a cameraCullingResult field in Custom Pass Context to give access to both custom pass and camera culling result.
- Added a slider to control the fallback value of the directional shadow when the cascade have no coverage.
+- Added a toggle to allow to include or exclude smooth surfaces from ray traced reflection denoising.
### Fixed
- Fixed probe volumes debug views.
- Fixed ShaderGraph Decal material not showing exposed properties.
+- Fixed couple samplers that had the wrong name in raytracing code
### Changed
- Removed the material pass probe volumes evaluation mode.
@@ -25,6 +27,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Now reflection probes cannot have SSAO, SSGI, SSR, ray tracing effects or volumetric reprojection.
- Removed the readonly keyword on the cullingResults of the CustomPassContext to allow users to overwrite.
- The DrawRenderers function of CustomPassUtils class now takes a sortingCriteria in parameter.
+- When in half res, RTR denoising is executed at half resolution and the upscale happens at the end.
+- Removed the upscale radius from the RTR.
## [10.3.0] - 2020-12-01
diff --git a/com.unity.render-pipelines.high-definition/Documentation~/Override-Screen-Space-Reflection.md b/com.unity.render-pipelines.high-definition/Documentation~/Override-Screen-Space-Reflection.md
index 8caf7660174..49f2ffd42db 100644
--- a/com.unity.render-pipelines.high-definition/Documentation~/Override-Screen-Space-Reflection.md
+++ b/com.unity.render-pipelines.high-definition/Documentation~/Override-Screen-Space-Reflection.md
@@ -49,22 +49,22 @@ The properties visible in the Inspector change depending on whether or not you e
### Ray-traced
-| Property | Description |
-| ------------------------- | ------------------------------------------------------------ |
-| **Reflect Sky** | Enable this feature to specify to HDRP that it should use the sky as a fall-back for ray-traced reflections when a ray doesn't find an intersection. |
-| **LayerMask** | Defines the layers that HDRP processes this ray-traced effect for. |
-| **Mode** | Defines if HDRP should evaluate the effect in **Performance** or **Quality** mode.
This property only appears if you select set **Supported Ray Tracing Mode** in your HDRP Asset to **Both**. |
-| **Quality** | Specifies the preset HDRP uses to populate the values of the following nested properties. The options are:
• **Low**: A preset that emphasizes performance over quality.
• **Medium**: A preset that balances performance and quality.
• **High**: A preset that emphasizes quality over performance.
• **Custom**: Allows you to override each property individually.
This property only appears if you set **Mode** to **Performance**. |
-| **Minimum Smoothness** | See **Minimum Smoothness** in [Screen-space](#screen-space). |
-| **Smoothness Fade Start** | See **Smoothness Fade Start** in [Screen-space](#screen-space). |
-| **Max Ray Length** | Controls the maximal length of global illumination rays. The higher this value is, the more expensive ray traced global illumination is. If a ray doesn't find an intersection. |
-| **Clamp Value** | Controls the threshold that HDRP uses to clamp the pre-exposed value. This reduces the range of values and makes the reflections more stable to denoise, but reduces quality. |
-| **Upscale Radius** | Controls the radius of the up-scaler that HDRP uses to build the reflection. The larger the radius, the more neighbors HDRP uses to build the reflection, the better the quality.
This property only appears if you set **Mode** to **Performance**. |
-| **Full Resolution** | Enable this feature to increase the ray budget to one ray per pixel, per frame. Disable this feature to decrease the ray budget to one ray per four pixels, per frame.
This property only appears if you set **Mode** to **Performance**. |
-| **Sample Count** | Controls the number of rays per pixel per frame. Increasing this value increases execution time linearly.
This property only appears if you set **Mode** to **Quality**. |
-| **Bounce Count** | Controls the number of bounces that reflection rays can do. Increasing this value increases execution time exponentially.
This property only appears if you set **Mode** to **Quality**. |
-| **Denoise** | Enables the spatio-temporal filter that HDRP uses to remove noise from the reflections. |
-| - **Denoiser Radius** | Controls the radius of the spatio-temporal filter. Increasing this value results in a more blurry result and a higher execution time. |
+| Property | Description |
+| ----------------------------- | ------------------------------------------------------------ |
+| **Reflect Sky** | Enable this feature to specify to HDRP that it should use the sky as a fall-back for ray-traced reflections when a ray doesn't find an intersection. |
+| **LayerMask** | Defines the layers that HDRP processes this ray-traced effect for. |
+| **Mode** | Defines if HDRP should evaluate the effect in **Performance** or **Quality** mode.
This property only appears if you select set **Supported Ray Tracing Mode** in your HDRP Asset to **Both**. |
+| **Quality** | Specifies the preset HDRP uses to populate the values of the following nested properties. The options are:
• **Low**: A preset that emphasizes performance over quality.
• **Medium**: A preset that balances performance and quality.
• **High**: A preset that emphasizes quality over performance.
• **Custom**: Allows you to override each property individually.
This property only appears if you set **Mode** to **Performance**. |
+| **Minimum Smoothness** | See **Minimum Smoothness** in [Screen-space](#screen-space). |
+| **Smoothness Fade Start** | See **Smoothness Fade Start** in [Screen-space](#screen-space). |
+| **Max Ray Length** | Controls the maximal length of global illumination rays. The higher this value is, the more expensive ray traced global illumination is. If a ray doesn't find an intersection. |
+| **Clamp Value** | Controls the threshold that HDRP uses to clamp the pre-exposed value. This reduces the range of values and makes the reflections more stable to denoise, but reduces quality. |
+| **Full Resolution** | Enable this feature to increase the ray budget to one ray per pixel, per frame. Disable this feature to decrease the ray budget to one ray per four pixels, per frame.
This property only appears if you set **Mode** to **Performance**. |
+| **Sample Count** | Controls the number of rays per pixel per frame. Increasing this value increases execution time linearly.
This property only appears if you set **Mode** to **Quality**. |
+| **Bounce Count** | Controls the number of bounces that reflection rays can do. Increasing this value increases execution time exponentially.
This property only appears if you set **Mode** to **Quality**. |
+| **Denoise** | Enables the spatio-temporal filter that HDRP uses to remove noise from the reflections. |
+| - **Denoiser Radius** | Controls the radius of the spatio-temporal filter. Increasing this value results in a more blurry result and a higher execution time. |
+| - **Affects Smooth Surfaces** | Indicates whether the denoiser affects perfectly smooth surfaces (surfaces with a **Smoothness** of 1.0) or not. |
## Limitations
diff --git a/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs b/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs
index e4d2572d8c0..075ab972199 100644
--- a/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs
+++ b/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs
@@ -29,10 +29,10 @@ class HDScreenSpaceReflectionEditor : VolumeComponentWithQualityEditor
SerializedDataParameter m_ClampValue;
SerializedDataParameter m_Denoise;
SerializedDataParameter m_DenoiserRadius;
+ SerializedDataParameter m_AffectsSmoothSurfaces;
SerializedDataParameter m_Mode;
// Performance
- SerializedDataParameter m_UpscaleRadius;
SerializedDataParameter m_FullResolution;
// Quality
@@ -63,10 +63,10 @@ public override void OnEnable()
m_ClampValue = Unpack(o.Find(x => x.clampValue));
m_Denoise = Unpack(o.Find(x => x.denoise));
m_DenoiserRadius = Unpack(o.Find(x => x.denoiserRadius));
+ m_AffectsSmoothSurfaces = Unpack(o.Find(x => x.affectSmoothSurfaces));
m_Mode = Unpack(o.Find(x => x.mode));
// Performance
- m_UpscaleRadius = Unpack(o.Find(x => x.upscaleRadius));
m_FullResolution = Unpack(o.Find(x => x.fullResolution));
// Quality
@@ -92,9 +92,9 @@ public override void OnEnable()
static public readonly GUIContent k_BounceCountText = EditorGUIUtility.TrTextContent("Bounce Count", "Number of bounces for reflection rays.");
static public readonly GUIContent k_ModeText = EditorGUIUtility.TrTextContent("Mode", "Controls which version of the effect should be used.");
static public readonly GUIContent k_DenoiseText = EditorGUIUtility.TrTextContent("Denoise", "Enable denoising on the ray traced reflections.");
- static public readonly GUIContent k_UpscaleRadiusText = EditorGUIUtility.TrTextContent("Upscale Radius", "Controls the size of the upscale radius.");
static public readonly GUIContent k_FullResolutionText = EditorGUIUtility.TrTextContent("Full Resolution", "Enables full resolution mode.");
static public readonly GUIContent k_DenoiseRadiusText = EditorGUIUtility.TrTextContent("Denoiser Radius", "Controls the radius of reflection denoiser.");
+ static public readonly GUIContent k_AffectsSmoothSurfacesText = EditorGUIUtility.TrTextContent("Affect Smooth Surfaces", "When enabled, the denoiser affects perfectly smooth surfaces.");
void RayTracingQualityModeGUI()
{
@@ -111,6 +111,7 @@ void RayTracingQualityModeGUI()
using (new HDEditorUtils.IndentScope())
{
PropertyField(m_DenoiserRadius, k_DenoiseRadiusText);
+ PropertyField(m_AffectsSmoothSurfaces, k_AffectsSmoothSurfacesText);
}
}
}
@@ -127,12 +128,12 @@ void RayTracingPerformanceModeGUI()
m_SmoothnessFadeStart.value.floatValue = Mathf.Max(m_MinSmoothness.value.floatValue, m_SmoothnessFadeStart.value.floatValue);
PropertyField(m_RayLength, k_RayLengthText);
PropertyField(m_ClampValue, k_ClampValueText);
- PropertyField(m_UpscaleRadius, k_UpscaleRadiusText);
PropertyField(m_FullResolution, k_FullResolutionText);
PropertyField(m_Denoise, k_DenoiseText);
using (new HDEditorUtils.IndentScope())
{
PropertyField(m_DenoiserRadius, k_DenoiseRadiusText);
+ PropertyField(m_AffectsSmoothSurfaces, k_AffectsSmoothSurfacesText);
}
}
}
@@ -238,10 +239,10 @@ public override QualitySettingsBlob SaveCustomQualitySettingsAsObject(QualitySet
settings.Save(m_SmoothnessFadeStart);
settings.Save(m_RayLength);
settings.Save(m_ClampValue);
- settings.Save(m_UpscaleRadius);
settings.Save(m_FullResolution);
settings.Save(m_Denoise);
settings.Save(m_DenoiserRadius);
+ settings.Save(m_AffectsSmoothSurfaces);
}
// SSR
else
@@ -260,10 +261,10 @@ public override void LoadSettingsFromObject(QualitySettingsBlob settings)
settings.TryLoad(ref m_SmoothnessFadeStart);
settings.TryLoad(ref m_RayLength);
settings.TryLoad(ref m_ClampValue);
- settings.TryLoad(ref m_UpscaleRadius);
settings.TryLoad(ref m_FullResolution);
settings.TryLoad(ref m_Denoise);
settings.TryLoad(ref m_DenoiserRadius);
+ settings.TryLoad(ref m_AffectsSmoothSurfaces);
}
// SSR
else
@@ -280,10 +281,10 @@ public override void LoadSettingsFromQualityPreset(RenderPipelineSettings settin
CopySetting(ref m_SmoothnessFadeStart, settings.lightingQualitySettings.RTRSmoothnessFadeStart[level]);
CopySetting(ref m_RayLength, settings.lightingQualitySettings.RTRRayLength[level]);
CopySetting(ref m_ClampValue, settings.lightingQualitySettings.RTRClampValue[level]);
- CopySetting(ref m_UpscaleRadius, settings.lightingQualitySettings.RTRUpScaleRadius[level]);
CopySetting(ref m_FullResolution, settings.lightingQualitySettings.RTRFullResolution[level]);
CopySetting(ref m_Denoise, settings.lightingQualitySettings.RTRDenoise[level]);
CopySetting(ref m_DenoiserRadius, settings.lightingQualitySettings.RTRDenoiserRadius[level]);
+ CopySetting(ref m_AffectsSmoothSurfaces, settings.lightingQualitySettings.RTRSmoothDenoising[level]);
}
// SSR
else
diff --git a/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs b/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs
index 0c1d9ad1c59..63192e2bd1a 100644
--- a/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs
+++ b/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs
@@ -764,18 +764,28 @@ void EnableProfilingRecordersRT()
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingBuildCluster));
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingCullLights));
+
+ // Ray Traced Reflections
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingReflectionDirectionGeneration));
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingReflectionEvaluation));
- m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingReflectionUpscaleGeneration));
- m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingFilterReflection));
+ m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingReflectionAdjustWeight));
+ m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingReflectionUpscale));
+ m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingReflectionFilter));
+
+ // Ray Traced Ambient Occlusion
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingAmbientOcclusion));
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingFilterAmbientOcclusion));
+
+ // Ray Traced Shadows
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingDirectionalLightShadow));
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingLightShadow));
+
+ // Ray Traced Indirect Diffuse
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingIndirectDiffuseDirectionGeneration));
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingIndirectDiffuseEvaluation));
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingIndirectDiffuseUpscale));
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingFilterIndirectDiffuse));
+
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingDebugOverlay));
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.ForwardPreRefraction));
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RayTracingRecursiveRendering));
diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/BilateralUpsample.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/BilateralUpsample.compute
index ba02926cf08..0fd78a21bcd 100644
--- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/BilateralUpsample.compute
+++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/BilateralUpsample.compute
@@ -9,9 +9,7 @@
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingCommon.hlsl"
-
-#define _UpsampleTolerance 1e-7f
-#define _NoiseFilterStrength 0.99999f
+#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/BilateralUpsample.hlsl"
// Mip chain depth buffer
TEXTURE2D_X(_DepthTexture);
@@ -27,34 +25,6 @@ CBUFFER_END
// The output of our upscaling pass
RW_TEXTURE2D_X(float4, _OutputUpscaledTexture);
-// THe bilateral upscale fonction (color version)
-float4 BilUpColor(float HiDepth, float4 LowDepths, float4 lowValue0, float4 lowValue1, float4 lowValue2, float4 lowValue3)
-{
- float4 weights = float4(9, 3, 1, 3) / (abs(HiDepth - LowDepths) + _UpsampleTolerance);
- float TotalWeight = dot(weights, 1) + _NoiseFilterStrength;
- float4 WeightedSum = lowValue0 * weights.x
- + lowValue1 * weights.y
- + lowValue2 * weights.z
- + lowValue3 * weights.w
- + _NoiseFilterStrength;
- return WeightedSum / TotalWeight;
-}
-
-// THe bilateral upscale fonction (single channel version)
-float BilUpSingle(float HiDepth, float4 LowDepths, float4 lowValue)
-{
- float4 weights = float4(9, 3, 1, 3) / (abs(HiDepth - LowDepths) + _UpsampleTolerance);
- float TotalWeight = dot(weights, 1) + _NoiseFilterStrength;
- float WeightedSum = dot(lowValue, weights) + _NoiseFilterStrength;
- return WeightedSum / TotalWeight;
-}
-
-// This table references the set of pixels that are used for bilateral upscale based on the expected order
-static const int2 UpscaleBilateralPixels[16] = {int2(0, 0), int2(0, -1), int2(-1, -1), int2(-1, 0)
- , int2(0, 0), int2(0, -1), int2(1, -1), int2(1, 0)
- , int2(0, 0) , int2(-1, 0), int2(-1, 1), int2(0, 1)
- , int2(0, 0), int2(1, 0), int2(1, 1), int2(0, 1), };
-
[numthreads(BILATERAL_UPSAMPLE_TILE_SIZE, BILATERAL_UPSAMPLE_TILE_SIZE, 1)]
void BILATERAL_UPSAMPLE(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 groupThreadId : SV_GroupThreadID, uint2 groupId : SV_GroupID)
{
diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/BilateralUpsample.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/BilateralUpsample.hlsl
new file mode 100644
index 00000000000..c2f10cb478a
--- /dev/null
+++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/BilateralUpsample.hlsl
@@ -0,0 +1,43 @@
+#define _UpsampleTolerance 1e-7f
+#define _NoiseFilterStrength 0.99999f
+
+// This table references the set of pixels that are used for bilateral upscale based on the expected order
+static const int2 UpscaleBilateralPixels[16] = {int2(0, 0), int2(0, -1), int2(-1, -1), int2(-1, 0)
+ , int2(0, 0), int2(0, -1), int2(1, -1), int2(1, 0)
+ , int2(0, 0) , int2(-1, 0), int2(-1, 1), int2(0, 1)
+ , int2(0, 0), int2(1, 0), int2(1, 1), int2(0, 1), };
+
+// THe bilateral upscale fonction (color3 version)
+float3 BilUpColor3(float HiDepth, float4 LowDepths, float3 lowValue0, float3 lowValue1, float3 lowValue2, float3 lowValue3)
+{
+ float4 weights = float4(9, 3, 1, 3) / (abs(HiDepth - LowDepths) + _UpsampleTolerance);
+ float TotalWeight = dot(weights, 1) + _NoiseFilterStrength;
+ float3 WeightedSum = lowValue0 * weights.x
+ + lowValue1 * weights.y
+ + lowValue2 * weights.z
+ + lowValue3 * weights.w
+ + _NoiseFilterStrength;
+ return WeightedSum / TotalWeight;
+}
+
+// THe bilateral upscale fonction (color4 version)
+float4 BilUpColor(float HiDepth, float4 LowDepths, float4 lowValue0, float4 lowValue1, float4 lowValue2, float4 lowValue3)
+{
+ float4 weights = float4(9, 3, 1, 3) / (abs(HiDepth - LowDepths) + _UpsampleTolerance);
+ float TotalWeight = dot(weights, 1) + _NoiseFilterStrength;
+ float4 WeightedSum = lowValue0 * weights.x
+ + lowValue1 * weights.y
+ + lowValue2 * weights.z
+ + lowValue3 * weights.w
+ + _NoiseFilterStrength;
+ return WeightedSum / TotalWeight;
+}
+
+// THe bilateral upscale fonction (single channel version)
+float BilUpSingle(float HiDepth, float4 LowDepths, float4 lowValue)
+{
+ float4 weights = float4(9, 3, 1, 3) / (abs(HiDepth - LowDepths) + _UpsampleTolerance);
+ float TotalWeight = dot(weights, 1) + _NoiseFilterStrength;
+ float WeightedSum = dot(lowValue, weights) + _NoiseFilterStrength;
+ return WeightedSum / TotalWeight;
+}
diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/BilateralUpsample.hlsl.meta b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/BilateralUpsample.hlsl.meta
new file mode 100644
index 00000000000..e34d2e6228e
--- /dev/null
+++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/BilateralUpsample.hlsl.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: 3005835033358a647b5f7f34350caa92
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ preprocessorOverride: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflection.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflection.cs
index 885cce8a719..17bc3c7da39 100644
--- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflection.cs
+++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflection.cs
@@ -177,27 +177,27 @@ public int denoiserRadius
}
set { m_DenoiserRadius.value = value; }
}
- ///
- /// Controls which version of the effect should be used.
- ///
- public RayTracingModeParameter mode = new RayTracingModeParameter(RayTracingMode.Quality);
- // Performance
///
- /// Controls the size of the upscale radius.
+ /// Controls if the denoising should affect pefectly smooth surfaces
///
- public int upscaleRadius
+ public bool affectSmoothSurfaces
{
get
{
- if (!UsesQualitySettings())
- return m_UpscaleRadius.value;
+ if (!UsesQualitySettings() || UsesRayTracingQualityMode())
+ return m_AffectSmoothSurfaces.value;
else
- return GetLightingQualitySettings().RTRUpScaleRadius[(int)quality.value];
+ return GetLightingQualitySettings().RTRSmoothDenoising[(int)quality.value];
}
- set { m_UpscaleRadius.value = value; }
+ set { m_AffectSmoothSurfaces.value = value; }
}
+ ///
+ /// Controls which version of the effect should be used.
+ ///
+ public RayTracingModeParameter mode = new RayTracingModeParameter(RayTracingMode.Quality);
+
///
/// Defines if the effect should be evaluated at full resolution.
///
@@ -255,10 +255,6 @@ public int rayMaxIterations
[Tooltip("Controls the clamp of intensity.")]
private ClampedFloatParameter m_ClampValue = new ClampedFloatParameter(1.0f, 0.001f, 10.0f);
- [SerializeField, FormerlySerializedAs("upscaleRadius")]
- [Tooltip("Upscale Radius")]
- private ClampedIntParameter m_UpscaleRadius = new ClampedIntParameter(2, 2, 6);
-
[SerializeField, FormerlySerializedAs("fullResolution")]
[Tooltip("Full Resolution")]
private BoolParameter m_FullResolution = new BoolParameter(false);
@@ -270,5 +266,9 @@ public int rayMaxIterations
[SerializeField, FormerlySerializedAs("denoiserRadius")]
[Tooltip("Controls the radius of the ray traced reflection denoiser.")]
private ClampedIntParameter m_DenoiserRadius = new ClampedIntParameter(8, 1, 32);
+
+ [SerializeField]
+ [Tooltip("Denoiser affects smooth surfaces.")]
+ private BoolParameter m_AffectSmoothSurfaces = new BoolParameter(false);
}
}
diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs
index 4c2bfb00bed..950612aa77f 100644
--- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs
+++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs
@@ -182,6 +182,7 @@ internal enum HistoryEffectSlot
{
GlobalIllumination0,
GlobalIllumination1,
+ RayTracedReflections,
Count
}
diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/GlobalLightingQualitySettings.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/GlobalLightingQualitySettings.cs
index 0b6e6452da0..93f40f82bf9 100644
--- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/GlobalLightingQualitySettings.cs
+++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/GlobalLightingQualitySettings.cs
@@ -123,10 +123,6 @@ internal GlobalLightingQualitySettings()
RTRClampValue[(int)ScalableSettingLevelParameter.Level.Medium] = 1.0f;
RTRClampValue[(int)ScalableSettingLevelParameter.Level.High] = 1.2f;
- RTRUpScaleRadius[(int)ScalableSettingLevelParameter.Level.Low] = 4;
- RTRUpScaleRadius[(int)ScalableSettingLevelParameter.Level.Medium] = 4;
- RTRUpScaleRadius[(int)ScalableSettingLevelParameter.Level.High] = 3;
-
RTRFullResolution[(int)ScalableSettingLevelParameter.Level.Low] = false;
RTRFullResolution[(int)ScalableSettingLevelParameter.Level.Medium] = false;
RTRFullResolution[(int)ScalableSettingLevelParameter.Level.High] = true;
@@ -139,6 +135,10 @@ internal GlobalLightingQualitySettings()
RTRDenoiserRadius[(int)ScalableSettingLevelParameter.Level.Medium] = 12;
RTRDenoiserRadius[(int)ScalableSettingLevelParameter.Level.High] = 16;
+ RTRSmoothDenoising[(int)ScalableSettingLevelParameter.Level.Low] = true;
+ RTRSmoothDenoising[(int)ScalableSettingLevelParameter.Level.Medium] = false;
+ RTRSmoothDenoising[(int)ScalableSettingLevelParameter.Level.High] = false;
+
// Fog
Fog_ControlMode[(int)ScalableSettingLevelParameter.Level.Low] = FogControl.Balance;
Fog_ControlMode[(int)ScalableSettingLevelParameter.Level.Medium] = FogControl.Balance;
@@ -231,14 +231,14 @@ internal GlobalLightingQualitySettings()
public float[] RTRRayLength = new float[s_QualitySettingCount];
/// Clamp value used to reduce the variance in the integration signal.
public float[] RTRClampValue = new float[s_QualitySettingCount];
- /// Radius for the up-sample pass.
- public int[] RTRUpScaleRadius = new int[s_QualitySettingCount];
/// Controls if the effect should be computed at full resolution.
public bool[] RTRFullResolution = new bool[s_QualitySettingCount];
/// Flag that enables the first denoising pass.
public bool[] RTRDenoise = new bool[s_QualitySettingCount];
/// Flag that defines the radius of the first denoiser.
public int[] RTRDenoiserRadius = new int[s_QualitySettingCount];
+ /// Flag that defines smooth denoising status.
+ public bool[] RTRSmoothDenoising = new bool[s_QualitySettingCount];
// TODO: Volumetric fog quality
/// Controls which control mode should be used to define the volumetric fog parameters.
diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDProfileId.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDProfileId.cs
index acda0f094c3..e5a333fc198 100644
--- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDProfileId.cs
+++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDProfileId.cs
@@ -95,8 +95,9 @@ internal enum HDProfileId
// RTR
RaytracingReflectionDirectionGeneration,
RaytracingReflectionEvaluation,
- RaytracingReflectionUpscaleGeneration,
- RaytracingFilterReflection,
+ RaytracingReflectionAdjustWeight,
+ RaytracingReflectionFilter,
+ RaytracingReflectionUpscale,
// RTAO
RaytracingAmbientOcclusion,
RaytracingFilterAmbientOcclusion,
diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs
index ff1c0245a48..496b22ee8e8 100644
--- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs
+++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs
@@ -371,6 +371,7 @@ static class HDShaderIDs
public static readonly int _SsrLightingTexture = Shader.PropertyToID("_SsrLightingTexture");
public static readonly int _SsrAccumPrev = Shader.PropertyToID("_SsrAccumPrev");
public static readonly int _SsrLightingTextureRW = Shader.PropertyToID("_SsrLightingTextureRW");
+ public static readonly int _DirectionPDFTexture = Shader.PropertyToID("_DirectionPDFTexture");
public static readonly int _SSRAccumTexture = Shader.PropertyToID("_SSRAccumTexture");
public static readonly int _SsrHitPointTexture = Shader.PropertyToID("_SsrHitPointTexture");
public static readonly int _SsrClearCoatMaskTexture = Shader.PropertyToID("_SsrClearCoatMaskTexture");
@@ -576,6 +577,10 @@ static class HDShaderIDs
public static readonly int _DistanceTexture = Shader.PropertyToID("_DistanceTexture");
public static readonly int _JitterFramePeriod = Shader.PropertyToID("_JitterFramePeriod");
public static readonly int _SingleReflectionBounce = Shader.PropertyToID("_SingleReflectionBounce");
+ public static readonly int _HistoryBufferSize = Shader.PropertyToID("_HistoryBufferSize");
+ public static readonly int _CurrentEffectResolution = Shader.PropertyToID("_CurrentEffectResolution");
+ public static readonly int _SampleCountTextureRW = Shader.PropertyToID("_SampleCountTextureRW");
+ public static readonly int _AffectSmoothSurfaces = Shader.PropertyToID("_AffectSmoothSurfaces");
// Reflections
public static readonly int _ReflectionHistorybufferRW = Shader.PropertyToID("_ReflectionHistorybufferRW");
@@ -663,6 +668,7 @@ static class HDShaderIDs
// Deferred Lighting
public static readonly int _RaytracingLitBufferRW = Shader.PropertyToID("_RaytracingLitBufferRW");
public static readonly int _RayTracingDiffuseLightingOnly = Shader.PropertyToID("_RayTracingDiffuseLightingOnly");
+ public static readonly int _RaytracingHalfResolution = Shader.PropertyToID("_RaytracingHalfResolution");
// Ray binning
public static readonly int _RayBinResult = Shader.PropertyToID("_RayBinResult");
diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDRaytracingDeferredLightLoop.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDRaytracingDeferredLightLoop.cs
index 66894c24524..44aa8788418 100644
--- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDRaytracingDeferredLightLoop.cs
+++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDRaytracingDeferredLightLoop.cs
@@ -175,6 +175,7 @@ static void RenderRaytracingDeferredLighting(CommandBuffer cmd, in DeferredLight
cmd.SetRayTracingTextureParam(parameters.gBufferRaytracingRT, HDShaderIDs._DepthTexture, buffers.depthStencilBuffer);
cmd.SetRayTracingTextureParam(parameters.gBufferRaytracingRT, HDShaderIDs._NormalBufferTexture, buffers.normalBuffer);
cmd.SetRayTracingTextureParam(parameters.gBufferRaytracingRT, HDShaderIDs._RaytracingDirectionBuffer, buffers.directionBuffer);
+ cmd.SetRayTracingIntParams(parameters.gBufferRaytracingRT, HDShaderIDs._RaytracingHalfResolution, parameters.halfResolution ? 1 : 0);
// Bind the output textures
cmd.SetRayTracingTextureParam(parameters.gBufferRaytracingRT, HDShaderIDs._GBufferTextureRW[0], buffers.gbuffer0);
@@ -208,7 +209,6 @@ static void RenderRaytracingDeferredLighting(CommandBuffer cmd, in DeferredLight
}
else
{
- cmd.SetRayTracingIntParams(parameters.gBufferRaytracingRT, "_RaytracingHalfResolution", parameters.halfResolution ? 1 : 0);
cmd.DispatchRays(parameters.gBufferRaytracingRT, m_RayGenGBuffer, widthResolution, heightResolution, (uint)parameters.viewCount);
}
diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDRaytracingReflection.RenderGraph.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDRaytracingReflection.RenderGraph.cs
index 6d96e1fe817..09e092fc288 100644
--- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDRaytracingReflection.RenderGraph.cs
+++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDRaytracingReflection.RenderGraph.cs
@@ -5,6 +5,7 @@ namespace UnityEngine.Rendering.HighDefinition
{
public partial class HDRenderPipeline
{
+ #region Direction Generation
class DirGenRTRPassData
{
public RTReflectionDirGenParameters parameters;
@@ -46,21 +47,25 @@ TextureHandle DirGenRTR(RenderGraph renderGraph, in RTReflectionDirGenParameters
}
}
- class UpscaleRTRPassData
+ #endregion
+
+ #region AdjustWeight
+
+ class AdjustWeightRTRPassData
{
- public RTReflectionUpscaleParameters parameters;
+ public RTRAdjustWeightParameters parameters;
public TextureHandle depthStencilBuffer;
public TextureHandle normalBuffer;
public TextureHandle clearCoatMaskTexture;
public TextureHandle lightingTexture;
- public TextureHandle hitPointTexture;
+ public TextureHandle directionTexture;
public TextureHandle outputTexture;
}
- TextureHandle UpscaleRTR(RenderGraph renderGraph, in RTReflectionUpscaleParameters parameters,
- TextureHandle depthPyramid, TextureHandle normalBuffer, TextureHandle clearCoatTexture, TextureHandle lightingTexture, TextureHandle hitPointTexture)
+ TextureHandle AdjustWeightRTR(RenderGraph renderGraph, in RTRAdjustWeightParameters parameters,
+ TextureHandle depthPyramid, TextureHandle normalBuffer, TextureHandle clearCoatTexture, TextureHandle lightingTexture, TextureHandle directionTexture)
{
- using (var builder = renderGraph.AddRenderPass("Upscale the RTR result", out var passData, ProfilingSampler.Get(HDProfileId.RaytracingIndirectDiffuseUpscale)))
+ using (var builder = renderGraph.AddRenderPass("Adjust Weight RTR", out var passData, ProfilingSampler.Get(HDProfileId.RaytracingReflectionAdjustWeight)))
{
builder.EnableAsyncCompute(false);
@@ -69,7 +74,49 @@ TextureHandle UpscaleRTR(RenderGraph renderGraph, in RTReflectionUpscaleParamete
passData.normalBuffer = builder.ReadTexture(normalBuffer);
passData.clearCoatMaskTexture = builder.ReadTexture(clearCoatTexture);
passData.lightingTexture = builder.ReadTexture(lightingTexture);
- passData.hitPointTexture = builder.ReadTexture(hitPointTexture);
+ passData.directionTexture = builder.ReadTexture(directionTexture);
+ passData.outputTexture = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true)
+ { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Reflection Ray Reflections" }));
+
+ builder.SetRenderFunc(
+ (AdjustWeightRTRPassData data, RenderGraphContext ctx) =>
+ {
+ // We need to fill the structure that holds the various resources
+ RTRAdjustWeightResources resources = new RTRAdjustWeightResources();
+ resources.depthStencilBuffer = data.depthStencilBuffer;
+ resources.normalBuffer = data.normalBuffer;
+ resources.clearCoatMaskTexture = data.clearCoatMaskTexture;
+ resources.lightingTexture = data.lightingTexture;
+ resources.directionTexture = data.directionTexture;
+ resources.outputTexture = data.outputTexture;
+ AdjustWeightRTReflections(ctx.cmd, data.parameters, resources);
+ });
+
+ return passData.outputTexture;
+ }
+ }
+
+ #endregion
+
+ #region Upscale
+
+ class UpscaleRTRPassData
+ {
+ public RTRUpscaleParameters parameters;
+ public TextureHandle depthStencilBuffer;
+ public TextureHandle lightingTexture;
+ public TextureHandle outputTexture;
+ }
+
+ TextureHandle UpscaleRTR(RenderGraph renderGraph, in RTRUpscaleParameters parameters, TextureHandle depthPyramid, TextureHandle lightingTexture)
+ {
+ using (var builder = renderGraph.AddRenderPass("Upscale RTR", out var passData, ProfilingSampler.Get(HDProfileId.RaytracingReflectionUpscale)))
+ {
+ builder.EnableAsyncCompute(false);
+
+ passData.parameters = parameters;
+ passData.depthStencilBuffer = builder.ReadTexture(depthPyramid);
+ passData.lightingTexture = builder.ReadTexture(lightingTexture);
passData.outputTexture = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true)
{ colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Reflection Ray Reflections" }));
@@ -77,20 +124,19 @@ TextureHandle UpscaleRTR(RenderGraph renderGraph, in RTReflectionUpscaleParamete
(UpscaleRTRPassData data, RenderGraphContext ctx) =>
{
// We need to fill the structure that holds the various resources
- RTReflectionUpscaleResources rtrUpscaleResources = new RTReflectionUpscaleResources();
- rtrUpscaleResources.depthStencilBuffer = data.depthStencilBuffer;
- rtrUpscaleResources.normalBuffer = data.normalBuffer;
- rtrUpscaleResources.clearCoatMaskTexture = data.clearCoatMaskTexture;
- rtrUpscaleResources.lightingTexture = data.lightingTexture;
- rtrUpscaleResources.hitPointTexture = data.hitPointTexture;
- rtrUpscaleResources.outputTexture = data.outputTexture;
- UpscaleRTReflections(ctx.cmd, data.parameters, rtrUpscaleResources);
+ RTRUpscaleResources resources = new RTRUpscaleResources();
+ resources.depthStencilBuffer = data.depthStencilBuffer;
+ resources.lightingTexture = data.lightingTexture;
+ resources.outputTexture = data.outputTexture;
+ UpscaleRTR(ctx.cmd, data.parameters, resources);
});
return passData.outputTexture;
}
}
+ #endregion
+
static RTHandle RequestRayTracedReflectionsHistoryTexture(HDCamera hdCamera)
{
return hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.RaytracedReflection)
@@ -114,9 +160,8 @@ TextureHandle RenderReflectionsPerformance(RenderGraph renderGraph, HDCamera hdC
DeferredLightingRTParameters deferredParamters = PrepareReflectionDeferredLightingRTParameters(hdCamera);
TextureHandle lightingBuffer = DeferredLightingRT(renderGraph, in deferredParamters, directionBuffer, depthPyramid, normalBuffer, skyTexture, rayCountTexture);
- RTReflectionUpscaleParameters rtrUpscaleParameters = PrepareRTReflectionUpscaleParameters(hdCamera, settings);
- rtrResult = UpscaleRTR(renderGraph, in rtrUpscaleParameters,
- depthPyramid, normalBuffer, clearCoatTexture, lightingBuffer, directionBuffer);
+ RTRAdjustWeightParameters rtrAdjustWeightParameters = PrepareRTRAdjustWeightParameters(hdCamera, settings);
+ rtrResult = AdjustWeightRTR(renderGraph, in rtrAdjustWeightParameters, depthPyramid, normalBuffer, clearCoatTexture, lightingBuffer, directionBuffer);
// Denoise if required
if (settings.denoise && !transparent)
@@ -126,14 +171,24 @@ TextureHandle RenderReflectionsPerformance(RenderGraph renderGraph, HDCamera hdC
// Prepare the parameters and the resources
HDReflectionDenoiser reflectionDenoiser = GetReflectionDenoiser();
- ReflectionDenoiserParameters reflDenoiserParameters = reflectionDenoiser.PrepareReflectionDenoiserParameters(hdCamera, EvaluateHistoryValidity(hdCamera), settings.denoiserRadius, true);
+ float historyValidity = EvaluateRayTracedReflectionHistoryValidity(hdCamera, settings.fullResolution, true);
+ ReflectionDenoiserParameters reflDenoiserParameters = reflectionDenoiser.PrepareReflectionDenoiserParameters(hdCamera, historyValidity, settings.denoiserRadius, settings.fullResolution, true, settings.affectSmoothSurfaces);
RTHandle historySignal = RequestRayTracedReflectionsHistoryTexture(hdCamera);
rtrResult = reflectionDenoiser.DenoiseRTR(renderGraph, in reflDenoiserParameters, hdCamera, depthPyramid, normalBuffer, motionVectors, clearCoatTexture, rtrResult, historySignal);
+ PropagateRayTracedReflectionsHistoryValidity(hdCamera, settings.fullResolution, true);
+ }
+
+ // We only need to upscale if the effect was not rendered in full res
+ if (!settings.fullResolution)
+ {
+ RTRUpscaleParameters rtrUpscaleParameters = PrepareRTRUpscaleParameters(hdCamera, settings);
+ rtrResult = UpscaleRTR(renderGraph, in rtrUpscaleParameters, depthPyramid, rtrResult);
}
return rtrResult;
}
+ #region Quality
class TraceQualityRTRPassData
{
public RTRQualityRenderingParameters parameters;
@@ -178,6 +233,8 @@ TextureHandle QualityRTR(RenderGraph renderGraph, in RTRQualityRenderingParamete
}
}
+ #endregion
+
TextureHandle RenderReflectionsQuality(RenderGraph renderGraph, HDCamera hdCamera,
TextureHandle depthPyramid, TextureHandle stencilBuffer, TextureHandle normalBuffer, TextureHandle motionVectors, TextureHandle rayCountTexture, TextureHandle clearCoatTexture, Texture skyTexture,
int frameCount, ShaderVariablesRaytracing shaderVariablesRaytracing, bool transparent)
@@ -197,9 +254,11 @@ TextureHandle RenderReflectionsQuality(RenderGraph renderGraph, HDCamera hdCamer
// Prepare the parameters and the resources
HDReflectionDenoiser reflectionDenoiser = GetReflectionDenoiser();
- ReflectionDenoiserParameters reflDenoiserParameters = reflectionDenoiser.PrepareReflectionDenoiserParameters(hdCamera, EvaluateHistoryValidity(hdCamera), settings.denoiserRadius, rtrQRenderingParameters.bounceCount == 1);
+ float historyValidity = EvaluateRayTracedReflectionHistoryValidity(hdCamera, true, true);
+ ReflectionDenoiserParameters reflDenoiserParameters = reflectionDenoiser.PrepareReflectionDenoiserParameters(hdCamera, historyValidity, settings.denoiserRadius, true, rtrQRenderingParameters.bounceCount == 1, settings.affectSmoothSurfaces);
RTHandle historySignal = RequestRayTracedReflectionsHistoryTexture(hdCamera);
rtrResult = reflectionDenoiser.DenoiseRTR(renderGraph, in reflDenoiserParameters, hdCamera, depthPyramid, normalBuffer, motionVectors, clearCoatTexture, rtrResult, historySignal);
+ PropagateRayTracedReflectionsHistoryValidity(hdCamera, true, true);
}
return rtrResult;
diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDRaytracingReflection.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDRaytracingReflection.cs
index b83d7ad8390..4b5caea03d1 100644
--- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDRaytracingReflection.cs
+++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDRaytracingReflection.cs
@@ -16,8 +16,9 @@ public partial class HDRenderPipeline
int m_RaytracingReflectionsHalfResKernel;
int m_RaytracingReflectionsTransparentFullResKernel;
int m_RaytracingReflectionsTransparentHalfResKernel;
- int m_ReflectionIntegrationUpscaleFullResKernel;
- int m_ReflectionIntegrationUpscaleHalfResKernel;
+ int m_ReflectionAdjustWeightKernel;
+ int m_ReflectionRescaleAndAdjustWeightKernel;
+ int m_ReflectionUpscaleKernel;
void InitRayTracedReflections()
{
@@ -29,8 +30,8 @@ void InitRayTracedReflections()
m_RaytracingReflectionsHalfResKernel = reflectionShaderCS.FindKernel("RaytracingReflectionsHalfRes");
m_RaytracingReflectionsTransparentFullResKernel = reflectionShaderCS.FindKernel("RaytracingReflectionsTransparentFullRes");
m_RaytracingReflectionsTransparentHalfResKernel = reflectionShaderCS.FindKernel("RaytracingReflectionsTransparentHalfRes");
- m_ReflectionIntegrationUpscaleFullResKernel = reflectionBilateralFilterCS.FindKernel("ReflectionIntegrationUpscaleFullRes");
- m_ReflectionIntegrationUpscaleHalfResKernel = reflectionBilateralFilterCS.FindKernel("ReflectionIntegrationUpscaleHalfRes");
+ m_ReflectionAdjustWeightKernel = reflectionBilateralFilterCS.FindKernel("ReflectionAdjustWeight");
+ m_ReflectionUpscaleKernel = reflectionBilateralFilterCS.FindKernel("ReflectionUpscale");
}
static RTHandle ReflectionHistoryBufferAllocatorFunction(string viewName, int frameIndex, RTHandleSystem rtHandleSystem)
@@ -40,6 +41,20 @@ static RTHandle ReflectionHistoryBufferAllocatorFunction(string viewName, int fr
name: string.Format("{0}_ReflectionHistoryBuffer{1}", viewName, frameIndex));
}
+ private float EvaluateRayTracedReflectionHistoryValidity(HDCamera hdCamera, bool fullResolution, bool rayTraced)
+ {
+ // Evaluate the history validity
+ float effectHistoryValidity = hdCamera.EffectHistoryValidity(HDCamera.HistoryEffectSlot.RayTracedReflections, fullResolution, rayTraced) ? 1.0f : 0.0f;
+ return EvaluateHistoryValidity(hdCamera) * effectHistoryValidity;
+ }
+
+ private void PropagateRayTracedReflectionsHistoryValidity(HDCamera hdCamera, bool fullResolution, bool rayTraced)
+ {
+ hdCamera.PropagateEffectHistoryValidity(HDCamera.HistoryEffectSlot.RayTracedReflections, fullResolution, rayTraced);
+ }
+
+ #region Direction Generation
+
struct RTReflectionDirGenParameters
{
// Camera parameters
@@ -48,13 +63,12 @@ struct RTReflectionDirGenParameters
public int viewCount;
// Generation parameters
- public bool fullResolution;
public float minSmoothness;
// Additional resources
- public BlueNoise.DitheredTextureSet ditheredTextureSet;
- public int dirGenKernel;
public ComputeShader directionGenCS;
+ public int dirGenKernel;
+ public BlueNoise.DitheredTextureSet ditheredTextureSet;
public ShaderVariablesRaytracing shaderVariablesRayTracingCB;
}
@@ -63,24 +77,19 @@ RTReflectionDirGenParameters PrepareRTReflectionDirGenParameters(HDCamera hdCame
RTReflectionDirGenParameters rtrDirGenParams = new RTReflectionDirGenParameters();
// Set the camera parameters
- rtrDirGenParams.texWidth = hdCamera.actualWidth;
- rtrDirGenParams.texHeight = hdCamera.actualHeight;
+ rtrDirGenParams.texWidth = settings.fullResolution ? hdCamera.actualWidth : hdCamera.actualWidth / 2;
+ rtrDirGenParams.texHeight = settings.fullResolution ? hdCamera.actualHeight : hdCamera.actualHeight / 2;
rtrDirGenParams.viewCount = hdCamera.viewCount;
// Set the generation parameters
- rtrDirGenParams.fullResolution = settings.fullResolution;
rtrDirGenParams.minSmoothness = settings.minSmoothness;
// Grab the right kernel
rtrDirGenParams.directionGenCS = m_Asset.renderPipelineRayTracingResources.reflectionRaytracingCS;
if (settings.fullResolution)
- {
rtrDirGenParams.dirGenKernel = transparent ? m_RaytracingReflectionsTransparentFullResKernel : m_RaytracingReflectionsFullResKernel;
- }
else
- {
rtrDirGenParams.dirGenKernel = transparent ? m_RaytracingReflectionsTransparentHalfResKernel : m_RaytracingReflectionsHalfResKernel;
- }
// Grab the additional parameters
BlueNoise blueNoise = GetBlueNoiseManager();
@@ -124,24 +133,17 @@ static void RTReflectionDirectionGeneration(CommandBuffer cmd, RTReflectionDirGe
// Bind the output buffers
cmd.SetComputeTextureParam(rtrDirGenParams.directionGenCS, rtrDirGenParams.dirGenKernel, HDShaderIDs._RaytracingDirectionBuffer, rtrDirGenResources.outputBuffer);
- int numTilesXHR, numTilesYHR;
- if (rtrDirGenParams.fullResolution)
- {
- // Evaluate the dispatch parameters
- numTilesXHR = (rtrDirGenParams.texWidth + (rtReflectionsComputeTileSize - 1)) / rtReflectionsComputeTileSize;
- numTilesYHR = (rtrDirGenParams.texHeight + (rtReflectionsComputeTileSize - 1)) / rtReflectionsComputeTileSize;
- }
- else
- {
- // Evaluate the dispatch parameters
- numTilesXHR = (rtrDirGenParams.texWidth / 2 + (rtReflectionsComputeTileSize - 1)) / rtReflectionsComputeTileSize;
- numTilesYHR = (rtrDirGenParams.texHeight / 2 + (rtReflectionsComputeTileSize - 1)) / rtReflectionsComputeTileSize;
- }
-
+ // Evaluate the dispatch parameters
+ int numTilesX = (rtrDirGenParams.texWidth + (rtReflectionsComputeTileSize - 1)) / rtReflectionsComputeTileSize;
+ int numTilesY = (rtrDirGenParams.texHeight + (rtReflectionsComputeTileSize - 1)) / rtReflectionsComputeTileSize;
// Compute the directions
- cmd.DispatchCompute(rtrDirGenParams.directionGenCS, rtrDirGenParams.dirGenKernel, numTilesXHR, numTilesYHR, rtrDirGenParams.viewCount);
+ cmd.DispatchCompute(rtrDirGenParams.directionGenCS, rtrDirGenParams.dirGenKernel, numTilesX, numTilesY, rtrDirGenParams.viewCount);
}
+ #endregion
+
+ #region Deferred Lighting
+
DeferredLightingRTParameters PrepareReflectionDeferredLightingRTParameters(HDCamera hdCamera)
{
DeferredLightingRTParameters deferredParameters = new DeferredLightingRTParameters();
@@ -194,77 +196,134 @@ DeferredLightingRTParameters PrepareReflectionDeferredLightingRTParameters(HDCam
return deferredParameters;
}
- struct RTReflectionUpscaleParameters
+ #endregion
+
+ #region AdjustWeight
+
+ struct RTRAdjustWeightParameters
{
// Camera parameters
public int texWidth;
public int texHeight;
public int viewCount;
- // Denoising parameters
- public int upscaleRadius;
- public bool denoise;
- public int denoiserRadius;
-
- // Kernels
- public int upscaleKernel;
+ public float minSmoothness;
+ public float smoothnessFadeStart;
// Other parameters
- public Texture2DArray blueNoiseTexture;
public ComputeShader reflectionFilterCS;
+ public int adjustWeightKernel;
+ public ShaderVariablesRaytracing shaderVariablesRayTracingCB;
}
- RTReflectionUpscaleParameters PrepareRTReflectionUpscaleParameters(HDCamera hdCamera, ScreenSpaceReflection settings)
+ RTRAdjustWeightParameters PrepareRTRAdjustWeightParameters(HDCamera hdCamera, ScreenSpaceReflection settings)
{
- RTReflectionUpscaleParameters rtrUpscaleParams = new RTReflectionUpscaleParameters();
+ RTRAdjustWeightParameters parameters = new RTRAdjustWeightParameters();
// Camera parameters
- rtrUpscaleParams.texWidth = hdCamera.actualWidth;
- rtrUpscaleParams.texHeight = hdCamera.actualHeight;
- rtrUpscaleParams.viewCount = hdCamera.viewCount;
+ parameters.texWidth = settings.fullResolution ? hdCamera.actualWidth : hdCamera.actualWidth / 2;
+ parameters.texHeight = settings.fullResolution ? hdCamera.actualHeight : hdCamera.actualHeight / 2;
+ parameters.viewCount = hdCamera.viewCount;
- // De-noising parameters
- rtrUpscaleParams.upscaleRadius = settings.upscaleRadius;
- rtrUpscaleParams.denoise = settings.denoise;
- rtrUpscaleParams.denoiserRadius = settings.denoiserRadius;
-
- // Kernels
- rtrUpscaleParams.upscaleKernel = settings.fullResolution ? m_ReflectionIntegrationUpscaleFullResKernel : m_ReflectionIntegrationUpscaleHalfResKernel;
+ // Requires parameters
+ parameters.minSmoothness = settings.minSmoothness;
+ parameters.smoothnessFadeStart = settings.smoothnessFadeStart;
// Other parameters
- rtrUpscaleParams.blueNoiseTexture = GetBlueNoiseManager().textureArray16RGB;
- rtrUpscaleParams.reflectionFilterCS = m_Asset.renderPipelineRayTracingResources.reflectionBilateralFilterCS;
- return rtrUpscaleParams;
+ parameters.reflectionFilterCS = m_Asset.renderPipelineRayTracingResources.reflectionBilateralFilterCS;
+ parameters.adjustWeightKernel = settings.fullResolution ? m_ReflectionAdjustWeightKernel : m_ReflectionRescaleAndAdjustWeightKernel;
+ parameters.shaderVariablesRayTracingCB = m_ShaderVariablesRayTracingCB;
+ return parameters;
}
- struct RTReflectionUpscaleResources
+ struct RTRAdjustWeightResources
{
public RTHandle depthStencilBuffer;
public RTHandle normalBuffer;
public RTHandle lightingTexture;
- public RTHandle hitPointTexture;
+ public RTHandle directionTexture;
public RTHandle outputTexture;
public RenderTargetIdentifier clearCoatMaskTexture;
}
- static void UpscaleRTReflections(CommandBuffer cmd, RTReflectionUpscaleParameters rtrUpscaleParameters, RTReflectionUpscaleResources rtrUpscaleResources)
+ static void AdjustWeightRTReflections(CommandBuffer cmd, RTRAdjustWeightParameters parameters, RTRAdjustWeightResources resources)
+ {
+ // Bind all the required scalars to the CB
+ parameters.shaderVariablesRayTracingCB._RaytracingReflectionMinSmoothness = parameters.minSmoothness;
+ parameters.shaderVariablesRayTracingCB._RaytracingReflectionSmoothnessFadeStart = parameters.smoothnessFadeStart;
+ ConstantBuffer.PushGlobal(cmd, parameters.shaderVariablesRayTracingCB, HDShaderIDs._ShaderVariablesRaytracing);
+
+ // Source input textures
+ cmd.SetComputeTextureParam(parameters.reflectionFilterCS, parameters.adjustWeightKernel, HDShaderIDs._DepthTexture, resources.depthStencilBuffer);
+ cmd.SetComputeTextureParam(parameters.reflectionFilterCS, parameters.adjustWeightKernel, HDShaderIDs._SsrClearCoatMaskTexture, resources.clearCoatMaskTexture);
+ cmd.SetComputeTextureParam(parameters.reflectionFilterCS, parameters.adjustWeightKernel, HDShaderIDs._NormalBufferTexture, resources.normalBuffer);
+ cmd.SetComputeTextureParam(parameters.reflectionFilterCS, parameters.adjustWeightKernel, HDShaderIDs._DirectionPDFTexture, resources.directionTexture);
+
+ // Lighting textures
+ cmd.SetComputeTextureParam(parameters.reflectionFilterCS, parameters.adjustWeightKernel, HDShaderIDs._SsrLightingTextureRW, resources.lightingTexture);
+
+ // Output texture
+ cmd.SetComputeTextureParam(parameters.reflectionFilterCS, parameters.adjustWeightKernel, HDShaderIDs._RaytracingReflectionTexture, resources.outputTexture);
+
+ // Compute the texture
+ int numTilesXHR = (parameters.texWidth + (rtReflectionsComputeTileSize - 1)) / rtReflectionsComputeTileSize;
+ int numTilesYHR = (parameters.texHeight + (rtReflectionsComputeTileSize - 1)) / rtReflectionsComputeTileSize;
+ cmd.DispatchCompute(parameters.reflectionFilterCS, parameters.adjustWeightKernel, numTilesXHR, numTilesYHR, parameters.viewCount);
+ }
+
+ #endregion
+
+ #region Upscale
+ struct RTRUpscaleParameters
+ {
+ // Camera parameters
+ public int texWidth;
+ public int texHeight;
+ public int viewCount;
+
+ // Other parameters
+ public ComputeShader reflectionFilterCS;
+ public int upscaleKernel;
+ }
+
+ RTRUpscaleParameters PrepareRTRUpscaleParameters(HDCamera hdCamera, ScreenSpaceReflection settings)
{
- // Inject all the parameters for the compute
- cmd.SetComputeTextureParam(rtrUpscaleParameters.reflectionFilterCS, rtrUpscaleParameters.upscaleKernel, HDShaderIDs._SsrLightingTextureRW, rtrUpscaleResources.lightingTexture);
- cmd.SetComputeTextureParam(rtrUpscaleParameters.reflectionFilterCS, rtrUpscaleParameters.upscaleKernel, HDShaderIDs._SsrHitPointTexture, rtrUpscaleResources.hitPointTexture);
- cmd.SetComputeTextureParam(rtrUpscaleParameters.reflectionFilterCS, rtrUpscaleParameters.upscaleKernel, HDShaderIDs._DepthTexture, rtrUpscaleResources.depthStencilBuffer);
- cmd.SetComputeTextureParam(rtrUpscaleParameters.reflectionFilterCS, rtrUpscaleParameters.upscaleKernel, HDShaderIDs._NormalBufferTexture, rtrUpscaleResources.normalBuffer);
- cmd.SetComputeTextureParam(rtrUpscaleParameters.reflectionFilterCS, rtrUpscaleParameters.upscaleKernel, HDShaderIDs._BlueNoiseTexture, rtrUpscaleParameters.blueNoiseTexture);
- cmd.SetComputeTextureParam(rtrUpscaleParameters.reflectionFilterCS, rtrUpscaleParameters.upscaleKernel, HDShaderIDs._RaytracingReflectionTexture, rtrUpscaleResources.outputTexture);
- cmd.SetComputeIntParam(rtrUpscaleParameters.reflectionFilterCS, HDShaderIDs._SpatialFilterRadius, rtrUpscaleParameters.upscaleRadius);
- cmd.SetComputeIntParam(rtrUpscaleParameters.reflectionFilterCS, HDShaderIDs._RaytracingDenoiseRadius, rtrUpscaleParameters.denoise ? rtrUpscaleParameters.denoiserRadius : 0);
- cmd.SetComputeTextureParam(rtrUpscaleParameters.reflectionFilterCS, rtrUpscaleParameters.upscaleKernel, HDShaderIDs._SsrClearCoatMaskTexture, rtrUpscaleResources.clearCoatMaskTexture);
+ RTRUpscaleParameters parameters = new RTRUpscaleParameters();
+ // Camera parameters
+ parameters.texWidth = hdCamera.actualWidth;
+ parameters.texHeight = hdCamera.actualHeight;
+ parameters.viewCount = hdCamera.viewCount;
+
+ // Other parameters
+ parameters.reflectionFilterCS = m_Asset.renderPipelineRayTracingResources.reflectionBilateralFilterCS;
+ parameters.upscaleKernel = m_ReflectionUpscaleKernel;
+ return parameters;
+ }
+
+ struct RTRUpscaleResources
+ {
+ public RTHandle depthStencilBuffer;
+ public RTHandle lightingTexture;
+ public RTHandle outputTexture;
+ }
+
+ static void UpscaleRTR(CommandBuffer cmd, RTRUpscaleParameters parameters, RTRUpscaleResources resources)
+ {
+ // Input textures
+ cmd.SetComputeTextureParam(parameters.reflectionFilterCS, parameters.upscaleKernel, HDShaderIDs._DepthTexture, resources.depthStencilBuffer);
+ cmd.SetComputeTextureParam(parameters.reflectionFilterCS, parameters.upscaleKernel, HDShaderIDs._SsrLightingTextureRW, resources.lightingTexture);
+
+ // Output texture
+ cmd.SetComputeTextureParam(parameters.reflectionFilterCS, parameters.upscaleKernel, HDShaderIDs._RaytracingReflectionTexture, resources.outputTexture);
// Compute the texture
- int numTilesXHR = (rtrUpscaleParameters.texWidth + (rtReflectionsComputeTileSize - 1)) / rtReflectionsComputeTileSize;
- int numTilesYHR = (rtrUpscaleParameters.texHeight + (rtReflectionsComputeTileSize - 1)) / rtReflectionsComputeTileSize;
- cmd.DispatchCompute(rtrUpscaleParameters.reflectionFilterCS, rtrUpscaleParameters.upscaleKernel, numTilesXHR, numTilesYHR, rtrUpscaleParameters.viewCount);
+ int numTilesXHR = (parameters.texWidth + (rtReflectionsComputeTileSize - 1)) / rtReflectionsComputeTileSize;
+ int numTilesYHR = (parameters.texHeight + (rtReflectionsComputeTileSize - 1)) / rtReflectionsComputeTileSize;
+ cmd.DispatchCompute(parameters.reflectionFilterCS, parameters.upscaleKernel, numTilesXHR, numTilesYHR, parameters.viewCount);
}
+ #endregion
+
+ #region Quality RTR
struct RTRQualityRenderingParameters
{
// Camera parameters
@@ -279,6 +338,8 @@ struct RTRQualityRenderingParameters
public int sampleCount;
public int bounceCount;
public bool transparent;
+ public float minSmoothness;
+ public float smoothnessFadeStart;
// Other parameters
public RayTracingAccelerationStructure accelerationStructure;
@@ -305,6 +366,8 @@ RTRQualityRenderingParameters PrepareRTRQualityRenderingParameters(HDCamera hdCa
rtrQualityRenderingParameters.sampleCount = settings.sampleCount.value;
rtrQualityRenderingParameters.bounceCount = settings.bounceCount.value;
rtrQualityRenderingParameters.transparent = transparent;
+ rtrQualityRenderingParameters.minSmoothness = settings.minSmoothness;
+ rtrQualityRenderingParameters.smoothnessFadeStart = settings.smoothnessFadeStart;
// Other parameters
rtrQualityRenderingParameters.accelerationStructure = RequestAccelerationStructure();
@@ -350,6 +413,9 @@ static void RenderQualityRayTracedReflections(CommandBuffer cmd, RTRQualityRende
// Set the number of bounces for reflections
rtrQRenderingParameters.shaderVariablesRayTracingCB._RaytracingMaxRecursion = rtrQRenderingParameters.bounceCount;
rtrQRenderingParameters.shaderVariablesRayTracingCB._RayTracingDiffuseLightingOnly = 0;
+ // Bind all the required scalars to the CB
+ rtrQRenderingParameters.shaderVariablesRayTracingCB._RaytracingReflectionMinSmoothness = rtrQRenderingParameters.minSmoothness;
+ rtrQRenderingParameters.shaderVariablesRayTracingCB._RaytracingReflectionSmoothnessFadeStart = rtrQRenderingParameters.smoothnessFadeStart;
ConstantBuffer.PushGlobal(cmd, rtrQRenderingParameters.shaderVariablesRayTracingCB, HDShaderIDs._ShaderVariablesRaytracing);
// Inject the ray-tracing sampling data
@@ -383,5 +449,7 @@ static void RenderQualityRayTracedReflections(CommandBuffer cmd, RTRQualityRende
// Disable multi-bounce
CoreUtils.SetKeyword(cmd, "MULTI_BOUNCE_INDIRECT", false);
}
+
+ #endregion
}
}
diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDReflectionDenoiser.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDReflectionDenoiser.cs
index 3db8b847e80..41bb39b6dd0 100644
--- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDReflectionDenoiser.cs
+++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDReflectionDenoiser.cs
@@ -13,17 +13,21 @@ internal struct ReflectionDenoiserParameters
// De-noising parameters
public int maxKernelSize;
public float historyValidity;
+ // Current inverse resolution of the history buffer
+ public Vector2 historyBufferSize;
+ // Resolution at which the effect is rendered (Half the _Screensize if half res)
+ public Vector4 currentEffectResolution;
+ public float pixelSpreadTangent;
+ public int affectSmoothSurfaces;
public int singleReflectionBounce;
- // Kernels
+ // Other parameters
+ public ComputeShader reflectionDenoiserCS;
public int temporalAccumulationKernel;
public int copyHistoryKernel;
public int bilateralFilterHKernel;
public int bilateralFilterVKernel;
-
- // Other parameters
public Texture2D reflectionFilterMapping;
- public ComputeShader reflectionDenoiserCS;
}
internal struct ReflectionDenoiserResources
@@ -32,6 +36,7 @@ internal struct ReflectionDenoiserResources
public RTHandle depthBuffer;
public RTHandle normalBuffer;
public RTHandle motionVectorBuffer;
+ public RTHandle historyDepth;
// Intermediate textures
public RTHandle intermediateBuffer0;
@@ -46,10 +51,13 @@ class HDReflectionDenoiser
{
ComputeShader m_ReflectionDenoiserCS;
Texture2D m_ReflectionFilterMapping;
- int s_TemporalAccumulationKernel;
+ int s_TemporalAccumulationFullResKernel;
+ int s_TemporalAccumulationHalfResKernel;
int s_CopyHistoryKernel;
- int s_BilateralFilterHKernel;
- int s_BilateralFilterVKernel;
+ int s_BilateralFilterH_FRKernel;
+ int s_BilateralFilterV_FRKernel;
+ int s_BilateralFilterH_HRKernel;
+ int s_BilateralFilterV_HRKernel;
public HDReflectionDenoiser()
{
@@ -61,90 +69,105 @@ public void Init(HDRenderPipelineRayTracingResources rpRTResources)
m_ReflectionFilterMapping = rpRTResources.reflectionFilterMapping;
// Fetch all the kernels we shall be using
- s_TemporalAccumulationKernel = m_ReflectionDenoiserCS.FindKernel("TemporalAccumulation");
+ s_TemporalAccumulationFullResKernel = m_ReflectionDenoiserCS.FindKernel("TemporalAccumulationFullRes");
+ s_TemporalAccumulationHalfResKernel = m_ReflectionDenoiserCS.FindKernel("TemporalAccumulationHalfRes");
s_CopyHistoryKernel = m_ReflectionDenoiserCS.FindKernel("CopyHistory");
- s_BilateralFilterHKernel = m_ReflectionDenoiserCS.FindKernel("BilateralFilterH");
- s_BilateralFilterVKernel = m_ReflectionDenoiserCS.FindKernel("BilateralFilterV");
+ s_BilateralFilterH_FRKernel = m_ReflectionDenoiserCS.FindKernel("BilateralFilterH_FR");
+ s_BilateralFilterV_FRKernel = m_ReflectionDenoiserCS.FindKernel("BilateralFilterV_FR");
+ s_BilateralFilterH_HRKernel = m_ReflectionDenoiserCS.FindKernel("BilateralFilterH_HR");
+ s_BilateralFilterV_HRKernel = m_ReflectionDenoiserCS.FindKernel("BilateralFilterV_HR");
}
public void Release()
{
}
- internal ReflectionDenoiserParameters PrepareReflectionDenoiserParameters(HDCamera hdCamera, float historyValidity, int maxKernelSize, bool singleReflectionBounce)
+ internal ReflectionDenoiserParameters PrepareReflectionDenoiserParameters(HDCamera hdCamera, float historyValidity, int maxKernelSize, bool fullResolution, bool singleReflectionBounce, bool affectSmoothSurfaces)
{
ReflectionDenoiserParameters reflDenoiserParams = new ReflectionDenoiserParameters();
// Camera parameters
- reflDenoiserParams.texWidth = hdCamera.actualWidth;
- reflDenoiserParams.texHeight = hdCamera.actualHeight;
+ reflDenoiserParams.texWidth = fullResolution ? hdCamera.actualWidth : (hdCamera.actualWidth / 2);
+ reflDenoiserParams.texHeight = fullResolution ? hdCamera.actualHeight : (hdCamera.actualHeight / 2);
reflDenoiserParams.viewCount = hdCamera.viewCount;
// De-noising parameters
reflDenoiserParams.historyValidity = historyValidity;
- reflDenoiserParams.maxKernelSize = maxKernelSize;
+ reflDenoiserParams.maxKernelSize = fullResolution ? maxKernelSize : maxKernelSize / 2;
+ reflDenoiserParams.historyBufferSize = new Vector2(1.0f / (float)hdCamera.historyRTHandleProperties.currentRenderTargetSize.x, 1.0f / (float)hdCamera.historyRTHandleProperties.currentRenderTargetSize.y);
+ reflDenoiserParams.currentEffectResolution = new Vector4(reflDenoiserParams.texWidth, reflDenoiserParams.texHeight, 1.0f / (float)reflDenoiserParams.texWidth, 1.0f / (float)reflDenoiserParams.texHeight);
+ reflDenoiserParams.pixelSpreadTangent = HDRenderPipeline.GetPixelSpreadTangent(hdCamera.camera.fieldOfView, reflDenoiserParams.texWidth, reflDenoiserParams.texHeight);
+ reflDenoiserParams.affectSmoothSurfaces = affectSmoothSurfaces ? 1 : 0;
reflDenoiserParams.singleReflectionBounce = singleReflectionBounce ? 1 : 0;
- // Kernels
- reflDenoiserParams.temporalAccumulationKernel = s_TemporalAccumulationKernel;
- reflDenoiserParams.copyHistoryKernel = s_CopyHistoryKernel;
- reflDenoiserParams.bilateralFilterHKernel = s_BilateralFilterHKernel;
- reflDenoiserParams.bilateralFilterVKernel = s_BilateralFilterVKernel;
-
// Other parameters
- reflDenoiserParams.reflectionFilterMapping = m_ReflectionFilterMapping;
reflDenoiserParams.reflectionDenoiserCS = m_ReflectionDenoiserCS;
+ reflDenoiserParams.temporalAccumulationKernel = fullResolution ? s_TemporalAccumulationFullResKernel : s_TemporalAccumulationHalfResKernel;
+ reflDenoiserParams.copyHistoryKernel = s_CopyHistoryKernel;
+ reflDenoiserParams.bilateralFilterHKernel = fullResolution ? s_BilateralFilterH_FRKernel : s_BilateralFilterH_HRKernel;
+ reflDenoiserParams.bilateralFilterVKernel = fullResolution ? s_BilateralFilterV_FRKernel : s_BilateralFilterV_HRKernel;
+ reflDenoiserParams.reflectionFilterMapping = m_ReflectionFilterMapping;
return reflDenoiserParams;
}
- public static void DenoiseBuffer(CommandBuffer cmd, ReflectionDenoiserParameters reflDenoiserParameters, ReflectionDenoiserResources reflDenoiserResources)
+ public static void DenoiseBuffer(CommandBuffer cmd, ReflectionDenoiserParameters parameters, ReflectionDenoiserResources reflDenoiserResources)
{
// Evaluate the dispatch parameters
int tileSize = 8;
- int numTilesX = (reflDenoiserParameters.texWidth + (tileSize - 1)) / tileSize;
- int numTilesY = (reflDenoiserParameters.texHeight + (tileSize - 1)) / tileSize;
-
- // Apply a vectorized temporal filtering pass and store it back in the denoisebuffer0 with the analytic value in the third channel
- cmd.SetComputeTextureParam(reflDenoiserParameters.reflectionDenoiserCS, reflDenoiserParameters.temporalAccumulationKernel, HDShaderIDs._DenoiseInputTexture, reflDenoiserResources.noisyToOutputSignal);
- cmd.SetComputeTextureParam(reflDenoiserParameters.reflectionDenoiserCS, reflDenoiserParameters.temporalAccumulationKernel, HDShaderIDs._HistoryBuffer, reflDenoiserResources.historySignal);
- cmd.SetComputeTextureParam(reflDenoiserParameters.reflectionDenoiserCS, reflDenoiserParameters.temporalAccumulationKernel, HDShaderIDs._DepthTexture, reflDenoiserResources.depthBuffer);
- cmd.SetComputeTextureParam(reflDenoiserParameters.reflectionDenoiserCS, reflDenoiserParameters.temporalAccumulationKernel, HDShaderIDs._CameraDepthTexture, reflDenoiserResources.depthBuffer);
-
- cmd.SetComputeTextureParam(reflDenoiserParameters.reflectionDenoiserCS, reflDenoiserParameters.temporalAccumulationKernel, HDShaderIDs._NormalBufferTexture, reflDenoiserResources.normalBuffer);
- cmd.SetComputeTextureParam(reflDenoiserParameters.reflectionDenoiserCS, reflDenoiserParameters.temporalAccumulationKernel, HDShaderIDs._DenoiseOutputTextureRW, reflDenoiserResources.intermediateBuffer0);
- cmd.SetComputeTextureParam(reflDenoiserParameters.reflectionDenoiserCS, reflDenoiserParameters.temporalAccumulationKernel, HDShaderIDs._CameraMotionVectorsTexture, reflDenoiserResources.motionVectorBuffer);
- cmd.SetComputeFloatParam(reflDenoiserParameters.reflectionDenoiserCS, HDShaderIDs._HistoryValidity, reflDenoiserParameters.historyValidity);
- cmd.SetComputeIntParam(reflDenoiserParameters.reflectionDenoiserCS, HDShaderIDs._SingleReflectionBounce, reflDenoiserParameters.singleReflectionBounce);
-
- cmd.DispatchCompute(reflDenoiserParameters.reflectionDenoiserCS, reflDenoiserParameters.temporalAccumulationKernel, numTilesX, numTilesY, reflDenoiserParameters.viewCount);
-
- cmd.SetComputeTextureParam(reflDenoiserParameters.reflectionDenoiserCS, reflDenoiserParameters.copyHistoryKernel, HDShaderIDs._DenoiseInputTexture, reflDenoiserResources.intermediateBuffer0);
- cmd.SetComputeTextureParam(reflDenoiserParameters.reflectionDenoiserCS, reflDenoiserParameters.copyHistoryKernel, HDShaderIDs._DenoiseOutputTextureRW, reflDenoiserResources.historySignal);
- cmd.DispatchCompute(reflDenoiserParameters.reflectionDenoiserCS, reflDenoiserParameters.copyHistoryKernel, numTilesX, numTilesY, reflDenoiserParameters.viewCount);
+ int numTilesX = (parameters.texWidth + (tileSize - 1)) / tileSize;
+ int numTilesY = (parameters.texHeight + (tileSize - 1)) / tileSize;
+
+ // Input data
+ cmd.SetComputeFloatParam(parameters.reflectionDenoiserCS, HDShaderIDs._HistoryValidity, parameters.historyValidity);
+ cmd.SetComputeFloatParam(parameters.reflectionDenoiserCS, HDShaderIDs._PixelSpreadAngleTangent, parameters.pixelSpreadTangent);
+ cmd.SetComputeVectorParam(parameters.reflectionDenoiserCS, HDShaderIDs._HistoryBufferSize, parameters.historyBufferSize);
+ cmd.SetComputeVectorParam(parameters.reflectionDenoiserCS, HDShaderIDs._CurrentEffectResolution, parameters.currentEffectResolution);
+ cmd.SetComputeIntParam(parameters.reflectionDenoiserCS, HDShaderIDs._AffectSmoothSurfaces, parameters.affectSmoothSurfaces);
+ cmd.SetComputeIntParam(parameters.reflectionDenoiserCS, HDShaderIDs._SingleReflectionBounce, parameters.singleReflectionBounce);
+ cmd.SetComputeTextureParam(parameters.reflectionDenoiserCS, parameters.temporalAccumulationKernel, HDShaderIDs._DenoiseInputTexture, reflDenoiserResources.noisyToOutputSignal);
+ cmd.SetComputeTextureParam(parameters.reflectionDenoiserCS, parameters.temporalAccumulationKernel, HDShaderIDs._DepthTexture, reflDenoiserResources.depthBuffer);
+ cmd.SetComputeTextureParam(parameters.reflectionDenoiserCS, parameters.temporalAccumulationKernel, HDShaderIDs._HistoryDepthTexture, reflDenoiserResources.historyDepth);
+ cmd.SetComputeTextureParam(parameters.reflectionDenoiserCS, parameters.temporalAccumulationKernel, HDShaderIDs._NormalBufferTexture, reflDenoiserResources.normalBuffer);
+ cmd.SetComputeTextureParam(parameters.reflectionDenoiserCS, parameters.temporalAccumulationKernel, HDShaderIDs._CameraMotionVectorsTexture, reflDenoiserResources.motionVectorBuffer);
+ cmd.SetComputeTextureParam(parameters.reflectionDenoiserCS, parameters.temporalAccumulationKernel, HDShaderIDs._HistoryBuffer, reflDenoiserResources.historySignal);
+
+ // Output texture
+ cmd.SetComputeTextureParam(parameters.reflectionDenoiserCS, parameters.temporalAccumulationKernel, HDShaderIDs._DenoiseOutputTextureRW, reflDenoiserResources.intermediateBuffer0);
+ cmd.SetComputeTextureParam(parameters.reflectionDenoiserCS, parameters.temporalAccumulationKernel, HDShaderIDs._SampleCountTextureRW, reflDenoiserResources.intermediateBuffer1);
+
+ // Do the temporal accumulation
+ cmd.DispatchCompute(parameters.reflectionDenoiserCS, parameters.temporalAccumulationKernel, numTilesX, numTilesY, parameters.viewCount);
+
+ // Copy the accumulated signal into the history buffer
+ cmd.SetComputeTextureParam(parameters.reflectionDenoiserCS, parameters.copyHistoryKernel, HDShaderIDs._DenoiseInputTexture, reflDenoiserResources.intermediateBuffer0);
+ cmd.SetComputeTextureParam(parameters.reflectionDenoiserCS, parameters.copyHistoryKernel, HDShaderIDs._DenoiseOutputTextureRW, reflDenoiserResources.historySignal);
+ cmd.SetComputeTextureParam(parameters.reflectionDenoiserCS, parameters.copyHistoryKernel, HDShaderIDs._SampleCountTextureRW, reflDenoiserResources.intermediateBuffer1);
+ cmd.DispatchCompute(parameters.reflectionDenoiserCS, parameters.copyHistoryKernel, numTilesX, numTilesY, parameters.viewCount);
// Horizontal pass of the bilateral filter
- cmd.SetComputeIntParam(reflDenoiserParameters.reflectionDenoiserCS, HDShaderIDs._DenoiserFilterRadius, reflDenoiserParameters.maxKernelSize);
- cmd.SetComputeTextureParam(reflDenoiserParameters.reflectionDenoiserCS, reflDenoiserParameters.bilateralFilterHKernel, HDShaderIDs._DenoiseInputTexture, reflDenoiserResources.intermediateBuffer0);
- cmd.SetComputeTextureParam(reflDenoiserParameters.reflectionDenoiserCS, reflDenoiserParameters.bilateralFilterHKernel, HDShaderIDs._DepthTexture, reflDenoiserResources.depthBuffer);
- cmd.SetComputeTextureParam(reflDenoiserParameters.reflectionDenoiserCS, reflDenoiserParameters.bilateralFilterHKernel, HDShaderIDs._NormalBufferTexture, reflDenoiserResources.normalBuffer);
- cmd.SetComputeTextureParam(reflDenoiserParameters.reflectionDenoiserCS, reflDenoiserParameters.bilateralFilterHKernel, HDShaderIDs._DenoiseOutputTextureRW, reflDenoiserResources.intermediateBuffer1);
- cmd.SetComputeTextureParam(reflDenoiserParameters.reflectionDenoiserCS, reflDenoiserParameters.bilateralFilterHKernel, HDShaderIDs._ReflectionFilterMapping, reflDenoiserParameters.reflectionFilterMapping);
- cmd.DispatchCompute(reflDenoiserParameters.reflectionDenoiserCS, reflDenoiserParameters.bilateralFilterHKernel, numTilesX, numTilesY, reflDenoiserParameters.viewCount);
+ cmd.SetComputeIntParam(parameters.reflectionDenoiserCS, HDShaderIDs._DenoiserFilterRadius, parameters.maxKernelSize);
+ cmd.SetComputeTextureParam(parameters.reflectionDenoiserCS, parameters.bilateralFilterHKernel, HDShaderIDs._DenoiseInputTexture, reflDenoiserResources.intermediateBuffer0);
+ cmd.SetComputeTextureParam(parameters.reflectionDenoiserCS, parameters.bilateralFilterHKernel, HDShaderIDs._DepthTexture, reflDenoiserResources.depthBuffer);
+ cmd.SetComputeTextureParam(parameters.reflectionDenoiserCS, parameters.bilateralFilterHKernel, HDShaderIDs._NormalBufferTexture, reflDenoiserResources.normalBuffer);
+ cmd.SetComputeTextureParam(parameters.reflectionDenoiserCS, parameters.bilateralFilterHKernel, HDShaderIDs._DenoiseOutputTextureRW, reflDenoiserResources.intermediateBuffer1);
+ cmd.SetComputeTextureParam(parameters.reflectionDenoiserCS, parameters.bilateralFilterHKernel, HDShaderIDs._ReflectionFilterMapping, parameters.reflectionFilterMapping);
+ cmd.DispatchCompute(parameters.reflectionDenoiserCS, parameters.bilateralFilterHKernel, numTilesX, numTilesY, parameters.viewCount);
// Horizontal pass of the bilateral filter
- cmd.SetComputeIntParam(reflDenoiserParameters.reflectionDenoiserCS, HDShaderIDs._DenoiserFilterRadius, reflDenoiserParameters.maxKernelSize);
- cmd.SetComputeTextureParam(reflDenoiserParameters.reflectionDenoiserCS, reflDenoiserParameters.bilateralFilterVKernel, HDShaderIDs._DenoiseInputTexture, reflDenoiserResources.intermediateBuffer1);
- cmd.SetComputeTextureParam(reflDenoiserParameters.reflectionDenoiserCS, reflDenoiserParameters.bilateralFilterVKernel, HDShaderIDs._DepthTexture, reflDenoiserResources.depthBuffer);
- cmd.SetComputeTextureParam(reflDenoiserParameters.reflectionDenoiserCS, reflDenoiserParameters.bilateralFilterVKernel, HDShaderIDs._NormalBufferTexture, reflDenoiserResources.normalBuffer);
- cmd.SetComputeTextureParam(reflDenoiserParameters.reflectionDenoiserCS, reflDenoiserParameters.bilateralFilterVKernel, HDShaderIDs._DenoiseOutputTextureRW, reflDenoiserResources.noisyToOutputSignal);
- cmd.SetComputeTextureParam(reflDenoiserParameters.reflectionDenoiserCS, reflDenoiserParameters.bilateralFilterVKernel, HDShaderIDs._ReflectionFilterMapping, reflDenoiserParameters.reflectionFilterMapping);
- cmd.DispatchCompute(reflDenoiserParameters.reflectionDenoiserCS, reflDenoiserParameters.bilateralFilterVKernel, numTilesX, numTilesY, reflDenoiserParameters.viewCount);
+ cmd.SetComputeIntParam(parameters.reflectionDenoiserCS, HDShaderIDs._DenoiserFilterRadius, parameters.maxKernelSize);
+ cmd.SetComputeTextureParam(parameters.reflectionDenoiserCS, parameters.bilateralFilterVKernel, HDShaderIDs._DenoiseInputTexture, reflDenoiserResources.intermediateBuffer1);
+ cmd.SetComputeTextureParam(parameters.reflectionDenoiserCS, parameters.bilateralFilterVKernel, HDShaderIDs._DepthTexture, reflDenoiserResources.depthBuffer);
+ cmd.SetComputeTextureParam(parameters.reflectionDenoiserCS, parameters.bilateralFilterVKernel, HDShaderIDs._NormalBufferTexture, reflDenoiserResources.normalBuffer);
+ cmd.SetComputeTextureParam(parameters.reflectionDenoiserCS, parameters.bilateralFilterVKernel, HDShaderIDs._DenoiseOutputTextureRW, reflDenoiserResources.noisyToOutputSignal);
+ cmd.SetComputeTextureParam(parameters.reflectionDenoiserCS, parameters.bilateralFilterVKernel, HDShaderIDs._ReflectionFilterMapping, parameters.reflectionFilterMapping);
+ cmd.DispatchCompute(parameters.reflectionDenoiserCS, parameters.bilateralFilterVKernel, numTilesX, numTilesY, parameters.viewCount);
}
class ReflectionDenoiserPassData
{
public ReflectionDenoiserParameters parameters;
public TextureHandle depthBuffer;
+ public TextureHandle historyDepth;
public TextureHandle normalBuffer;
public TextureHandle motionVectorBuffer;
public TextureHandle intermediateBuffer0;
@@ -156,7 +179,7 @@ class ReflectionDenoiserPassData
public TextureHandle DenoiseRTR(RenderGraph renderGraph, in ReflectionDenoiserParameters parameters, HDCamera hdCamera,
TextureHandle depthPyramid, TextureHandle normalBuffer, TextureHandle motionVectorBuffer, TextureHandle clearCoatTexture, TextureHandle lightingTexture, RTHandle historyBuffer)
{
- using (var builder = renderGraph.AddRenderPass("Denoise ray traced reflections", out var passData, ProfilingSampler.Get(HDProfileId.RaytracingFilterReflection)))
+ using (var builder = renderGraph.AddRenderPass("Denoise ray traced reflections", out var passData, ProfilingSampler.Get(HDProfileId.RaytracingReflectionFilter)))
{
builder.EnableAsyncCompute(false);
@@ -164,6 +187,8 @@ public TextureHandle DenoiseRTR(RenderGraph renderGraph, in ReflectionDenoiserPa
passData.depthBuffer = builder.ReadTexture(depthPyramid);
passData.normalBuffer = builder.ReadTexture(normalBuffer);
passData.motionVectorBuffer = builder.ReadTexture(motionVectorBuffer);
+ RTHandle depthT = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.Depth);
+ passData.historyDepth = depthT != null ? renderGraph.ImportTexture(hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.Depth)) : renderGraph.defaultResources.blackTextureXR;
passData.intermediateBuffer0 = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true)
{ colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "IntermediateTexture0" });
@@ -172,20 +197,20 @@ public TextureHandle DenoiseRTR(RenderGraph renderGraph, in ReflectionDenoiserPa
passData.historySignal = builder.ReadWriteTexture(renderGraph.ImportTexture(historyBuffer));
passData.noisyToOutputSignal = builder.ReadWriteTexture(lightingTexture);
- builder.SetRenderFunc(
- (ReflectionDenoiserPassData data, RenderGraphContext ctx) =>
- {
- // We need to fill the structure that holds the various resources
- ReflectionDenoiserResources rtrDenoiseResources = new ReflectionDenoiserResources();
- rtrDenoiseResources.depthBuffer = data.depthBuffer;
- rtrDenoiseResources.normalBuffer = data.normalBuffer;
- rtrDenoiseResources.motionVectorBuffer = data.motionVectorBuffer;
- rtrDenoiseResources.intermediateBuffer0 = data.intermediateBuffer0;
- rtrDenoiseResources.intermediateBuffer1 = data.intermediateBuffer1;
- rtrDenoiseResources.historySignal = data.historySignal;
- rtrDenoiseResources.noisyToOutputSignal = data.noisyToOutputSignal;
- DenoiseBuffer(ctx.cmd, data.parameters, rtrDenoiseResources);
- });
+ builder.SetRenderFunc((ReflectionDenoiserPassData data, RenderGraphContext ctx) =>
+ {
+ // We need to fill the structure that holds the various resources
+ ReflectionDenoiserResources rtrDenoiseResources = new ReflectionDenoiserResources();
+ rtrDenoiseResources.depthBuffer = data.depthBuffer;
+ rtrDenoiseResources.historyDepth = data.historyDepth;
+ rtrDenoiseResources.normalBuffer = data.normalBuffer;
+ rtrDenoiseResources.motionVectorBuffer = data.motionVectorBuffer;
+ rtrDenoiseResources.intermediateBuffer0 = data.intermediateBuffer0;
+ rtrDenoiseResources.intermediateBuffer1 = data.intermediateBuffer1;
+ rtrDenoiseResources.historySignal = data.historySignal;
+ rtrDenoiseResources.noisyToOutputSignal = data.noisyToOutputSignal;
+ DenoiseBuffer(ctx.cmd, data.parameters, rtrDenoiseResources);
+ });
return passData.noisyToOutputSignal;
}
diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Deferred/RaytracingDeferred.compute b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Deferred/RaytracingDeferred.compute
index 3bf105004b8..b9ebdc3dd89 100644
--- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Deferred/RaytracingDeferred.compute
+++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Deferred/RaytracingDeferred.compute
@@ -55,9 +55,11 @@ void RAYTRACING_DEFERRED(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 gro
// Read the depth value
float depthValue = LOAD_TEXTURE2D_X(_DepthTexture, currentCoord).x;
+ // If this is a background pixel or an invalid ray, leave right away
if (depthValue == UNITY_RAW_FAR_CLIP_VALUE || LOAD_TEXTURE2D_X(_RaytracingDirectionBuffer, currentCoord).w < 0.0f)
return;
+ // If the distance is negative, this means it is a sky pixel or an unlit material
if (LOAD_TEXTURE2D_X(_RaytracingDistanceBuffer, currentCoord).x < 0.0)
{
float3 newSampleColor = clamp(LOAD_TEXTURE2D_X(_GBufferTexture3, currentCoord).rgb * GetCurrentExposureMultiplier(), 0.0, _RaytracingIntensityClamp)
@@ -68,12 +70,11 @@ void RAYTRACING_DEFERRED(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 gro
// First let's compute the position of the pixel from which the ray has been shot
PositionInputs sourcePosInput = GetPositionInput(currentCoord, _ScreenSize.zw, depthValue, UNITY_MATRIX_I_VP, GetWorldToViewMatrix(), 0);
- float3 positionWS = sourcePosInput.positionWS;
// Then compute the pos input of the intersection vertice
float3 rayDirection = LOAD_TEXTURE2D_X(_RaytracingDirectionBuffer, currentCoord).xyz;
float rayDistance = LOAD_TEXTURE2D_X(_RaytracingDistanceBuffer, currentCoord).x;
- float3 intersectionPositionWS = positionWS + rayDirection * rayDistance;
+ float3 intersectionPositionWS = sourcePosInput.positionWS + rayDirection * rayDistance;
PositionInputs posInput = GetPositionInput(currentCoord, _ScreenSize.zw, intersectionPositionWS);
@@ -104,7 +105,7 @@ void RAYTRACING_DEFERRED(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 gro
float3 finalColor = (diffuseLighting + specularLighting);
// Apply fog attenuation
- ApplyFogAttenuation(positionWS, rayDirection, rayDistance, finalColor, true);
+ ApplyFogAttenuation(sourcePosInput.positionWS, rayDirection, rayDistance, finalColor, true);
// Expose, clamp and inverse exposure
finalColor = clamp(finalColor * GetCurrentExposureMultiplier(), 0.0, _RaytracingIntensityClamp) * (_RaytracingPreExposition ? 1.0 : GetInverseCurrentExposureMultiplier());
_RaytracingLitBufferRW[COORD_TEXTURE2D_X(currentCoord)] = float4(finalColor, 1.0);
diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Deferred/RaytracingGBuffer.raytrace b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Deferred/RaytracingGBuffer.raytrace
index b964e85ffe2..377db8ab84b 100644
--- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Deferred/RaytracingGBuffer.raytrace
+++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Deferred/RaytracingGBuffer.raytrace
@@ -64,60 +64,59 @@ void MissShaderGBuffer(inout RayIntersectionGBuffer rayIntersection : SV_RayPayl
rayIntersection.t = -1.0;
}
-[shader("raygeneration")]
-void RayGenGBuffer()
+struct PixelCoordinates
{
- // Grab the dimensions of the current raytrace shader
- uint3 LaunchIndex = DispatchRaysIndex();
- uint3 LaunchDim = DispatchRaysDimensions();
-
- UNITY_XR_ASSIGN_VIEW_INDEX(LaunchIndex.z);
-
- // Pixel coordinate of the current pixel
- uint2 currentPixelCoord = uint2(LaunchIndex.x, LaunchIndex.y);
-
- // Pick the right pixel if in half res
- if (_RaytracingHalfResolution)
- {
- currentPixelCoord *=2;
- }
+ // Cordinates that the shader will write to
+ uint2 outputCoords;
+ // Coordinates from where the ray direction is read
+ uint2 directionCoords;
+ // Coordinates from which the depth and normal is read
+ uint2 geometryCoords;
+};
+
+void TraceGBuffer(PixelCoordinates coords)
+{
+ _RaytracingDistanceBuffer[COORD_TEXTURE2D_X(coords.outputCoords)] = _RaytracingRayMaxLength;
+ _GBufferTexture0RW[COORD_TEXTURE2D_X(coords.outputCoords)] = float4(1.0, 0.0, 0.5, 1.0);
+ _GBufferTexture1RW[COORD_TEXTURE2D_X(coords.outputCoords)] = float4(0.0, 0.0, 0.0, 0.0);
+ _GBufferTexture2RW[COORD_TEXTURE2D_X(coords.outputCoords)] = float4(0.0, 0.0, 0.0, 0.0);
+ _GBufferTexture3RW[COORD_TEXTURE2D_X(coords.outputCoords)] = float4(0.0, 0.0, 0.0, 0.0);
// Read the depth value
- float depthValue = _DepthTexture[COORD_TEXTURE2D_X(currentPixelCoord)].x;
+ float depthValue = LOAD_TEXTURE2D_X(_DepthTexture, coords.geometryCoords);
+
+ // Read the direction
+ float4 direction = LOAD_TEXTURE2D_X(_RaytracingDirectionBuffer, coords.directionCoords);
// If this is the background, or UnL is null or this pixel has been flagged as invalid, no
- if (depthValue == UNITY_RAW_FAR_CLIP_VALUE || _RaytracingDirectionBuffer[COORD_TEXTURE2D_X(currentPixelCoord)].w < 0.0)
+ if (depthValue == UNITY_RAW_FAR_CLIP_VALUE || direction.w < 0.0)
{
- _RaytracingDistanceBuffer[COORD_TEXTURE2D_X(currentPixelCoord)] = _RaytracingRayMaxLength;
- _GBufferTexture0RW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(0.0, 0.0, 0.0, 0.0);
- _GBufferTexture1RW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(0.0, 0.0, 0.0, 0.0);
- _GBufferTexture2RW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(0.0, 0.0, 0.0, 0.0);
- _GBufferTexture3RW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(0.0, 0.0, 0.0, 0.0);
+ _RaytracingDistanceBuffer[COORD_TEXTURE2D_X(coords.outputCoords)] = _RaytracingRayMaxLength;
+ _GBufferTexture0RW[COORD_TEXTURE2D_X(coords.outputCoords)] = float4(0.0, 0.0, 0.0, 0.0);
+ _GBufferTexture1RW[COORD_TEXTURE2D_X(coords.outputCoords)] = float4(0.0, 0.0, 0.0, 0.0);
+ _GBufferTexture2RW[COORD_TEXTURE2D_X(coords.outputCoords)] = float4(0.0, 0.0, 0.0, 0.0);
+ _GBufferTexture3RW[COORD_TEXTURE2D_X(coords.outputCoords)] = float4(0.0, 0.0, 0.0, 0.0);
return;
}
// Compute the position input structure
- PositionInputs posInput = GetPositionInput(currentPixelCoord, _ScreenSize.zw, depthValue, UNITY_MATRIX_I_VP, GetWorldToViewMatrix(), 0);
+ PositionInputs posInput = GetPositionInput(coords.geometryCoords, _ScreenSize.zw, depthValue, UNITY_MATRIX_I_VP, GetWorldToViewMatrix(), 0);
+
// Decode the world space normal
NormalData normalData;
- DecodeFromNormalBuffer(currentPixelCoord, normalData);
+ DecodeFromNormalBuffer(coords.geometryCoords, normalData);
// Keep track of the new ray in the counters
if (_RayCountEnabled > 0)
{
- uint3 counterIdx = uint3(currentPixelCoord, INDEX_TEXTURE2D_ARRAY_X(_RayCountType));
+ uint3 counterIdx = uint3(coords.outputCoords, INDEX_TEXTURE2D_ARRAY_X(_RayCountType));
_RayCountTexture[counterIdx] = _RayCountTexture[counterIdx] + 1;
}
- // Read the ray distance
- float3 rayDirection = _RaytracingDirectionBuffer[COORD_TEXTURE2D_X(currentPixelCoord)].xyz;
-
- float3 rayOrigin = posInput.positionWS + normalData.normalWS * _RaytracingRayBias;
-
// Create the ray descriptor for this pixel
RayDesc rayDescriptor;
- rayDescriptor.Origin = rayOrigin;
- rayDescriptor.Direction = rayDirection;
+ rayDescriptor.Origin = posInput.positionWS + normalData.normalWS * _RaytracingRayBias;;
+ rayDescriptor.Direction = direction.xyz;
rayDescriptor.TMin = 0.0;
rayDescriptor.TMax = _RaytracingRayMaxLength;
@@ -133,11 +132,41 @@ void RayGenGBuffer()
TraceRay(_RaytracingAccelerationStructure, RAY_FLAG_CULL_BACK_FACING_TRIANGLES, _RayTracingLayerMask, 0, 1, 0, rayDescriptor, rayIntersection);
// Output the gbuffer
- _GBufferTexture0RW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(LinearToSRGB(rayIntersection.gbuffer0.xyz), rayIntersection.gbuffer0.w);
- _GBufferTexture1RW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(rayIntersection.gbuffer1);
- _GBufferTexture2RW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(rayIntersection.gbuffer2);
- _GBufferTexture3RW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(rayIntersection.gbuffer3);
- _RaytracingDistanceBuffer[COORD_TEXTURE2D_X(currentPixelCoord)] = rayIntersection.t;
+ _GBufferTexture0RW[COORD_TEXTURE2D_X(coords.outputCoords)] = float4(LinearToSRGB(rayIntersection.gbuffer0.xyz), rayIntersection.gbuffer0.w);
+ _GBufferTexture1RW[COORD_TEXTURE2D_X(coords.outputCoords)] = float4(rayIntersection.gbuffer1);
+ _GBufferTexture2RW[COORD_TEXTURE2D_X(coords.outputCoords)] = float4(rayIntersection.gbuffer2);
+ _GBufferTexture3RW[COORD_TEXTURE2D_X(coords.outputCoords)] = float4(rayIntersection.gbuffer3);
+ _RaytracingDistanceBuffer[COORD_TEXTURE2D_X(coords.outputCoords)] = rayIntersection.t;
+}
+
+[shader("raygeneration")]
+void RayGenGBuffer()
+{
+ // Grab the dimensions of the current raytrace shader
+ uint3 LaunchIndex = DispatchRaysIndex();
+ uint3 LaunchDim = DispatchRaysDimensions();
+
+ UNITY_XR_ASSIGN_VIEW_INDEX(LaunchIndex.z);
+
+ // Pixel coordinate of the current pixel
+ uint2 currentPixelCoord = uint2(LaunchIndex.x, LaunchIndex.y);
+
+ // For the full res ray tracing, everything is read from the same pixel coordinates
+ PixelCoordinates coords;
+ coords.outputCoords = currentPixelCoord;
+ coords.directionCoords = currentPixelCoord;
+ coords.geometryCoords = currentPixelCoord;
+
+ // For the half res coordinates, we need to adjust the positions
+ if (_RaytracingHalfResolution)
+ {
+ coords.geometryCoords = ComputeSourceCoordinates(coords.outputCoords, _RaytracingFrameIndex);
+ coords.outputCoords *= 2;
+ coords.directionCoords *= 2;
+ }
+
+ // Trace and output the gbuffer
+ TraceGBuffer(coords);
}
StructuredBuffer _RayBinResult;
@@ -170,68 +199,18 @@ void RayGenGBufferBinned()
if (localTileIndex > _RayBinSizeResult[tileIndex])
return;
- _RaytracingDistanceBuffer[COORD_TEXTURE2D_X(currentPixelCoord)] = _RaytracingRayMaxLength;
- _GBufferTexture0RW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(1.0, 0.0, 0.5, 1.0);
- _GBufferTexture1RW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(0.0, 0.0, 0.0, 0.0);
- _GBufferTexture2RW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(0.0, 0.0, 0.0, 0.0);
- _GBufferTexture3RW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(0.0, 0.0, 0.0, 0.0);
-
-
- // Read the depth value
- float depthValue = _DepthTexture[COORD_TEXTURE2D_X(currentPixelCoord)].x;
-
- // If this is the background, or UnL is null or this pixel has been flagged as invalid, no
- if (depthValue == UNITY_RAW_FAR_CLIP_VALUE || _RaytracingDirectionBuffer[COORD_TEXTURE2D_X(currentPixelCoord)].w < 0.0)
- {
- _RaytracingDistanceBuffer[COORD_TEXTURE2D_X(currentPixelCoord)] = _RaytracingRayMaxLength;
- _GBufferTexture0RW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(0.0, 0.0, 0.0, 0.0);
- _GBufferTexture1RW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(0.0, 0.0, 0.0, 0.0);
- _GBufferTexture2RW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(0.0, 0.0, 0.0, 0.0);
- _GBufferTexture3RW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(0.0, 0.0, 0.0, 0.0);
- return;
- }
-
- // Compute the position input structure
- PositionInputs posInput = GetPositionInput(currentPixelCoord, _ScreenSize.zw, depthValue, UNITY_MATRIX_I_VP, GetWorldToViewMatrix(), 0);
- float distanceToCamera = length(posInput.positionWS);
- // Decode the world space normal
- NormalData normalData;
- DecodeFromNormalBuffer(currentPixelCoord, normalData);
-
- // Keep track of the new ray in the counters
- if (_RayCountEnabled > 0)
+ // For the full res ray tracing, everything is read from the same pixel coordinates
+ PixelCoordinates coords;
+ coords.outputCoords = currentPixelCoord;
+ coords.directionCoords = currentPixelCoord;
+ coords.geometryCoords = currentPixelCoord;
+ // For the half res coordinates, we need to adjust the positions
+ if (_RaytracingHalfResolution)
{
- uint3 counterIdx = uint3(currentPixelCoord, INDEX_TEXTURE2D_ARRAY_X(_RayCountType));
- _RayCountTexture[counterIdx] = _RayCountTexture[counterIdx] + 1;
+ coords.geometryCoords = ComputeSourceCoordinates(coords.outputCoords * 0.5, _RaytracingFrameIndex);
+ // For the output and direction coords, the ray binning should make sure we are pointing at the right position
}
- // Read the ray distance
- float3 rayDirection = _RaytracingDirectionBuffer[COORD_TEXTURE2D_X(currentPixelCoord)].xyz;
-
- float3 rayOrigin = posInput.positionWS + normalData.normalWS * _RaytracingRayBias;
-
- // Create the ray descriptor for this pixel
- RayDesc rayDescriptor;
- rayDescriptor.Origin = rayOrigin;
- rayDescriptor.Direction = rayDirection;
- rayDescriptor.TMin = 0.0;
- rayDescriptor.TMax = _RaytracingRayMaxLength;
-
- // Create and init the RayIntersection structure for this
- RayIntersectionGBuffer rayIntersection;
- rayIntersection.t = -1.0;
- rayIntersection.gbuffer0 = float4(0.0, 0.0, 0.0, 0.0);
- rayIntersection.gbuffer1 = float4(0.0, 0.0, 0.0, 0.0);
- rayIntersection.gbuffer2 = float4(0.0, 0.0, 0.0, 0.0);
- rayIntersection.gbuffer3 = float4(0.0, 0.0, 0.0, 0.0);
-
- // Evaluate the ray visibility term and PDF
- TraceRay(_RaytracingAccelerationStructure, RAY_FLAG_CULL_BACK_FACING_TRIANGLES, _RayTracingLayerMask, 0, 1, 0, rayDescriptor, rayIntersection);
-
- // Output the gbuffer
- _GBufferTexture0RW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(LinearToSRGB(rayIntersection.gbuffer0.xyz), rayIntersection.gbuffer0.w);
- _GBufferTexture1RW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(rayIntersection.gbuffer1);
- _GBufferTexture2RW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(rayIntersection.gbuffer2);
- _GBufferTexture3RW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(rayIntersection.gbuffer3);
- _RaytracingDistanceBuffer[COORD_TEXTURE2D_X(currentPixelCoord)] = rayIntersection.t;
+ // Trace and output the gbuffer
+ TraceGBuffer(coords);
}
diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Denoising/ReflectionDenoiser.compute b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Denoising/ReflectionDenoiser.compute
index 2a9a2dc439d..5f35c1bd5f2 100644
--- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Denoising/ReflectionDenoiser.compute
+++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Denoising/ReflectionDenoiser.compute
@@ -1,11 +1,12 @@
#pragma only_renderers d3d11
-#pragma kernel TemporalAccumulation
+#pragma kernel TemporalAccumulationFullRes TEMPORAL_ACCUMULATION=TemporalAccumulationFullRes
+#pragma kernel TemporalAccumulationHalfRes TEMPORAL_ACCUMULATION=TemporalAccumulationHalfRes HALF_RESOLUTION
#pragma kernel CopyHistory
-#pragma kernel BilateralFilterH BILATERAL_FILTER=BilateralFilterH
-#pragma kernel BilateralFilterV BILATERAL_FILTER=BilateralFilterV FINAL_PASS
-
-#pragma only_renderers d3d11
+#pragma kernel BilateralFilterH_FR BILATERAL_FILTER=BilateralFilterH_FR
+#pragma kernel BilateralFilterV_FR BILATERAL_FILTER=BilateralFilterV_FR FINAL_PASS
+#pragma kernel BilateralFilterH_HR BILATERAL_FILTER=BilateralFilterH_HR HALF_RESOLUTION
+#pragma kernel BilateralFilterV_HR BILATERAL_FILTER=BilateralFilterV_HR FINAL_PASS HALF_RESOLUTION
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
@@ -17,6 +18,8 @@
#define BILATERAL_ROUGHNESS
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Denoising/BilateralFilter.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/ShaderVariablesRaytracing.cs.hlsl"
+#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingCommon.hlsl"
+
// Tile size of this compute
#define REFLECTION_FILTER_TILE_SIZE 8
@@ -24,99 +27,164 @@
// Thereshold at which we decide to reject the reflection history
#define REFLECTION_HISTORY_REJECTION_THRESHOLD 0.75
+// Threshold at which we go from accumulation to clampiong
+#define SMOOTHNESS_ACCUMULATION_THRESHOLD 0.5
+// Input textures
TEXTURE2D_X(_DenoiseInputTexture);
TEXTURE2D_X(_HistoryBuffer);
-RW_TEXTURE2D_X(float4, _DenoiseOutputTextureRW);
+TEXTURE2D_X(_HistoryDepthTexture);
// Value that tells us if the current history should be discarded based on scene-level data
float _HistoryValidity;
+// Current inverse resolution of the history buffer
+float2 _HistoryBufferSize;
+// Resolution at which the effect is rendered (Half the _Screensize if half res)
+float4 _CurrentEffectResolution;
+float _PixelSpreadAngleTangent;
+int _AffectSmoothSurfaces;
int _SingleReflectionBounce;
+// Output texture
+RW_TEXTURE2D_X(float4, _DenoiseOutputTextureRW);
+RW_TEXTURE2D_X(float, _SampleCountTextureRW);
+
[numthreads(REFLECTION_FILTER_TILE_SIZE, REFLECTION_FILTER_TILE_SIZE, 1)]
-void TemporalAccumulation(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 groupThreadId : SV_GroupThreadID, uint2 groupId : SV_GroupID)
+void TEMPORAL_ACCUMULATION(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 groupThreadId : SV_GroupThreadID, uint2 groupId : SV_GroupID)
{
UNITY_XR_ASSIGN_VIEW_INDEX(dispatchThreadId.z);
// Fetch the current pixel coordinate
- uint2 centerCoord = groupId * REFLECTION_FILTER_TILE_SIZE + groupThreadId;
+ uint2 mainCoord = groupId * REFLECTION_FILTER_TILE_SIZE + groupThreadId;
- // If the history is flagged as invalid, write the current value and leave right away
- if (_HistoryValidity == 0.0)
+ // The source coordinate for the normal and depth depends if we are in half res or not
+ #ifdef HALF_RESOLUTION
+ uint2 geometryCoords = ComputeSourceCoordinates(mainCoord, _RaytracingFrameIndex);
+ #else
+ uint2 geometryCoords = mainCoord;
+ #endif
+
+ // Fetch the depth
+ float depth = LOAD_TEXTURE2D_X(_DepthTexture, geometryCoords).x;
+
+ // If the history is flagged as invalid or this is a a background pixel write the noisy value and leave right away
+ if (_HistoryValidity == 0.0 || depth == UNITY_RAW_FAR_CLIP_VALUE)
{
- _DenoiseOutputTextureRW[COORD_TEXTURE2D_X(centerCoord)] = LOAD_TEXTURE2D_X(_DenoiseInputTexture, centerCoord);
+ _DenoiseOutputTextureRW[COORD_TEXTURE2D_X(mainCoord)] = LOAD_TEXTURE2D_X(_DenoiseInputTexture, mainCoord);
+ _SampleCountTextureRW[COORD_TEXTURE2D_X(mainCoord)] = 0;
return;
}
- float depth = LOAD_TEXTURE2D_X(_DepthTexture, centerCoord).r;
- PositionInputs posInputs = GetPositionInput(centerCoord, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, GetWorldToViewMatrix());
-
- float2 closest = GetClosestFragmentCompute(posInputs.positionSS);
+ // Real the normal data for this pixel
+ NormalData normalData;
+ DecodeFromNormalBuffer(geometryCoords, normalData);
+ // Read the depth and velocity vectors
float2 velocity;
- DecodeMotionVector(LOAD_TEXTURE2D_X(_CameraMotionVectorsTexture, closest), velocity);
- float velocityLength = length(velocity);
+ DecodeMotionVector(LOAD_TEXTURE2D_X(_CameraMotionVectorsTexture, geometryCoords), velocity);
- float2 uv = posInputs.positionNDC;
- float3 color = Fetch(_DenoiseInputTexture, uv, 0.0, _RTHandleScale.xy) * GetCurrentExposureMultiplier();
- float4 historyRaw = Fetch4(_HistoryBuffer, posInputs.positionNDC - velocity, 0.0, _RTHandleScaleHistory.xy);
+ // Compute the current and history UV coordinates
+ float2 currentUV = (mainCoord + 0.5f) * _ScreenSize.zw;
+ float2 historyCoordinate = ((float2)(mainCoord + 0.5f) - velocity * _CurrentEffectResolution.xy);
+ float2 historyUV = historyCoordinate * _HistoryBufferSize.xy;
+
+ // Fetch the current and history values and apply the exposition to it.
+ float3 color = Fetch(_DenoiseInputTexture, currentUV, 0.0, _RTHandleScale.xy) * GetCurrentExposureMultiplier();
+ float4 historyRaw = Fetch4(_HistoryBuffer, historyUV, 0.0, 1.0);
float3 history = historyRaw.xyz * GetCurrentExposureMultiplier();
- // If the validity of the history is lower than a given threshold, we do not want to use it
- if (historyRaw.w < REFLECTION_HISTORY_REJECTION_THRESHOLD)
+ if (_AffectSmoothSurfaces == 0 && _SingleReflectionBounce == 1 && PerceptualRoughnessToPerceptualSmoothness(normalData.perceptualRoughness) > 0.99)
{
- _DenoiseOutputTextureRW[COORD_TEXTURE2D_X(centerCoord)] = float4(color * GetInverseCurrentExposureMultiplier(), LOAD_TEXTURE2D_X(_DenoiseInputTexture, centerCoord).w);
+ _DenoiseOutputTextureRW[COORD_TEXTURE2D_X(mainCoord)] = float4(color * GetInverseCurrentExposureMultiplier(), LOAD_TEXTURE2D_X(_DenoiseInputTexture, mainCoord).w);
+ _SampleCountTextureRW[COORD_TEXTURE2D_X(mainCoord)] = 1;
return;
}
- // Decode the normal data
- NormalData normalData;
- DecodeFromNormalBuffer(centerCoord, normalData);
- // If this is close to a perfectly smooth surface, we do not want to use the history (it introduced unwanted ghosting)
- if (_SingleReflectionBounce == 1 && PerceptualRoughnessToPerceptualSmoothness(normalData.perceptualRoughness) > 0.99)
+ float sampleCount = historyRaw.w;
+ float3 result;
+ if (normalData.perceptualRoughness > SMOOTHNESS_ACCUMULATION_THRESHOLD)
{
- _DenoiseOutputTextureRW[COORD_TEXTURE2D_X(centerCoord)] = float4(color * GetInverseCurrentExposureMultiplier(), LOAD_TEXTURE2D_X(_DenoiseInputTexture, centerCoord).w);
- return;
- }
+ bool canBeReprojected = true;
- float3 topLeft = Fetch(_DenoiseInputTexture, uv, -RADIUS, _RTHandleScale.xy) * GetCurrentExposureMultiplier();
- float3 bottomRight = Fetch(_DenoiseInputTexture, uv, RADIUS, _RTHandleScale.xy) * GetCurrentExposureMultiplier();
+ // If the pixel was outside of the screen during the previous frame, invalidate the history
+ if (historyCoordinate.x >= _CurrentEffectResolution.x || historyCoordinate.x < 0 || historyCoordinate.y >= _CurrentEffectResolution.y || historyCoordinate.y < 0)
+ canBeReprojected = false;
- float3 corners = 4.0 * (topLeft + bottomRight) - 2.0 * color;
+ #ifdef HALF_RESOLUTION
+ float2 historyDepthUV = ((float2)(mainCoord * 2.0 + 0.5f) - velocity * _CurrentEffectResolution.xy * 2.0f) * _HistoryBufferSize.xy;
+ #else
+ float2 historyDepthUV = historyUV;
+ #endif
+
+ // Fetch the depth of the history pixel. If the history position was a background point, invalidate the history
+ float historyDepth = SAMPLE_TEXTURE2D_X_LOD(_HistoryDepthTexture, s_linear_clamp_sampler, historyDepthUV, 0).r;
+ if (historyDepth == UNITY_RAW_FAR_CLIP_VALUE)
+ canBeReprojected = false;
- color = clamp(color, 0.0, CLAMP_MAX);
+ // Compute the world space position
+ PositionInputs posInput = GetPositionInput(geometryCoords, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V);
- float3 average = FastTonemap((corners + color) / 7.0);
+ // Compute the world space position (from previous frame)
+ float3 historyPositionWS = ComputeWorldSpacePosition(posInput.positionNDC - velocity, historyDepth, UNITY_MATRIX_PREV_I_VP);
- topLeft = FastTonemap(topLeft);
- bottomRight = FastTonemap(bottomRight);
- color = FastTonemap(color);
+ // Is it too far from the current position?
+ if (length(historyPositionWS - posInput.positionWS) > 0.1)
+ canBeReprojected = false;
- float colorLuma = Luminance(color);
- float averageLuma = Luminance(average);
- float nudge = lerp(4.0, 0.25, saturate(velocityLength * 100.0)) * abs(averageLuma - colorLuma);
+ if (canBeReprojected && sampleCount != 0.0)
+ {
+ float accumulationFactor = sampleCount >= 8.0 ? 0.93 : (sampleCount / (sampleCount + 1.0));
+ result = (color * (1.0 - accumulationFactor) + history * accumulationFactor);
+ sampleCount = max(sampleCount + 1.0, 8.0);
+ }
+ else
+ {
+ result = color;
+ sampleCount = 1.0;
+ }
+ }
+ else
+ {
+ float3 topLeft = Fetch(_DenoiseInputTexture, currentUV, -RADIUS, _RTHandleScale.xy) * GetCurrentExposureMultiplier();
+ float3 bottomRight = Fetch(_DenoiseInputTexture, currentUV, RADIUS, _RTHandleScale.xy) * GetCurrentExposureMultiplier();
- float3 minimum = min(bottomRight, topLeft) - nudge;
- float3 maximum = max(topLeft, bottomRight) + nudge;
+ float3 corners = 4.0 * (topLeft + bottomRight) - 2.0 * color;
- history = FastTonemap(history);
+ color = clamp(color, 0.0, CLAMP_MAX);
- // Clip history samples
- history = DirectClipToAABB(history, minimum, maximum);
+ float3 average = FastTonemap((corners + color) / 7.0);
- // Blend color & history
- // Feedback weight from unbiased luminance diff (Timothy Lottes)
- float historyLuma = Luminance(history);
- float diff = abs(colorLuma - historyLuma) / Max3(colorLuma, historyLuma, 0.2);
- float weight = 1.0 - diff;
- const float feedbackMin = 0.96;
- const float feedbackMax = 0.91;
- float feedback = lerp(feedbackMin, feedbackMax, weight * weight);
+ topLeft = FastTonemap(topLeft);
+ bottomRight = FastTonemap(bottomRight);
+ color = FastTonemap(color);
+ float colorLuma = Luminance(color);
+ float averageLuma = Luminance(average);
+ float velocityLength = length(velocity);
+ float nudge = lerp(4.0, 0.25, saturate(velocityLength * 100.0)) * abs(averageLuma - colorLuma);
- color = FastTonemapInvert(lerp(color, history, feedback));
- color = clamp(color, 0.0, CLAMP_MAX);
+ float3 minimum = min(bottomRight, topLeft) - nudge;
+ float3 maximum = max(topLeft, bottomRight) + nudge;
- _DenoiseOutputTextureRW[COORD_TEXTURE2D_X(centerCoord)] = float4(color * GetInverseCurrentExposureMultiplier(), LOAD_TEXTURE2D_X(_DenoiseInputTexture, centerCoord).w);
+ history = FastTonemap(history);
+
+ // Clip history samples
+ history = DirectClipToAABB(history, minimum, maximum);
+
+ // Blend color & history
+ // Feedback weight from unbiased luminance diff (Timothy Lottes)
+ float historyLuma = Luminance(history);
+ float diff = abs(colorLuma - historyLuma) / Max3(colorLuma, historyLuma, 0.2);
+ float weight = 1.0 - diff;
+ const float feedbackMin = 0.96;
+ const float feedbackMax = 0.91;
+ float feedback = lerp(feedbackMin, feedbackMax, weight * weight);
+
+ color = FastTonemapInvert(lerp(color, history, feedback));
+ result = clamp(color, 0.0, CLAMP_MAX);
+ }
+
+ _DenoiseOutputTextureRW[COORD_TEXTURE2D_X(mainCoord)] = float4(result * GetInverseCurrentExposureMultiplier(), LOAD_TEXTURE2D_X(_DenoiseInputTexture, mainCoord).w);
+ _SampleCountTextureRW[COORD_TEXTURE2D_X(mainCoord)] = sampleCount;
}
[numthreads(REFLECTION_FILTER_TILE_SIZE, REFLECTION_FILTER_TILE_SIZE, 1)]
@@ -127,14 +195,16 @@ void CopyHistory(uint3 dispatchThreadId : SV_DispatchThreadID)
if (any(dispatchThreadId.xy > uint2(_ScreenSize.xy)))
return; // Out of bounds, discard
- float4 currentColor = _DenoiseInputTexture[COORD_TEXTURE2D_X(dispatchThreadId.xy)];
+ float4 currentColor = LOAD_TEXTURE2D_X(_DenoiseInputTexture, dispatchThreadId.xy);
// We need to apply a step function on the blend factor to evaluate the validity of the history (if it is stricly higher than 0.0 then its valid)
- _DenoiseOutputTextureRW[COORD_TEXTURE2D_X(dispatchThreadId.xy)] = float4(currentColor.xyz, currentColor.w > 0.0 ? 1.0 : 0.0);
+ _DenoiseOutputTextureRW[COORD_TEXTURE2D_X(dispatchThreadId.xy)] = float4(currentColor.xyz, _SampleCountTextureRW[COORD_TEXTURE2D_X(dispatchThreadId.xy)].x);
}
int _DenoiserFilterRadius;
TEXTURE2D(_ReflectionFilterMapping);
+#define BILATERAL_FILTER_SIGMA 0.9
+
// Separated bilateral filter (two passes, each with 2*Radius taps)
[numthreads(REFLECTION_FILTER_TILE_SIZE, REFLECTION_FILTER_TILE_SIZE, 1)]
void BILATERAL_FILTER(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 groupThreadId : SV_GroupThreadID, uint2 groupId : SV_GroupID)
@@ -151,8 +221,13 @@ void BILATERAL_FILTER(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 groupT
const uint2 passIncr = uint2(0, 1);
#endif
+ #if HALF_RESOLUTION
+ uint2 geometrCoords = ComputeSourceCoordinates(centerCoord, _RaytracingFrameIndex);
+ #else
+ uint2 geometrCoords = centerCoord;
+ #endif
// Tap the central pixel coordinates
- const BilateralData center = TapBilateralData(centerCoord);
+ const BilateralData center = TapBilateralData(geometrCoords);
// Compute the effective radius we should be using for the filtering
const float3 viewWS = GetWorldSpaceNormalizeViewDir(center.position);
@@ -163,7 +238,7 @@ void BILATERAL_FILTER(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 groupT
#else
const float radius = _DenoiserFilterRadius * radiusScale.y;
#endif
- const float sigma = 0.5 * radius;
+ const float sigma = radius * BILATERAL_FILTER_SIGMA;
const int effectiveRadius = min(sigma * 2.0, radius);
// Store the intermediate result
@@ -183,8 +258,13 @@ void BILATERAL_FILTER(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 groupT
if (tapCoord.x >= _ScreenSize.x || tapCoord.x < 0 || tapCoord.y >= _ScreenSize.y || tapCoord.y < 0)
continue;
+ #if HALF_RESOLUTION
+ uint2 tapGeometryCoords = ComputeSourceCoordinates(tapCoord, _RaytracingFrameIndex);
+ #else
+ uint2 tapGeometryCoords = tapCoord;
+ #endif
// Compute the weight (skip computation for the center)
- const BilateralData tapData = TapBilateralData(tapCoord);
+ const BilateralData tapData = TapBilateralData(tapGeometryCoords);
float w = r ? gaussian(r, sigma) * ComputeBilateralWeight(center, tapData) : 1.0;
w = _RaytracingReflectionMinSmoothness > PerceptualRoughnessToPerceptualSmoothness(tapData.roughness) ? 0.0 : w;
colorSum += LOAD_TEXTURE2D_X(_DenoiseInputTexture, tapCoord).xyz * w;
diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/IndirectDiffuse/RaytracingIndirectDiffuse.compute b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/IndirectDiffuse/RaytracingIndirectDiffuse.compute
index 88fd8ac1b93..68023c0a978 100644
--- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/IndirectDiffuse/RaytracingIndirectDiffuse.compute
+++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/IndirectDiffuse/RaytracingIndirectDiffuse.compute
@@ -41,16 +41,11 @@ void RaytracingIndirectDiffuseHalfRes(uint3 dispatchThreadId : SV_DispatchThread
// Compute the pixel position to process
uint2 halfResCoord = groupId * RAYTRACING_INDIRECT_DIFFUSE_TILE_SIZE + groupThreadId;
- // Pick which subpixel we will be launching our effects from
- float subPixelSample = GetBNDSequenceSample(halfResCoord, _RaytracingFrameIndex, 3);
- int subPixel = clamp((int)(subPixelSample * 4.0), 0, 3);
- uint2 shift = HalfResIndexToCoordinateShift[subPixel];
-
// Pixel where we will store the result of the raytracing
uint2 outputCoord = halfResCoord * 2;
// Pixel coordinate in full res of the pixel that we will be using for our computation
- uint2 sourceCoord = outputCoord + shift;
+ uint2 sourceCoord = ComputeSourceCoordinates(halfResCoord, _RaytracingFrameIndex);
// Read the depth value
float depthValue = LOAD_TEXTURE2D_X(_DepthTexture, sourceCoord).r;
@@ -83,7 +78,6 @@ void RaytracingIndirectDiffuseHalfRes(uint3 dispatchThreadId : SV_DispatchThread
_RaytracingDirectionBuffer[COORD_TEXTURE2D_X(outputCoord)] = float4(sampleDir, 1.0 / samplePDF);
}
-
[numthreads(RAYTRACING_INDIRECT_DIFFUSE_TILE_SIZE, RAYTRACING_INDIRECT_DIFFUSE_TILE_SIZE, 1)]
void RaytracingIndirectDiffuseFullRes(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 groupThreadId : SV_GroupThreadID, uint2 groupId : SV_GroupID)
{
@@ -111,7 +105,7 @@ void RaytracingIndirectDiffuseFullRes(uint3 dispatchThreadId : SV_DispatchThread
NormalData normalData;
DecodeFromNormalBuffer(currentCoord, normalData);
- // Generate the new sample (follwing values of the sequence)
+ // Generate the new sample (following values of the sequence)
float2 sample;
sample.x = GetBNDSequenceSample(currentCoord, _RaytracingFrameIndex, 0);
sample.y = GetBNDSequenceSample(currentCoord, _RaytracingFrameIndex, 1);
@@ -201,10 +195,8 @@ void INDIRECT_DIFFUSE_INTEGRATION_UPSCALE(uint3 dispatchThreadId : SV_DispatchTh
float4 sampleColor = LOAD_TEXTURE2D_X(_IndirectDiffuseTexture, sampleCoord);
// Compute the position of the actual source pixel
- uint subPixel = clamp(floor(sampleColor.w * 4.0f), 0, 3);
- uint2 shift = HalfResIndexToCoordinateShift[subPixel];
#ifdef HALF_RESOLUTION
- uint2 actualSourceCoord = sampleCoord + shift;
+ uint2 actualSourceCoord = ComputeSourceCoordinates(sampleCoord / 2, _RaytracingFrameIndex);
#else
uint2 actualSourceCoord = sampleCoord;
#endif
diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingCommon.hlsl b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingCommon.hlsl
index 05d569609e4..6ae0d642877 100644
--- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingCommon.hlsl
+++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingCommon.hlsl
@@ -1,5 +1,8 @@
#ifndef RAY_TRACING_COMMON_HLSL
#define RAY_TRACING_COMMON_HLSL
+
+#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingSampling.hlsl"
+
// This array converts an index to the local coordinate shift of the half resolution texture
static const uint2 HalfResIndexToCoordinateShift[4] = { uint2(0,0), uint2(1, 0), uint2(0, 1), uint2(1, 1) };
@@ -49,4 +52,9 @@ struct StandardBSDFData
uint isUnlit;
};
+// This function defines what is the source pixel from where we should read the depth and normal for rendering in half resolution
+uint2 ComputeSourceCoordinates(uint2 halfResCoord, int frameIndex)
+{
+ return halfResCoord * 2;
+}
#endif // RAY_TRACING_COMMON_HLSL
diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingReflectionFilter.compute b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingReflectionFilter.compute
index 79641f2185d..40968601ced 100644
--- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingReflectionFilter.compute
+++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingReflectionFilter.compute
@@ -1,5 +1,6 @@
-#pragma kernel ReflectionIntegrationUpscaleHalfRes REFLECTION_INTEGRATION_UPSCALE=ReflectionIntegrationUpscaleHalfRes HALF_RESOLUTION
-#pragma kernel ReflectionIntegrationUpscaleFullRes REFLECTION_INTEGRATION_UPSCALE=ReflectionIntegrationUpscaleFullRes
+#pragma kernel ReflectionRescaleAndAdjustWeight
+#pragma kernel ReflectionAdjustWeight
+#pragma kernel ReflectionUpscale
#pragma only_renderers d3d11
@@ -10,48 +11,85 @@
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Builtin/BuiltinData.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/BSDF.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/PreIntegratedFGD/PreIntegratedFGD.hlsl"
+#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/BilateralUpsample.hlsl"
+#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceLighting.hlsl"
// Raytracing Includes
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/OnlineVariance.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingCommon.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/ShaderVariablesRaytracing.hlsl"
-#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceLighting.hlsl"
// Tile size of this compute
#define RAYTRACING_REFLECTION_TILE_SIZE 8
+// #pragma enable_d3d11_debug_symbols
+
// Input textures for the spatial filtering
-Texture2DArray _BlueNoiseTexture;
TEXTURE2D_X(_DepthTexture);
TEXTURE2D_X(_SsrLightingTextureRW);
-TEXTURE2D_X(_SsrHitPointTexture);
+TEXTURE2D_X(_DirectionPDFTexture);
TEXTURE2D_X(_SsrClearCoatMaskTexture);
// Output Textures for the spatial filtering
RW_TEXTURE2D_X(float4, _RaytracingReflectionTexture);
-int _SpatialFilterRadius;
-int _RaytracingDenoiseRadius;
+
+// Compute the weight of this pixel based on the smoothness of the pixel and the min and fadestart values
+float ComputeWeightValue(float perceptualSmoothness)
+{
+ return (_RaytracingReflectionSmoothnessFadeStart == _RaytracingReflectionMinSmoothness) ? 1.0 : max(saturate((perceptualSmoothness - _RaytracingReflectionMinSmoothness) / (_RaytracingReflectionSmoothnessFadeStart -_RaytracingReflectionMinSmoothness)), 0.001);
+}
[numthreads(RAYTRACING_REFLECTION_TILE_SIZE, RAYTRACING_REFLECTION_TILE_SIZE, 1)]
-void REFLECTION_INTEGRATION_UPSCALE(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 groupThreadId : SV_GroupThreadID, uint2 groupId : SV_GroupID)
+void ReflectionRescaleAndAdjustWeight(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 groupThreadId : SV_GroupThreadID, uint2 groupId : SV_GroupID)
{
UNITY_XR_ASSIGN_VIEW_INDEX(dispatchThreadId.z);
- #ifdef HALF_RESOLUTION
- // Compute the half res coordinate that we shall be using for our effect
- uint2 targetCoord = dispatchThreadId.xy;
- uint2 sourceCoord = targetCoord / 2;
- #else
- uint2 targetCoord = dispatchThreadId.xy;
- uint2 sourceCoord = targetCoord;
- #endif
+ // Half resolution coordinate that should be processed
+ uint2 halfResCoord = dispatchThreadId.xy;
+
+ // Evaluate which full resolution coordinate should be used for depth, normal, smoothness and clear coat evaluation
+ uint2 centerGeometryCoord = ComputeSourceCoordinates(halfResCoord, _RaytracingFrameIndex);
- // Compute the subpixel index that matches this full screen pixel.
- int localIndex = (targetCoord.x & 1) + (targetCoord.y & 1) * 2;
+ // Pixel coordinate where the direction an lighting are stored
+ uint2 fullResCoord = halfResCoord * 2;
// Fetch the depth
- float depth = LOAD_TEXTURE2D_X(_DepthTexture, targetCoord).x;
+ float depth = LOAD_TEXTURE2D_X(_DepthTexture, centerGeometryCoord).x;
+ // Fetch the normal
+ NormalData normalData;
+ DecodeFromNormalBuffer(centerGeometryCoord, normalData);
+
+ // We use a texture to identify if we use a clear coat constant for perceptualRoughness for SSR or use value from normal buffer.
+ // When we use a forward material we can output the normal and perceptualRoughness for the coat for SSR, so we simply bind a black 1x1 texture
+ // When we use deferred material we need to bind the gbuffer2 and read the coat mask
+ float4 coatMask = LOAD_TEXTURE2D_X(_SsrClearCoatMaskTexture, centerGeometryCoord);
+ normalData.perceptualRoughness = HasClearCoatMask(coatMask) ? CLEAR_COAT_PERCEPTUAL_ROUGHNESS : normalData.perceptualRoughness;
+
+ // Duplicating same early out condition we do on reflection dispatchrays as that info is 1/2 res while we need full res granularity here.
+ // Also, this operates on data we fetch anyway, while the _SsrLightingTextureRW at central pixel is needed only if that pixel contributes to filtering below.
+ float perceptualSmoothness = PerceptualRoughnessToPerceptualSmoothness(normalData.perceptualRoughness);
+ if (depth == UNITY_RAW_FAR_CLIP_VALUE || perceptualSmoothness < _RaytracingReflectionMinSmoothness || LOAD_TEXTURE2D_X(_DirectionPDFTexture, fullResCoord).w < 0.0)
+ {
+ _RaytracingReflectionTexture[COORD_TEXTURE2D_X(halfResCoord)] = float4(0.0f, 0.0f, 0.0f, 0.0f);
+ return;
+ }
+
+ // We also need to compute the fade factor for this sample
+ float weight = ComputeWeightValue(perceptualSmoothness);
+ _RaytracingReflectionTexture[COORD_TEXTURE2D_X(halfResCoord)] = float4(LOAD_TEXTURE2D_X(_SsrLightingTextureRW, fullResCoord).xyz, weight);
+}
+
+[numthreads(RAYTRACING_REFLECTION_TILE_SIZE, RAYTRACING_REFLECTION_TILE_SIZE, 1)]
+void ReflectionAdjustWeight(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 groupThreadId : SV_GroupThreadID, uint2 groupId : SV_GroupID)
+{
+ UNITY_XR_ASSIGN_VIEW_INDEX(dispatchThreadId.z);
+
+ // Target texture coordinate
+ uint2 targetCoord = dispatchThreadId.xy;
+
+ // Fetch the depth and normal
+ float depth = LOAD_TEXTURE2D_X(_DepthTexture, targetCoord).x;
NormalData normalData;
DecodeFromNormalBuffer(targetCoord, normalData);
@@ -60,121 +98,77 @@ void REFLECTION_INTEGRATION_UPSCALE(uint3 dispatchThreadId : SV_DispatchThreadID
// When we use deferred material we need to bind the gbuffer2 and read the coat mask
float4 coatMask = LOAD_TEXTURE2D_X(_SsrClearCoatMaskTexture, targetCoord);
normalData.perceptualRoughness = HasClearCoatMask(coatMask) ? CLEAR_COAT_PERCEPTUAL_ROUGHNESS : normalData.perceptualRoughness;
- // Fetch the roughness
- float roughness = PerceptualRoughnessToRoughness(normalData.perceptualRoughness);
// Duplicating same early out condition we do on reflection dispatchrays as that info is 1/2 res while we need full res granularity here.
// Also, this operates on data we fetch anyway, while the _SsrLightingTextureRW at central pixel is needed only if that pixel contributes to filtering below.
float perceptualSmoothness = PerceptualRoughnessToPerceptualSmoothness(normalData.perceptualRoughness);
- if (depth == UNITY_RAW_FAR_CLIP_VALUE || perceptualSmoothness < _RaytracingReflectionMinSmoothness)
+ if (depth == UNITY_RAW_FAR_CLIP_VALUE || perceptualSmoothness < _RaytracingReflectionMinSmoothness || LOAD_TEXTURE2D_X(_DirectionPDFTexture, targetCoord).w < 0.0)
{
_RaytracingReflectionTexture[COORD_TEXTURE2D_X(targetCoord)] = float4(0.0f, 0.0f, 0.0f, 0.0f);
return;
}
- // Compute the world space position
- PositionInputs posInput = GetPositionInput(targetCoord, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V);
+ // Fetch the lighting and compute the weight
+ float3 lighting = LOAD_TEXTURE2D_X(_SsrLightingTextureRW, targetCoord);
+ float weight = ComputeWeightValue(perceptualSmoothness);
- // Compute the view in world space
- const float3 viewWS = GetWorldSpaceNormalizeViewDir(posInput.positionWS);
+ // Output the result to the half resolution part of the texture
+ _RaytracingReflectionTexture[COORD_TEXTURE2D_X(targetCoord)] = float4(lighting, weight);
+}
- // Compute NdotV and clamp it
- const float NdotV = saturate(dot(viewWS, normalData.normalWS));
+[numthreads(RAYTRACING_REFLECTION_TILE_SIZE, RAYTRACING_REFLECTION_TILE_SIZE, 1)]
+void ReflectionUpscale(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 groupThreadId : SV_GroupThreadID, uint2 groupId : SV_GroupID)
+{
+ UNITY_XR_ASSIGN_VIEW_INDEX(dispatchThreadId.z);
- // Compute the reflected direction for this view direction
- float3 reflDir = reflect(-viewWS, normalData.normalWS);
+ // Compute the three coordinates we need to be reading from
+ uint2 fullResolution = dispatchThreadId.xy;
- // Initialize the output pixels
- float4 resultSum = float4(0.0 ,0.0, 0.0, 0.0);
- uint sampleCount = 0;
+ // Fetch the full resolution depth
+ float hiResDepth = LOAD_TEXTURE2D_X(_DepthTexture, fullResolution).x;
- // We want to avoid overblur for smoothsurfaces, so the upscale radius is lerped between the minimal value and the maximal value
- const int upscaleRadius = lerp(2, _SpatialFilterRadius, normalData.perceptualRoughness);
- const float radiusSq = upscaleRadius * upscaleRadius;
+ // Compute the main half resolution pixel
+ uint2 halfResolution = fullResolution / 2;
- for(int y = -upscaleRadius; y < upscaleRadius; ++y)
- {
- for(int x = -upscaleRadius; x < upscaleRadius; ++x)
- {
- float radiusDistanceSq = (y*y + x*x);
- if(radiusDistanceSq > radiusSq) continue;
-
- // Compute the noise position that shall be used
- int2 relativeHRShift = uint2(8 + x, 8 + y);
-
- // Full res sample position
- #ifdef HALF_RESOLUTION
- int2 sampleCoord = (sourceCoord + uint2(x,y)) * 2;
- #else
- int2 sampleCoord = (sourceCoord + uint2(x,y));
- #endif
-
- // If this pixel is outside of the screen, we cannot use it
- if(sampleCoord.x < 0 || sampleCoord.x > _ScreenSize.x
- || sampleCoord.y < 0 || sampleCoord.y > _ScreenSize.y)
- continue;
-
- // Fetch the target color
- float4 sampleColor = _SsrLightingTextureRW[COORD_TEXTURE2D_X(sampleCoord)];
-
- // Compute the position of the actual source pixel
- uint subPixel = clamp(floor(sampleColor.w * 4.0f), 0, 3);
- uint2 shift = HalfResIndexToCoordinateShift[subPixel];
- #ifdef HALF_RESOLUTION
- uint2 actualSourceCoord = sampleCoord + shift;
- #else
- uint2 actualSourceCoord = sampleCoord;
- #endif
-
- // Fetch the Depth
- float sampleDepth = LOAD_TEXTURE2D_X(_DepthTexture, actualSourceCoord).x;
- // If this the background, it should not be used as a valid sample
- if(sampleDepth == 0.0f) continue;
-
- // Compute the target pixel that it will impact
- float sample = _BlueNoiseTexture[int3(relativeHRShift, 0)].x;
- int index = clamp(floor(sample * 4.0f), 0, 3);
-
- if (index != localIndex) continue;
-
- // Let's fetch the half res sample's properties
- // Get the direction and pdf
- float4 directionPDF = _SsrHitPointTexture[COORD_TEXTURE2D_X(sampleCoord)];
-
- // If this direction is under the candidate surface, then it is not valid
- if(dot(directionPDF.xyz, normalData.normalWS) <= 0.0f) continue;
-
- // If this direction is not in the hemisphere of the reflected view direction, then it is not valid
- if(dot(directionPDF.xyz, reflDir) <= 0.0f) continue;
-
- // Compute the brdf of this sample
- float weight = 1.0f;
- if(roughness > 0.001)
- {
- // Compute the brdf of this sample
- float3 H = normalize(directionPDF.xyz + viewWS);
- float NdotH = dot(normalData.normalWS, H);
- float NdotL = dot(directionPDF.xyz, normalData.normalWS);
- float localBRDF = D_GGX(NdotH, roughness) * V_SmithJointGGX(NdotL, NdotV, roughness) * NdotL;
- weight = localBRDF * directionPDF.w;
- }
-
- // Contirbute to all the output values
- float3 sampleResult = sampleColor.xyz * weight;
- resultSum += float4(sampleResult, weight);
- sampleCount += 1;
- }
- }
+ // And the representative coordinate
+ uint2 representativeCoord = ComputeSourceCoordinates(halfResolution, _RaytracingFrameIndex);
- // Compute the full res coordinate
- if(depth == 0.0f || sampleCount == 0 || resultSum.w == 0.0)
+ // If the full resolution depth is a background pixel, write the invalid data and we are done
+ if (hiResDepth == UNITY_RAW_FAR_CLIP_VALUE)
{
- _RaytracingReflectionTexture[COORD_TEXTURE2D_X(targetCoord)] = float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
- else
- {
- // We also need to compute the fade factor for this sample
- float weightValue = _RaytracingReflectionSmoothnessFadeStart == _RaytracingReflectionMinSmoothness ? 1.0 : saturate((perceptualSmoothness - _RaytracingReflectionMinSmoothness) / (_RaytracingReflectionSmoothnessFadeStart -_RaytracingReflectionMinSmoothness));
- _RaytracingReflectionTexture[COORD_TEXTURE2D_X(targetCoord)] = float4(resultSum.xyz / resultSum.w, weightValue);
+ _RaytracingReflectionTexture[COORD_TEXTURE2D_X(fullResolution)] = float4(0.0f, 0.0f, 0.0f, 0.0f);
+ return;
}
+
+ // Compute the shift within the half res
+ int2 halfResShift = fullResolution - representativeCoord;
+
+ // Compute the shift of the pixel in the group
+ int shiftIndex = halfResShift.y * 2 + halfResShift.x;
+
+ // Compute the shift in the upscale table
+ int offsetInCoordTable = shiftIndex * 4;
+
+ float2 halfScreenSize = _ScreenSize.xy * 0.5;
+
+ // Compute the half resolution coordinates we should tap from
+ int2 halfResTap0 = clamp(0, halfResolution + UpscaleBilateralPixels[offsetInCoordTable], halfScreenSize - 1);
+ int2 halfResTap1 = clamp(0, halfResolution + UpscaleBilateralPixels[offsetInCoordTable + 1], halfScreenSize - 1);
+ int2 halfResTap2 = clamp(0, halfResolution + UpscaleBilateralPixels[offsetInCoordTable + 2], halfScreenSize - 1);
+ int2 halfResTap3 = clamp(0, halfResolution + UpscaleBilateralPixels[offsetInCoordTable + 3], halfScreenSize - 1);
+
+ // We are not using the depth pyramid to read the half res depths, so we need to multiply them by 2.
+ float4 lowDepths = float4(LOAD_TEXTURE2D_X(_DepthTexture, ComputeSourceCoordinates(halfResTap0, _RaytracingFrameIndex)).x
+ , LOAD_TEXTURE2D_X(_DepthTexture, ComputeSourceCoordinates(halfResTap1, _RaytracingFrameIndex)).x
+ , LOAD_TEXTURE2D_X(_DepthTexture, ComputeSourceCoordinates(halfResTap2, _RaytracingFrameIndex)).x
+ , LOAD_TEXTURE2D_X(_DepthTexture, ComputeSourceCoordinates(halfResTap3, _RaytracingFrameIndex)).x);
+
+ // Grab all the color values required for upscale
+ float4 lowResCol0 = max(0, LOAD_TEXTURE2D_X(_SsrLightingTextureRW, halfResTap0));
+ float4 lowResCol1 = max(0, LOAD_TEXTURE2D_X(_SsrLightingTextureRW, halfResTap1));
+ float4 lowResCol2 = max(0, LOAD_TEXTURE2D_X(_SsrLightingTextureRW, halfResTap2));
+ float4 lowResCol3 = max(0, LOAD_TEXTURE2D_X(_SsrLightingTextureRW, halfResTap3));
+
+ // Bilateral upscale and output the result
+ _RaytracingReflectionTexture[COORD_TEXTURE2D_X(fullResolution)] = BilUpColor(hiResDepth, lowDepths, lowResCol0, lowResCol1, lowResCol2, lowResCol3);
}
diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Reflections/RaytracingReflections.compute b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Reflections/RaytracingReflections.compute
index ecf3caa573c..ef8daca1091 100644
--- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Reflections/RaytracingReflections.compute
+++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Reflections/RaytracingReflections.compute
@@ -10,6 +10,8 @@
#pragma only_renderers d3d11
+// #pragma enable_d3d11_debug_symbols
+
// HDRP generic includes
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
@@ -26,13 +28,60 @@
// Tile size of this compute
#define RAYTRACING_REFLECTIONS_TILE_SIZE 8
+// Input data
TEXTURE2D_X(_DepthTexture);
-RW_TEXTURE2D_X(float4, _RaytracingDirectionBuffer);
-TEXTURE2D_X(_SsrClearCoatMaskTexture);
-
-// Flag value that defines if a given pixel recieves reflections or not
TEXTURE2D_X_UINT2(_StencilTexture);
+// Flag value that defines if a given pixel recieves reflections or not
int _SsrStencilBit;
+TEXTURE2D_X(_SsrClearCoatMaskTexture);
+
+// Output data
+RW_TEXTURE2D_X(float4, _RaytracingDirectionBuffer);
+
+// Structure that holds everything that defines a GGX sample
+struct GGXSample
+{
+ float3 direction;
+ float pdf;
+};
+
+GGXSample GenerateGGXSampleDirection(uint2 currentCoord, float3 normalWS, float3 viewWS, float roughness, int frameIndex)
+{
+ // Create the local ortho basis
+ float3x3 localToWorld = GetLocalFrame(normalWS);
+
+ // Generate the new sample (follwing values of the sequence)
+ int initialFrameIndex = frameIndex;
+ float2 sample;
+ sample.x = GetBNDSequenceSample(currentCoord, initialFrameIndex, 0);
+ sample.y = GetBNDSequenceSample(currentCoord, initialFrameIndex, 1);
+
+ // Importance sample the direction
+ float3 sampleDir = float3(0.0, 0.0, 0.0);
+ float NdotL, NdotH, VdotH;
+ SampleGGXDir(sample, viewWS, localToWorld, roughness, sampleDir, NdotL, NdotH, VdotH);
+
+ // If this direction is under the surface, let's generate a new one that won't be.
+ // We allow ourselves 8 as the total of number of tries.
+ // TODO: use Eric's paper on visible normal distribution sampling
+ initialFrameIndex += 8;
+ for (int i = 1; i < 8; ++i)
+ {
+ if (dot(sampleDir, normalWS) >= 0.00f)
+ break;
+
+ sample.x = GetBNDSequenceSample(currentCoord, initialFrameIndex + i, 0);
+ sample.y = GetBNDSequenceSample(currentCoord, initialFrameIndex + i, 1);
+ SampleGGXDir(sample, viewWS, localToWorld, roughness, sampleDir, NdotL, NdotH, VdotH);
+ }
+
+ // Build the sample and return it
+ GGXSample ggxSample;
+ ggxSample.direction = sampleDir;
+ // Given that GGX is invalid for a pure smooth material, we handle the case this by stating that the pdf == 1.0
+ ggxSample.pdf = roughness > 0.001 ? D_GGX(NdotH, roughness) * NdotH / (4.0 * VdotH) : 1.0;
+ return ggxSample;
+}
[numthreads(RAYTRACING_REFLECTIONS_TILE_SIZE, RAYTRACING_REFLECTIONS_TILE_SIZE, 1)]
void RaytracingReflectionsHalfRes(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 groupThreadId : SV_GroupThreadID, uint2 groupId : SV_GroupID)
@@ -42,41 +91,37 @@ void RaytracingReflectionsHalfRes(uint3 dispatchThreadId : SV_DispatchThreadID,
// Compute the pixel position to process
uint2 halfResCoord = groupId * RAYTRACING_REFLECTIONS_TILE_SIZE + groupThreadId;
- // Pick which subpixel we will be launching our effects from
- float subPixelSample = GetBNDSequenceSample(halfResCoord, _RaytracingFrameIndex, 3);
- int subPixel = clamp((int)(subPixelSample * 4.0), 0, 3);
- uint2 shift = HalfResIndexToCoordinateShift[subPixel];
-
- // Pixel where we will store the result of the raytracing
+ // Pixel where we will store the result of the direction generation
uint2 outputCoord = halfResCoord * 2;
- // Pixel coordinate in full res of the pixel that we will be using for our computation
- uint2 sourceCoord = outputCoord + shift;
+ // Pixel coordinate in full res that we will be using to pick depth, normal and smoothness values.
+ uint2 sourceCoord = ComputeSourceCoordinates(halfResCoord, _RaytracingFrameIndex);
// Read the depth value
float depthValue = LOAD_TEXTURE2D_X(_DepthTexture, sourceCoord).r;
- // In the second texture, we store the sampled direction and the invPDF of the sample
+ // We initialize the output texture in case we early return. The last channel is set to -1.0 to mark the invalidity of the direction.
_RaytracingDirectionBuffer[COORD_TEXTURE2D_X(outputCoord)] = float4(0.0, 0.0, 0.0, -1.0);
// This point is part of the background, we don't really care
if (depthValue == UNITY_RAW_FAR_CLIP_VALUE)
return;
- // Does this pixel have SSS?
+ // Does this pixel have SSR?
uint stencilValue = GetStencilValue(LOAD_TEXTURE2D_X(_StencilTexture, sourceCoord));
if ((stencilValue & _SsrStencilBit) == 0)
return;
// Convert this to a world space position
PositionInputs posInput = GetPositionInput(sourceCoord, _ScreenSize.zw, depthValue, UNITY_MATRIX_I_VP, GetWorldToViewMatrix(), 0);
- float distanceToCamera = length(posInput.positionWS);
- // Compute the incident vector on the surfaces
+
+ // Compute the view vector
const float3 viewWS = GetWorldSpaceNormalizeViewDir(posInput.positionWS);
// Decode the world space normal
NormalData normalData;
DecodeFromNormalBuffer(sourceCoord, normalData);
+
// Override the roughness by the clearcoat value of this is a clear coat
float4 coatMask = LOAD_TEXTURE2D_X(_SsrClearCoatMaskTexture, sourceCoord);
normalData.perceptualRoughness = HasClearCoatMask(coatMask) ? CLEAR_COAT_PERCEPTUAL_ROUGHNESS : normalData.perceptualRoughness;
@@ -91,40 +136,15 @@ void RaytracingReflectionsHalfRes(uint3 dispatchThreadId : SV_DispatchThreadID,
// Compute the actual roughness
float roughness = PerceptualRoughnessToRoughness(normalData.perceptualRoughness);
- int globalSampleIndex = _RaytracingFrameIndex;
-
- // Generate the new sample (follwing values of the sequence)
- float2 sample;
- sample.x = GetBNDSequenceSample(halfResCoord, globalSampleIndex, 0);
- sample.y = GetBNDSequenceSample(halfResCoord, globalSampleIndex, 1);
-
- // Importance sample the direction
- float3 sampleDir = float3(0.0, 0.0, 0.0);
- float NdotL, NdotH, VdotH;
- SampleGGXDir(sample, viewWS, localToWorld, roughness, sampleDir, NdotL, NdotH, VdotH);
-
- // If this direction is under the surface, let's generate a new one that won't be
- // TODO: use Eric's paper on visible normal distribution sampling
- globalSampleIndex += 8;
- for (int i = 1; i < 8; ++i)
- {
- if (dot(sampleDir, normalData.normalWS) >= 0.00f)
- break;
+ // Generate a GGX direction
+ GGXSample ggxSample = GenerateGGXSampleDirection(halfResCoord, normalData.normalWS, viewWS, roughness, _RaytracingFrameIndex);
- sample.x = GetBNDSequenceSample(halfResCoord, globalSampleIndex + i, 0);
- sample.y = GetBNDSequenceSample(halfResCoord, globalSampleIndex + i, 1);
- SampleGGXDir(sample, viewWS, localToWorld, roughness, sampleDir, NdotL, NdotH, VdotH);
- }
-
- // If we were not able to generate a direction over the surface, we are done
- if (dot(sampleDir, normalData.normalWS) <= 0.00f)
+ // If we failed, return.
+ if (dot(ggxSample.direction, normalData.normalWS) <= 0.00f)
return;
- // Given that GGX is invalid for a pure smooth material, we handle the case this by stating that the pdf == 1.0
- float samplePDF = roughness > 0.001 ? D_GGX(NdotH, roughness) * NdotH / (4.0 * VdotH) : 1.0;
-
- // In the second texture, we store the sampled direction and the invPDF of the sample
- _RaytracingDirectionBuffer[COORD_TEXTURE2D_X(outputCoord)] = float4(sampleDir, 1.0 / samplePDF);
+ // Store the generated direction and inverted PDF
+ _RaytracingDirectionBuffer[COORD_TEXTURE2D_X(outputCoord)] = float4(ggxSample.direction, 1.0 / ggxSample.pdf);
}
[numthreads(RAYTRACING_REFLECTIONS_TILE_SIZE, RAYTRACING_REFLECTIONS_TILE_SIZE, 1)]
@@ -135,36 +155,31 @@ void RaytracingReflectionsTransparentHalfRes(uint3 dispatchThreadId : SV_Dispatc
// Compute the pixel position to process
uint2 halfResCoord = groupId * RAYTRACING_REFLECTIONS_TILE_SIZE + groupThreadId;
- // Pick which subpixel we will be launching our effects from
- float subPixelSample = GetBNDSequenceSample(halfResCoord, _RaytracingFrameIndex, 3);
- int subPixel = clamp((int)(subPixelSample * 4.0), 0, 3);
- uint2 shift = HalfResIndexToCoordinateShift[subPixel];
-
- // Pixel where we will store the result of the raytracing
+ // Pixel where we will store the result of the direction generation
uint2 outputCoord = halfResCoord * 2;
- // Pixel coordinate in full res of the pixel that we will be using for our computation
- uint2 sourceCoord = outputCoord + shift;
+ // Pixel coordinate in full res that we will be using to pick depth and normal
+ uint2 sourceCoord = ComputeSourceCoordinates(halfResCoord, _RaytracingFrameIndex);
// Read the depth value
float depthValue = LOAD_TEXTURE2D_X(_DepthTexture, sourceCoord).r;
- // In the second texture, we store the sampled direction and the invPDF of the sample
+ // We initialize the output texture in case we early return. The last channel is set to -1.0 to mark the invalidity of the direction.
_RaytracingDirectionBuffer[COORD_TEXTURE2D_X(outputCoord)] = float4(0.0, 0.0, 0.0, -1.0);
// This point is part of the background, we don't really care
if (depthValue == UNITY_RAW_FAR_CLIP_VALUE)
return;
- // Does this pixel have SSS?
+ // Does this pixel have SSR?
uint stencilValue = GetStencilValue(LOAD_TEXTURE2D_X(_StencilTexture, sourceCoord));
if ((stencilValue & _SsrStencilBit) == 0)
return;
// Convert this to a world space position
PositionInputs posInput = GetPositionInput(sourceCoord, _ScreenSize.zw, depthValue, UNITY_MATRIX_I_VP, GetWorldToViewMatrix(), 0);
- float distanceToCamera = length(posInput.positionWS);
- // Compute the incident vector on the surfaces
+
+ // Compute the view vector
const float3 viewWS = GetWorldSpaceNormalizeViewDir(posInput.positionWS);
// Decode the world space normal
@@ -175,11 +190,8 @@ void RaytracingReflectionsTransparentHalfRes(uint3 dispatchThreadId : SV_Dispatc
if (_RaytracingReflectionMinSmoothness > PerceptualRoughnessToPerceptualSmoothness(normalData.perceptualRoughness))
return;
- // Compute the reflected direction
- float3 reflectionDir = reflect(-viewWS, normalData.normalWS);
-
- // In the second texture, we store the sampled direction and the invPDF of the sample
- _RaytracingDirectionBuffer[COORD_TEXTURE2D_X(outputCoord)] = float4(reflectionDir, 1.0);
+ // Store the reflected direction and 1.0 in the w channel.
+ _RaytracingDirectionBuffer[COORD_TEXTURE2D_X(outputCoord)] = float4(reflect(-viewWS, normalData.normalWS), 1.0);
}
[numthreads(RAYTRACING_REFLECTIONS_TILE_SIZE, RAYTRACING_REFLECTIONS_TILE_SIZE, 1)]
@@ -200,68 +212,44 @@ void RaytracingReflectionsFullRes(uint3 dispatchThreadId : SV_DispatchThreadID,
if (depthValue == UNITY_RAW_FAR_CLIP_VALUE)
return;
- // Does this pixel have SSS?
+ // Does this pixel have SSR?
uint stencilValue = GetStencilValue(LOAD_TEXTURE2D_X(_StencilTexture, currentCoord));
if ((stencilValue & _SsrStencilBit) == 0)
return;
// Convert this to a world space position
PositionInputs posInput = GetPositionInput(currentCoord, _ScreenSize.zw, depthValue, UNITY_MATRIX_I_VP, GetWorldToViewMatrix(), 0);
- float distanceToCamera = length(posInput.positionWS);
- // Compute the incident vector on the surfaces
+ // Compute the view vector
const float3 viewWS = GetWorldSpaceNormalizeViewDir(posInput.positionWS);
// Decode the world space normal
NormalData normalData;
DecodeFromNormalBuffer(currentCoord, normalData);
+
// Override the roughness by the clearcoat value of this is a clear coat
float4 coatMask = LOAD_TEXTURE2D_X(_SsrClearCoatMaskTexture, currentCoord);
normalData.perceptualRoughness = HasClearCoatMask(coatMask) ? CLEAR_COAT_PERCEPTUAL_ROUGHNESS : normalData.perceptualRoughness;
- // Create the local ortho basis
- float3x3 localToWorld = GetLocalFrame(normalData.normalWS);
-
// If this value is beyond the smothness that we allow, no need to compute it
if (_RaytracingReflectionMinSmoothness > PerceptualRoughnessToPerceptualSmoothness(normalData.perceptualRoughness))
return;
+ // Create the local ortho basis
+ float3x3 localToWorld = GetLocalFrame(normalData.normalWS);
+
// Compute the actual roughness
float roughness = PerceptualRoughnessToRoughness(normalData.perceptualRoughness);
- // Generate the new sample (follwing values of the sequence)
- int globalSampleIndex = _RaytracingFrameIndex;
- float2 sample;
- sample.x = GetBNDSequenceSample(currentCoord, globalSampleIndex, 0);
- sample.y = GetBNDSequenceSample(currentCoord, globalSampleIndex, 1);
+ // Generate a GGX direction
+ GGXSample ggxSample = GenerateGGXSampleDirection(currentCoord, normalData.normalWS, viewWS, roughness, _RaytracingFrameIndex);
- // Importance sample the direction
- float3 sampleDir = float3(0.0, 0.0, 0.0);
- float NdotL, NdotH, VdotH;
- SampleGGXDir(sample, viewWS, localToWorld, roughness, sampleDir, NdotL, NdotH, VdotH);
-
- // If this direction is under the surface, let's generate a new one that won't be
- // TODO: use Eric's paper on visible normal distribution sampling
- globalSampleIndex += 8;
- for (int i = 1; i < 8; ++i)
- {
- if (dot(sampleDir, normalData.normalWS) >= 0.00f)
- break;
-
- sample.x = GetBNDSequenceSample(currentCoord, globalSampleIndex + i, 0);
- sample.y = GetBNDSequenceSample(currentCoord, globalSampleIndex + i, 1);
- SampleGGXDir(sample, viewWS, localToWorld, roughness, sampleDir, NdotL, NdotH, VdotH);
- }
-
- // If we were not able to generate a direction over the surface, we are done
- if (dot(sampleDir, normalData.normalWS) <= 0.00f)
+ // If we failed, return.
+ if (dot(ggxSample.direction, normalData.normalWS) <= 0.00f)
return;
- // Given that GGX is invalid for a pure smooth material, we handle the case this by stating that the pdf == 1.0
- float samplePDF = roughness > 0.001 ? D_GGX(NdotH, roughness) * NdotH / (4.0 * VdotH) : 1.0;
-
- // Write the output ray data
- _RaytracingDirectionBuffer[COORD_TEXTURE2D_X(currentCoord)] = float4(sampleDir, 1.0 / samplePDF);
+ // Store the generated direction and inverted PDF
+ _RaytracingDirectionBuffer[COORD_TEXTURE2D_X(currentCoord)] = float4(ggxSample.direction, 1.0 / ggxSample.pdf);
}
[numthreads(RAYTRACING_REFLECTIONS_TILE_SIZE, RAYTRACING_REFLECTIONS_TILE_SIZE, 1)]
@@ -272,7 +260,7 @@ void RaytracingReflectionsTransparentFullRes(uint3 dispatchThreadId : SV_Dispatc
// Compute the pixel position to process
uint2 currentCoord = groupId * RAYTRACING_REFLECTIONS_TILE_SIZE + groupThreadId;
- // Clear the output color texture
+ // We initialize the output texture in case we early return. The last channel is set to -1.0 to mark the invalidity of the direction.
_RaytracingDirectionBuffer[COORD_TEXTURE2D_X(currentCoord)] = float4(0.0, 0.0, 0.0, -1.0f);
// Read the depth value
@@ -282,16 +270,15 @@ void RaytracingReflectionsTransparentFullRes(uint3 dispatchThreadId : SV_Dispatc
if (depthValue == UNITY_RAW_FAR_CLIP_VALUE)
return;
- // Does this pixel have SSS?
+ // Does this pixel have SSR?
uint stencilValue = GetStencilValue(LOAD_TEXTURE2D_X(_StencilTexture, currentCoord));
if ((stencilValue & _SsrStencilBit) == 0)
return;
// Convert this to a world space position
PositionInputs posInput = GetPositionInput(currentCoord, _ScreenSize.zw, depthValue, UNITY_MATRIX_I_VP, GetWorldToViewMatrix(), 0);
- float distanceToCamera = length(posInput.positionWS);
- // Compute the incident vector on the surfaces
+ // Compute the view vector
const float3 viewWS = GetWorldSpaceNormalizeViewDir(posInput.positionWS);
// Decode the world space normal
@@ -302,9 +289,6 @@ void RaytracingReflectionsTransparentFullRes(uint3 dispatchThreadId : SV_Dispatc
if (_RaytracingReflectionMinSmoothness > PerceptualRoughnessToPerceptualSmoothness(normalData.perceptualRoughness))
return;
- // Compute the reflected direction
- float3 reflectionDir = reflect(-viewWS, normalData.normalWS);
-
// Write the output ray data
- _RaytracingDirectionBuffer[COORD_TEXTURE2D_X(currentCoord)] = float4(reflectionDir, 1.0);
+ _RaytracingDirectionBuffer[COORD_TEXTURE2D_X(currentCoord)] = float4(reflect(-viewWS, normalData.normalWS), 1.0);
}