From e850ef84bc8861988b0a49d39dc37491a57b16b9 Mon Sep 17 00:00:00 2001 From: Emmanuel Turquin Date: Thu, 19 Nov 2020 18:04:50 +0100 Subject: [PATCH 1/6] Added proper computation of geometric normal in path tracing. --- .../Raytracing/Shaders/RaytracingIntersection.hlsl | 11 +++++++++++ .../ShaderPass/ShaderPassPathTracing.hlsl | 5 ++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingIntersection.hlsl b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingIntersection.hlsl index 0f1cfacb0c8..a644452386c 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingIntersection.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingIntersection.hlsl @@ -174,4 +174,15 @@ void GetCurrentIntersectionVertex(AttributeData attributeData, out IntersectionV #endif } +// Compute the proper world space geometric normal from the intersected triangle +void GetCurrentIntersectionGeometricNormal(AttributeData attributeData, out float3 geomNormalWS) +{ + uint3 triangleIndices = UnityRayTracingFetchTriangleIndices(PrimitiveIndex()); + float3 p0 = UnityRayTracingFetchVertexAttribute3(triangleIndices.x, kVertexAttributePosition); + float3 p1 = UnityRayTracingFetchVertexAttribute3(triangleIndices.y, kVertexAttributePosition); + float3 p2 = UnityRayTracingFetchVertexAttribute3(triangleIndices.z, kVertexAttributePosition); + + geomNormalWS = normalize(mul(cross(p1 - p0, p2 - p0), (float3x3)WorldToObject3x4())); +} + #endif // UNITY_RAYTRACING_INTERSECTION_INCLUDED diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassPathTracing.hlsl b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassPathTracing.hlsl index 4bfe1991715..691f6ae05d2 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassPathTracing.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassPathTracing.hlsl @@ -75,7 +75,10 @@ void ComputeSurfaceScattering(inout PathIntersection pathIntersection : SV_RayPa #ifndef SHADER_UNLIT - // Let's compute the world space position (the non-camera relative one if camera relative rendering is enabled) + // Override the geometric normal (otherwise, it is merely the non-mapped smooth normal) + GetCurrentIntersectionGeometricNormal(attributeData, bsdfData.geomNormalWS); + + // Compute the world space position (the non-camera relative one if camera relative rendering is enabled) float3 shadingPosition = fragInput.positionRWS; // Get current path throughput From f598f4fd750c1de3a0f6e1c336fc5d7915c7931b Mon Sep 17 00:00:00 2001 From: Emmanuel Turquin Date: Thu, 19 Nov 2020 18:19:12 +0100 Subject: [PATCH 2/6] Updated changelog. --- com.unity.render-pipelines.high-definition/CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/CHANGELOG.md b/com.unity.render-pipelines.high-definition/CHANGELOG.md index 9a02fe28686..a97661f15ba 100644 --- a/com.unity.render-pipelines.high-definition/CHANGELOG.md +++ b/com.unity.render-pipelines.high-definition/CHANGELOG.md @@ -100,7 +100,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Fixed picking for materials with depth offset. - Fixed issue with exposure history being uninitialized on second frame. - Fixed issue when changing FoV with the physical camera fold-out closed. -- Fixes some labels being clipped in the Render Graph Viewer +- Fixed some labels being clipped in the Render Graph Viewer. +- Fixed computation of geometric normal in path tracing (case 1293029). ### Changed - Combined occlusion meshes into one to reduce draw calls and state changes with XR single-pass. From 1c756a7ec0b490920c1eaac3b6806478da16547b Mon Sep 17 00:00:00 2001 From: Emmanuel Turquin Date: Mon, 23 Nov 2020 15:42:48 +0100 Subject: [PATCH 3/6] Keeps input geom normal orientation. --- .../ShaderPass/ShaderPassPathTracing.hlsl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassPathTracing.hlsl b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassPathTracing.hlsl index 691f6ae05d2..b721eb4e472 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassPathTracing.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassPathTracing.hlsl @@ -20,6 +20,14 @@ float3 GetPositionBias(float3 geomNormal, float bias, bool below) return geomNormal * (below ? -bias : bias); } +void OverrideGeometricNormal(AttributeData attributeData, inout float3 geomNormal) +{ + // Make sure we conserve orientation (for double-sidedness) + float3 newGeomNormal; + GetCurrentIntersectionGeometricNormal(attributeData, newGeomNormal); + geomNormal = dot(newGeomNormal, geomNormal) > 0.0 ? newGeomNormal : -newGeomNormal; +} + // Function responsible for surface scattering void ComputeSurfaceScattering(inout PathIntersection pathIntersection : SV_RayPayload, AttributeData attributeData : SV_IntersectionAttributes, float4 inputSample) { @@ -76,7 +84,7 @@ void ComputeSurfaceScattering(inout PathIntersection pathIntersection : SV_RayPa #ifndef SHADER_UNLIT // Override the geometric normal (otherwise, it is merely the non-mapped smooth normal) - GetCurrentIntersectionGeometricNormal(attributeData, bsdfData.geomNormalWS); + OverrideGeometricNormal(attributeData, bsdfData.geomNormalWS); // Compute the world space position (the non-camera relative one if camera relative rendering is enabled) float3 shadingPosition = fragInput.positionRWS; From 0d2045a2ac2f3ebb9d5486c13fac3952a0b9ef59 Mon Sep 17 00:00:00 2001 From: Emmanuel Turquin Date: Mon, 23 Nov 2020 18:51:25 +0100 Subject: [PATCH 4/6] Changed the approach slightly, so as to handle all double-sidedness cases with as little an intrusion into the material code as possible. --- .../ShaderPass/ShaderPassPathTracing.hlsl | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassPathTracing.hlsl b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassPathTracing.hlsl index b721eb4e472..ca9b6f809b6 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassPathTracing.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassPathTracing.hlsl @@ -20,14 +20,6 @@ float3 GetPositionBias(float3 geomNormal, float bias, bool below) return geomNormal * (below ? -bias : bias); } -void OverrideGeometricNormal(AttributeData attributeData, inout float3 geomNormal) -{ - // Make sure we conserve orientation (for double-sidedness) - float3 newGeomNormal; - GetCurrentIntersectionGeometricNormal(attributeData, newGeomNormal); - geomNormal = dot(newGeomNormal, geomNormal) > 0.0 ? newGeomNormal : -newGeomNormal; -} - // Function responsible for surface scattering void ComputeSurfaceScattering(inout PathIntersection pathIntersection : SV_RayPayload, AttributeData attributeData : SV_IntersectionAttributes, float4 inputSample) { @@ -62,6 +54,11 @@ void ComputeSurfaceScattering(inout PathIntersection pathIntersection : SV_RayPa posInput.positionWS = fragInput.positionRWS; posInput.positionSS = pathIntersection.pixelCoord; + // For path tracing, we want the front-facing test to be performed on the actual geometric normal + float3 geomNormal; + GetCurrentIntersectionGeometricNormal(attributeData, geomNormal); + fragInput.isFrontFace = dot(WorldRayDirection(), geomNormal) < 0.0; + // Build the surfacedata and builtindata SurfaceData surfaceData; BuiltinData builtinData; @@ -84,7 +81,8 @@ void ComputeSurfaceScattering(inout PathIntersection pathIntersection : SV_RayPa #ifndef SHADER_UNLIT // Override the geometric normal (otherwise, it is merely the non-mapped smooth normal) - OverrideGeometricNormal(attributeData, bsdfData.geomNormalWS); + // Also make sure that it is in the same hemisphere as the shading normal (which may have been flipped) + bsdfData.geomNormalWS = dot(bsdfData.normalWS, geomNormal) > 0.0 ? geomNormal : -geomNormal; // Compute the world space position (the non-camera relative one if camera relative rendering is enabled) float3 shadingPosition = fragInput.positionRWS; From 4433e0f394838eb33f6fcfeb470263eceeef49a8 Mon Sep 17 00:00:00 2001 From: Emmanuel Turquin Date: Tue, 15 Dec 2020 15:59:31 +0100 Subject: [PATCH 5/6] Updated reference images for PT tests. --- .../Linear/WindowsEditor/Direct3D12/None/5001_PathTracing.png | 4 ++-- .../WindowsEditor/Direct3D12/None/5006_PathTracing_DoF.png | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/5001_PathTracing.png b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/5001_PathTracing.png index d955c665188..c78283a6402 100644 --- a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/5001_PathTracing.png +++ b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/5001_PathTracing.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:60972ed3fac11868812d547e46e20cb41c22bbe11e38433a69e14ee1eaf8160c -size 594959 +oid sha256:292d270609c93cd8db32588523ab4d477fa693fd8e7c81d0590ce1133b3296fb +size 595404 diff --git a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/5006_PathTracing_DoF.png b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/5006_PathTracing_DoF.png index 9f615549e99..afe33c09740 100644 --- a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/5006_PathTracing_DoF.png +++ b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/5006_PathTracing_DoF.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f0d0ee8840624839d44e46b03d4fb624dee9a7f889b78a064f21f788bb734d01 -size 582422 +oid sha256:4a1be4770d57a043a2c05efdfa1b8034bc05213e4e9d377ed97d7d0effe31d6e +size 581407 From c539942b0f4e7ba4a4426eb9dc77b5c0c6660702 Mon Sep 17 00:00:00 2001 From: Sebastien Lagarde Date: Tue, 15 Dec 2020 16:20:48 +0100 Subject: [PATCH 6/6] Update 1000_RaytracingQualityKeyword_PathTracer_Default.png --- .../None/1000_RaytracingQualityKeyword_PathTracer_Default.png | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/1000_RaytracingQualityKeyword_PathTracer_Default.png b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/1000_RaytracingQualityKeyword_PathTracer_Default.png index 510a66bdae4..58f3ec3b244 100644 --- a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/1000_RaytracingQualityKeyword_PathTracer_Default.png +++ b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/1000_RaytracingQualityKeyword_PathTracer_Default.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:08b57a5a118c31de7a0b88921a96aab1fe7f029eeed3e4bcd5e04d13067cb1a5 -size 594548 +oid sha256:8ceb91cb624b7c428911efde6befd0b903cb4a4c0c6f429715f378c0096428f9 +size 593509