From 19a8055cca5dd6f85a56c590f3fa04491ae5351f Mon Sep 17 00:00:00 2001 From: Erik Hakala Date: Mon, 19 Oct 2020 21:17:26 +0300 Subject: [PATCH 01/23] Debug culling render feature --- .../RendererFeatures/DebugCullingFeature.cs | 404 ++++++++++++++++++ .../DebugCullingFeature.cs.meta | 11 + 2 files changed, 415 insertions(+) create mode 100644 com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs create mode 100644 com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs.meta diff --git a/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs b/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs new file mode 100644 index 00000000000..2e4c30d6504 --- /dev/null +++ b/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs @@ -0,0 +1,404 @@ +using System; +using UnityEditor.Graphs; + +namespace UnityEngine.Rendering.Universal +{ + internal static class DebugCullingHelpers + { + static readonly Vector4[] s_NdcFrustum = + { + new Vector4(-1, 1, -1, 1), + new Vector4( 1, 1, -1, 1), + new Vector4( 1, -1, -1, 1), + new Vector4(-1, -1, -1, 1), + + new Vector4(-1, 1, 1, 1), + new Vector4( 1, 1, 1, 1), + new Vector4( 1, -1, 1, 1), + new Vector4(-1, -1, 1, 1) + }; + + // Cube with edge of length 1 + private static readonly Vector4[] s_UnitCube = + { + new Vector4(-0.5f, 0.5f, -0.5f, 1), + new Vector4( 0.5f, 0.5f, -0.5f, 1), + new Vector4( 0.5f, -0.5f, -0.5f, 1), + new Vector4(-0.5f, -0.5f, -0.5f, 1), + + new Vector4(-0.5f, 0.5f, 0.5f, 1), + new Vector4( 0.5f, 0.5f, 0.5f, 1), + new Vector4( 0.5f, -0.5f, 0.5f, 1), + new Vector4(-0.5f, -0.5f, 0.5f, 1) + }; + + // Sphere with radius of 1 + private static readonly Vector4[] s_UnitSphere = MakeUnitSphere(16); + + // Square with edge of length 1 + private static readonly Vector4[] s_UnitSquare = + { + new Vector4(-0.5f, 0.5f, 0, 1), + new Vector4( 0.5f, 0.5f, 0, 1), + new Vector4( 0.5f,-0.5f, 0, 1), + new Vector4(-0.5f,-0.5f, 0, 1), + }; + + private static Vector4[] MakeUnitSphere(int len) + { + Debug.Assert(len > 2); + var v = new Vector4[len*3]; + for (int i = 0; i < len; i++) + { + var f = i / (float) len; + float c = Mathf.Cos(f * (float)(Math.PI * 2.0)); + float s = Mathf.Sin(f * (float)(Math.PI * 2.0)); + v[0 * len + i] = new Vector4(c, s, 0, 1); + v[1 * len + i] = new Vector4(0, c, s, 1); + v[2 * len + i] = new Vector4(s, 0, c, 1); + } + return v; + } + + public static void DrawFrustum(Matrix4x4 projMatrix) { DrawFrustum(projMatrix, Color.red, Color.magenta, Color.blue); } + public static void DrawFrustum(Matrix4x4 projMatrix, Color near, Color edge, Color far) + { + Vector4[] v = s_NdcFrustum; + Matrix4x4 m = projMatrix.inverse; + // Near + for (int i = 0; i < 4; i++) + { + var s = m * v[i]; + var e = m * v[(i + 1) % 4]; + Debug.DrawLine(s / s.w, e / e.w, near); + } + // Far + for (int i = 0; i < 4; i++) + { + var s = m * v[4 + i]; + var e = m * v[4 + ((i + 1) % 4)]; + Debug.DrawLine(s / s.w, e / e.w, far); + } + // Middle + for (int i = 0; i < 4; i++) + { + var s = m * v[i]; + var e = m * v[i + 4]; + Debug.DrawLine(s / s.w, e / e.w, edge); + } + } + + public static void DrawBox(Vector4 pos, Vector3 size, Color color) + { + Vector4[] v = s_UnitCube; + Vector4 sz = new Vector4(size.x, size. y, size.z, 1); + for (int i = 0; i < 4; i++) + { + var s = pos + Vector4.Scale(v[i], sz); + var e = pos + Vector4.Scale(v[(i + 1) % 4], sz); + Debug.DrawLine(s , e , color); + } + for (int i = 0; i < 4; i++) + { + var s = pos + Vector4.Scale(v[4 + i], sz); + var e = pos + Vector4.Scale(v[4 + ((i + 1) % 4)], sz); + Debug.DrawLine(s , e , color); + } + for (int i = 0; i < 4; i++) + { + var s = pos + Vector4.Scale(v[i], sz); + var e = pos + Vector4.Scale(v[i + 4], sz); + Debug.DrawLine(s , e , color); + } + } + + public static void DrawBox(Matrix4x4 transform, Color color) + { + Vector4[] v = s_UnitCube; + Matrix4x4 m = transform; + for (int i = 0; i < 4; i++) + { + var s = m * v[i]; + var e = m * v[(i + 1) % 4]; + Debug.DrawLine(s , e , color); + } + for (int i = 0; i < 4; i++) + { + var s = m * v[4 + i]; + var e = m * v[4 + ((i + 1) % 4)]; + Debug.DrawLine(s , e , color); + } + for (int i = 0; i < 4; i++) + { + var s = m * v[i]; + var e = m * v[i + 4]; + Debug.DrawLine(s , e , color); + } + } + + public static void DrawSphere(Vector4 pos, float radius, Color color) + { + Vector4[] v = s_UnitSphere; + int len = s_UnitSphere.Length / 3; + for (int i = 0; i < len; i++) + { + var sX = pos + radius * v[0 * len + i]; + var eX = pos + radius * v[0 * len + (i + 1) % len]; + var sY = pos + radius * v[1 * len + i]; + var eY = pos + radius * v[1 * len + (i + 1) % len]; + var sZ = pos + radius * v[2 * len + i]; + var eZ = pos + radius * v[2 * len + (i + 1) % len]; + Debug.DrawLine(sX, eX, color); + Debug.DrawLine(sY, eY, color); + Debug.DrawLine(sZ, eZ, color); + } + } + + public static void DrawPoint(Vector4 pos, float scale, Color color) + { + var sX = pos + new Vector4(+scale, 0, 0); + var eX = pos + new Vector4(-scale, 0, 0); + var sY = pos + new Vector4(0, +scale, 0); + var eY = pos + new Vector4(0, -scale, 0); + var sZ = pos + new Vector4(0, 0, +scale); + var eZ = pos + new Vector4(0, 0, -scale); + Debug.DrawLine(sX , eX , color); + Debug.DrawLine(sY , eY , color); + Debug.DrawLine(sZ , eZ , color); + } + + public static void DrawAxes(Vector4 pos, float scale = 1.0f) + { + Debug.DrawLine( pos, pos + new Vector4(scale,0,0), Color.red); + Debug.DrawLine( pos, pos + new Vector4(0,scale,0), Color.green); + Debug.DrawLine( pos, pos + new Vector4(0,0,scale), Color.blue); + } + + public static void DrawAxes(Matrix4x4 transform, float scale = 1.0f) + { + Vector4 p = transform * new Vector4(0, 0, 0, 1); + Vector4 x = transform * new Vector4(scale, 0, 0, 1); + Vector4 y = transform * new Vector4(0, scale, 0, 1); + Vector4 z = transform * new Vector4(0, 0, scale, 1); + + Debug.DrawLine( p, x, Color.red); + Debug.DrawLine( p, y, Color.green); + Debug.DrawLine( p, z, Color.blue); + } + + public static void DrawPlane(Plane plane, float scale, Color edgeColor, float normalScale, Color normalColor) + { + // Flip plane distance: Unity Plane distance is from plane to origin + DrawPlane(new Vector4(plane.normal.x, plane.normal.y, plane.normal.z, -plane.distance), scale, edgeColor, normalScale, normalColor); + } + public static void DrawPlane(Vector4 plane, float scale, Color edgeColor, float normalScale, Color normalColor) + { + Vector3 n = Vector3.Normalize(plane); + float d = plane.w; + + Vector3 u = Vector3.up; + Vector3 r = Vector3.right; + if (n == u) + u = r; + + r = Vector3.Cross(n, u); + u = Vector3.Cross(n, r); + + for (int i = 0; i < 4; i++) + { + var s = scale * s_UnitSquare[i]; + var e = scale * s_UnitSquare[(i + 1) % 4]; + s = s.x * r + s.y * u + n * d; + e = e.x * r + e.y * u + n * d; + Debug.DrawLine(s, e, edgeColor); + } + + // Diagonals + { + var s = scale * s_UnitSquare[0]; + var e = scale * s_UnitSquare[2]; + s = s.x * r + s.y * u + n * d; + e = e.x * r + e.y * u + n * d; + Debug.DrawLine(s, e, edgeColor); + } + { + var s = scale * s_UnitSquare[1]; + var e = scale * s_UnitSquare[3]; + s = s.x * r + s.y * u + n * d; + e = e.x * r + e.y * u + n * d; + Debug.DrawLine(s, e, edgeColor); + } + + Debug.DrawLine(n * d, n * (d+1*normalScale), normalColor); + } + } + + [DisallowMultipleRendererFeature] + public class DebugCullingFeature : ScriptableRendererFeature + { + private DebugCullingPass m_Pass; + public class DebugCullingPass : ScriptableRenderPass + { + public DebugCullingPass() + { + base.renderPassEvent = RenderPassEvent.BeforeRendering; + base.profilingSampler = new ProfilingSampler(nameof(ScriptableRenderPass)); + } + + /// + /// Execute the pass. This is where custom rendering occurs. Specific details are left to the implementation + /// + /// Use this render context to issue any draw commands during execution + /// Current rendering state information + public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) + { + if (renderingData.cameraData.camera.cameraType == CameraType.Game && renderingData.cameraData.camera.name != "Preview Camera") + { + var camPos = renderingData.cameraData.camera.cameraToWorldMatrix * new Vector4(0,0,0,1); + var camFront = renderingData.cameraData.camera.cameraToWorldMatrix.GetColumn(2); + foreach (var l in renderingData.lightData.visibleLights) + { + Debug.DrawLine( camPos, l.localToWorldMatrix.GetColumn(3), Color.yellow); + + if (false) + { + DebugCullingHelpers.DrawSphere(l.localToWorldMatrix.GetColumn(3), l.range, Color.yellow); + } + } + + DebugCullingHelpers.DrawFrustum(renderingData.cameraData.camera.cullingMatrix); + DebugCullingHelpers.DrawAxes(renderingData.cameraData.camera.cameraToWorldMatrix, 0.25f); + + DebugCullingHelpers.DrawPlane(new Vector4(1,0,0,2), 4, Color.red, 10,Color.red ); + DebugCullingHelpers.DrawPlane(new Vector4(0,1,0,2), 4, Color.green, 10,Color.green ); + DebugCullingHelpers.DrawPlane(new Vector4(0,0,1,2), 4, Color.blue, 10,Color.blue ); + DebugCullingHelpers.DrawPlane(new Vector4(1,1,1,3.46f), 4, Color.white, 10,Color.white ); + // Test + /*{ + DebugCullingHelpers.DrawPlane(new Vector4(1,0,1,0), 10, Color.green, 5,Color.white ); + + DebugCullingHelpers.DrawBox(new Vector4(0,0,5,1), new Vector3(1, 2, 3 ), Color.gray ); + DebugCullingHelpers.DrawPoint(new Vector4(3,1,0,1), 1, Color.cyan ); + }*/ + + // Origin + { + Debug.DrawLine( Vector3.zero, new Vector3(1,0,0), Color.red); + Debug.DrawLine( Vector3.zero, new Vector3(0,1,0), Color.green); + Debug.DrawLine( Vector3.zero, new Vector3(0,0,1), Color.blue); + } + + int mainLightIndex = renderingData.lightData.mainLightIndex; + VisibleLight mainLight = renderingData.lightData.visibleLights[mainLightIndex]; + + Bounds bounds; + bool boundsFound = renderingData.cullResults.GetShadowCasterBounds(mainLightIndex, out bounds); + if (boundsFound) + { + DebugCullingHelpers.DrawBox(bounds.center, bounds.size, Color.gray ); + } + + var shadowCascadesCount = renderingData.shadowData.mainLightShadowCascadesCount; + Matrix4x4[] view = new Matrix4x4[shadowCascadesCount]; + Matrix4x4[] proj = new Matrix4x4[shadowCascadesCount]; + ShadowSplitData[] shadowSplitData = new ShadowSplitData[shadowCascadesCount]; + + { + int shadowResolution = ShadowUtils.GetMaxTileResolutionInAtlas(renderingData.shadowData.mainLightShadowmapWidth, + renderingData.shadowData.mainLightShadowmapHeight, shadowCascadesCount); + for (int cascadeIndex = 0; cascadeIndex < shadowCascadesCount; ++cascadeIndex) + { + bool success = renderingData.cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(mainLightIndex, + cascadeIndex, renderingData.shadowData.mainLightShadowCascadesCount, renderingData.shadowData.mainLightShadowCascadesSplit, shadowResolution, mainLight.light.shadowNearPlane, + out view[cascadeIndex], out proj[cascadeIndex], out shadowSplitData[cascadeIndex]); + } + } + + for (int cascadeIndex = 0; cascadeIndex < shadowCascadesCount; ++cascadeIndex) + { + var shadowTransform = proj[cascadeIndex] * view[cascadeIndex]; + DebugCullingHelpers.DrawFrustum( shadowTransform, Color.white, Color.yellow, Color.black); + DebugCullingHelpers.DrawAxes(shadowTransform.inverse, 0.25f); + } + + for (int cascadeIndex = 0; cascadeIndex < shadowCascadesCount; ++cascadeIndex) + { + Vector4 s = shadowSplitData[cascadeIndex].cullingSphere; + Vector3 c = s; + float radius = s.w; + DebugCullingHelpers.DrawSphere( c, radius, Color.white); + DebugCullingHelpers.DrawPoint( c, 0.5f, Color.white); + } + + //for (int cascadeIndex = 0; cascadeIndex < shadowCascadesCount; ++cascadeIndex) + /*{ + var cascadeIndex = 0; + + var pc = Color.Lerp(Color.cyan, Color.black, cascadeIndex / (float) shadowCascadesCount); + var nc = Color.Lerp(Color.blue, Color.black, cascadeIndex / (float) shadowCascadesCount); + var ssd = shadowSplitData[cascadeIndex]; + + var pi = 8; + //for (int pi = 0; pi < ssd.cullingPlaneCount; pi++) + { + var p = ssd.GetCullingPlane(pi); + DebugCullingHelpers.DrawPlane(p,100.0f, pc, 5.0f, nc); + } + }*/ + + //var camFrontPlane = camFront; + //camFrontPlane.w = Vector3.Dot(camPos, camFront) - splitDistances.x; + //DebugCullingHelpers.DrawPlane(camFrontPlane, 5, Color.white, 3, Color.red); + } + } + + static Matrix4x4 GetShadowTransform(Matrix4x4 proj, Matrix4x4 view) + { + // Currently CullResults ComputeDirectionalShadowMatricesAndCullingPrimitives doesn't + // apply z reversal to projection matrix. We need to do it manually here. + /*if (SystemInfo.usesReversedZBuffer) + { + proj.m20 = -proj.m20; + proj.m21 = -proj.m21; + proj.m22 = -proj.m22; + proj.m23 = -proj.m23; + }*/ + + Matrix4x4 worldToShadow = proj * view; + + var textureScaleAndBias = Matrix4x4.identity; + textureScaleAndBias.m00 = 0.5f; + textureScaleAndBias.m11 = 0.5f; + textureScaleAndBias.m22 = 0.5f; + textureScaleAndBias.m03 = 0.5f; + textureScaleAndBias.m23 = 0.5f; + textureScaleAndBias.m13 = 0.5f; + + // Apply texture scale and offset to save a MAD in shader. + return textureScaleAndBias * worldToShadow; + } + } + + /// + /// Initializes this feature's resources. This is called every time serialization happens. + /// + public override void Create() + { + m_Pass = new DebugCullingPass(); + } + + /// + /// Injects one or multiple ScriptableRenderPass in the renderer. + /// + /// List of render passes to add to. + /// Rendering state. Use this to setup render passes. + public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) + { + + + renderer.EnqueuePass(m_Pass); + } + } + + +} diff --git a/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs.meta b/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs.meta new file mode 100644 index 00000000000..ea59425fd51 --- /dev/null +++ b/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 464317e1f23804c2b89edd97eea28a9f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 615edb8a4f654d902d998ffbbcbc3e7a1a1e2bf6 Mon Sep 17 00:00:00 2001 From: Erik Hakala Date: Tue, 20 Oct 2020 12:17:43 +0300 Subject: [PATCH 02/23] Very basic UI for toggling debug features. --- .../Editor/ScriptableRendererDataEditor.cs | 11 +- .../RendererFeatures/DebugCullingFeature.cs | 156 +++++++++++++----- 2 files changed, 124 insertions(+), 43 deletions(-) diff --git a/com.unity.render-pipelines.universal/Editor/ScriptableRendererDataEditor.cs b/com.unity.render-pipelines.universal/Editor/ScriptableRendererDataEditor.cs index 8e153df81ac..8eec35a2b8e 100644 --- a/com.unity.render-pipelines.universal/Editor/ScriptableRendererDataEditor.cs +++ b/com.unity.render-pipelines.universal/Editor/ScriptableRendererDataEditor.cs @@ -195,8 +195,15 @@ private void AddComponent(object type) { serializedObject.Update(); - ScriptableObject component = CreateInstance((string)type); - component.name = $"New{(string)type}"; + string name = (string) type; + ScriptableObject component = CreateInstance(name); + if (component == null) + { + Debug.LogWarning($"Couldn't create ScriptableObject for feature '{name}'. Make sure the both, the script and the class, has the same name."); + return; + } + + component.name = $"New{name}"; Undo.RegisterCreatedObjectUndo(component, "Add Renderer Feature"); // Store this new effect as a sub-asset so we can reference it safely afterwards diff --git a/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs b/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs index 2e4c30d6504..3fca5739d2b 100644 --- a/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs +++ b/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs @@ -1,4 +1,5 @@ using System; +using Unity.Mathematics; using UnityEditor.Graphs; namespace UnityEngine.Rendering.Universal @@ -237,12 +238,41 @@ public static void DrawPlane(Vector4 plane, float scale, Color edgeColor, float public class DebugCullingFeature : ScriptableRendererFeature { private DebugCullingPass m_Pass; + + // Settings + public bool drawOrigin = false; + public bool drawCullingFrustum = true; + public bool drawCullingSpheres = false; + + public bool drawCullingPlanes = false; + public bool drawSingleCullingPlane = false; + public int drawSingleCullingPlaneIndex = 0; // TODO: better interface, a range? a slider? + public int drawSingleCullingPlaneCascadeIndex = 0; + + public bool drawVisibleLights = false; + public bool drawVisibleLightRadius = false; + + public bool drawShadowCasterBounds = false; + + public bool drawDirectLightFrustum = false; + public bool drawSpotLightFrustum = false; + + //TODO: + // - spot light frustum + // - cascade split distances in frustum + // - perhaps add a point param to drawPlane, and use it to align/move the plane gizmo along the plane (i.e the gizmo tracks the point) + // - better UI and controls + // + public class DebugCullingPass : ScriptableRenderPass { - public DebugCullingPass() + private DebugCullingFeature m_Feature; + public DebugCullingPass(DebugCullingFeature feature) { base.renderPassEvent = RenderPassEvent.BeforeRendering; base.profilingSampler = new ProfilingSampler(nameof(ScriptableRenderPass)); + + m_Feature = feature; } /// @@ -256,23 +286,13 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData { var camPos = renderingData.cameraData.camera.cameraToWorldMatrix * new Vector4(0,0,0,1); var camFront = renderingData.cameraData.camera.cameraToWorldMatrix.GetColumn(2); - foreach (var l in renderingData.lightData.visibleLights) - { - Debug.DrawLine( camPos, l.localToWorldMatrix.GetColumn(3), Color.yellow); - if (false) - { - DebugCullingHelpers.DrawSphere(l.localToWorldMatrix.GetColumn(3), l.range, Color.yellow); - } - } - - DebugCullingHelpers.DrawFrustum(renderingData.cameraData.camera.cullingMatrix); - DebugCullingHelpers.DrawAxes(renderingData.cameraData.camera.cameraToWorldMatrix, 0.25f); - - DebugCullingHelpers.DrawPlane(new Vector4(1,0,0,2), 4, Color.red, 10,Color.red ); + // Test + /*DebugCullingHelpers.DrawPlane(new Vector4(1,0,0,2), 4, Color.red, 10,Color.red ); DebugCullingHelpers.DrawPlane(new Vector4(0,1,0,2), 4, Color.green, 10,Color.green ); DebugCullingHelpers.DrawPlane(new Vector4(0,0,1,2), 4, Color.blue, 10,Color.blue ); - DebugCullingHelpers.DrawPlane(new Vector4(1,1,1,3.46f), 4, Color.white, 10,Color.white ); + DebugCullingHelpers.DrawPlane(new Vector4(1,1,1,3.46f), 4, Color.white, 10,Color.white );*/ + // Test /*{ DebugCullingHelpers.DrawPlane(new Vector4(1,0,1,0), 10, Color.green, 5,Color.white ); @@ -282,18 +302,27 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData }*/ // Origin + if(m_Feature.drawOrigin) { Debug.DrawLine( Vector3.zero, new Vector3(1,0,0), Color.red); Debug.DrawLine( Vector3.zero, new Vector3(0,1,0), Color.green); Debug.DrawLine( Vector3.zero, new Vector3(0,0,1), Color.blue); } + // Frustum + if (m_Feature.drawCullingFrustum) + { + DebugCullingHelpers.DrawFrustum(renderingData.cameraData.camera.cullingMatrix); + DebugCullingHelpers.DrawAxes(renderingData.cameraData.camera.cameraToWorldMatrix, 0.25f); + } + int mainLightIndex = renderingData.lightData.mainLightIndex; VisibleLight mainLight = renderingData.lightData.visibleLights[mainLightIndex]; + // Shadow caster bounds Bounds bounds; bool boundsFound = renderingData.cullResults.GetShadowCasterBounds(mainLightIndex, out bounds); - if (boundsFound) + if (boundsFound && m_Feature.drawShadowCasterBounds) { DebugCullingHelpers.DrawBox(bounds.center, bounds.size, Color.gray ); } @@ -314,41 +343,86 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData } } - for (int cascadeIndex = 0; cascadeIndex < shadowCascadesCount; ++cascadeIndex) + // Direct light frustum + if (m_Feature.drawDirectLightFrustum) { - var shadowTransform = proj[cascadeIndex] * view[cascadeIndex]; - DebugCullingHelpers.DrawFrustum( shadowTransform, Color.white, Color.yellow, Color.black); - DebugCullingHelpers.DrawAxes(shadowTransform.inverse, 0.25f); + for (int cascadeIndex = 0; cascadeIndex < shadowCascadesCount; ++cascadeIndex) + { + var shadowTransform = proj[cascadeIndex] * view[cascadeIndex]; + DebugCullingHelpers.DrawFrustum( shadowTransform, Color.white, Color.yellow, Color.black); + DebugCullingHelpers.DrawAxes(shadowTransform.inverse, 0.25f); + } } - for (int cascadeIndex = 0; cascadeIndex < shadowCascadesCount; ++cascadeIndex) + // Visible lights + if (m_Feature.drawVisibleLights) { - Vector4 s = shadowSplitData[cascadeIndex].cullingSphere; - Vector3 c = s; - float radius = s.w; - DebugCullingHelpers.DrawSphere( c, radius, Color.white); - DebugCullingHelpers.DrawPoint( c, 0.5f, Color.white); + foreach (var l in renderingData.lightData.visibleLights) + { + Debug.DrawLine( camPos, l.localToWorldMatrix.GetColumn(3), Color.yellow); + + if (m_Feature.drawVisibleLightRadius) + { + var c = l.localToWorldMatrix.GetColumn(3); + DebugCullingHelpers.DrawSphere(c, l.range, Color.yellow); + DebugCullingHelpers.DrawPoint(c, 0.25f, Color.yellow); + } + } } - //for (int cascadeIndex = 0; cascadeIndex < shadowCascadesCount; ++cascadeIndex) - /*{ - var cascadeIndex = 0; + // Culling spheres + if (m_Feature.drawCullingSpheres) + { + for (int cascadeIndex = 0; cascadeIndex < shadowCascadesCount; ++cascadeIndex) + { + Vector4 s = shadowSplitData[cascadeIndex].cullingSphere; + Vector3 c = s; + float radius = s.w; + DebugCullingHelpers.DrawSphere( c, radius, Color.white); + DebugCullingHelpers.DrawPoint( c, 0.5f, Color.white); + } + } + + // Culling planes + if (m_Feature.drawCullingPlanes || m_Feature.drawSingleCullingPlane) + { + Color planeColor = Color.cyan; + Color normalColor = Color.blue; - var pc = Color.Lerp(Color.cyan, Color.black, cascadeIndex / (float) shadowCascadesCount); - var nc = Color.Lerp(Color.blue, Color.black, cascadeIndex / (float) shadowCascadesCount); - var ssd = shadowSplitData[cascadeIndex]; + m_Feature.drawSingleCullingPlaneCascadeIndex = math.clamp(m_Feature.drawSingleCullingPlaneCascadeIndex, 0, shadowCascadesCount - 1); + m_Feature.drawSingleCullingPlaneIndex = math.clamp(m_Feature.drawSingleCullingPlaneIndex, 0, shadowSplitData[m_Feature.drawSingleCullingPlaneCascadeIndex].cullingPlaneCount - 1); - var pi = 8; - //for (int pi = 0; pi < ssd.cullingPlaneCount; pi++) + if (m_Feature.drawSingleCullingPlane) { - var p = ssd.GetCullingPlane(pi); - DebugCullingHelpers.DrawPlane(p,100.0f, pc, 5.0f, nc); + var cascadeIndex = m_Feature.drawSingleCullingPlaneCascadeIndex; + + var pc = Color.Lerp(planeColor, Color.black, cascadeIndex / (float) shadowCascadesCount); + var nc = Color.Lerp(normalColor, Color.black, cascadeIndex / (float) shadowCascadesCount); + var ssd = shadowSplitData[cascadeIndex]; + + var pi = m_Feature.drawSingleCullingPlaneIndex; + { + var p = ssd.GetCullingPlane(pi); + DebugCullingHelpers.DrawPlane(p,100.0f, pc, 5.0f, nc); + } + } + else + { + for (int cascadeIndex = 0; cascadeIndex < shadowCascadesCount; ++cascadeIndex) + { + var pc = Color.Lerp(planeColor, Color.black, cascadeIndex / (float) shadowCascadesCount); + var nc = Color.Lerp(normalColor, Color.black, cascadeIndex / (float) shadowCascadesCount); + var ssd = shadowSplitData[cascadeIndex]; + + for (int pi = 0; pi < ssd.cullingPlaneCount; pi++) + { + var p = ssd.GetCullingPlane(pi); + DebugCullingHelpers.DrawPlane(p,100.0f, pc, 5.0f, nc); + } + } } - }*/ - //var camFrontPlane = camFront; - //camFrontPlane.w = Vector3.Dot(camPos, camFront) - splitDistances.x; - //DebugCullingHelpers.DrawPlane(camFrontPlane, 5, Color.white, 3, Color.red); + } } } @@ -384,7 +458,7 @@ static Matrix4x4 GetShadowTransform(Matrix4x4 proj, Matrix4x4 view) /// public override void Create() { - m_Pass = new DebugCullingPass(); + m_Pass = new DebugCullingPass(this); } /// From 159958d0211d8b3a279e3b23d580aa8bb1024b05 Mon Sep 17 00:00:00 2001 From: Erik Hakala Date: Tue, 20 Oct 2020 15:43:10 +0300 Subject: [PATCH 03/23] Add support for shadow cascade debug and spotlights. --- .../Editor/ScriptableRendererDataEditor.cs | 2 +- .../RendererFeatures/DebugCullingFeature.cs | 138 +++++++++++++++--- 2 files changed, 121 insertions(+), 19 deletions(-) diff --git a/com.unity.render-pipelines.universal/Editor/ScriptableRendererDataEditor.cs b/com.unity.render-pipelines.universal/Editor/ScriptableRendererDataEditor.cs index 8eec35a2b8e..3faef4aa309 100644 --- a/com.unity.render-pipelines.universal/Editor/ScriptableRendererDataEditor.cs +++ b/com.unity.render-pipelines.universal/Editor/ScriptableRendererDataEditor.cs @@ -199,7 +199,7 @@ private void AddComponent(object type) ScriptableObject component = CreateInstance(name); if (component == null) { - Debug.LogWarning($"Couldn't create ScriptableObject for feature '{name}'. Make sure the both, the script and the class, has the same name."); + Debug.LogWarning($"Couldn't create ScriptableObject for ScriptableRendererFeature '{name}'. Make sure the both, the script and the class, have the same name."); return; } diff --git a/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs b/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs index 3fca5739d2b..e2da6df9ad1 100644 --- a/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs +++ b/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs @@ -64,28 +64,85 @@ private static Vector4[] MakeUnitSphere(int len) public static void DrawFrustum(Matrix4x4 projMatrix) { DrawFrustum(projMatrix, Color.red, Color.magenta, Color.blue); } public static void DrawFrustum(Matrix4x4 projMatrix, Color near, Color edge, Color far) { - Vector4[] v = s_NdcFrustum; + Vector4[] v = new Vector4[s_NdcFrustum.Length]; Matrix4x4 m = projMatrix.inverse; + + for (int i = 0; i < s_NdcFrustum.Length; i++) + { + var s = m * s_NdcFrustum[i]; + v[i] = s / s.w; + } + // Near for (int i = 0; i < 4; i++) { - var s = m * v[i]; - var e = m * v[(i + 1) % 4]; - Debug.DrawLine(s / s.w, e / e.w, near); + var s = v[i]; + var e = v[(i + 1) % 4]; + Debug.DrawLine(s, e, near); } // Far for (int i = 0; i < 4; i++) { - var s = m * v[4 + i]; - var e = m * v[4 + ((i + 1) % 4)]; - Debug.DrawLine(s / s.w, e / e.w, far); + var s = v[4 + i]; + var e = v[4 + ((i + 1) % 4)]; + Debug.DrawLine(s, e, far); } // Middle for (int i = 0; i < 4; i++) + { + var s = v[i]; + var e = v[i + 4]; + Debug.DrawLine(s, e, edge); + } + } + + public static void DrawFrustumSplits(Matrix4x4 projMatrix, float splitMaxPct, Vector3 splitPct, int splitStart, int splitCount, Color color) + { + Vector4[] v = s_NdcFrustum; + Matrix4x4 m = projMatrix.inverse; + + // Compute camera frustum + Vector4[] f = new Vector4[s_NdcFrustum.Length]; + for (int i = 0; i < s_NdcFrustum.Length; i++) { var s = m * v[i]; - var e = m * v[i + 4]; - Debug.DrawLine(s / s.w, e / e.w, edge); + f[i] = s / s.w; + } + + // Compute shadow far plane/quad + Vector4[] qMax = new Vector4[4]; + for (int i = 0; i < 4; i++) + { + qMax[i] = Vector4.Lerp(f[i], f[4+i], splitMaxPct); + } + + // Draw Shadow far/max quad + for (int i = 0; i < 4; i++) + { + var s = qMax[i]; + var e = qMax[(i + 1) % 4]; + Debug.DrawLine(s, e, Color.black); + } + + // Compute split quad (between near/shadow far) + Vector4[] q = new Vector4[4]; + for (int j = splitStart; j < splitCount; j++) + { + + float d = splitPct[j]; + for (int i = 0; i < 4; i++) + { + q[i] = Vector4.Lerp(f[i], qMax[i], d); + + } + + // Draw + for (int i = 0; i < 4; i++) + { + var s = q[i]; + var e = q[(i + 1) % 4]; + Debug.DrawLine(s, e, color); + } } } @@ -187,6 +244,18 @@ public static void DrawAxes(Matrix4x4 transform, float scale = 1.0f) Debug.DrawLine( p, z, Color.blue); } + public static void DrawQuad(Matrix4x4 transform, Color color) + { + Vector4[] v = s_UnitSquare; + Matrix4x4 m = transform; + for (int i = 0; i < 4; i++) + { + var s = m * v[i]; + var e = m * v[(i + 1) % 4]; + Debug.DrawLine(s , e , color); + } + } + public static void DrawPlane(Plane plane, float scale, Color edgeColor, float normalScale, Color normalColor) { // Flip plane distance: Unity Plane distance is from plane to origin @@ -240,13 +309,14 @@ public class DebugCullingFeature : ScriptableRendererFeature private DebugCullingPass m_Pass; // Settings - public bool drawOrigin = false; - public bool drawCullingFrustum = true; - public bool drawCullingSpheres = false; - - public bool drawCullingPlanes = false; - public bool drawSingleCullingPlane = false; - public int drawSingleCullingPlaneIndex = 0; // TODO: better interface, a range? a slider? + public bool drawOrigin = false; + public bool drawCullingFrustum = true; + public bool drawCullingFrustumSplits = true; + public bool drawCullingSpheres = false; + + public bool drawCullingPlanes = false; + public bool drawSingleCullingPlane = false; + public int drawSingleCullingPlaneIndex = 0; // TODO: better interface, a range? a slider? public int drawSingleCullingPlaneCascadeIndex = 0; public bool drawVisibleLights = false; @@ -259,7 +329,6 @@ public class DebugCullingFeature : ScriptableRendererFeature //TODO: // - spot light frustum - // - cascade split distances in frustum // - perhaps add a point param to drawPlane, and use it to align/move the plane gizmo along the plane (i.e the gizmo tracks the point) // - better UI and controls // @@ -286,6 +355,7 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData { var camPos = renderingData.cameraData.camera.cameraToWorldMatrix * new Vector4(0,0,0,1); var camFront = renderingData.cameraData.camera.cameraToWorldMatrix.GetColumn(2); + var shadowCascadesCount = renderingData.shadowData.mainLightShadowCascadesCount; // Test /*DebugCullingHelpers.DrawPlane(new Vector4(1,0,0,2), 4, Color.red, 10,Color.red ); @@ -314,6 +384,15 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData { DebugCullingHelpers.DrawFrustum(renderingData.cameraData.camera.cullingMatrix); DebugCullingHelpers.DrawAxes(renderingData.cameraData.camera.cameraToWorldMatrix, 0.25f); + + if (m_Feature.drawCullingFrustumSplits && shadowCascadesCount > 1) + { + var f = renderingData.cameraData.camera.farClipPlane; + var n = renderingData.cameraData.camera.nearClipPlane; + var s = renderingData.cameraData.maxShadowDistance; + var sMax = (s - n) / f; + DebugCullingHelpers.DrawFrustumSplits(renderingData.cameraData.camera.cullingMatrix, sMax, renderingData.shadowData.mainLightShadowCascadesSplit, 0, shadowCascadesCount - 1, Color.gray ); + } } int mainLightIndex = renderingData.lightData.mainLightIndex; @@ -327,7 +406,7 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData DebugCullingHelpers.DrawBox(bounds.center, bounds.size, Color.gray ); } - var shadowCascadesCount = renderingData.shadowData.mainLightShadowCascadesCount; + Matrix4x4[] view = new Matrix4x4[shadowCascadesCount]; Matrix4x4[] proj = new Matrix4x4[shadowCascadesCount]; ShadowSplitData[] shadowSplitData = new ShadowSplitData[shadowCascadesCount]; @@ -354,6 +433,29 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData } } + // Spot light frustum + + if (m_Feature.drawSpotLightFrustum) + { + var lightCount = renderingData.lightData.visibleLights.Length; + ShadowSplitData[] spotShadowSplitData = new ShadowSplitData[lightCount]; + Matrix4x4[] spotView = new Matrix4x4[lightCount]; + Matrix4x4[] spotProj = new Matrix4x4[lightCount]; + + for (int li = 0; li < lightCount; li++) + { + VisibleLight l = renderingData.lightData.visibleLights[li]; + if (l.lightType == LightType.Spot) + { + renderingData.cullResults.ComputeSpotShadowMatricesAndCullingPrimitives(li, out spotView[li], out spotProj[li], out spotShadowSplitData[li]); + var shadowTransform = spotProj[li] * spotView[li]; + DebugCullingHelpers.DrawFrustum( shadowTransform, Color.white, Color.yellow, Color.black); + DebugCullingHelpers.DrawAxes(spotView[li].inverse, 0.5f); + } + } + + } + // Visible lights if (m_Feature.drawVisibleLights) { From a7f9504571f3404f715a4167aded3c9788520bc9 Mon Sep 17 00:00:00 2001 From: Erik Hakala Date: Tue, 20 Oct 2020 20:06:05 +0300 Subject: [PATCH 04/23] Added main camera culling debug viewer. --- .../RendererFeatures/DebugCullingFeature.cs | 1 - .../Runtime/UniversalRenderPipeline.cs | 26 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs b/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs index e2da6df9ad1..839431c66b6 100644 --- a/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs +++ b/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs @@ -328,7 +328,6 @@ public class DebugCullingFeature : ScriptableRendererFeature public bool drawSpotLightFrustum = false; //TODO: - // - spot light frustum // - perhaps add a point param to drawPlane, and use it to align/move the plane gizmo along the plane (i.e the gizmo tracks the point) // - better UI and controls // diff --git a/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs b/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs index 74f0c7d1c70..716751e1dae 100644 --- a/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs +++ b/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs @@ -309,6 +309,31 @@ static bool TryGetCullingParameters(CameraData cameraData, out ScriptableCulling return cameraData.camera.TryGetCullingParameters(false, out cullingParams); } + // TODO: rename this + internal static class DebugCullingHelper + { + public static bool debugCullEnabled = false; + + private static ScriptableCullingParameters debugCullingParameters; + + // TODO: better interface, pick a camera to debug etc. + + public static void ApplyDebugCulling(Camera camera, ref ScriptableCullingParameters cullingParameters) + { + if (debugCullEnabled) + { + if (camera.cameraType == CameraType.Game && camera.name != "Preview Camera") + { + debugCullingParameters = cullingParameters; + } + if (camera.cameraType == CameraType.SceneView) + { + cullingParameters = debugCullingParameters; + } + } + } + } + /// /// Renders a single camera. This method will do culling, setup and execution of the renderer. /// @@ -359,6 +384,7 @@ static void RenderSingleCamera(ScriptableRenderContext context, CameraData camer } #endif + DebugCullingHelper.ApplyDebugCulling(camera, ref cullingParameters); var cullResults = context.Cull(ref cullingParameters); InitializeRenderingData(asset, ref cameraData, ref cullResults, anyPostProcessingEnabled, out var renderingData); From f784053657f45306599493b579f7f000cd741533 Mon Sep 17 00:00:00 2001 From: Erik Hakala Date: Tue, 10 Nov 2020 14:37:04 +0200 Subject: [PATCH 05/23] Fix indexing bug when no direct lights. --- .../RendererFeatures/DebugCullingFeature.cs | 162 +++++++++--------- 1 file changed, 81 insertions(+), 81 deletions(-) diff --git a/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs b/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs index 839431c66b6..b8861d247d0 100644 --- a/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs +++ b/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs @@ -395,45 +395,99 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData } int mainLightIndex = renderingData.lightData.mainLightIndex; - VisibleLight mainLight = renderingData.lightData.visibleLights[mainLightIndex]; - - // Shadow caster bounds - Bounds bounds; - bool boundsFound = renderingData.cullResults.GetShadowCasterBounds(mainLightIndex, out bounds); - if (boundsFound && m_Feature.drawShadowCasterBounds) + if (mainLightIndex >= 0) { - DebugCullingHelpers.DrawBox(bounds.center, bounds.size, Color.gray ); - } + VisibleLight mainLight = renderingData.lightData.visibleLights[mainLightIndex]; + // Shadow caster bounds + Bounds bounds; + bool boundsFound = renderingData.cullResults.GetShadowCasterBounds(mainLightIndex, out bounds); + if (boundsFound && m_Feature.drawShadowCasterBounds) + { + DebugCullingHelpers.DrawBox(bounds.center, bounds.size, Color.gray); + } - Matrix4x4[] view = new Matrix4x4[shadowCascadesCount]; - Matrix4x4[] proj = new Matrix4x4[shadowCascadesCount]; - ShadowSplitData[] shadowSplitData = new ShadowSplitData[shadowCascadesCount]; + Matrix4x4[] view = new Matrix4x4[shadowCascadesCount]; + Matrix4x4[] proj = new Matrix4x4[shadowCascadesCount]; + ShadowSplitData[] shadowSplitData = new ShadowSplitData[shadowCascadesCount]; - { - int shadowResolution = ShadowUtils.GetMaxTileResolutionInAtlas(renderingData.shadowData.mainLightShadowmapWidth, - renderingData.shadowData.mainLightShadowmapHeight, shadowCascadesCount); - for (int cascadeIndex = 0; cascadeIndex < shadowCascadesCount; ++cascadeIndex) { - bool success = renderingData.cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(mainLightIndex, - cascadeIndex, renderingData.shadowData.mainLightShadowCascadesCount, renderingData.shadowData.mainLightShadowCascadesSplit, shadowResolution, mainLight.light.shadowNearPlane, - out view[cascadeIndex], out proj[cascadeIndex], out shadowSplitData[cascadeIndex]); + int shadowResolution = ShadowUtils.GetMaxTileResolutionInAtlas(renderingData.shadowData.mainLightShadowmapWidth, + renderingData.shadowData.mainLightShadowmapHeight, shadowCascadesCount); + for (int cascadeIndex = 0; cascadeIndex < shadowCascadesCount; ++cascadeIndex) + { + bool success = renderingData.cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(mainLightIndex, + cascadeIndex, renderingData.shadowData.mainLightShadowCascadesCount, renderingData.shadowData.mainLightShadowCascadesSplit, shadowResolution, mainLight.light.shadowNearPlane, + out view[cascadeIndex], out proj[cascadeIndex], out shadowSplitData[cascadeIndex]); + } } - } - // Direct light frustum - if (m_Feature.drawDirectLightFrustum) - { - for (int cascadeIndex = 0; cascadeIndex < shadowCascadesCount; ++cascadeIndex) + // Direct light frustum + if (m_Feature.drawDirectLightFrustum) { - var shadowTransform = proj[cascadeIndex] * view[cascadeIndex]; - DebugCullingHelpers.DrawFrustum( shadowTransform, Color.white, Color.yellow, Color.black); - DebugCullingHelpers.DrawAxes(shadowTransform.inverse, 0.25f); + for (int cascadeIndex = 0; cascadeIndex < shadowCascadesCount; ++cascadeIndex) + { + var shadowTransform = proj[cascadeIndex] * view[cascadeIndex]; + DebugCullingHelpers.DrawFrustum( shadowTransform, Color.white, Color.yellow, Color.black); + DebugCullingHelpers.DrawAxes(shadowTransform.inverse, 0.25f); + } + } + + // Culling spheres + if (m_Feature.drawCullingSpheres) + { + for (int cascadeIndex = 0; cascadeIndex < shadowCascadesCount; ++cascadeIndex) + { + Vector4 s = shadowSplitData[cascadeIndex].cullingSphere; + Vector3 c = s; + float radius = s.w; + DebugCullingHelpers.DrawSphere( c, radius, Color.white); + DebugCullingHelpers.DrawPoint( c, 0.5f, Color.white); + } + } + + // Culling planes + if (m_Feature.drawCullingPlanes || m_Feature.drawSingleCullingPlane) + { + Color planeColor = Color.cyan; + Color normalColor = Color.blue; + + m_Feature.drawSingleCullingPlaneCascadeIndex = math.clamp(m_Feature.drawSingleCullingPlaneCascadeIndex, 0, shadowCascadesCount - 1); + m_Feature.drawSingleCullingPlaneIndex = math.clamp(m_Feature.drawSingleCullingPlaneIndex, 0, shadowSplitData[m_Feature.drawSingleCullingPlaneCascadeIndex].cullingPlaneCount - 1); + + if (m_Feature.drawSingleCullingPlane) + { + var cascadeIndex = m_Feature.drawSingleCullingPlaneCascadeIndex; + + var pc = Color.Lerp(planeColor, Color.black, cascadeIndex / (float) shadowCascadesCount); + var nc = Color.Lerp(normalColor, Color.black, cascadeIndex / (float) shadowCascadesCount); + var ssd = shadowSplitData[cascadeIndex]; + + var pi = m_Feature.drawSingleCullingPlaneIndex; + { + var p = ssd.GetCullingPlane(pi); + DebugCullingHelpers.DrawPlane(p,100.0f, pc, 5.0f, nc); + } + } + else + { + for (int cascadeIndex = 0; cascadeIndex < shadowCascadesCount; ++cascadeIndex) + { + var pc = Color.Lerp(planeColor, Color.black, cascadeIndex / (float) shadowCascadesCount); + var nc = Color.Lerp(normalColor, Color.black, cascadeIndex / (float) shadowCascadesCount); + var ssd = shadowSplitData[cascadeIndex]; + + for (int pi = 0; pi < ssd.cullingPlaneCount; pi++) + { + var p = ssd.GetCullingPlane(pi); + DebugCullingHelpers.DrawPlane(p,100.0f, pc, 5.0f, nc); + } + } + } } } // Spot light frustum - if (m_Feature.drawSpotLightFrustum) { var lightCount = renderingData.lightData.visibleLights.Length; @@ -470,60 +524,6 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData } } } - - // Culling spheres - if (m_Feature.drawCullingSpheres) - { - for (int cascadeIndex = 0; cascadeIndex < shadowCascadesCount; ++cascadeIndex) - { - Vector4 s = shadowSplitData[cascadeIndex].cullingSphere; - Vector3 c = s; - float radius = s.w; - DebugCullingHelpers.DrawSphere( c, radius, Color.white); - DebugCullingHelpers.DrawPoint( c, 0.5f, Color.white); - } - } - - // Culling planes - if (m_Feature.drawCullingPlanes || m_Feature.drawSingleCullingPlane) - { - Color planeColor = Color.cyan; - Color normalColor = Color.blue; - - m_Feature.drawSingleCullingPlaneCascadeIndex = math.clamp(m_Feature.drawSingleCullingPlaneCascadeIndex, 0, shadowCascadesCount - 1); - m_Feature.drawSingleCullingPlaneIndex = math.clamp(m_Feature.drawSingleCullingPlaneIndex, 0, shadowSplitData[m_Feature.drawSingleCullingPlaneCascadeIndex].cullingPlaneCount - 1); - - if (m_Feature.drawSingleCullingPlane) - { - var cascadeIndex = m_Feature.drawSingleCullingPlaneCascadeIndex; - - var pc = Color.Lerp(planeColor, Color.black, cascadeIndex / (float) shadowCascadesCount); - var nc = Color.Lerp(normalColor, Color.black, cascadeIndex / (float) shadowCascadesCount); - var ssd = shadowSplitData[cascadeIndex]; - - var pi = m_Feature.drawSingleCullingPlaneIndex; - { - var p = ssd.GetCullingPlane(pi); - DebugCullingHelpers.DrawPlane(p,100.0f, pc, 5.0f, nc); - } - } - else - { - for (int cascadeIndex = 0; cascadeIndex < shadowCascadesCount; ++cascadeIndex) - { - var pc = Color.Lerp(planeColor, Color.black, cascadeIndex / (float) shadowCascadesCount); - var nc = Color.Lerp(normalColor, Color.black, cascadeIndex / (float) shadowCascadesCount); - var ssd = shadowSplitData[cascadeIndex]; - - for (int pi = 0; pi < ssd.cullingPlaneCount; pi++) - { - var p = ssd.GetCullingPlane(pi); - DebugCullingHelpers.DrawPlane(p,100.0f, pc, 5.0f, nc); - } - } - } - - } } } From ba8be04d63f160d2a39f4dff8dc297a23e5491c0 Mon Sep 17 00:00:00 2001 From: Erik Hakala Date: Fri, 20 Nov 2020 15:22:10 +0200 Subject: [PATCH 06/23] Refactor --- .../Editor/ScriptableRendererDataEditor.cs | 3 +- .../RendererFeatures/DebugCullingFeature.cs | 86 +++++++++---------- 2 files changed, 42 insertions(+), 47 deletions(-) diff --git a/com.unity.render-pipelines.universal/Editor/ScriptableRendererDataEditor.cs b/com.unity.render-pipelines.universal/Editor/ScriptableRendererDataEditor.cs index 903135659d7..dd86acf5e1f 100644 --- a/com.unity.render-pipelines.universal/Editor/ScriptableRendererDataEditor.cs +++ b/com.unity.render-pipelines.universal/Editor/ScriptableRendererDataEditor.cs @@ -47,6 +47,7 @@ private void OnEnable() m_FalseBool = editorObj.FindProperty(nameof(falseBool)); UpdateEditorList(); } + private void OnDisable() { ClearEditorsList(); @@ -199,7 +200,7 @@ private void AddComponent(object type) { serializedObject.Update(); - string name = (string) type; + string name = (string)type; ScriptableObject component = CreateInstance(name); if (component == null) { diff --git a/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs b/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs index b8861d247d0..b494f040f41 100644 --- a/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs +++ b/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs @@ -9,13 +9,13 @@ internal static class DebugCullingHelpers static readonly Vector4[] s_NdcFrustum = { new Vector4(-1, 1, -1, 1), - new Vector4( 1, 1, -1, 1), - new Vector4( 1, -1, -1, 1), + new Vector4(1, 1, -1, 1), + new Vector4(1, -1, -1, 1), new Vector4(-1, -1, -1, 1), new Vector4(-1, 1, 1, 1), - new Vector4( 1, 1, 1, 1), - new Vector4( 1, -1, 1, 1), + new Vector4(1, 1, 1, 1), + new Vector4(1, -1, 1, 1), new Vector4(-1, -1, 1, 1) }; @@ -23,13 +23,13 @@ internal static class DebugCullingHelpers private static readonly Vector4[] s_UnitCube = { new Vector4(-0.5f, 0.5f, -0.5f, 1), - new Vector4( 0.5f, 0.5f, -0.5f, 1), - new Vector4( 0.5f, -0.5f, -0.5f, 1), + new Vector4(0.5f, 0.5f, -0.5f, 1), + new Vector4(0.5f, -0.5f, -0.5f, 1), new Vector4(-0.5f, -0.5f, -0.5f, 1), new Vector4(-0.5f, 0.5f, 0.5f, 1), - new Vector4( 0.5f, 0.5f, 0.5f, 1), - new Vector4( 0.5f, -0.5f, 0.5f, 1), + new Vector4(0.5f, 0.5f, 0.5f, 1), + new Vector4(0.5f, -0.5f, 0.5f, 1), new Vector4(-0.5f, -0.5f, 0.5f, 1) }; @@ -40,18 +40,18 @@ internal static class DebugCullingHelpers private static readonly Vector4[] s_UnitSquare = { new Vector4(-0.5f, 0.5f, 0, 1), - new Vector4( 0.5f, 0.5f, 0, 1), - new Vector4( 0.5f,-0.5f, 0, 1), - new Vector4(-0.5f,-0.5f, 0, 1), + new Vector4(0.5f, 0.5f, 0, 1), + new Vector4(0.5f, -0.5f, 0, 1), + new Vector4(-0.5f, -0.5f, 0, 1), }; private static Vector4[] MakeUnitSphere(int len) { Debug.Assert(len > 2); - var v = new Vector4[len*3]; + var v = new Vector4[len * 3]; for (int i = 0; i < len; i++) { - var f = i / (float) len; + var f = i / (float)len; float c = Mathf.Cos(f * (float)(Math.PI * 2.0)); float s = Mathf.Sin(f * (float)(Math.PI * 2.0)); v[0 * len + i] = new Vector4(c, s, 0, 1); @@ -113,7 +113,7 @@ public static void DrawFrustumSplits(Matrix4x4 projMatrix, float splitMaxPct, Ve Vector4[] qMax = new Vector4[4]; for (int i = 0; i < 4; i++) { - qMax[i] = Vector4.Lerp(f[i], f[4+i], splitMaxPct); + qMax[i] = Vector4.Lerp(f[i], f[4 + i], splitMaxPct); } // Draw Shadow far/max quad @@ -128,12 +128,10 @@ public static void DrawFrustumSplits(Matrix4x4 projMatrix, float splitMaxPct, Ve Vector4[] q = new Vector4[4]; for (int j = splitStart; j < splitCount; j++) { - float d = splitPct[j]; for (int i = 0; i < 4; i++) { q[i] = Vector4.Lerp(f[i], qMax[i], d); - } // Draw @@ -149,7 +147,7 @@ public static void DrawFrustumSplits(Matrix4x4 projMatrix, float splitMaxPct, Ve public static void DrawBox(Vector4 pos, Vector3 size, Color color) { Vector4[] v = s_UnitCube; - Vector4 sz = new Vector4(size.x, size. y, size.z, 1); + Vector4 sz = new Vector4(size.x, size.y, size.z, 1); for (int i = 0; i < 4; i++) { var s = pos + Vector4.Scale(v[i], sz); @@ -227,9 +225,9 @@ public static void DrawPoint(Vector4 pos, float scale, Color color) public static void DrawAxes(Vector4 pos, float scale = 1.0f) { - Debug.DrawLine( pos, pos + new Vector4(scale,0,0), Color.red); - Debug.DrawLine( pos, pos + new Vector4(0,scale,0), Color.green); - Debug.DrawLine( pos, pos + new Vector4(0,0,scale), Color.blue); + Debug.DrawLine(pos, pos + new Vector4(scale, 0, 0), Color.red); + Debug.DrawLine(pos, pos + new Vector4(0, scale, 0), Color.green); + Debug.DrawLine(pos, pos + new Vector4(0, 0, scale), Color.blue); } public static void DrawAxes(Matrix4x4 transform, float scale = 1.0f) @@ -239,9 +237,9 @@ public static void DrawAxes(Matrix4x4 transform, float scale = 1.0f) Vector4 y = transform * new Vector4(0, scale, 0, 1); Vector4 z = transform * new Vector4(0, 0, scale, 1); - Debug.DrawLine( p, x, Color.red); - Debug.DrawLine( p, y, Color.green); - Debug.DrawLine( p, z, Color.blue); + Debug.DrawLine(p, x, Color.red); + Debug.DrawLine(p, y, Color.green); + Debug.DrawLine(p, z, Color.blue); } public static void DrawQuad(Matrix4x4 transform, Color color) @@ -261,6 +259,7 @@ public static void DrawPlane(Plane plane, float scale, Color edgeColor, float no // Flip plane distance: Unity Plane distance is from plane to origin DrawPlane(new Vector4(plane.normal.x, plane.normal.y, plane.normal.z, -plane.distance), scale, edgeColor, normalScale, normalColor); } + public static void DrawPlane(Vector4 plane, float scale, Color edgeColor, float normalScale, Color normalColor) { Vector3 n = Vector3.Normalize(plane); @@ -299,7 +298,7 @@ public static void DrawPlane(Vector4 plane, float scale, Color edgeColor, float Debug.DrawLine(s, e, edgeColor); } - Debug.DrawLine(n * d, n * (d+1*normalScale), normalColor); + Debug.DrawLine(n * d, n * (d + 1 * normalScale), normalColor); } } @@ -352,7 +351,7 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData { if (renderingData.cameraData.camera.cameraType == CameraType.Game && renderingData.cameraData.camera.name != "Preview Camera") { - var camPos = renderingData.cameraData.camera.cameraToWorldMatrix * new Vector4(0,0,0,1); + var camPos = renderingData.cameraData.camera.cameraToWorldMatrix * new Vector4(0, 0, 0, 1); var camFront = renderingData.cameraData.camera.cameraToWorldMatrix.GetColumn(2); var shadowCascadesCount = renderingData.shadowData.mainLightShadowCascadesCount; @@ -371,11 +370,11 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData }*/ // Origin - if(m_Feature.drawOrigin) + if (m_Feature.drawOrigin) { - Debug.DrawLine( Vector3.zero, new Vector3(1,0,0), Color.red); - Debug.DrawLine( Vector3.zero, new Vector3(0,1,0), Color.green); - Debug.DrawLine( Vector3.zero, new Vector3(0,0,1), Color.blue); + Debug.DrawLine(Vector3.zero, new Vector3(1, 0, 0), Color.red); + Debug.DrawLine(Vector3.zero, new Vector3(0, 1, 0), Color.green); + Debug.DrawLine(Vector3.zero, new Vector3(0, 0, 1), Color.blue); } // Frustum @@ -390,7 +389,7 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData var n = renderingData.cameraData.camera.nearClipPlane; var s = renderingData.cameraData.maxShadowDistance; var sMax = (s - n) / f; - DebugCullingHelpers.DrawFrustumSplits(renderingData.cameraData.camera.cullingMatrix, sMax, renderingData.shadowData.mainLightShadowCascadesSplit, 0, shadowCascadesCount - 1, Color.gray ); + DebugCullingHelpers.DrawFrustumSplits(renderingData.cameraData.camera.cullingMatrix, sMax, renderingData.shadowData.mainLightShadowCascadesSplit, 0, shadowCascadesCount - 1, Color.gray); } } @@ -428,7 +427,7 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData for (int cascadeIndex = 0; cascadeIndex < shadowCascadesCount; ++cascadeIndex) { var shadowTransform = proj[cascadeIndex] * view[cascadeIndex]; - DebugCullingHelpers.DrawFrustum( shadowTransform, Color.white, Color.yellow, Color.black); + DebugCullingHelpers.DrawFrustum(shadowTransform, Color.white, Color.yellow, Color.black); DebugCullingHelpers.DrawAxes(shadowTransform.inverse, 0.25f); } } @@ -441,8 +440,8 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData Vector4 s = shadowSplitData[cascadeIndex].cullingSphere; Vector3 c = s; float radius = s.w; - DebugCullingHelpers.DrawSphere( c, radius, Color.white); - DebugCullingHelpers.DrawPoint( c, 0.5f, Color.white); + DebugCullingHelpers.DrawSphere(c, radius, Color.white); + DebugCullingHelpers.DrawPoint(c, 0.5f, Color.white); } } @@ -459,28 +458,28 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData { var cascadeIndex = m_Feature.drawSingleCullingPlaneCascadeIndex; - var pc = Color.Lerp(planeColor, Color.black, cascadeIndex / (float) shadowCascadesCount); - var nc = Color.Lerp(normalColor, Color.black, cascadeIndex / (float) shadowCascadesCount); + var pc = Color.Lerp(planeColor, Color.black, cascadeIndex / (float)shadowCascadesCount); + var nc = Color.Lerp(normalColor, Color.black, cascadeIndex / (float)shadowCascadesCount); var ssd = shadowSplitData[cascadeIndex]; var pi = m_Feature.drawSingleCullingPlaneIndex; { var p = ssd.GetCullingPlane(pi); - DebugCullingHelpers.DrawPlane(p,100.0f, pc, 5.0f, nc); + DebugCullingHelpers.DrawPlane(p, 100.0f, pc, 5.0f, nc); } } else { for (int cascadeIndex = 0; cascadeIndex < shadowCascadesCount; ++cascadeIndex) { - var pc = Color.Lerp(planeColor, Color.black, cascadeIndex / (float) shadowCascadesCount); - var nc = Color.Lerp(normalColor, Color.black, cascadeIndex / (float) shadowCascadesCount); + var pc = Color.Lerp(planeColor, Color.black, cascadeIndex / (float)shadowCascadesCount); + var nc = Color.Lerp(normalColor, Color.black, cascadeIndex / (float)shadowCascadesCount); var ssd = shadowSplitData[cascadeIndex]; for (int pi = 0; pi < ssd.cullingPlaneCount; pi++) { var p = ssd.GetCullingPlane(pi); - DebugCullingHelpers.DrawPlane(p,100.0f, pc, 5.0f, nc); + DebugCullingHelpers.DrawPlane(p, 100.0f, pc, 5.0f, nc); } } } @@ -502,11 +501,10 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData { renderingData.cullResults.ComputeSpotShadowMatricesAndCullingPrimitives(li, out spotView[li], out spotProj[li], out spotShadowSplitData[li]); var shadowTransform = spotProj[li] * spotView[li]; - DebugCullingHelpers.DrawFrustum( shadowTransform, Color.white, Color.yellow, Color.black); + DebugCullingHelpers.DrawFrustum(shadowTransform, Color.white, Color.yellow, Color.black); DebugCullingHelpers.DrawAxes(spotView[li].inverse, 0.5f); } } - } // Visible lights @@ -514,7 +512,7 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData { foreach (var l in renderingData.lightData.visibleLights) { - Debug.DrawLine( camPos, l.localToWorldMatrix.GetColumn(3), Color.yellow); + Debug.DrawLine(camPos, l.localToWorldMatrix.GetColumn(3), Color.yellow); if (m_Feature.drawVisibleLightRadius) { @@ -569,11 +567,7 @@ public override void Create() /// Rendering state. Use this to setup render passes. public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) { - - renderer.EnqueuePass(m_Pass); } } - - } From 8bbd14801ab408e14fe8879070a1574d7b070736 Mon Sep 17 00:00:00 2001 From: Erik Hakala Date: Thu, 14 Jan 2021 20:22:52 +0200 Subject: [PATCH 07/23] Basic frustum debug support for point light shadows. --- .../RendererFeatures/DebugCullingFeature.cs | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs b/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs index b494f040f41..2313358b83c 100644 --- a/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs +++ b/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs @@ -325,6 +325,8 @@ public class DebugCullingFeature : ScriptableRendererFeature public bool drawDirectLightFrustum = false; public bool drawSpotLightFrustum = false; + public bool drawPointLightFrusta = false; + public bool noPointLightFrustumBias = false; //TODO: // - perhaps add a point param to drawPlane, and use it to align/move the plane gizmo along the plane (i.e the gizmo tracks the point) @@ -507,6 +509,34 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData } } + if (m_Feature.drawPointLightFrusta) + { + var lightCount = renderingData.lightData.visibleLights.Length; + ShadowSplitData[] pointShadowSplitData = new ShadowSplitData[lightCount]; + Matrix4x4[] pointView = new Matrix4x4[lightCount]; + Matrix4x4[] pointProj = new Matrix4x4[lightCount]; + + for (int li = 0; li < lightCount; li++) + { + VisibleLight l = renderingData.lightData.visibleLights[li]; + if (l.lightType == LightType.Point) + { + float fovBias = m_Feature.noPointLightFrustumBias + ? 0.0f + : Internal.AdditionalLightsShadowCasterPass.GetPointLightShadowFrustumFovBiasInDegrees(renderingData.shadowData.resolution[li], (l.light.shadows == LightShadows.Soft)); + for (int f = 0; f < 6; f++) + { + CubemapFace face = (CubemapFace)f; + renderingData.cullResults.ComputePointShadowMatricesAndCullingPrimitives(li, face, fovBias, out pointView[li], out pointProj[li], out pointShadowSplitData[li]); + var shadowTransform = pointProj[li] * pointView[li]; + DebugCullingHelpers.DrawFrustum(shadowTransform, Color.white, Color.yellow, Color.black); + } + + DebugCullingHelpers.DrawAxes(pointView[li].inverse, 0.5f); + } + } + } + // Visible lights if (m_Feature.drawVisibleLights) { From 2ec5e04b6a7ed31a2181e0d1ee05bd1bae9dced1 Mon Sep 17 00:00:00 2001 From: Nigel Williams Date: Tue, 4 May 2021 22:05:00 +0200 Subject: [PATCH 08/23] Added minimal enclosing sphere chicken bit and also iteration . --- .../UniversalRenderPipelineAssetEditor.cs | 6 ++- .../Data/UniversalRenderPipelineAsset.cs | 7 ++++ .../RendererFeatures/DebugCullingFeature.cs | 41 +++++++++++++++++-- .../Runtime/UniversalRenderPipeline.cs | 5 +++ .../Runtime/UniversalRenderer.cs | 2 + 5 files changed, 57 insertions(+), 4 deletions(-) diff --git a/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAssetEditor.cs b/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAssetEditor.cs index d0d79b43622..0ca7733db79 100644 --- a/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAssetEditor.cs +++ b/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAssetEditor.cs @@ -61,6 +61,8 @@ internal class Styles public static GUIContent shadowDepthBias = EditorGUIUtility.TrTextContent("Depth Bias", "Controls the distance at which the shadows will be pushed away from the light. Useful for avoiding false self-shadowing artifacts."); public static GUIContent shadowNormalBias = EditorGUIUtility.TrTextContent("Normal Bias", "Controls distance at which the shadow casting surfaces will be shrunk along the surface normal. Useful for avoiding false self-shadowing artifacts."); public static GUIContent supportsSoftShadows = EditorGUIUtility.TrTextContent("Soft Shadows", "If enabled pipeline will perform shadow filtering. Otherwise all lights that cast shadows will fallback to perform a single shadow sample."); + public static GUIContent tightEnclosingSphere = EditorGUIUtility.TrTextContent("Tight Enclosing Sphere", "If enabled, as tight conservative enclosing sphere is used. If disabled, the sphere will be smaller than the cascade size."); + // Post-processing public static GUIContent colorGradingMode = EditorGUIUtility.TrTextContent("Grading Mode", "Defines how color grading will be applied. Operators will react differently depending on the mode."); @@ -139,8 +141,8 @@ internal class Styles SerializedProperty m_ShadowCascadeBorderProp; SerializedProperty m_ShadowDepthBiasProp; SerializedProperty m_ShadowNormalBiasProp; - SerializedProperty m_SoftShadowsSupportedProp; + SerializedProperty m_TightEnclosingSphereProp; SerializedProperty m_SRPBatcher; SerializedProperty m_SupportsDynamicBatching; @@ -221,6 +223,7 @@ void OnEnable() m_ShadowDepthBiasProp = serializedObject.FindProperty("m_ShadowDepthBias"); m_ShadowNormalBiasProp = serializedObject.FindProperty("m_ShadowNormalBias"); m_SoftShadowsSupportedProp = serializedObject.FindProperty("m_SoftShadowsSupported"); + m_TightEnclosingSphereProp = serializedObject.FindProperty("m_TightEnclosingSphere"); m_SRPBatcher = serializedObject.FindProperty("m_UseSRPBatcher"); m_SupportsDynamicBatching = serializedObject.FindProperty("m_SupportsDynamicBatching"); @@ -425,6 +428,7 @@ void DrawShadowSettings() m_ShadowDepthBiasProp.floatValue = EditorGUILayout.Slider(Styles.shadowDepthBias, m_ShadowDepthBiasProp.floatValue, 0.0f, UniversalRenderPipeline.maxShadowBias); m_ShadowNormalBiasProp.floatValue = EditorGUILayout.Slider(Styles.shadowNormalBias, m_ShadowNormalBiasProp.floatValue, 0.0f, UniversalRenderPipeline.maxShadowBias); EditorGUILayout.PropertyField(m_SoftShadowsSupportedProp, Styles.supportsSoftShadows); + EditorGUILayout.PropertyField(m_TightEnclosingSphereProp, Styles.tightEnclosingSphere); EditorGUI.indentLevel--; EditorGUILayout.Space(); EditorGUILayout.Space(); diff --git a/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAsset.cs b/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAsset.cs index 3b53f61dc35..341912c315b 100644 --- a/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAsset.cs +++ b/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAsset.cs @@ -143,6 +143,7 @@ public partial class UniversalRenderPipelineAsset : RenderPipelineAsset, ISerial [SerializeField] float m_ShadowDepthBias = 1.0f; [SerializeField] float m_ShadowNormalBias = 1.0f; [SerializeField] bool m_SoftShadowsSupported = false; + [SerializeField] bool m_TightEnclosingSphere = false; // Advanced settings [SerializeField] bool m_UseSRPBatcher = true; @@ -751,6 +752,12 @@ public bool useAdaptivePerformance set { m_UseAdaptivePerformance = value; } } + public bool tightEnclosingSphere + { + get { return m_TightEnclosingSphere; } + set { m_TightEnclosingSphere = value; } + } + public override Material defaultMaterial { get { return GetMaterial(DefaultMaterialType.Standard); } diff --git a/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs b/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs index 2313358b83c..b45e5e1a251 100644 --- a/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs +++ b/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs @@ -128,6 +128,23 @@ public static void DrawFrustumSplits(Matrix4x4 projMatrix, float splitMaxPct, Ve Vector4[] q = new Vector4[4]; for (int j = splitStart; j < splitCount; j++) { + Color color1; + switch (j) + { + case 0: + color1 = Color.cyan; + break; + case 1: + color1 = Color.yellow; + break; + case 2: + color1 = Color.blue; + break; + default: + color1 = Color.red; + break; + } + float d = splitPct[j]; for (int i = 0; i < 4; i++) { @@ -139,7 +156,7 @@ public static void DrawFrustumSplits(Matrix4x4 projMatrix, float splitMaxPct, Ve { var s = q[i]; var e = q[(i + 1) % 4]; - Debug.DrawLine(s, e, color); + Debug.DrawLine(s, e, color1); } } } @@ -392,6 +409,7 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData var s = renderingData.cameraData.maxShadowDistance; var sMax = (s - n) / f; DebugCullingHelpers.DrawFrustumSplits(renderingData.cameraData.camera.cullingMatrix, sMax, renderingData.shadowData.mainLightShadowCascadesSplit, 0, shadowCascadesCount - 1, Color.gray); + } } @@ -439,11 +457,28 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData { for (int cascadeIndex = 0; cascadeIndex < shadowCascadesCount; ++cascadeIndex) { + Color color; + switch(cascadeIndex) + { + case 0: + color = Color.green; + break; + case 1: + color = Color.red; + break; + case 2: + color = Color.blue; + break; + default: + color = Color.yellow; + break; + } + Vector4 s = shadowSplitData[cascadeIndex].cullingSphere; Vector3 c = s; float radius = s.w; - DebugCullingHelpers.DrawSphere(c, radius, Color.white); - DebugCullingHelpers.DrawPoint(c, 0.5f, Color.white); + DebugCullingHelpers.DrawSphere(c, radius, color); + DebugCullingHelpers.DrawPoint(c, 0.5f, color); } } diff --git a/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs b/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs index 19bbef13feb..8b3cbe89a1f 100644 --- a/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs +++ b/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs @@ -103,6 +103,11 @@ public static float maxRenderScale get => 2.0f; } + public static bool tightEnclosingSphere + { + get => false; + } + // Amount of Lights that can be shaded per object (in the for loop in the shader) public static int maxPerObjectLights { diff --git a/com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs b/com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs index 67763289c96..aa17efe871e 100644 --- a/com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs +++ b/com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs @@ -661,6 +661,8 @@ public override void SetupCullingParameters(ref ScriptableCullingParameters cull cullingParameters.maximumVisibleLights = UniversalRenderPipeline.maxVisibleAdditionalLights + 1; } cullingParameters.shadowDistance = cameraData.maxShadowDistance; + + cullingParameters.tightEnclosingSphere = UniversalRenderPipeline.asset.tightEnclosingSphere; } /// From 839062b326197734ea58983bd2225fda78bb2197 Mon Sep 17 00:00:00 2001 From: Nigel Williams Date: Thu, 6 May 2021 15:21:30 +0200 Subject: [PATCH 09/23] Added user control for number of iterations --- .../Editor/UniversalRenderPipelineAssetEditor.cs | 9 +++++++++ .../Runtime/Data/UniversalRenderPipelineAsset.cs | 7 +++++++ .../Runtime/UniversalRenderPipeline.cs | 7 ++++++- .../Runtime/UniversalRenderer.cs | 3 +++ 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAssetEditor.cs b/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAssetEditor.cs index 0ca7733db79..b497b9e808d 100644 --- a/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAssetEditor.cs +++ b/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAssetEditor.cs @@ -62,6 +62,7 @@ internal class Styles public static GUIContent shadowNormalBias = EditorGUIUtility.TrTextContent("Normal Bias", "Controls distance at which the shadow casting surfaces will be shrunk along the surface normal. Useful for avoiding false self-shadowing artifacts."); public static GUIContent supportsSoftShadows = EditorGUIUtility.TrTextContent("Soft Shadows", "If enabled pipeline will perform shadow filtering. Otherwise all lights that cast shadows will fallback to perform a single shadow sample."); public static GUIContent tightEnclosingSphere = EditorGUIUtility.TrTextContent("Tight Enclosing Sphere", "If enabled, as tight conservative enclosing sphere is used. If disabled, the sphere will be smaller than the cascade size."); + public static GUIContent numIterationsEnclosingSphere = EditorGUIUtility.TrTextContent("Number of Iterations", "Number of iterations for the minimal enclosing sphere iterative method. A higher number of iterations will minimize the sphere but increases CPU computation necessary."); // Post-processing @@ -143,6 +144,7 @@ internal class Styles SerializedProperty m_ShadowNormalBiasProp; SerializedProperty m_SoftShadowsSupportedProp; SerializedProperty m_TightEnclosingSphereProp; + SerializedProperty m_NumIterationsEnclosingSphereProp; SerializedProperty m_SRPBatcher; SerializedProperty m_SupportsDynamicBatching; @@ -224,6 +226,7 @@ void OnEnable() m_ShadowNormalBiasProp = serializedObject.FindProperty("m_ShadowNormalBias"); m_SoftShadowsSupportedProp = serializedObject.FindProperty("m_SoftShadowsSupported"); m_TightEnclosingSphereProp = serializedObject.FindProperty("m_TightEnclosingSphere"); + m_NumIterationsEnclosingSphereProp = serializedObject.FindProperty("m_NumIterationsEnclosingSphere"); m_SRPBatcher = serializedObject.FindProperty("m_UseSRPBatcher"); m_SupportsDynamicBatching = serializedObject.FindProperty("m_SupportsDynamicBatching"); @@ -429,6 +432,12 @@ void DrawShadowSettings() m_ShadowNormalBiasProp.floatValue = EditorGUILayout.Slider(Styles.shadowNormalBias, m_ShadowNormalBiasProp.floatValue, 0.0f, UniversalRenderPipeline.maxShadowBias); EditorGUILayout.PropertyField(m_SoftShadowsSupportedProp, Styles.supportsSoftShadows); EditorGUILayout.PropertyField(m_TightEnclosingSphereProp, Styles.tightEnclosingSphere); + if (m_TightEnclosingSphereProp.boolValue) + { + EditorGUI.indentLevel++; + EditorGUILayout.IntSlider(m_NumIterationsEnclosingSphereProp, 1, UniversalRenderPipeline.maxNumIterationsEnclosingSphere, Styles.numIterationsEnclosingSphere); + EditorGUI.indentLevel--; + } EditorGUI.indentLevel--; EditorGUILayout.Space(); EditorGUILayout.Space(); diff --git a/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAsset.cs b/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAsset.cs index 341912c315b..e6e08a5dc67 100644 --- a/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAsset.cs +++ b/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAsset.cs @@ -144,6 +144,7 @@ public partial class UniversalRenderPipelineAsset : RenderPipelineAsset, ISerial [SerializeField] float m_ShadowNormalBias = 1.0f; [SerializeField] bool m_SoftShadowsSupported = false; [SerializeField] bool m_TightEnclosingSphere = false; + [SerializeField] int m_NumIterationsEnclosingSphere = 64; // Advanced settings [SerializeField] bool m_UseSRPBatcher = true; @@ -758,6 +759,12 @@ public bool tightEnclosingSphere set { m_TightEnclosingSphere = value; } } + public int numItertionsEnclosingSphere + { + get { return m_NumIterationsEnclosingSphere; } + set { m_NumIterationsEnclosingSphere = value; } + } + public override Material defaultMaterial { get { return GetMaterial(DefaultMaterialType.Standard); } diff --git a/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs b/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs index 8b3cbe89a1f..2316622bdef 100644 --- a/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs +++ b/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs @@ -103,9 +103,14 @@ public static float maxRenderScale get => 2.0f; } - public static bool tightEnclosingSphere + /*public static bool tightEnclosingSphere { get => false; + }*/ + + public static int maxNumIterationsEnclosingSphere + { + get => 1000; } // Amount of Lights that can be shaded per object (in the for loop in the shader) diff --git a/com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs b/com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs index aa17efe871e..fc6d916b32e 100644 --- a/com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs +++ b/com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs @@ -1,6 +1,7 @@ using UnityEngine.Rendering.Universal.Internal; using UnityEngine.Experimental.Rendering; using System.Reflection; +using System; namespace UnityEngine.Rendering.Universal { @@ -663,6 +664,8 @@ public override void SetupCullingParameters(ref ScriptableCullingParameters cull cullingParameters.shadowDistance = cameraData.maxShadowDistance; cullingParameters.tightEnclosingSphere = UniversalRenderPipeline.asset.tightEnclosingSphere; + + cullingParameters.numIterationsEnclosingSphere = UniversalRenderPipeline.asset.numItertionsEnclosingSphere; } /// From a8ef4eeaf87502053d8f4c658fa95fec104c313f Mon Sep 17 00:00:00 2001 From: Nigel Williams Date: Tue, 15 Jun 2021 15:25:46 +0200 Subject: [PATCH 10/23] Reverted changes to debug culling feature --- .../Runtime/RendererFeatures/DebugCullingFeature.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs b/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs index 09113736eaa..b45e5e1a251 100644 --- a/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs +++ b/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs @@ -467,7 +467,7 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData color = Color.red; break; case 2: - color = Color.cyan; + color = Color.blue; break; default: color = Color.yellow; From 6386692da645564e42edd24b726323830cc868b6 Mon Sep 17 00:00:00 2001 From: Nigel Williams Date: Tue, 15 Jun 2021 15:43:36 +0200 Subject: [PATCH 11/23] Remove debug files --- .../RendererFeatures/DebugCullingFeature.cs | 41 ++----------------- 1 file changed, 3 insertions(+), 38 deletions(-) diff --git a/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs b/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs index b45e5e1a251..2313358b83c 100644 --- a/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs +++ b/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs @@ -128,23 +128,6 @@ public static void DrawFrustumSplits(Matrix4x4 projMatrix, float splitMaxPct, Ve Vector4[] q = new Vector4[4]; for (int j = splitStart; j < splitCount; j++) { - Color color1; - switch (j) - { - case 0: - color1 = Color.cyan; - break; - case 1: - color1 = Color.yellow; - break; - case 2: - color1 = Color.blue; - break; - default: - color1 = Color.red; - break; - } - float d = splitPct[j]; for (int i = 0; i < 4; i++) { @@ -156,7 +139,7 @@ public static void DrawFrustumSplits(Matrix4x4 projMatrix, float splitMaxPct, Ve { var s = q[i]; var e = q[(i + 1) % 4]; - Debug.DrawLine(s, e, color1); + Debug.DrawLine(s, e, color); } } } @@ -409,7 +392,6 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData var s = renderingData.cameraData.maxShadowDistance; var sMax = (s - n) / f; DebugCullingHelpers.DrawFrustumSplits(renderingData.cameraData.camera.cullingMatrix, sMax, renderingData.shadowData.mainLightShadowCascadesSplit, 0, shadowCascadesCount - 1, Color.gray); - } } @@ -457,28 +439,11 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData { for (int cascadeIndex = 0; cascadeIndex < shadowCascadesCount; ++cascadeIndex) { - Color color; - switch(cascadeIndex) - { - case 0: - color = Color.green; - break; - case 1: - color = Color.red; - break; - case 2: - color = Color.blue; - break; - default: - color = Color.yellow; - break; - } - Vector4 s = shadowSplitData[cascadeIndex].cullingSphere; Vector3 c = s; float radius = s.w; - DebugCullingHelpers.DrawSphere(c, radius, color); - DebugCullingHelpers.DrawPoint(c, 0.5f, color); + DebugCullingHelpers.DrawSphere(c, radius, Color.white); + DebugCullingHelpers.DrawPoint(c, 0.5f, Color.white); } } From 5472010f4e361a72b75338ea0b3de5572ed7ba94 Mon Sep 17 00:00:00 2001 From: Nigel Williams Date: Tue, 15 Jun 2021 15:49:06 +0200 Subject: [PATCH 12/23] Removed debug cull files --- .../RendererFeatures/DebugCullingFeature.cs | 603 ------------------ .../DebugCullingFeature.cs.meta | 11 - 2 files changed, 614 deletions(-) delete mode 100644 com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs delete mode 100644 com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs.meta diff --git a/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs b/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs deleted file mode 100644 index 2313358b83c..00000000000 --- a/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs +++ /dev/null @@ -1,603 +0,0 @@ -using System; -using Unity.Mathematics; -using UnityEditor.Graphs; - -namespace UnityEngine.Rendering.Universal -{ - internal static class DebugCullingHelpers - { - static readonly Vector4[] s_NdcFrustum = - { - new Vector4(-1, 1, -1, 1), - new Vector4(1, 1, -1, 1), - new Vector4(1, -1, -1, 1), - new Vector4(-1, -1, -1, 1), - - new Vector4(-1, 1, 1, 1), - new Vector4(1, 1, 1, 1), - new Vector4(1, -1, 1, 1), - new Vector4(-1, -1, 1, 1) - }; - - // Cube with edge of length 1 - private static readonly Vector4[] s_UnitCube = - { - new Vector4(-0.5f, 0.5f, -0.5f, 1), - new Vector4(0.5f, 0.5f, -0.5f, 1), - new Vector4(0.5f, -0.5f, -0.5f, 1), - new Vector4(-0.5f, -0.5f, -0.5f, 1), - - new Vector4(-0.5f, 0.5f, 0.5f, 1), - new Vector4(0.5f, 0.5f, 0.5f, 1), - new Vector4(0.5f, -0.5f, 0.5f, 1), - new Vector4(-0.5f, -0.5f, 0.5f, 1) - }; - - // Sphere with radius of 1 - private static readonly Vector4[] s_UnitSphere = MakeUnitSphere(16); - - // Square with edge of length 1 - private static readonly Vector4[] s_UnitSquare = - { - new Vector4(-0.5f, 0.5f, 0, 1), - new Vector4(0.5f, 0.5f, 0, 1), - new Vector4(0.5f, -0.5f, 0, 1), - new Vector4(-0.5f, -0.5f, 0, 1), - }; - - private static Vector4[] MakeUnitSphere(int len) - { - Debug.Assert(len > 2); - var v = new Vector4[len * 3]; - for (int i = 0; i < len; i++) - { - var f = i / (float)len; - float c = Mathf.Cos(f * (float)(Math.PI * 2.0)); - float s = Mathf.Sin(f * (float)(Math.PI * 2.0)); - v[0 * len + i] = new Vector4(c, s, 0, 1); - v[1 * len + i] = new Vector4(0, c, s, 1); - v[2 * len + i] = new Vector4(s, 0, c, 1); - } - return v; - } - - public static void DrawFrustum(Matrix4x4 projMatrix) { DrawFrustum(projMatrix, Color.red, Color.magenta, Color.blue); } - public static void DrawFrustum(Matrix4x4 projMatrix, Color near, Color edge, Color far) - { - Vector4[] v = new Vector4[s_NdcFrustum.Length]; - Matrix4x4 m = projMatrix.inverse; - - for (int i = 0; i < s_NdcFrustum.Length; i++) - { - var s = m * s_NdcFrustum[i]; - v[i] = s / s.w; - } - - // Near - for (int i = 0; i < 4; i++) - { - var s = v[i]; - var e = v[(i + 1) % 4]; - Debug.DrawLine(s, e, near); - } - // Far - for (int i = 0; i < 4; i++) - { - var s = v[4 + i]; - var e = v[4 + ((i + 1) % 4)]; - Debug.DrawLine(s, e, far); - } - // Middle - for (int i = 0; i < 4; i++) - { - var s = v[i]; - var e = v[i + 4]; - Debug.DrawLine(s, e, edge); - } - } - - public static void DrawFrustumSplits(Matrix4x4 projMatrix, float splitMaxPct, Vector3 splitPct, int splitStart, int splitCount, Color color) - { - Vector4[] v = s_NdcFrustum; - Matrix4x4 m = projMatrix.inverse; - - // Compute camera frustum - Vector4[] f = new Vector4[s_NdcFrustum.Length]; - for (int i = 0; i < s_NdcFrustum.Length; i++) - { - var s = m * v[i]; - f[i] = s / s.w; - } - - // Compute shadow far plane/quad - Vector4[] qMax = new Vector4[4]; - for (int i = 0; i < 4; i++) - { - qMax[i] = Vector4.Lerp(f[i], f[4 + i], splitMaxPct); - } - - // Draw Shadow far/max quad - for (int i = 0; i < 4; i++) - { - var s = qMax[i]; - var e = qMax[(i + 1) % 4]; - Debug.DrawLine(s, e, Color.black); - } - - // Compute split quad (between near/shadow far) - Vector4[] q = new Vector4[4]; - for (int j = splitStart; j < splitCount; j++) - { - float d = splitPct[j]; - for (int i = 0; i < 4; i++) - { - q[i] = Vector4.Lerp(f[i], qMax[i], d); - } - - // Draw - for (int i = 0; i < 4; i++) - { - var s = q[i]; - var e = q[(i + 1) % 4]; - Debug.DrawLine(s, e, color); - } - } - } - - public static void DrawBox(Vector4 pos, Vector3 size, Color color) - { - Vector4[] v = s_UnitCube; - Vector4 sz = new Vector4(size.x, size.y, size.z, 1); - for (int i = 0; i < 4; i++) - { - var s = pos + Vector4.Scale(v[i], sz); - var e = pos + Vector4.Scale(v[(i + 1) % 4], sz); - Debug.DrawLine(s , e , color); - } - for (int i = 0; i < 4; i++) - { - var s = pos + Vector4.Scale(v[4 + i], sz); - var e = pos + Vector4.Scale(v[4 + ((i + 1) % 4)], sz); - Debug.DrawLine(s , e , color); - } - for (int i = 0; i < 4; i++) - { - var s = pos + Vector4.Scale(v[i], sz); - var e = pos + Vector4.Scale(v[i + 4], sz); - Debug.DrawLine(s , e , color); - } - } - - public static void DrawBox(Matrix4x4 transform, Color color) - { - Vector4[] v = s_UnitCube; - Matrix4x4 m = transform; - for (int i = 0; i < 4; i++) - { - var s = m * v[i]; - var e = m * v[(i + 1) % 4]; - Debug.DrawLine(s , e , color); - } - for (int i = 0; i < 4; i++) - { - var s = m * v[4 + i]; - var e = m * v[4 + ((i + 1) % 4)]; - Debug.DrawLine(s , e , color); - } - for (int i = 0; i < 4; i++) - { - var s = m * v[i]; - var e = m * v[i + 4]; - Debug.DrawLine(s , e , color); - } - } - - public static void DrawSphere(Vector4 pos, float radius, Color color) - { - Vector4[] v = s_UnitSphere; - int len = s_UnitSphere.Length / 3; - for (int i = 0; i < len; i++) - { - var sX = pos + radius * v[0 * len + i]; - var eX = pos + radius * v[0 * len + (i + 1) % len]; - var sY = pos + radius * v[1 * len + i]; - var eY = pos + radius * v[1 * len + (i + 1) % len]; - var sZ = pos + radius * v[2 * len + i]; - var eZ = pos + radius * v[2 * len + (i + 1) % len]; - Debug.DrawLine(sX, eX, color); - Debug.DrawLine(sY, eY, color); - Debug.DrawLine(sZ, eZ, color); - } - } - - public static void DrawPoint(Vector4 pos, float scale, Color color) - { - var sX = pos + new Vector4(+scale, 0, 0); - var eX = pos + new Vector4(-scale, 0, 0); - var sY = pos + new Vector4(0, +scale, 0); - var eY = pos + new Vector4(0, -scale, 0); - var sZ = pos + new Vector4(0, 0, +scale); - var eZ = pos + new Vector4(0, 0, -scale); - Debug.DrawLine(sX , eX , color); - Debug.DrawLine(sY , eY , color); - Debug.DrawLine(sZ , eZ , color); - } - - public static void DrawAxes(Vector4 pos, float scale = 1.0f) - { - Debug.DrawLine(pos, pos + new Vector4(scale, 0, 0), Color.red); - Debug.DrawLine(pos, pos + new Vector4(0, scale, 0), Color.green); - Debug.DrawLine(pos, pos + new Vector4(0, 0, scale), Color.blue); - } - - public static void DrawAxes(Matrix4x4 transform, float scale = 1.0f) - { - Vector4 p = transform * new Vector4(0, 0, 0, 1); - Vector4 x = transform * new Vector4(scale, 0, 0, 1); - Vector4 y = transform * new Vector4(0, scale, 0, 1); - Vector4 z = transform * new Vector4(0, 0, scale, 1); - - Debug.DrawLine(p, x, Color.red); - Debug.DrawLine(p, y, Color.green); - Debug.DrawLine(p, z, Color.blue); - } - - public static void DrawQuad(Matrix4x4 transform, Color color) - { - Vector4[] v = s_UnitSquare; - Matrix4x4 m = transform; - for (int i = 0; i < 4; i++) - { - var s = m * v[i]; - var e = m * v[(i + 1) % 4]; - Debug.DrawLine(s , e , color); - } - } - - public static void DrawPlane(Plane plane, float scale, Color edgeColor, float normalScale, Color normalColor) - { - // Flip plane distance: Unity Plane distance is from plane to origin - DrawPlane(new Vector4(plane.normal.x, plane.normal.y, plane.normal.z, -plane.distance), scale, edgeColor, normalScale, normalColor); - } - - public static void DrawPlane(Vector4 plane, float scale, Color edgeColor, float normalScale, Color normalColor) - { - Vector3 n = Vector3.Normalize(plane); - float d = plane.w; - - Vector3 u = Vector3.up; - Vector3 r = Vector3.right; - if (n == u) - u = r; - - r = Vector3.Cross(n, u); - u = Vector3.Cross(n, r); - - for (int i = 0; i < 4; i++) - { - var s = scale * s_UnitSquare[i]; - var e = scale * s_UnitSquare[(i + 1) % 4]; - s = s.x * r + s.y * u + n * d; - e = e.x * r + e.y * u + n * d; - Debug.DrawLine(s, e, edgeColor); - } - - // Diagonals - { - var s = scale * s_UnitSquare[0]; - var e = scale * s_UnitSquare[2]; - s = s.x * r + s.y * u + n * d; - e = e.x * r + e.y * u + n * d; - Debug.DrawLine(s, e, edgeColor); - } - { - var s = scale * s_UnitSquare[1]; - var e = scale * s_UnitSquare[3]; - s = s.x * r + s.y * u + n * d; - e = e.x * r + e.y * u + n * d; - Debug.DrawLine(s, e, edgeColor); - } - - Debug.DrawLine(n * d, n * (d + 1 * normalScale), normalColor); - } - } - - [DisallowMultipleRendererFeature] - public class DebugCullingFeature : ScriptableRendererFeature - { - private DebugCullingPass m_Pass; - - // Settings - public bool drawOrigin = false; - public bool drawCullingFrustum = true; - public bool drawCullingFrustumSplits = true; - public bool drawCullingSpheres = false; - - public bool drawCullingPlanes = false; - public bool drawSingleCullingPlane = false; - public int drawSingleCullingPlaneIndex = 0; // TODO: better interface, a range? a slider? - public int drawSingleCullingPlaneCascadeIndex = 0; - - public bool drawVisibleLights = false; - public bool drawVisibleLightRadius = false; - - public bool drawShadowCasterBounds = false; - - public bool drawDirectLightFrustum = false; - public bool drawSpotLightFrustum = false; - public bool drawPointLightFrusta = false; - public bool noPointLightFrustumBias = false; - - //TODO: - // - perhaps add a point param to drawPlane, and use it to align/move the plane gizmo along the plane (i.e the gizmo tracks the point) - // - better UI and controls - // - - public class DebugCullingPass : ScriptableRenderPass - { - private DebugCullingFeature m_Feature; - public DebugCullingPass(DebugCullingFeature feature) - { - base.renderPassEvent = RenderPassEvent.BeforeRendering; - base.profilingSampler = new ProfilingSampler(nameof(ScriptableRenderPass)); - - m_Feature = feature; - } - - /// - /// Execute the pass. This is where custom rendering occurs. Specific details are left to the implementation - /// - /// Use this render context to issue any draw commands during execution - /// Current rendering state information - public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) - { - if (renderingData.cameraData.camera.cameraType == CameraType.Game && renderingData.cameraData.camera.name != "Preview Camera") - { - var camPos = renderingData.cameraData.camera.cameraToWorldMatrix * new Vector4(0, 0, 0, 1); - var camFront = renderingData.cameraData.camera.cameraToWorldMatrix.GetColumn(2); - var shadowCascadesCount = renderingData.shadowData.mainLightShadowCascadesCount; - - // Test - /*DebugCullingHelpers.DrawPlane(new Vector4(1,0,0,2), 4, Color.red, 10,Color.red ); - DebugCullingHelpers.DrawPlane(new Vector4(0,1,0,2), 4, Color.green, 10,Color.green ); - DebugCullingHelpers.DrawPlane(new Vector4(0,0,1,2), 4, Color.blue, 10,Color.blue ); - DebugCullingHelpers.DrawPlane(new Vector4(1,1,1,3.46f), 4, Color.white, 10,Color.white );*/ - - // Test - /*{ - DebugCullingHelpers.DrawPlane(new Vector4(1,0,1,0), 10, Color.green, 5,Color.white ); - - DebugCullingHelpers.DrawBox(new Vector4(0,0,5,1), new Vector3(1, 2, 3 ), Color.gray ); - DebugCullingHelpers.DrawPoint(new Vector4(3,1,0,1), 1, Color.cyan ); - }*/ - - // Origin - if (m_Feature.drawOrigin) - { - Debug.DrawLine(Vector3.zero, new Vector3(1, 0, 0), Color.red); - Debug.DrawLine(Vector3.zero, new Vector3(0, 1, 0), Color.green); - Debug.DrawLine(Vector3.zero, new Vector3(0, 0, 1), Color.blue); - } - - // Frustum - if (m_Feature.drawCullingFrustum) - { - DebugCullingHelpers.DrawFrustum(renderingData.cameraData.camera.cullingMatrix); - DebugCullingHelpers.DrawAxes(renderingData.cameraData.camera.cameraToWorldMatrix, 0.25f); - - if (m_Feature.drawCullingFrustumSplits && shadowCascadesCount > 1) - { - var f = renderingData.cameraData.camera.farClipPlane; - var n = renderingData.cameraData.camera.nearClipPlane; - var s = renderingData.cameraData.maxShadowDistance; - var sMax = (s - n) / f; - DebugCullingHelpers.DrawFrustumSplits(renderingData.cameraData.camera.cullingMatrix, sMax, renderingData.shadowData.mainLightShadowCascadesSplit, 0, shadowCascadesCount - 1, Color.gray); - } - } - - int mainLightIndex = renderingData.lightData.mainLightIndex; - if (mainLightIndex >= 0) - { - VisibleLight mainLight = renderingData.lightData.visibleLights[mainLightIndex]; - - // Shadow caster bounds - Bounds bounds; - bool boundsFound = renderingData.cullResults.GetShadowCasterBounds(mainLightIndex, out bounds); - if (boundsFound && m_Feature.drawShadowCasterBounds) - { - DebugCullingHelpers.DrawBox(bounds.center, bounds.size, Color.gray); - } - - Matrix4x4[] view = new Matrix4x4[shadowCascadesCount]; - Matrix4x4[] proj = new Matrix4x4[shadowCascadesCount]; - ShadowSplitData[] shadowSplitData = new ShadowSplitData[shadowCascadesCount]; - - { - int shadowResolution = ShadowUtils.GetMaxTileResolutionInAtlas(renderingData.shadowData.mainLightShadowmapWidth, - renderingData.shadowData.mainLightShadowmapHeight, shadowCascadesCount); - for (int cascadeIndex = 0; cascadeIndex < shadowCascadesCount; ++cascadeIndex) - { - bool success = renderingData.cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(mainLightIndex, - cascadeIndex, renderingData.shadowData.mainLightShadowCascadesCount, renderingData.shadowData.mainLightShadowCascadesSplit, shadowResolution, mainLight.light.shadowNearPlane, - out view[cascadeIndex], out proj[cascadeIndex], out shadowSplitData[cascadeIndex]); - } - } - - // Direct light frustum - if (m_Feature.drawDirectLightFrustum) - { - for (int cascadeIndex = 0; cascadeIndex < shadowCascadesCount; ++cascadeIndex) - { - var shadowTransform = proj[cascadeIndex] * view[cascadeIndex]; - DebugCullingHelpers.DrawFrustum(shadowTransform, Color.white, Color.yellow, Color.black); - DebugCullingHelpers.DrawAxes(shadowTransform.inverse, 0.25f); - } - } - - // Culling spheres - if (m_Feature.drawCullingSpheres) - { - for (int cascadeIndex = 0; cascadeIndex < shadowCascadesCount; ++cascadeIndex) - { - Vector4 s = shadowSplitData[cascadeIndex].cullingSphere; - Vector3 c = s; - float radius = s.w; - DebugCullingHelpers.DrawSphere(c, radius, Color.white); - DebugCullingHelpers.DrawPoint(c, 0.5f, Color.white); - } - } - - // Culling planes - if (m_Feature.drawCullingPlanes || m_Feature.drawSingleCullingPlane) - { - Color planeColor = Color.cyan; - Color normalColor = Color.blue; - - m_Feature.drawSingleCullingPlaneCascadeIndex = math.clamp(m_Feature.drawSingleCullingPlaneCascadeIndex, 0, shadowCascadesCount - 1); - m_Feature.drawSingleCullingPlaneIndex = math.clamp(m_Feature.drawSingleCullingPlaneIndex, 0, shadowSplitData[m_Feature.drawSingleCullingPlaneCascadeIndex].cullingPlaneCount - 1); - - if (m_Feature.drawSingleCullingPlane) - { - var cascadeIndex = m_Feature.drawSingleCullingPlaneCascadeIndex; - - var pc = Color.Lerp(planeColor, Color.black, cascadeIndex / (float)shadowCascadesCount); - var nc = Color.Lerp(normalColor, Color.black, cascadeIndex / (float)shadowCascadesCount); - var ssd = shadowSplitData[cascadeIndex]; - - var pi = m_Feature.drawSingleCullingPlaneIndex; - { - var p = ssd.GetCullingPlane(pi); - DebugCullingHelpers.DrawPlane(p, 100.0f, pc, 5.0f, nc); - } - } - else - { - for (int cascadeIndex = 0; cascadeIndex < shadowCascadesCount; ++cascadeIndex) - { - var pc = Color.Lerp(planeColor, Color.black, cascadeIndex / (float)shadowCascadesCount); - var nc = Color.Lerp(normalColor, Color.black, cascadeIndex / (float)shadowCascadesCount); - var ssd = shadowSplitData[cascadeIndex]; - - for (int pi = 0; pi < ssd.cullingPlaneCount; pi++) - { - var p = ssd.GetCullingPlane(pi); - DebugCullingHelpers.DrawPlane(p, 100.0f, pc, 5.0f, nc); - } - } - } - } - } - - // Spot light frustum - if (m_Feature.drawSpotLightFrustum) - { - var lightCount = renderingData.lightData.visibleLights.Length; - ShadowSplitData[] spotShadowSplitData = new ShadowSplitData[lightCount]; - Matrix4x4[] spotView = new Matrix4x4[lightCount]; - Matrix4x4[] spotProj = new Matrix4x4[lightCount]; - - for (int li = 0; li < lightCount; li++) - { - VisibleLight l = renderingData.lightData.visibleLights[li]; - if (l.lightType == LightType.Spot) - { - renderingData.cullResults.ComputeSpotShadowMatricesAndCullingPrimitives(li, out spotView[li], out spotProj[li], out spotShadowSplitData[li]); - var shadowTransform = spotProj[li] * spotView[li]; - DebugCullingHelpers.DrawFrustum(shadowTransform, Color.white, Color.yellow, Color.black); - DebugCullingHelpers.DrawAxes(spotView[li].inverse, 0.5f); - } - } - } - - if (m_Feature.drawPointLightFrusta) - { - var lightCount = renderingData.lightData.visibleLights.Length; - ShadowSplitData[] pointShadowSplitData = new ShadowSplitData[lightCount]; - Matrix4x4[] pointView = new Matrix4x4[lightCount]; - Matrix4x4[] pointProj = new Matrix4x4[lightCount]; - - for (int li = 0; li < lightCount; li++) - { - VisibleLight l = renderingData.lightData.visibleLights[li]; - if (l.lightType == LightType.Point) - { - float fovBias = m_Feature.noPointLightFrustumBias - ? 0.0f - : Internal.AdditionalLightsShadowCasterPass.GetPointLightShadowFrustumFovBiasInDegrees(renderingData.shadowData.resolution[li], (l.light.shadows == LightShadows.Soft)); - for (int f = 0; f < 6; f++) - { - CubemapFace face = (CubemapFace)f; - renderingData.cullResults.ComputePointShadowMatricesAndCullingPrimitives(li, face, fovBias, out pointView[li], out pointProj[li], out pointShadowSplitData[li]); - var shadowTransform = pointProj[li] * pointView[li]; - DebugCullingHelpers.DrawFrustum(shadowTransform, Color.white, Color.yellow, Color.black); - } - - DebugCullingHelpers.DrawAxes(pointView[li].inverse, 0.5f); - } - } - } - - // Visible lights - if (m_Feature.drawVisibleLights) - { - foreach (var l in renderingData.lightData.visibleLights) - { - Debug.DrawLine(camPos, l.localToWorldMatrix.GetColumn(3), Color.yellow); - - if (m_Feature.drawVisibleLightRadius) - { - var c = l.localToWorldMatrix.GetColumn(3); - DebugCullingHelpers.DrawSphere(c, l.range, Color.yellow); - DebugCullingHelpers.DrawPoint(c, 0.25f, Color.yellow); - } - } - } - } - } - - static Matrix4x4 GetShadowTransform(Matrix4x4 proj, Matrix4x4 view) - { - // Currently CullResults ComputeDirectionalShadowMatricesAndCullingPrimitives doesn't - // apply z reversal to projection matrix. We need to do it manually here. - /*if (SystemInfo.usesReversedZBuffer) - { - proj.m20 = -proj.m20; - proj.m21 = -proj.m21; - proj.m22 = -proj.m22; - proj.m23 = -proj.m23; - }*/ - - Matrix4x4 worldToShadow = proj * view; - - var textureScaleAndBias = Matrix4x4.identity; - textureScaleAndBias.m00 = 0.5f; - textureScaleAndBias.m11 = 0.5f; - textureScaleAndBias.m22 = 0.5f; - textureScaleAndBias.m03 = 0.5f; - textureScaleAndBias.m23 = 0.5f; - textureScaleAndBias.m13 = 0.5f; - - // Apply texture scale and offset to save a MAD in shader. - return textureScaleAndBias * worldToShadow; - } - } - - /// - /// Initializes this feature's resources. This is called every time serialization happens. - /// - public override void Create() - { - m_Pass = new DebugCullingPass(this); - } - - /// - /// Injects one or multiple ScriptableRenderPass in the renderer. - /// - /// List of render passes to add to. - /// Rendering state. Use this to setup render passes. - public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) - { - renderer.EnqueuePass(m_Pass); - } - } -} diff --git a/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs.meta b/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs.meta deleted file mode 100644 index ea59425fd51..00000000000 --- a/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DebugCullingFeature.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 464317e1f23804c2b89edd97eea28a9f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: From 61da6069aab4c408bfae356235487d2a2151f46b Mon Sep 17 00:00:00 2001 From: Nigel Williams Date: Tue, 15 Jun 2021 16:03:53 +0200 Subject: [PATCH 13/23] Removed code specific to debug --- .../Runtime/UniversalRenderPipeline.cs | 31 ------------------- 1 file changed, 31 deletions(-) diff --git a/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs b/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs index 4625649b95c..380b3d8021b 100644 --- a/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs +++ b/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs @@ -103,11 +103,6 @@ public static float maxRenderScale get => 2.0f; } - /*public static bool tightEnclosingSphere - { - get => false; - }*/ - public static int maxNumIterationsEnclosingSphere { get => 1000; @@ -349,31 +344,6 @@ static bool TryGetCullingParameters(CameraData cameraData, out ScriptableCulling return cameraData.camera.TryGetCullingParameters(false, out cullingParams); } - // TODO: rename this - internal static class DebugCullingHelper - { - public static bool debugCullEnabled = false; - - private static ScriptableCullingParameters debugCullingParameters; - - // TODO: better interface, pick a camera to debug etc. - - public static void ApplyDebugCulling(Camera camera, ref ScriptableCullingParameters cullingParameters) - { - if (debugCullEnabled) - { - if (camera.cameraType == CameraType.Game && camera.name != "Preview Camera") - { - debugCullingParameters = cullingParameters; - } - if (camera.cameraType == CameraType.SceneView) - { - cullingParameters = debugCullingParameters; - } - } - } - } - /// /// Renders a single camera. This method will do culling, setup and execution of the renderer. /// @@ -430,7 +400,6 @@ static void RenderSingleCamera(ScriptableRenderContext context, CameraData camer } #endif - DebugCullingHelper.ApplyDebugCulling(camera, ref cullingParameters); var cullResults = context.Cull(ref cullingParameters); InitializeRenderingData(asset, ref cameraData, ref cullResults, anyPostProcessingEnabled, out var renderingData); From 62c34bbdf9f9bccca2b0a222eea005313e806959 Mon Sep 17 00:00:00 2001 From: Nigel Williams Date: Tue, 15 Jun 2021 16:10:11 +0200 Subject: [PATCH 14/23] removed more old code --- .../Editor/ScriptableRendererDataEditor.cs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/com.unity.render-pipelines.universal/Editor/ScriptableRendererDataEditor.cs b/com.unity.render-pipelines.universal/Editor/ScriptableRendererDataEditor.cs index 3e023d5a4cb..258bb0267a7 100644 --- a/com.unity.render-pipelines.universal/Editor/ScriptableRendererDataEditor.cs +++ b/com.unity.render-pipelines.universal/Editor/ScriptableRendererDataEditor.cs @@ -221,15 +221,8 @@ private void AddComponent(object type) { serializedObject.Update(); - string name = (string)type; - ScriptableObject component = CreateInstance(name); - if (component == null) - { - Debug.LogWarning($"Couldn't create ScriptableObject for ScriptableRendererFeature '{name}'. Make sure the both, the script and the class, have the same name."); - return; - } - - component.name = $"New{name}"; + ScriptableObject component = CreateInstance((string)type); + component.name = $"New{(string)type}"; Undo.RegisterCreatedObjectUndo(component, "Add Renderer Feature"); // Store this new effect as a sub-asset so we can reference it safely afterwards From 3619666e0bde516b7d98ad4af508ca39d73df5cd Mon Sep 17 00:00:00 2001 From: nigeljw-unity <72749964+nigeljw-unity@users.noreply.github.com> Date: Tue, 15 Jun 2021 16:15:43 +0200 Subject: [PATCH 15/23] Removed old includes --- .../Runtime/UniversalRenderer.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs b/com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs index b4cfde9083c..d988e8c93ca 100644 --- a/com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs +++ b/com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs @@ -1,8 +1,5 @@ using System.Collections.Generic; using UnityEngine.Rendering.Universal.Internal; -using UnityEngine.Experimental.Rendering; -using System.Reflection; -using System; namespace UnityEngine.Rendering.Universal { From 51979d6f434c5ae371a4cba718b8f580370e47dc Mon Sep 17 00:00:00 2001 From: Nigel Williams Date: Thu, 19 Aug 2021 16:02:44 +0200 Subject: [PATCH 16/23] Fixed merge conflight and renamed to conservative enclosing sphere --- .../SerializedUniversalRenderPipelineAsset.cs | 5 ++++- .../UniversalRenderPipelineAssetUI.Drawers.cs | 10 ++++++++++ .../UniversalRenderPipelineAssetUI.Skin.cs | 2 ++ .../Runtime/Data/UniversalRenderPipelineAsset.cs | 8 ++++---- .../Runtime/UniversalRenderer.cs | 2 +- 5 files changed, 21 insertions(+), 6 deletions(-) diff --git a/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/SerializedUniversalRenderPipelineAsset.cs b/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/SerializedUniversalRenderPipelineAsset.cs index b4a3c1dbaf2..91660216fea 100644 --- a/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/SerializedUniversalRenderPipelineAsset.cs +++ b/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/SerializedUniversalRenderPipelineAsset.cs @@ -45,8 +45,9 @@ internal class SerializedUniversalRenderPipelineAsset public SerializedProperty shadowCascadeBorderProp { get; } public SerializedProperty shadowDepthBiasProp { get; } public SerializedProperty shadowNormalBiasProp { get; } - public SerializedProperty softShadowsSupportedProp { get; } + public SerializedProperty conservativeEnclosingSphereProp { get; } + public SerializedProperty numIterationsEnclosingSphereProp { get; } public SerializedProperty srpBatcher { get; } public SerializedProperty supportsDynamicBatching { get; } @@ -111,6 +112,8 @@ public SerializedUniversalRenderPipelineAsset(SerializedObject serializedObject) shadowDepthBiasProp = serializedObject.FindProperty("m_ShadowDepthBias"); shadowNormalBiasProp = serializedObject.FindProperty("m_ShadowNormalBias"); softShadowsSupportedProp = serializedObject.FindProperty("m_SoftShadowsSupported"); + conservativeEnclosingSphereProp = serializedObject.FindProperty("m_ConservativeEnclosingSphere"); + numIterationsEnclosingSphereProp = serializedObject.FindProperty("m_NumIterationsEnclosingSphere"); srpBatcher = serializedObject.FindProperty("m_UseSRPBatcher"); supportsDynamicBatching = serializedObject.FindProperty("m_SupportsDynamicBatching"); diff --git a/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Drawers.cs b/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Drawers.cs index b1c7ceb13b9..1eeaf7d247b 100644 --- a/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Drawers.cs +++ b/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Drawers.cs @@ -293,6 +293,16 @@ static void DrawShadows(SerializedUniversalRenderPipelineAsset serialized, Edito serialized.shadowDepthBiasProp.floatValue = EditorGUILayout.Slider(Styles.shadowDepthBias, serialized.shadowDepthBiasProp.floatValue, 0.0f, UniversalRenderPipeline.maxShadowBias); serialized.shadowNormalBiasProp.floatValue = EditorGUILayout.Slider(Styles.shadowNormalBias, serialized.shadowNormalBiasProp.floatValue, 0.0f, UniversalRenderPipeline.maxShadowBias); EditorGUILayout.PropertyField(serialized.softShadowsSupportedProp, Styles.supportsSoftShadows); + + EditorGUILayout.PropertyField(serialized.conservativeEnclosingSphereProp, Styles.conservativeEnclosingSphere); + + if (serialized.conservativeEnclosingSphereProp.boolValue) + { + EditorGUI.indentLevel++; + EditorGUILayout.IntSlider(serialized.numIterationsEnclosingSphereProp, 1, UniversalRenderPipeline.maxNumIterationsEnclosingSphere, Styles.numIterationsEnclosingSphere); + EditorGUI.indentLevel--; + } + EditorGUI.indentLevel--; } diff --git a/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Skin.cs b/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Skin.cs index 5d177b67a67..6b204c344ac 100644 --- a/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Skin.cs +++ b/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Skin.cs @@ -74,6 +74,8 @@ public static class Styles public static GUIContent shadowDepthBias = EditorGUIUtility.TrTextContent("Depth Bias", "Controls the distance at which the shadows will be pushed away from the light. Useful for avoiding false self-shadowing artifacts."); public static GUIContent shadowNormalBias = EditorGUIUtility.TrTextContent("Normal Bias", "Controls distance at which the shadow casting surfaces will be shrunk along the surface normal. Useful for avoiding false self-shadowing artifacts."); public static GUIContent supportsSoftShadows = EditorGUIUtility.TrTextContent("Soft Shadows", "If enabled pipeline will perform shadow filtering. Otherwise all lights that cast shadows will fallback to perform a single shadow sample."); + public static GUIContent conservativeEnclosingSphere = EditorGUIUtility.TrTextContent("Conservative Enclosing Sphere", "If enabled, a conservative enclosing sphere is used. If disabled, the sphere will be smaller than the cascade size, and shadows will be culled in the corners of the cascades."); + public static GUIContent numIterationsEnclosingSphere = EditorGUIUtility.TrTextContent("Number of Iterations", "Number of iterations for the minimal enclosing sphere iterative method. A higher number of iterations will minimize the sphere but increases CPU computation necessary."); // Post-processing public static GUIContent colorGradingMode = EditorGUIUtility.TrTextContent("Grading Mode", "Defines how color grading will be applied. Operators will react differently depending on the mode."); diff --git a/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAsset.cs b/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAsset.cs index 0fd961ae122..77d7434ac8b 100644 --- a/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAsset.cs +++ b/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAsset.cs @@ -198,7 +198,7 @@ public partial class UniversalRenderPipelineAsset : RenderPipelineAsset, ISerial [SerializeField] float m_ShadowDepthBias = 1.0f; [SerializeField] float m_ShadowNormalBias = 1.0f; [SerializeField] bool m_SoftShadowsSupported = false; - [SerializeField] bool m_TightEnclosingSphere = false; + [SerializeField] bool m_ConservativeEnclosingSphere = false; [SerializeField] int m_NumIterationsEnclosingSphere = 64; // Light Cookie Settings @@ -911,10 +911,10 @@ public bool useAdaptivePerformance set { m_UseAdaptivePerformance = value; } } - public bool tightEnclosingSphere + public bool conservativeEnclosingSphere { - get { return m_TightEnclosingSphere; } - set { m_TightEnclosingSphere = value; } + get { return m_ConservativeEnclosingSphere; } + set { m_ConservativeEnclosingSphere = value; } } public int numItertionsEnclosingSphere diff --git a/com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs b/com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs index 51371a866d9..7b4df3a5fdc 100644 --- a/com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs +++ b/com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs @@ -889,7 +889,7 @@ public override void SetupCullingParameters(ref ScriptableCullingParameters cull } cullingParameters.shadowDistance = cameraData.maxShadowDistance; - cullingParameters.tightEnclosingSphere = UniversalRenderPipeline.asset.tightEnclosingSphere; + cullingParameters.conservativeEnclosingSphere = UniversalRenderPipeline.asset.conservativeEnclosingSphere; cullingParameters.numIterationsEnclosingSphere = UniversalRenderPipeline.asset.numItertionsEnclosingSphere; } From 3ac50086007aecd849049e639c87d8e69ef963c1 Mon Sep 17 00:00:00 2001 From: Nigel Williams Date: Thu, 19 Aug 2021 16:37:32 +0200 Subject: [PATCH 17/23] Enable for new projects --- .../Runtime/Data/UniversalRenderPipelineAsset.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAsset.cs b/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAsset.cs index 77d7434ac8b..e494525f617 100644 --- a/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAsset.cs +++ b/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAsset.cs @@ -262,6 +262,9 @@ public static UniversalRenderPipelineAsset Create(ScriptableRendererData rendere // Initialize default Renderer instance.m_EditorResourcesAsset = instance.editorResources; + // Only enable for new URP assets by default + instance.m_ConservativeEnclosingSphere = true; + return instance; } From 3ef8d83122470e1f04e4bb5b2110b9d90e8ae3aa Mon Sep 17 00:00:00 2001 From: Nigel Williams Date: Thu, 16 Sep 2021 16:56:38 +0200 Subject: [PATCH 18/23] Addressed UX design feedback --- .../UniversalRenderPipelineAssetUI.Drawers.cs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Drawers.cs b/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Drawers.cs index 1eeaf7d247b..5ed4f8566d0 100644 --- a/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Drawers.cs +++ b/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Drawers.cs @@ -25,6 +25,7 @@ enum ExpandableAdditional Rendering = 1 << 1, Lighting = 1 << 2, PostProcessing = 1 << 3, + Shadows = 1 << 4, } internal static void RegisterEditor(UniversalRenderPipelineAssetEditor editor) @@ -103,7 +104,7 @@ static bool ValidateRendererGraphicsAPIs(UniversalRenderPipelineAsset pipelineAs CED.AdditionalPropertiesFoldoutGroup(Styles.renderingSettingsText, Expandable.Rendering, k_ExpandedState, ExpandableAdditional.Rendering, k_AdditionalPropertiesState, DrawRendering, DrawRenderingAdditional), CED.FoldoutGroup(Styles.qualitySettingsText, Expandable.Quality, k_ExpandedState, CED.Group(DrawQuality)), CED.AdditionalPropertiesFoldoutGroup(Styles.lightingSettingsText, Expandable.Lighting, k_ExpandedState, ExpandableAdditional.Lighting, k_AdditionalPropertiesState, DrawLighting, DrawLightingAdditional), - CED.FoldoutGroup(Styles.shadowSettingsText, Expandable.Shadows, k_ExpandedState, CED.Group(DrawShadows)), + CED.AdditionalPropertiesFoldoutGroup(Styles.shadowSettingsText, Expandable.Shadows, k_ExpandedState, ExpandableAdditional.Shadows, k_AdditionalPropertiesState, DrawShadows, DrawShadowsAdditional), CED.AdditionalPropertiesFoldoutGroup(Styles.postProcessingSettingsText, Expandable.PostProcessing, k_ExpandedState, ExpandableAdditional.PostProcessing, k_AdditionalPropertiesState, DrawPostProcessing, DrawPostProcessingAdditional) #if ADAPTIVE_PERFORMANCE_2_0_0_OR_NEWER , CED.FoldoutGroup(Styles.adaptivePerformanceText, Expandable.AdaptivePerformance, k_ExpandedState, CED.Group(DrawAdvanced)), @@ -294,18 +295,14 @@ static void DrawShadows(SerializedUniversalRenderPipelineAsset serialized, Edito serialized.shadowNormalBiasProp.floatValue = EditorGUILayout.Slider(Styles.shadowNormalBias, serialized.shadowNormalBiasProp.floatValue, 0.0f, UniversalRenderPipeline.maxShadowBias); EditorGUILayout.PropertyField(serialized.softShadowsSupportedProp, Styles.supportsSoftShadows); - EditorGUILayout.PropertyField(serialized.conservativeEnclosingSphereProp, Styles.conservativeEnclosingSphere); - - if (serialized.conservativeEnclosingSphereProp.boolValue) - { - EditorGUI.indentLevel++; - EditorGUILayout.IntSlider(serialized.numIterationsEnclosingSphereProp, 1, UniversalRenderPipeline.maxNumIterationsEnclosingSphere, Styles.numIterationsEnclosingSphere); - EditorGUI.indentLevel--; - } - EditorGUI.indentLevel--; } + static void DrawShadowsAdditional(SerializedUniversalRenderPipelineAsset serialized, Editor ownerEditor) + { + EditorGUILayout.PropertyField(serialized.conservativeEnclosingSphereProp, Styles.conservativeEnclosingSphere); + } + static void DrawCascadeSliders(SerializedUniversalRenderPipelineAsset serialized, int splitCount, bool useMetric, float baseMetric) { Vector4 shadowCascadeSplit = Vector4.one; From 114346295a40fd824577d149009fb928a52d1d6a Mon Sep 17 00:00:00 2001 From: Nigel Williams Date: Thu, 16 Sep 2021 17:03:28 +0200 Subject: [PATCH 19/23] Removed orphan UI element --- .../UniversalRenderPipelineAssetUI.Skin.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Skin.cs b/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Skin.cs index 6b204c344ac..10eef278a35 100644 --- a/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Skin.cs +++ b/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Skin.cs @@ -75,7 +75,6 @@ public static class Styles public static GUIContent shadowNormalBias = EditorGUIUtility.TrTextContent("Normal Bias", "Controls distance at which the shadow casting surfaces will be shrunk along the surface normal. Useful for avoiding false self-shadowing artifacts."); public static GUIContent supportsSoftShadows = EditorGUIUtility.TrTextContent("Soft Shadows", "If enabled pipeline will perform shadow filtering. Otherwise all lights that cast shadows will fallback to perform a single shadow sample."); public static GUIContent conservativeEnclosingSphere = EditorGUIUtility.TrTextContent("Conservative Enclosing Sphere", "If enabled, a conservative enclosing sphere is used. If disabled, the sphere will be smaller than the cascade size, and shadows will be culled in the corners of the cascades."); - public static GUIContent numIterationsEnclosingSphere = EditorGUIUtility.TrTextContent("Number of Iterations", "Number of iterations for the minimal enclosing sphere iterative method. A higher number of iterations will minimize the sphere but increases CPU computation necessary."); // Post-processing public static GUIContent colorGradingMode = EditorGUIUtility.TrTextContent("Grading Mode", "Defines how color grading will be applied. Operators will react differently depending on the mode."); From 941171cc371e2041a716a033ca18659826065adb Mon Sep 17 00:00:00 2001 From: Nigel Williams Date: Thu, 16 Sep 2021 17:06:40 +0200 Subject: [PATCH 20/23] Removed orphan prop --- .../SerializedUniversalRenderPipelineAsset.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/SerializedUniversalRenderPipelineAsset.cs b/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/SerializedUniversalRenderPipelineAsset.cs index 91660216fea..71103e44ba1 100644 --- a/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/SerializedUniversalRenderPipelineAsset.cs +++ b/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/SerializedUniversalRenderPipelineAsset.cs @@ -47,7 +47,6 @@ internal class SerializedUniversalRenderPipelineAsset public SerializedProperty shadowNormalBiasProp { get; } public SerializedProperty softShadowsSupportedProp { get; } public SerializedProperty conservativeEnclosingSphereProp { get; } - public SerializedProperty numIterationsEnclosingSphereProp { get; } public SerializedProperty srpBatcher { get; } public SerializedProperty supportsDynamicBatching { get; } @@ -113,7 +112,6 @@ public SerializedUniversalRenderPipelineAsset(SerializedObject serializedObject) shadowNormalBiasProp = serializedObject.FindProperty("m_ShadowNormalBias"); softShadowsSupportedProp = serializedObject.FindProperty("m_SoftShadowsSupported"); conservativeEnclosingSphereProp = serializedObject.FindProperty("m_ConservativeEnclosingSphere"); - numIterationsEnclosingSphereProp = serializedObject.FindProperty("m_NumIterationsEnclosingSphere"); srpBatcher = serializedObject.FindProperty("m_UseSRPBatcher"); supportsDynamicBatching = serializedObject.FindProperty("m_SupportsDynamicBatching"); From 5201d3f3b6ab5cad87290b380c0b2c0525719615 Mon Sep 17 00:00:00 2001 From: Nigel Williams Date: Fri, 17 Sep 2021 11:40:11 +0200 Subject: [PATCH 21/23] Updated tooltip from feedback from docs team and added changelog --- com.unity.render-pipelines.universal/CHANGELOG.md | 1 + .../UniversalRenderPipelineAssetUI.Skin.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.universal/CHANGELOG.md b/com.unity.render-pipelines.universal/CHANGELOG.md index 12c7a69b7e5..0471128d6fe 100644 --- a/com.unity.render-pipelines.universal/CHANGELOG.md +++ b/com.unity.render-pipelines.universal/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Fixed - URP asset can now use multi-edit. [case 1364966](https://issuetracker.unity3d.com/issues/urp-universalrenderpipelineasset-does-not-support-multi-edit) +- Added "Conservative Enclosing Sphere" setting to fix shadow frustum culling issue where shadows are erroneously culled in corners of cascades [case 1153151](https://issuetracker.unity3d.com/issues/lwrp-shadows-are-being-culled-incorrectly-in-the-corner-of-the-camera-viewport-when-the-far-clip-plane-is-small) ## [12.0.0] - 2021-01-11 ### Added diff --git a/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Skin.cs b/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Skin.cs index 10eef278a35..629e0ece74b 100644 --- a/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Skin.cs +++ b/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Skin.cs @@ -74,7 +74,7 @@ public static class Styles public static GUIContent shadowDepthBias = EditorGUIUtility.TrTextContent("Depth Bias", "Controls the distance at which the shadows will be pushed away from the light. Useful for avoiding false self-shadowing artifacts."); public static GUIContent shadowNormalBias = EditorGUIUtility.TrTextContent("Normal Bias", "Controls distance at which the shadow casting surfaces will be shrunk along the surface normal. Useful for avoiding false self-shadowing artifacts."); public static GUIContent supportsSoftShadows = EditorGUIUtility.TrTextContent("Soft Shadows", "If enabled pipeline will perform shadow filtering. Otherwise all lights that cast shadows will fallback to perform a single shadow sample."); - public static GUIContent conservativeEnclosingSphere = EditorGUIUtility.TrTextContent("Conservative Enclosing Sphere", "If enabled, a conservative enclosing sphere is used. If disabled, the sphere will be smaller than the cascade size, and shadows will be culled in the corners of the cascades."); + public static GUIContent conservativeEnclosingSphere = EditorGUIUtility.TrTextContent("Conservative Enclosing Sphere", "Enable this option to improve shadow frustum culling and prevent Unity from excessively culling shadows in the corners of the shadow cascades. Disable this option only for compatibility purposes of existing projects created in previous Unity versions."); // Post-processing public static GUIContent colorGradingMode = EditorGUIUtility.TrTextContent("Grading Mode", "Defines how color grading will be applied. Operators will react differently depending on the mode."); From 9629cf5754468009949d5ba5895213424f48c6a6 Mon Sep 17 00:00:00 2001 From: Oleksandr Kokoshyn Date: Fri, 17 Sep 2021 12:33:31 +0200 Subject: [PATCH 22/23] Added the Conservative Enclosing Sphere description to URP Asset page. --- .../Documentation~/universalrp-asset.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/com.unity.render-pipelines.universal/Documentation~/universalrp-asset.md b/com.unity.render-pipelines.universal/Documentation~/universalrp-asset.md index ea610d4a65c..6f924e4d2d8 100644 --- a/com.unity.render-pipelines.universal/Documentation~/universalrp-asset.md +++ b/com.unity.render-pipelines.universal/Documentation~/universalrp-asset.md @@ -87,8 +87,7 @@ The **Shadows** section has the following properties. | **Depth Bias** | Use this setting to reduce [shadow acne](https://docs.unity3d.com/Manual/ShadowPerformance.html). | | **Normal Bias** | Use this setting to reduce [shadow acne](https://docs.unity3d.com/Manual/ShadowPerformance.html). | | __Soft Shadows__ | Select this check box to enable extra processing of the shadow maps to give them a smoother look.
When enabled, Unity uses the following shadow map filtering method:
Desktop platforms: 5x5 tent filter, mobile platforms: 4 tap filter.
**Performance impact**: high.
When this option is disabled, Unity samples the shadow map once with the default hardware filtering. | - - +| **Conservative Enclosing Sphere** | Enable this option to improve shadow frustum culling and prevent Unity from excessively culling shadows in the corners of the shadow cascades.
Disable this option only for compatibility purposes of existing projects created in previous Unity versions.
If you enable this option in an existing project, you might need to adjust the shadows cascade distances because the shadow culling enclosing spheres change their size and position. | ### Post-processing From 3399711944504e3a521e73b032e8724d66f81f6b Mon Sep 17 00:00:00 2001 From: Oleksandr Kokoshyn Date: Fri, 17 Sep 2021 13:03:02 +0200 Subject: [PATCH 23/23] Added a note about performance. --- .../Documentation~/universalrp-asset.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.universal/Documentation~/universalrp-asset.md b/com.unity.render-pipelines.universal/Documentation~/universalrp-asset.md index 6f924e4d2d8..50d7542b2d4 100644 --- a/com.unity.render-pipelines.universal/Documentation~/universalrp-asset.md +++ b/com.unity.render-pipelines.universal/Documentation~/universalrp-asset.md @@ -87,7 +87,7 @@ The **Shadows** section has the following properties. | **Depth Bias** | Use this setting to reduce [shadow acne](https://docs.unity3d.com/Manual/ShadowPerformance.html). | | **Normal Bias** | Use this setting to reduce [shadow acne](https://docs.unity3d.com/Manual/ShadowPerformance.html). | | __Soft Shadows__ | Select this check box to enable extra processing of the shadow maps to give them a smoother look.
When enabled, Unity uses the following shadow map filtering method:
Desktop platforms: 5x5 tent filter, mobile platforms: 4 tap filter.
**Performance impact**: high.
When this option is disabled, Unity samples the shadow map once with the default hardware filtering. | -| **Conservative Enclosing Sphere** | Enable this option to improve shadow frustum culling and prevent Unity from excessively culling shadows in the corners of the shadow cascades.
Disable this option only for compatibility purposes of existing projects created in previous Unity versions.
If you enable this option in an existing project, you might need to adjust the shadows cascade distances because the shadow culling enclosing spheres change their size and position. | +| **Conservative Enclosing Sphere** | Enable this option to improve shadow frustum culling and prevent Unity from excessively culling shadows in the corners of the shadow cascades.
Disable this option only for compatibility purposes of existing projects created in previous Unity versions.
If you enable this option in an existing project, you might need to adjust the shadows cascade distances because the shadow culling enclosing spheres change their size and position.
**Performance impact**: enabling this option is likely to improve performance, because the option minimizes the overlap of shadow cascades, which reduces the number of redundant static shadow casters. | ### Post-processing