From 43a05011919229b56690964a7c61cbc53e94a63f Mon Sep 17 00:00:00 2001 From: Pavlos Mavridis Date: Thu, 16 Apr 2020 20:00:26 +0200 Subject: [PATCH 01/18] Path traced DoF implementation --- .../Camera/HDCameraUI.Drawers.cs | 1 + .../RenderPipeline/Camera/HDCameraUI.Skin.cs | 1 + .../Camera/SerializedHDCamera.cs | 2 + .../PathTracing/PathTracingEditor.cs | 3 ++ .../Camera/HDAdditionalCameraData.cs | 10 ++++ .../RenderPipeline/HDStringConstants.cs | 4 ++ .../RenderPipeline/PathTracing/PathTracing.cs | 26 ++++++++++ .../Shaders/PathTracingMain.raytrace | 52 +++++++++++++++++-- 8 files changed, 96 insertions(+), 3 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/HDCameraUI.Drawers.cs b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/HDCameraUI.Drawers.cs index f2db83088ee..90a27f2fa36 100644 --- a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/HDCameraUI.Drawers.cs +++ b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/HDCameraUI.Drawers.cs @@ -377,6 +377,7 @@ static void Drawer_PhysicalCamera(SerializedHDCamera p, Editor owner) cam.focalLength.floatValue = focalLengthVal; } + EditorGUILayout.PropertyField(p.focusDistance, focusDistanceContent); EditorGUILayout.PropertyField(p.aperture, apertureContent); EditorGUILayout.PropertyField(cam.lensShift, lensShiftContent); } diff --git a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/HDCameraUI.Skin.cs b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/HDCameraUI.Skin.cs index fa013832629..c49060369b9 100644 --- a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/HDCameraUI.Skin.cs +++ b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/HDCameraUI.Skin.cs @@ -45,6 +45,7 @@ static partial class HDCameraUI static readonly GUIContent curvatureContent = EditorGUIUtility.TrTextContent("Curvature"); static readonly GUIContent barrelClippingContent = EditorGUIUtility.TrTextContent("Barrel Clipping"); static readonly GUIContent anamorphismContent = EditorGUIUtility.TrTextContent("Anamorphism"); + static readonly GUIContent focusDistanceContent = EditorGUIUtility.TrTextContent("Focus Distance", "Sets the distance to the focus point from the Camera."); static readonly GUIContent antialiasingContent = EditorGUIUtility.TrTextContent("Anti-aliasing", "The anti-aliasing method to use."); static readonly GUIContent SMAAQualityPresetContent = EditorGUIUtility.TrTextContent("SMAA Quality Preset", "The quality preset for SMAA, low has the best performance but worst quality, High has the highest quality but worst performance."); diff --git a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/SerializedHDCamera.cs b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/SerializedHDCamera.cs index 415bc740a51..0b37f7b30e3 100644 --- a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/SerializedHDCamera.cs +++ b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/SerializedHDCamera.cs @@ -18,6 +18,7 @@ class SerializedHDCamera public SerializedProperty curvature; public SerializedProperty barrelClipping; public SerializedProperty anamorphism; + public SerializedProperty focusDistance; public SerializedProperty antialiasing; public SerializedProperty SMAAQuality; @@ -70,6 +71,7 @@ public SerializedHDCamera(SerializedObject serializedObject) curvature = serializedAdditionalDataObject.FindProperty("physicalParameters.m_Curvature"); barrelClipping = serializedAdditionalDataObject.FindProperty("physicalParameters.m_BarrelClipping"); anamorphism = serializedAdditionalDataObject.FindProperty("physicalParameters.m_Anamorphism"); + focusDistance = serializedAdditionalDataObject.FindProperty("physicalParameters.m_FocusDistance"); antialiasing = serializedAdditionalDataObject.Find((HDAdditionalCameraData d) => d.antialiasing); SMAAQuality = serializedAdditionalDataObject.Find((HDAdditionalCameraData d) => d.SMAAQuality); diff --git a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/PathTracing/PathTracingEditor.cs b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/PathTracing/PathTracingEditor.cs index 38718398b5f..5928b19b825 100644 --- a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/PathTracing/PathTracingEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/PathTracing/PathTracingEditor.cs @@ -17,6 +17,7 @@ class PathTracingEditor : VolumeComponentEditor SerializedDataParameter m_MinDepth; SerializedDataParameter m_MaxDepth; SerializedDataParameter m_MaxIntensity; + SerializedDataParameter m_EnableDepthOfField; public override void OnEnable() { @@ -28,6 +29,7 @@ public override void OnEnable() m_MinDepth = Unpack(o.Find(x => x.minimumDepth)); m_MaxDepth = Unpack(o.Find(x => x.maximumDepth)); m_MaxIntensity = Unpack(o.Find(x => x.maximumIntensity)); + m_EnableDepthOfField = Unpack(o.Find(x => x.enableDepthOfField)); } public override void OnInspectorGUI() @@ -53,6 +55,7 @@ public override void OnInspectorGUI() PropertyField(m_MinDepth); PropertyField(m_MaxDepth); PropertyField(m_MaxIntensity); + PropertyField(m_EnableDepthOfField); EditorGUI.indentLevel--; // Make sure MaxDepth is always greater or equal than MinDepth diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDAdditionalCameraData.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDAdditionalCameraData.cs index 74c7adcfcfb..386bf96b71f 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDAdditionalCameraData.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDAdditionalCameraData.cs @@ -37,6 +37,7 @@ public class HDPhysicalCamera // Lens // Note: focalLength is already defined in the regular camera component [SerializeField] [Range(kMinAperture, kMaxAperture)] float m_Aperture = 16f; + [SerializeField] [Min(0f)] float m_FocusDistance = 1.0f; // Aperture shape [SerializeField] [Range(kMinBladeCount, kMaxBladeCount)] int m_BladeCount = 5; @@ -112,6 +113,15 @@ public float anamorphism set => m_Anamorphism = Mathf.Clamp(value, -1f, 1f); } + /// + /// The focus distancec of the camera. + /// + public float focusDistance + { + get => m_FocusDistance; + set => m_FocusDistance = Mathf.Max(value, 0f); + } + /// /// Copies the settings of this instance to another instance. /// 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 f221e32003a..be7b42b1c7d 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs @@ -458,6 +458,10 @@ static class HDShaderIDs public static readonly int _RaytracingPixelSpreadAngle = Shader.PropertyToID("_RaytracingPixelSpreadAngle"); public static readonly string _RaytracingAccelerationStructureName = "_RaytracingAccelerationStructure"; + // Path tracing variables + public static readonly int _PathTracedDoFConstants = Shader.PropertyToID("_PathTracedDoFConstants"); + public static readonly int _InvViewportTransform = Shader.PropertyToID("_InvViewportTransform"); + // Light Cluster public static readonly int _MinClusterPos = Shader.PropertyToID("_MinClusterPos"); public static readonly int _MaxClusterPos = Shader.PropertyToID("_MaxClusterPos"); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs index d30b4c852a7..42c4749109f 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs @@ -48,7 +48,14 @@ public sealed class PathTracing : VolumeComponent /// [Tooltip("Defines the maximum intensity value computed for a path segment.")] public ClampedFloatParameter maximumIntensity = new ClampedFloatParameter(10f, 0f, 100f); + + /// + /// Defines the maximum intensity value computed for a path segment. + /// + [Tooltip("Enables path-traced defocus blur / depth of field.")] + public BoolParameter enableDepthOfField = new BoolParameter(false); } + public partial class HDRenderPipeline { PathTracing m_PathTracingSettings = null; @@ -95,6 +102,23 @@ internal void ResetPathTracing() m_SubFrameManager.Reset(); } + // Computes the transform from viewport to normalized device coordinates + internal Matrix4x4 ComputeInverseViewportMatrix(HDCamera hdCamera) + { + float verticalFoV = hdCamera.camera.GetGateFittedFieldOfView() * Mathf.Deg2Rad; + Vector2 lensShift = hdCamera.camera.GetGateFittedLensShift(); + + return HDUtils.ComputePixelCoordToWorldSpaceViewDirectionMatrix(verticalFoV, lensShift, hdCamera.screenSize, Matrix4x4.identity, false, hdCamera.camera.aspect); + } + + internal Vector4 ComputeDoFConstants(HDCamera hdCamera, PathTracing settings) + { + // focalLength is in mm, so we need to convert to meters. We also want the aperture radius, not diameter, so we divide by two. + float apertureRadius = 0.5f * 0.001f * hdCamera.camera.focalLength / hdCamera.physicalParameters.aperture; + + return new Vector4(settings.enableDepthOfField.value ? apertureRadius : 0.0f, hdCamera.physicalParameters.focusDistance, 0.0f, 0.0f) ; + } + #if UNITY_EDITOR private void OnSceneEdit() @@ -275,6 +299,8 @@ void RenderPathTracing(HDCamera hdCamera, CommandBuffer cmd, RTHandle outputText // Additional data for path tracing cmd.SetRayTracingTextureParam(pathTracingShader, HDShaderIDs._RadianceTexture, m_RadianceTexture); cmd.SetRayTracingMatrixParam(pathTracingShader, HDShaderIDs._PixelCoordToViewDirWS, hdCamera.mainViewConstants.pixelCoordToViewDirWS); + cmd.SetRayTracingMatrixParam(pathTracingShader, HDShaderIDs._InvViewportTransform, ComputeInverseViewportMatrix(hdCamera)); + cmd.SetRayTracingVectorParam(pathTracingShader, HDShaderIDs._PathTracedDoFConstants, ComputeDoFConstants(hdCamera, m_PathTracingSettings)); // Run the computation cmd.DispatchRays(pathTracingShader, "RayGen", (uint)hdCamera.actualWidth, (uint)hdCamera.actualHeight, 1); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace index 954056c50b9..7a985c8ffc6 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace @@ -22,6 +22,10 @@ float4x4 _PixelCoordToViewDirWS; int _RaytracingCameraSkyEnabled; float3 _RaytracingCameraClearColor; +// DoF related parameters +float4x4 _InvViewportTransform; +float4 _PathTracedDoFConstants; // x: aperture radius, y: focus distance, zw: unused + // Output(s) RWTexture2D _RadianceTexture; @@ -53,6 +57,13 @@ void MissMaterial(inout PathIntersection pathIntersection : SV_RayPayload) ApplyFogAttenuation(WorldRayOrigin(), WorldRayDirection(), pathIntersection.value); } +float2 UniformPointWithinCircle(float radius, float u1, float u2) +{ + float r = radius * sqrt(u1); + float theta = 2 * u2 * PI; + return float2(r * cos(theta), r * sin(theta)); +} + [shader("raygeneration")] void RayGen() { @@ -66,12 +77,47 @@ void RayGen() jitteredPixelCoord.x += GetSample(currentPixelCoord, _RaytracingSampleIndex, 40); jitteredPixelCoord.y += GetSample(currentPixelCoord, _RaytracingSampleIndex, 41); - // Compute the ray direction, from those coordinates - float3 directionWS = -normalize(mul(jitteredPixelCoord, (float3x3)_PixelCoordToViewDirWS)); + float3 directionWS; + float3 cameraPosWS; + + float apertureRadius = _PathTracedDoFConstants.x; + if (apertureRadius == 0.0) + { + // Compute the ray direction, from those coordinates for a pinhole camera + directionWS = -normalize(mul(jitteredPixelCoord, (float3x3)_PixelCoordToViewDirWS)); + cameraPosWS = _WorldSpaceCameraPos; + } + else + { + float focusDistance = _PathTracedDoFConstants.y; + + // Apply the inverse viewport transform to go from vieport coordinates to NDC + jitteredPixelCoord = mul(jitteredPixelCoord, (float3x3)_InvViewportTransform); + + // Sample the lens apperture + float r1 = GetSample(currentPixelCoord, _RaytracingSampleIndex, 106); + float r2 = GetSample(currentPixelCoord, _RaytracingSampleIndex, 107); + float2 uv = UniformPointWithinCircle(apertureRadius, r1, r2); + + // Compute the new ray origin + float3x3 camera = -_ViewMatrix; + // camera[0] = left, camera[1] = up, camera[2] = forward + float3 focusPoint = _WorldSpaceCameraPos + camera[2] * focusDistance; + cameraPosWS = _WorldSpaceCameraPos + camera[0] * uv.x + camera[1] * uv.y; + + // create the new orthonormal basis + float3 newForward = normalize(cameraPosWS - focusPoint); + float3 newLeft = cross(camera[1], newForward); + float3 newUp = cross(newLeft, newForward); + + // Compute the ray direction using the new orthonormal basis + float3x3 newRotation = float3x3(newLeft, newUp, newForward); + directionWS = -normalize(mul(jitteredPixelCoord, newRotation)); + } // Create the ray descriptor for this pixel RayDesc rayDescriptor; - rayDescriptor.Origin = _WorldSpaceCameraPos; + rayDescriptor.Origin = cameraPosWS; rayDescriptor.Direction = directionWS; rayDescriptor.TMin = _RaytracingCameraNearPlane; rayDescriptor.TMax = FLT_INF; From 80d7a4ed1734c303504f8921c1d36c2f0f008867 Mon Sep 17 00:00:00 2001 From: Pavlos Mavridis Date: Thu, 16 Apr 2020 20:13:13 +0200 Subject: [PATCH 02/18] Move focus distance from volume to physical camera --- .../Editor/PostProcessing/DepthOfFieldEditor.cs | 7 ------- .../Runtime/PostProcessing/Components/DepthOfField.cs | 6 ------ .../Runtime/PostProcessing/PostProcessSystem.cs | 2 +- 3 files changed, 1 insertion(+), 14 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Editor/PostProcessing/DepthOfFieldEditor.cs b/com.unity.render-pipelines.high-definition/Editor/PostProcessing/DepthOfFieldEditor.cs index b83fe275edf..79bd2f3a8a9 100644 --- a/com.unity.render-pipelines.high-definition/Editor/PostProcessing/DepthOfFieldEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/PostProcessing/DepthOfFieldEditor.cs @@ -9,9 +9,6 @@ sealed class DepthOfFieldEditor : VolumeComponentWithQualityEditor { SerializedDataParameter m_FocusMode; - // Physical mode - SerializedDataParameter m_FocusDistance; - // Manual mode SerializedDataParameter m_NearFocusStart; SerializedDataParameter m_NearFocusEnd; @@ -38,8 +35,6 @@ public override void OnEnable() m_FocusMode = Unpack(o.Find(x => x.focusMode)); - m_FocusDistance = Unpack(o.Find(x => x.focusDistance)); - m_NearFocusStart = Unpack(o.Find(x => x.nearFocusStart)); m_NearFocusEnd = Unpack(o.Find(x => x.nearFocusEnd)); m_FarFocusStart = Unpack(o.Find(x => x.farFocusStart)); @@ -68,8 +63,6 @@ public override void OnInspectorGUI() if (mode == (int)DepthOfFieldMode.UsePhysicalCamera) { - PropertyField(m_FocusDistance); - if (advanced) { GUI.enabled = useCustomValue; diff --git a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Components/DepthOfField.cs b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Components/DepthOfField.cs index 5969c50c4de..b953921c856 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Components/DepthOfField.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Components/DepthOfField.cs @@ -64,12 +64,6 @@ public sealed class DepthOfField : VolumeComponentWithQuality, IPostProcessCompo // Physical settings // - /// - /// Sets the distance to the focus point from the Camera. - /// - [Tooltip("Sets the distance to the focus point from the Camera.")] - public MinFloatParameter focusDistance = new MinFloatParameter(10f, 0.1f); - // ------------------------------------------- // Manual settings // Note: because they can't mathematically be mapped to physical settings, interpolating diff --git a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs index a3d37de005c..05c3466aecc 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs @@ -1200,7 +1200,7 @@ void DoDepthOfField(CommandBuffer cmd, HDCamera camera, RTHandle source, RTHandl // "A Lens and Aperture Camera Model for Synthetic Image Generation" [Potmesil81] float F = camera.camera.focalLength / 1000f; float A = camera.camera.focalLength / m_PhysicalCamera.aperture; - float P = m_DepthOfField.focusDistance.value; + float P = camera.physicalParameters.focusDistance; float maxCoC = (A * F) / Mathf.Max((P - F), 1e-6f); kernel = cs.FindKernel("KMainPhysical"); From fb0b981bc7fdc2fbea030d3a2ecc6de9a1d1096c Mon Sep 17 00:00:00 2001 From: Pavlos Mavridis Date: Thu, 16 Apr 2020 21:23:30 +0200 Subject: [PATCH 03/18] Small fixes --- .../Runtime/PostProcessing/PostProcessSystem.cs | 2 +- .../Runtime/RenderPipeline/Camera/HDAdditionalCameraData.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs index 05c3466aecc..68229150021 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs @@ -1200,7 +1200,7 @@ void DoDepthOfField(CommandBuffer cmd, HDCamera camera, RTHandle source, RTHandl // "A Lens and Aperture Camera Model for Synthetic Image Generation" [Potmesil81] float F = camera.camera.focalLength / 1000f; float A = camera.camera.focalLength / m_PhysicalCamera.aperture; - float P = camera.physicalParameters.focusDistance; + float P = m_PhysicalCamera.focusDistance; float maxCoC = (A * F) / Mathf.Max((P - F), 1e-6f); kernel = cs.FindKernel("KMainPhysical"); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDAdditionalCameraData.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDAdditionalCameraData.cs index 386bf96b71f..fc26c072a43 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDAdditionalCameraData.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDAdditionalCameraData.cs @@ -135,6 +135,7 @@ public void CopyTo(HDPhysicalCamera c) c.curvature = curvature; c.barrelClipping = barrelClipping; c.anamorphism = anamorphism; + c.focusDistance = focusDistance; } } From ee3307cc69b42b0b6766afb3ec9fbe009923f6d8 Mon Sep 17 00:00:00 2001 From: Pavlos Mavridis Date: Thu, 16 Apr 2020 21:35:52 +0200 Subject: [PATCH 04/18] Small fixes in math --- .../PathTracing/Shaders/PathTracingMain.raytrace | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace index 7a985c8ffc6..067a30d0c10 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace @@ -100,14 +100,14 @@ void RayGen() float2 uv = UniformPointWithinCircle(apertureRadius, r1, r2); // Compute the new ray origin - float3x3 camera = -_ViewMatrix; + float3x3 camera = _ViewMatrix; // camera[0] = left, camera[1] = up, camera[2] = forward float3 focusPoint = _WorldSpaceCameraPos + camera[2] * focusDistance; cameraPosWS = _WorldSpaceCameraPos + camera[0] * uv.x + camera[1] * uv.y; // create the new orthonormal basis - float3 newForward = normalize(cameraPosWS - focusPoint); - float3 newLeft = cross(camera[1], newForward); + float3 newForward = normalize(focusPoint - cameraPosWS); + float3 newLeft = cross(newForward, camera[1]); float3 newUp = cross(newLeft, newForward); // Compute the ray direction using the new orthonormal basis From 54c0e4b4164c27c36bfaa12a1e8c577b6c921c5d Mon Sep 17 00:00:00 2001 From: Pavlos Mavridis Date: Thu, 16 Apr 2020 22:06:09 +0200 Subject: [PATCH 05/18] Small fixes in math 2 --- .../PathTracing/Shaders/PathTracingMain.raytrace | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace index 067a30d0c10..62666008f89 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace @@ -99,19 +99,17 @@ void RayGen() float r2 = GetSample(currentPixelCoord, _RaytracingSampleIndex, 107); float2 uv = UniformPointWithinCircle(apertureRadius, r1, r2); - // Compute the new ray origin - float3x3 camera = _ViewMatrix; - // camera[0] = left, camera[1] = up, camera[2] = forward - float3 focusPoint = _WorldSpaceCameraPos + camera[2] * focusDistance; - cameraPosWS = _WorldSpaceCameraPos + camera[0] * uv.x + camera[1] * uv.y; + // Compute the new ray origin ( _ViewMatrix[0] = right, _ViewMatrix[1] = up, _ViewMatrix[2] = forward ) + float3 focusPoint = _WorldSpaceCameraPos - _ViewMatrix[2] * focusDistance; + cameraPosWS = _WorldSpaceCameraPos + _ViewMatrix[0] * uv.x + _ViewMatrix[1] * uv.y; // create the new orthonormal basis - float3 newForward = normalize(focusPoint - cameraPosWS); - float3 newLeft = cross(newForward, camera[1]); + float3 newForward = normalize(cameraPosWS - focusPoint); + float3 newRight = cross(newForward, _ViewMatrix[1]); float3 newUp = cross(newLeft, newForward); // Compute the ray direction using the new orthonormal basis - float3x3 newRotation = float3x3(newLeft, newUp, newForward); + float3x3 newRotation = float3x3(newRight, newUp, newForward); directionWS = -normalize(mul(jitteredPixelCoord, newRotation)); } From 4e3ddbfdbb3e170b34c8460aa80ea1239a5d4dc8 Mon Sep 17 00:00:00 2001 From: Pavlos Mavridis Date: Thu, 16 Apr 2020 22:06:57 +0200 Subject: [PATCH 06/18] Compile error --- .../RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace index 62666008f89..f02668a3285 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace @@ -106,7 +106,7 @@ void RayGen() // create the new orthonormal basis float3 newForward = normalize(cameraPosWS - focusPoint); float3 newRight = cross(newForward, _ViewMatrix[1]); - float3 newUp = cross(newLeft, newForward); + float3 newUp = cross(newRight, newForward); // Compute the ray direction using the new orthonormal basis float3x3 newRotation = float3x3(newRight, newUp, newForward); From 3264781131e541bd6697150331b1c43fca6309d4 Mon Sep 17 00:00:00 2001 From: Pavlos Mavridis Date: Thu, 16 Apr 2020 22:12:09 +0200 Subject: [PATCH 07/18] Make new functions private --- .../Runtime/RenderPipeline/PathTracing/PathTracing.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs index 42c4749109f..53211d34dc0 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs @@ -103,7 +103,7 @@ internal void ResetPathTracing() } // Computes the transform from viewport to normalized device coordinates - internal Matrix4x4 ComputeInverseViewportMatrix(HDCamera hdCamera) + private Matrix4x4 ComputeInverseViewportMatrix(HDCamera hdCamera) { float verticalFoV = hdCamera.camera.GetGateFittedFieldOfView() * Mathf.Deg2Rad; Vector2 lensShift = hdCamera.camera.GetGateFittedLensShift(); @@ -111,7 +111,7 @@ internal Matrix4x4 ComputeInverseViewportMatrix(HDCamera hdCamera) return HDUtils.ComputePixelCoordToWorldSpaceViewDirectionMatrix(verticalFoV, lensShift, hdCamera.screenSize, Matrix4x4.identity, false, hdCamera.camera.aspect); } - internal Vector4 ComputeDoFConstants(HDCamera hdCamera, PathTracing settings) + private Vector4 ComputeDoFConstants(HDCamera hdCamera, PathTracing settings) { // focalLength is in mm, so we need to convert to meters. We also want the aperture radius, not diameter, so we divide by two. float apertureRadius = 0.5f * 0.001f * hdCamera.camera.focalLength / hdCamera.physicalParameters.aperture; From 704decfa46172e5c51d767a6377d648aad9d4097 Mon Sep 17 00:00:00 2001 From: Pavlos Mavridis Date: Thu, 16 Apr 2020 22:18:37 +0200 Subject: [PATCH 08/18] Cosmetic changes --- .../PathTracing/Shaders/PathTracingMain.raytrace | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace index f02668a3285..64c9b9ea341 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace @@ -61,7 +61,7 @@ float2 UniformPointWithinCircle(float radius, float u1, float u2) { float r = radius * sqrt(u1); float theta = 2 * u2 * PI; - return float2(r * cos(theta), r * sin(theta)); + return float2(r * cos(theta), r * sin(theta)); } [shader("raygeneration")] @@ -83,13 +83,13 @@ void RayGen() float apertureRadius = _PathTracedDoFConstants.x; if (apertureRadius == 0.0) { - // Compute the ray direction, from those coordinates for a pinhole camera + // Compute the ray direction from those coordinates (fast path for zero aperture) directionWS = -normalize(mul(jitteredPixelCoord, (float3x3)_PixelCoordToViewDirWS)); cameraPosWS = _WorldSpaceCameraPos; } else { - float focusDistance = _PathTracedDoFConstants.y; + // Compute the ray origin and direction for a lens with non-zero aperture // Apply the inverse viewport transform to go from vieport coordinates to NDC jitteredPixelCoord = mul(jitteredPixelCoord, (float3x3)_InvViewportTransform); @@ -100,10 +100,11 @@ void RayGen() float2 uv = UniformPointWithinCircle(apertureRadius, r1, r2); // Compute the new ray origin ( _ViewMatrix[0] = right, _ViewMatrix[1] = up, _ViewMatrix[2] = forward ) + float focusDistance = _PathTracedDoFConstants.y; float3 focusPoint = _WorldSpaceCameraPos - _ViewMatrix[2] * focusDistance; cameraPosWS = _WorldSpaceCameraPos + _ViewMatrix[0] * uv.x + _ViewMatrix[1] * uv.y; - // create the new orthonormal basis + // Create the new orthonormal basis float3 newForward = normalize(cameraPosWS - focusPoint); float3 newRight = cross(newForward, _ViewMatrix[1]); float3 newUp = cross(newRight, newForward); From f6958f2a82fe1a0ce13de4f7325d7e2174d59268 Mon Sep 17 00:00:00 2001 From: Pavlos Mavridis Date: Fri, 17 Apr 2020 10:00:24 +0200 Subject: [PATCH 09/18] Move viewport matrix function to utils --- .../Runtime/RenderPipeline/PathTracing/PathTracing.cs | 11 +---------- .../Runtime/RenderPipeline/Utility/HDUtils.cs | 9 +++++++++ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs index 53211d34dc0..e9b65c77a15 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs @@ -102,15 +102,6 @@ internal void ResetPathTracing() m_SubFrameManager.Reset(); } - // Computes the transform from viewport to normalized device coordinates - private Matrix4x4 ComputeInverseViewportMatrix(HDCamera hdCamera) - { - float verticalFoV = hdCamera.camera.GetGateFittedFieldOfView() * Mathf.Deg2Rad; - Vector2 lensShift = hdCamera.camera.GetGateFittedLensShift(); - - return HDUtils.ComputePixelCoordToWorldSpaceViewDirectionMatrix(verticalFoV, lensShift, hdCamera.screenSize, Matrix4x4.identity, false, hdCamera.camera.aspect); - } - private Vector4 ComputeDoFConstants(HDCamera hdCamera, PathTracing settings) { // focalLength is in mm, so we need to convert to meters. We also want the aperture radius, not diameter, so we divide by two. @@ -299,7 +290,7 @@ void RenderPathTracing(HDCamera hdCamera, CommandBuffer cmd, RTHandle outputText // Additional data for path tracing cmd.SetRayTracingTextureParam(pathTracingShader, HDShaderIDs._RadianceTexture, m_RadianceTexture); cmd.SetRayTracingMatrixParam(pathTracingShader, HDShaderIDs._PixelCoordToViewDirWS, hdCamera.mainViewConstants.pixelCoordToViewDirWS); - cmd.SetRayTracingMatrixParam(pathTracingShader, HDShaderIDs._InvViewportTransform, ComputeInverseViewportMatrix(hdCamera)); + cmd.SetRayTracingMatrixParam(pathTracingShader, HDShaderIDs._InvViewportTransform, HDUtils.ComputeInverseViewportMatrix(hdCamera)); cmd.SetRayTracingVectorParam(pathTracingShader, HDShaderIDs._PathTracedDoFConstants, ComputeDoFConstants(hdCamera, m_PathTracingSettings)); // Run the computation diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Utility/HDUtils.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Utility/HDUtils.cs index 69e5fee1443..bf9a92078ac 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Utility/HDUtils.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Utility/HDUtils.cs @@ -196,6 +196,15 @@ internal static Matrix4x4 ComputePixelCoordToWorldSpaceViewDirectionMatrix(float return Matrix4x4.Transpose(worldToViewMatrix.transpose * viewSpaceRasterTransform); } + // Computes the transform from unormilezed viewport/pixel coordinates to normalized device coordinates + internal static Matrix4x4 ComputeInverseViewportMatrix(HDCamera hdCamera) + { + float verticalFoV = hdCamera.camera.GetGateFittedFieldOfView() * Mathf.Deg2Rad; + Vector2 lensShift = hdCamera.camera.GetGateFittedLensShift(); + + return HDUtils.ComputePixelCoordToWorldSpaceViewDirectionMatrix(verticalFoV, lensShift, hdCamera.screenSize, Matrix4x4.identity, false, hdCamera.camera.aspect); + } + internal static float ComputZPlaneTexelSpacing(float planeDepth, float verticalFoV, float resolutionY) { float tanHalfVertFoV = Mathf.Tan(0.5f * verticalFoV); From 7748e13bc044e7ce66b32cb78c7bcc24f0e066b1 Mon Sep 17 00:00:00 2001 From: Pavlos Mavridis Date: Mon, 20 Apr 2020 10:27:49 +0200 Subject: [PATCH 10/18] Keep focus distance in the volume --- .../Editor/PostProcessing/DepthOfFieldEditor.cs | 7 +++++++ .../RenderPipeline/Camera/HDCameraUI.Drawers.cs | 1 - .../Editor/RenderPipeline/Camera/HDCameraUI.Skin.cs | 1 - .../RenderPipeline/Camera/SerializedHDCamera.cs | 2 -- .../RenderPipeline/PathTracing/PathTracingEditor.cs | 3 --- .../Runtime/PostProcessing/Components/DepthOfField.cs | 6 ++++++ .../Runtime/PostProcessing/PostProcessSystem.cs | 9 +++++++-- .../RenderPipeline/Camera/HDAdditionalCameraData.cs | 11 ----------- .../Runtime/RenderPipeline/PathTracing/PathTracing.cs | 11 ++++------- 9 files changed, 24 insertions(+), 27 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Editor/PostProcessing/DepthOfFieldEditor.cs b/com.unity.render-pipelines.high-definition/Editor/PostProcessing/DepthOfFieldEditor.cs index 79bd2f3a8a9..b83fe275edf 100644 --- a/com.unity.render-pipelines.high-definition/Editor/PostProcessing/DepthOfFieldEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/PostProcessing/DepthOfFieldEditor.cs @@ -9,6 +9,9 @@ sealed class DepthOfFieldEditor : VolumeComponentWithQualityEditor { SerializedDataParameter m_FocusMode; + // Physical mode + SerializedDataParameter m_FocusDistance; + // Manual mode SerializedDataParameter m_NearFocusStart; SerializedDataParameter m_NearFocusEnd; @@ -35,6 +38,8 @@ public override void OnEnable() m_FocusMode = Unpack(o.Find(x => x.focusMode)); + m_FocusDistance = Unpack(o.Find(x => x.focusDistance)); + m_NearFocusStart = Unpack(o.Find(x => x.nearFocusStart)); m_NearFocusEnd = Unpack(o.Find(x => x.nearFocusEnd)); m_FarFocusStart = Unpack(o.Find(x => x.farFocusStart)); @@ -63,6 +68,8 @@ public override void OnInspectorGUI() if (mode == (int)DepthOfFieldMode.UsePhysicalCamera) { + PropertyField(m_FocusDistance); + if (advanced) { GUI.enabled = useCustomValue; diff --git a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/HDCameraUI.Drawers.cs b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/HDCameraUI.Drawers.cs index 90a27f2fa36..f2db83088ee 100644 --- a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/HDCameraUI.Drawers.cs +++ b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/HDCameraUI.Drawers.cs @@ -377,7 +377,6 @@ static void Drawer_PhysicalCamera(SerializedHDCamera p, Editor owner) cam.focalLength.floatValue = focalLengthVal; } - EditorGUILayout.PropertyField(p.focusDistance, focusDistanceContent); EditorGUILayout.PropertyField(p.aperture, apertureContent); EditorGUILayout.PropertyField(cam.lensShift, lensShiftContent); } diff --git a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/HDCameraUI.Skin.cs b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/HDCameraUI.Skin.cs index c49060369b9..fa013832629 100644 --- a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/HDCameraUI.Skin.cs +++ b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/HDCameraUI.Skin.cs @@ -45,7 +45,6 @@ static partial class HDCameraUI static readonly GUIContent curvatureContent = EditorGUIUtility.TrTextContent("Curvature"); static readonly GUIContent barrelClippingContent = EditorGUIUtility.TrTextContent("Barrel Clipping"); static readonly GUIContent anamorphismContent = EditorGUIUtility.TrTextContent("Anamorphism"); - static readonly GUIContent focusDistanceContent = EditorGUIUtility.TrTextContent("Focus Distance", "Sets the distance to the focus point from the Camera."); static readonly GUIContent antialiasingContent = EditorGUIUtility.TrTextContent("Anti-aliasing", "The anti-aliasing method to use."); static readonly GUIContent SMAAQualityPresetContent = EditorGUIUtility.TrTextContent("SMAA Quality Preset", "The quality preset for SMAA, low has the best performance but worst quality, High has the highest quality but worst performance."); diff --git a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/SerializedHDCamera.cs b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/SerializedHDCamera.cs index 0b37f7b30e3..415bc740a51 100644 --- a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/SerializedHDCamera.cs +++ b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/SerializedHDCamera.cs @@ -18,7 +18,6 @@ class SerializedHDCamera public SerializedProperty curvature; public SerializedProperty barrelClipping; public SerializedProperty anamorphism; - public SerializedProperty focusDistance; public SerializedProperty antialiasing; public SerializedProperty SMAAQuality; @@ -71,7 +70,6 @@ public SerializedHDCamera(SerializedObject serializedObject) curvature = serializedAdditionalDataObject.FindProperty("physicalParameters.m_Curvature"); barrelClipping = serializedAdditionalDataObject.FindProperty("physicalParameters.m_BarrelClipping"); anamorphism = serializedAdditionalDataObject.FindProperty("physicalParameters.m_Anamorphism"); - focusDistance = serializedAdditionalDataObject.FindProperty("physicalParameters.m_FocusDistance"); antialiasing = serializedAdditionalDataObject.Find((HDAdditionalCameraData d) => d.antialiasing); SMAAQuality = serializedAdditionalDataObject.Find((HDAdditionalCameraData d) => d.SMAAQuality); diff --git a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/PathTracing/PathTracingEditor.cs b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/PathTracing/PathTracingEditor.cs index 5928b19b825..38718398b5f 100644 --- a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/PathTracing/PathTracingEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/PathTracing/PathTracingEditor.cs @@ -17,7 +17,6 @@ class PathTracingEditor : VolumeComponentEditor SerializedDataParameter m_MinDepth; SerializedDataParameter m_MaxDepth; SerializedDataParameter m_MaxIntensity; - SerializedDataParameter m_EnableDepthOfField; public override void OnEnable() { @@ -29,7 +28,6 @@ public override void OnEnable() m_MinDepth = Unpack(o.Find(x => x.minimumDepth)); m_MaxDepth = Unpack(o.Find(x => x.maximumDepth)); m_MaxIntensity = Unpack(o.Find(x => x.maximumIntensity)); - m_EnableDepthOfField = Unpack(o.Find(x => x.enableDepthOfField)); } public override void OnInspectorGUI() @@ -55,7 +53,6 @@ public override void OnInspectorGUI() PropertyField(m_MinDepth); PropertyField(m_MaxDepth); PropertyField(m_MaxIntensity); - PropertyField(m_EnableDepthOfField); EditorGUI.indentLevel--; // Make sure MaxDepth is always greater or equal than MinDepth diff --git a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Components/DepthOfField.cs b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Components/DepthOfField.cs index b953921c856..5969c50c4de 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Components/DepthOfField.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Components/DepthOfField.cs @@ -64,6 +64,12 @@ public sealed class DepthOfField : VolumeComponentWithQuality, IPostProcessCompo // Physical settings // + /// + /// Sets the distance to the focus point from the Camera. + /// + [Tooltip("Sets the distance to the focus point from the Camera.")] + public MinFloatParameter focusDistance = new MinFloatParameter(10f, 0.1f); + // ------------------------------------------- // Manual settings // Note: because they can't mathematically be mapped to physical settings, interpolating diff --git a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs index 68229150021..7d77e659d20 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs @@ -517,9 +517,14 @@ void PoolSource(ref RTHandle src, RTHandle dst) } } + // If Path tracing is enabled, then DoF is computed in the path tracer by sampling the lens aperure + bool isPathTracingEnabled = (camera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) && + camera.volumeStack.GetComponent().enable.value && + camera.camera.cameraType != CameraType.Preview); + // Depth of Field is done right after TAA as it's easier to just re-project the CoC // map rather than having to deal with all the implications of doing it before TAA - if (m_DepthOfField.IsActive() && !isSceneView && m_DepthOfFieldFS) + if (m_DepthOfField.IsActive() && !isSceneView && m_DepthOfFieldFS && !isPathTracingEnabled) { using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.DepthOfField))) { @@ -1200,7 +1205,7 @@ void DoDepthOfField(CommandBuffer cmd, HDCamera camera, RTHandle source, RTHandl // "A Lens and Aperture Camera Model for Synthetic Image Generation" [Potmesil81] float F = camera.camera.focalLength / 1000f; float A = camera.camera.focalLength / m_PhysicalCamera.aperture; - float P = m_PhysicalCamera.focusDistance; + float P = m_DepthOfField.focusDistance.value; float maxCoC = (A * F) / Mathf.Max((P - F), 1e-6f); kernel = cs.FindKernel("KMainPhysical"); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDAdditionalCameraData.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDAdditionalCameraData.cs index fc26c072a43..74c7adcfcfb 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDAdditionalCameraData.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDAdditionalCameraData.cs @@ -37,7 +37,6 @@ public class HDPhysicalCamera // Lens // Note: focalLength is already defined in the regular camera component [SerializeField] [Range(kMinAperture, kMaxAperture)] float m_Aperture = 16f; - [SerializeField] [Min(0f)] float m_FocusDistance = 1.0f; // Aperture shape [SerializeField] [Range(kMinBladeCount, kMaxBladeCount)] int m_BladeCount = 5; @@ -113,15 +112,6 @@ public float anamorphism set => m_Anamorphism = Mathf.Clamp(value, -1f, 1f); } - /// - /// The focus distancec of the camera. - /// - public float focusDistance - { - get => m_FocusDistance; - set => m_FocusDistance = Mathf.Max(value, 0f); - } - /// /// Copies the settings of this instance to another instance. /// @@ -135,7 +125,6 @@ public void CopyTo(HDPhysicalCamera c) c.curvature = curvature; c.barrelClipping = barrelClipping; c.anamorphism = anamorphism; - c.focusDistance = focusDistance; } } diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs index e9b65c77a15..180710f8f36 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs @@ -48,12 +48,6 @@ public sealed class PathTracing : VolumeComponent /// [Tooltip("Defines the maximum intensity value computed for a path segment.")] public ClampedFloatParameter maximumIntensity = new ClampedFloatParameter(10f, 0f, 100f); - - /// - /// Defines the maximum intensity value computed for a path segment. - /// - [Tooltip("Enables path-traced defocus blur / depth of field.")] - public BoolParameter enableDepthOfField = new BoolParameter(false); } public partial class HDRenderPipeline @@ -107,7 +101,10 @@ private Vector4 ComputeDoFConstants(HDCamera hdCamera, PathTracing settings) // focalLength is in mm, so we need to convert to meters. We also want the aperture radius, not diameter, so we divide by two. float apertureRadius = 0.5f * 0.001f * hdCamera.camera.focalLength / hdCamera.physicalParameters.aperture; - return new Vector4(settings.enableDepthOfField.value ? apertureRadius : 0.0f, hdCamera.physicalParameters.focusDistance, 0.0f, 0.0f) ; + var dofSettings = hdCamera.volumeStack.GetComponent(); + bool enableDof = (dofSettings.focusMode.value == DepthOfFieldMode.UsePhysicalCamera); + + return new Vector4(enableDof ? apertureRadius : 0.0f, dofSettings.focusDistance.value, 0.0f, 0.0f); } #if UNITY_EDITOR From 29cc8dff04c5e4c28b1ede3494015a5cdbacc57a Mon Sep 17 00:00:00 2001 From: Pavlos Mavridis Date: Mon, 20 Apr 2020 10:56:28 +0200 Subject: [PATCH 11/18] Do not enable in scene view camera --- .../Runtime/RenderPipeline/PathTracing/PathTracing.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs index 180710f8f36..b2c376778eb 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs @@ -102,7 +102,7 @@ private Vector4 ComputeDoFConstants(HDCamera hdCamera, PathTracing settings) float apertureRadius = 0.5f * 0.001f * hdCamera.camera.focalLength / hdCamera.physicalParameters.aperture; var dofSettings = hdCamera.volumeStack.GetComponent(); - bool enableDof = (dofSettings.focusMode.value == DepthOfFieldMode.UsePhysicalCamera); + bool enableDof = (dofSettings.focusMode.value == DepthOfFieldMode.UsePhysicalCamera) && !(hdCamera.camera.cameraType == CameraType.SceneView); return new Vector4(enableDof ? apertureRadius : 0.0f, dofSettings.focusDistance.value, 0.0f, 0.0f); } From 04cd6547d3aa9c89cf9653f79e2643cb7f6c3a38 Mon Sep 17 00:00:00 2001 From: Pavlos Mavridis Date: Mon, 20 Apr 2020 11:09:01 +0200 Subject: [PATCH 12/18] Changelog --- com.unity.render-pipelines.high-definition/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/com.unity.render-pipelines.high-definition/CHANGELOG.md b/com.unity.render-pipelines.high-definition/CHANGELOG.md index 97934f201e4..2a786a8694d 100644 --- a/com.unity.render-pipelines.high-definition/CHANGELOG.md +++ b/com.unity.render-pipelines.high-definition/CHANGELOG.md @@ -117,6 +117,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Added information for fabric materials in fabric scene - Added a DisplayInfo attribute to specify a name override and a display order for Volume Component fields (used only in default inspector for now). - Added Min distance to contact shadows. +- Added support for Depth of Field in path tracing (by sampling the lens aperture). ### Fixed - Fix when rescale probe all direction below zero (1219246) From 2078af8c38a30404bae659cc8d9929c13b5b288b Mon Sep 17 00:00:00 2001 From: Pavlos Mavridis Date: Mon, 20 Apr 2020 13:36:43 +0200 Subject: [PATCH 13/18] Review feedback --- .../Shaders/PathTracingMain.raytrace | 24 +++++++------------ .../Runtime/RenderPipeline/Utility/HDUtils.cs | 2 +- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace index 64c9b9ea341..397c1f1283b 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace @@ -6,6 +6,7 @@ #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Sampling/Sampling.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Builtin/BuiltinData.hlsl" @@ -57,13 +58,6 @@ void MissMaterial(inout PathIntersection pathIntersection : SV_RayPayload) ApplyFogAttenuation(WorldRayOrigin(), WorldRayDirection(), pathIntersection.value); } -float2 UniformPointWithinCircle(float radius, float u1, float u2) -{ - float r = radius * sqrt(u1); - float theta = 2 * u2 * PI; - return float2(r * cos(theta), r * sin(theta)); -} - [shader("raygeneration")] void RayGen() { @@ -91,27 +85,25 @@ void RayGen() { // Compute the ray origin and direction for a lens with non-zero aperture - // Apply the inverse viewport transform to go from vieport coordinates to NDC + // Apply the inverse viewport transform to go from viewport coordinates to NDC jitteredPixelCoord = mul(jitteredPixelCoord, (float3x3)_InvViewportTransform); - // Sample the lens apperture + // Sample the lens apperture using the next available dimensions (we use 40 for path tracing, 2 for sub-pixel jittering, 64 for SSS -> 106, 107) float r1 = GetSample(currentPixelCoord, _RaytracingSampleIndex, 106); float r2 = GetSample(currentPixelCoord, _RaytracingSampleIndex, 107); - float2 uv = UniformPointWithinCircle(apertureRadius, r1, r2); + float2 uv = apertureRadius * SampleDiskUniform(r1, r2); // Compute the new ray origin ( _ViewMatrix[0] = right, _ViewMatrix[1] = up, _ViewMatrix[2] = forward ) float focusDistance = _PathTracedDoFConstants.y; float3 focusPoint = _WorldSpaceCameraPos - _ViewMatrix[2] * focusDistance; cameraPosWS = _WorldSpaceCameraPos + _ViewMatrix[0] * uv.x + _ViewMatrix[1] * uv.y; - // Create the new orthonormal basis - float3 newForward = normalize(cameraPosWS - focusPoint); + // Create the new view matrix + float3 newForward = normalize(focusPoint - cameraPosWS); float3 newRight = cross(newForward, _ViewMatrix[1]); - float3 newUp = cross(newRight, newForward); + float3x3 newViewMatrix = GetLocalFrame(newForward, newRight); - // Compute the ray direction using the new orthonormal basis - float3x3 newRotation = float3x3(newRight, newUp, newForward); - directionWS = -normalize(mul(jitteredPixelCoord, newRotation)); + directionWS = normalize(mul(jitteredPixelCoord, newViewMatrix)); } // Create the ray descriptor for this pixel diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Utility/HDUtils.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Utility/HDUtils.cs index bf9a92078ac..00716dc3aa9 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Utility/HDUtils.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Utility/HDUtils.cs @@ -196,7 +196,7 @@ internal static Matrix4x4 ComputePixelCoordToWorldSpaceViewDirectionMatrix(float return Matrix4x4.Transpose(worldToViewMatrix.transpose * viewSpaceRasterTransform); } - // Computes the transform from unormilezed viewport/pixel coordinates to normalized device coordinates + // Computes the transform from unnormalized viewport/pixel coordinates to normalized device coordinates internal static Matrix4x4 ComputeInverseViewportMatrix(HDCamera hdCamera) { float verticalFoV = hdCamera.camera.GetGateFittedFieldOfView() * Mathf.Deg2Rad; From a4dc84b9665ecd4138e256057c92ed46d7b3caab Mon Sep 17 00:00:00 2001 From: Pavlos Mavridis Date: Mon, 20 Apr 2020 14:43:37 +0200 Subject: [PATCH 14/18] Use scale and bias instead of matrix mul for the viewport transform --- .../Runtime/RenderPipeline/HDStringConstants.cs | 2 +- .../RenderPipeline/PathTracing/PathTracing.cs | 2 +- .../PathTracing/Shaders/PathTracingMain.raytrace | 4 ++-- .../Runtime/RenderPipeline/Utility/HDUtils.cs | 14 +++++++++++--- 4 files changed, 15 insertions(+), 7 deletions(-) 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 be7b42b1c7d..28dc5a92ebe 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs @@ -460,7 +460,7 @@ static class HDShaderIDs // Path tracing variables public static readonly int _PathTracedDoFConstants = Shader.PropertyToID("_PathTracedDoFConstants"); - public static readonly int _InvViewportTransform = Shader.PropertyToID("_InvViewportTransform"); + public static readonly int _InvViewportScaleBias = Shader.PropertyToID("_InvViewportScaleBias"); // Light Cluster public static readonly int _MinClusterPos = Shader.PropertyToID("_MinClusterPos"); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs index b2c376778eb..94640372e02 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs @@ -287,8 +287,8 @@ void RenderPathTracing(HDCamera hdCamera, CommandBuffer cmd, RTHandle outputText // Additional data for path tracing cmd.SetRayTracingTextureParam(pathTracingShader, HDShaderIDs._RadianceTexture, m_RadianceTexture); cmd.SetRayTracingMatrixParam(pathTracingShader, HDShaderIDs._PixelCoordToViewDirWS, hdCamera.mainViewConstants.pixelCoordToViewDirWS); - cmd.SetRayTracingMatrixParam(pathTracingShader, HDShaderIDs._InvViewportTransform, HDUtils.ComputeInverseViewportMatrix(hdCamera)); cmd.SetRayTracingVectorParam(pathTracingShader, HDShaderIDs._PathTracedDoFConstants, ComputeDoFConstants(hdCamera, m_PathTracingSettings)); + cmd.SetRayTracingVectorParam(pathTracingShader, HDShaderIDs._InvViewportScaleBias, HDUtils.ComputeInverseViewportScaleBias(hdCamera)); // Run the computation cmd.DispatchRays(pathTracingShader, "RayGen", (uint)hdCamera.actualWidth, (uint)hdCamera.actualHeight, 1); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace index 397c1f1283b..96d27f76657 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingMain.raytrace @@ -24,8 +24,8 @@ int _RaytracingCameraSkyEnabled; float3 _RaytracingCameraClearColor; // DoF related parameters -float4x4 _InvViewportTransform; float4 _PathTracedDoFConstants; // x: aperture radius, y: focus distance, zw: unused +float4 _InvViewportScaleBias; // Output(s) RWTexture2D _RadianceTexture; @@ -86,7 +86,7 @@ void RayGen() // Compute the ray origin and direction for a lens with non-zero aperture // Apply the inverse viewport transform to go from viewport coordinates to NDC - jitteredPixelCoord = mul(jitteredPixelCoord, (float3x3)_InvViewportTransform); + jitteredPixelCoord.xy = jitteredPixelCoord.xy * _InvViewportScaleBias.xy + _InvViewportScaleBias.zw; // Sample the lens apperture using the next available dimensions (we use 40 for path tracing, 2 for sub-pixel jittering, 64 for SSS -> 106, 107) float r1 = GetSample(currentPixelCoord, _RaytracingSampleIndex, 106); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Utility/HDUtils.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Utility/HDUtils.cs index 00716dc3aa9..e4eb93d15cf 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Utility/HDUtils.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Utility/HDUtils.cs @@ -196,13 +196,21 @@ internal static Matrix4x4 ComputePixelCoordToWorldSpaceViewDirectionMatrix(float return Matrix4x4.Transpose(worldToViewMatrix.transpose * viewSpaceRasterTransform); } - // Computes the transform from unnormalized viewport/pixel coordinates to normalized device coordinates - internal static Matrix4x4 ComputeInverseViewportMatrix(HDCamera hdCamera) + // Scale and bias to transform unnormalized viewport/pixel coordinates to normalized device coordinates + internal static Vector4 ComputeInverseViewportScaleBias(HDCamera hdCamera) { float verticalFoV = hdCamera.camera.GetGateFittedFieldOfView() * Mathf.Deg2Rad; Vector2 lensShift = hdCamera.camera.GetGateFittedLensShift(); - return HDUtils.ComputePixelCoordToWorldSpaceViewDirectionMatrix(verticalFoV, lensShift, hdCamera.screenSize, Matrix4x4.identity, false, hdCamera.camera.aspect); + float aspectRatio = hdCamera.camera.aspect < 0 ? hdCamera.screenSize.x * hdCamera.screenSize.w : hdCamera.camera.aspect; + float tanHalfVertFoV = Mathf.Tan(0.5f * verticalFoV); + + // See the comment in ComputePixelCoordToWorldSpaceViewDirectionMatrix for the derivation + return new Vector4( + -2.0f * hdCamera.screenSize.z * tanHalfVertFoV * aspectRatio, + -2.0f * hdCamera.screenSize.w * tanHalfVertFoV, + (1.0f - 2.0f * lensShift.x) * tanHalfVertFoV * aspectRatio, + (1.0f - 2.0f * lensShift.y) * tanHalfVertFoV); } internal static float ComputZPlaneTexelSpacing(float planeDepth, float verticalFoV, float resolutionY) From 9133ecc749aa547eabfe2e452a7ee209c4a39ce3 Mon Sep 17 00:00:00 2001 From: Pavlos Mavridis Date: Tue, 21 Apr 2020 08:47:02 +0200 Subject: [PATCH 15/18] Bugfix: post process DoF should still be executed for non-physical mode --- .../Runtime/PostProcessing/PostProcessSystem.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs index 7d77e659d20..67d648c6c13 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs @@ -517,14 +517,15 @@ void PoolSource(ref RTHandle src, RTHandle dst) } } - // If Path tracing is enabled, then DoF is computed in the path tracer by sampling the lens aperure - bool isPathTracingEnabled = (camera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) && + // If Path tracing is enabled, then DoF is computed in the path tracer by sampling the lens aperure (when using the phgysical camera mode) + bool isDoFPathTraced = (camera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) && camera.volumeStack.GetComponent().enable.value && - camera.camera.cameraType != CameraType.Preview); + camera.camera.cameraType != CameraType.Preview && + m_DepthOfField.focusMode == DepthOfFieldMode.UsePhysicalCamera); // Depth of Field is done right after TAA as it's easier to just re-project the CoC // map rather than having to deal with all the implications of doing it before TAA - if (m_DepthOfField.IsActive() && !isSceneView && m_DepthOfFieldFS && !isPathTracingEnabled) + if (m_DepthOfField.IsActive() && !isSceneView && m_DepthOfFieldFS && !isDoFPathTraced) { using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.DepthOfField))) { From 47a769551f328d5736b15fd9073aa76eb234f611 Mon Sep 17 00:00:00 2001 From: Pavlos Mavridis Date: Tue, 21 Apr 2020 09:38:54 +0200 Subject: [PATCH 16/18] Typo --- .../Runtime/PostProcessing/PostProcessSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs index 67d648c6c13..53acbb6240e 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs @@ -517,7 +517,7 @@ void PoolSource(ref RTHandle src, RTHandle dst) } } - // If Path tracing is enabled, then DoF is computed in the path tracer by sampling the lens aperure (when using the phgysical camera mode) + // If Path tracing is enabled, then DoF is computed in the path tracer by sampling the lens aperure (when using the physical camera mode) bool isDoFPathTraced = (camera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) && camera.volumeStack.GetComponent().enable.value && camera.camera.cameraType != CameraType.Preview && From 4392824a4d0627bdea0a31caeec47788c4b0a83a Mon Sep 17 00:00:00 2001 From: Pavlos Mavridis Date: Tue, 21 Apr 2020 16:48:41 +0200 Subject: [PATCH 17/18] avoid null reference when physical params is null --- .../Runtime/RenderPipeline/PathTracing/PathTracing.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs index 94640372e02..ae07113360f 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs @@ -98,12 +98,12 @@ internal void ResetPathTracing() private Vector4 ComputeDoFConstants(HDCamera hdCamera, PathTracing settings) { - // focalLength is in mm, so we need to convert to meters. We also want the aperture radius, not diameter, so we divide by two. - float apertureRadius = 0.5f * 0.001f * hdCamera.camera.focalLength / hdCamera.physicalParameters.aperture; - var dofSettings = hdCamera.volumeStack.GetComponent(); bool enableDof = (dofSettings.focusMode.value == DepthOfFieldMode.UsePhysicalCamera) && !(hdCamera.camera.cameraType == CameraType.SceneView); + // focalLength is in mm, so we need to convert to meters. We also want the aperture radius, not diameter, so we divide by two. + float apertureRadius = (enableDof && hdCamera.physicalParameters != null && hdCamera.physicalParameters.aperture > 0) ? 0.5f * 0.001f * hdCamera.camera.focalLength / hdCamera.physicalParameters.aperture : 0.0f; + return new Vector4(enableDof ? apertureRadius : 0.0f, dofSettings.focusDistance.value, 0.0f, 0.0f); } From 5369ca74d57fa8afe2f8634c5fb955b440039450 Mon Sep 17 00:00:00 2001 From: Pavlos Mavridis Date: Tue, 21 Apr 2020 17:07:08 +0200 Subject: [PATCH 18/18] remove redundant check --- .../Runtime/RenderPipeline/PathTracing/PathTracing.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs index ae07113360f..d558250091e 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs @@ -104,7 +104,7 @@ private Vector4 ComputeDoFConstants(HDCamera hdCamera, PathTracing settings) // focalLength is in mm, so we need to convert to meters. We also want the aperture radius, not diameter, so we divide by two. float apertureRadius = (enableDof && hdCamera.physicalParameters != null && hdCamera.physicalParameters.aperture > 0) ? 0.5f * 0.001f * hdCamera.camera.focalLength / hdCamera.physicalParameters.aperture : 0.0f; - return new Vector4(enableDof ? apertureRadius : 0.0f, dofSettings.focusDistance.value, 0.0f, 0.0f); + return new Vector4(apertureRadius, dofSettings.focusDistance.value, 0.0f, 0.0f); } #if UNITY_EDITOR