From c2078930248c56fdaa937f4449b4875010f4b676 Mon Sep 17 00:00:00 2001 From: Torbjorn Laedre <271210+tlaedre@users.noreply.github.com> Date: Thu, 28 Oct 2021 20:42:28 +0200 Subject: [PATCH 1/6] Add probe volume debug modes for l0, l0l1 and placement virtual offset. --- .../ProbeGIBaking.VirtualOffset.cs | 64 +++++++- .../Lighting/ProbeVolume/ProbeGIBaking.cs | 30 ++-- .../ProbeVolume/ProbeReferenceVolume.Debug.cs | 139 ++++++++++++------ .../ProbeReferenceVolume.Debug.cs.hlsl | 8 +- .../ProbeVolume/ProbeReferenceVolume.cs | 11 +- .../Runtime/Utilities/ResourceReloader.cs | 11 ++ .../Runtime/Debug/ProbeVolumeDebug.hlsl | 118 +++++++++++++++ .../Runtime/Debug/ProbeVolumeDebug.hlsl.meta | 7 + .../Runtime/Debug/ProbeVolumeDebug.shader | 103 +------------ .../Debug/ProbeVolumeOffsetDebug.shader | 74 ++++++++++ .../Debug/ProbeVolumeOffsetDebug.shader.meta | 10 ++ .../RenderPipeline/HDRenderPipeline.cs | 4 +- .../HDRenderPipelineRuntimeResources.cs | 4 + .../HDRenderPipelineRuntimeResources.asset | 20 ++- 14 files changed, 422 insertions(+), 181 deletions(-) create mode 100644 com.unity.render-pipelines.high-definition/Runtime/Debug/ProbeVolumeDebug.hlsl create mode 100644 com.unity.render-pipelines.high-definition/Runtime/Debug/ProbeVolumeDebug.hlsl.meta create mode 100644 com.unity.render-pipelines.high-definition/Runtime/Debug/ProbeVolumeOffsetDebug.shader create mode 100644 com.unity.render-pipelines.high-definition/Runtime/Debug/ProbeVolumeOffsetDebug.shader.meta diff --git a/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.VirtualOffset.cs b/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.VirtualOffset.cs index 558fb0ad1e0..3b425855d55 100644 --- a/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.VirtualOffset.cs +++ b/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.VirtualOffset.cs @@ -12,12 +12,54 @@ partial class ProbeGIBaking { static List addedOccluders; - private static void AddOccluders() + static void ApplyVirtualOffsets(Vector3[] positions, out Vector3[] offsets) + { + var voSettings = m_BakingSettings.virtualOffsetSettings; + if (!voSettings.useVirtualOffset) + { + offsets = null; + return; + } + + var queriesHitBackBefore = Physics.queriesHitBackfaces; + try + { + Physics.queriesHitBackfaces = true; + + AddOccluders(); + ApplyVirtualOffsetsSingleThreaded(positions, out offsets, voSettings); + } + finally + { + Physics.queriesHitBackfaces = queriesHitBackBefore; + CleanupOccluders(); + } + } + + static void ApplyVirtualOffsetsSingleThreaded(Vector3[] positions, out Vector3[] offsets, VirtualOffsetSettings voSettings) + { + offsets = new Vector3[positions.Length]; + for (int i = 0; i < positions.Length; ++i) + { + int subdivLevel = 0; + m_BakingBatch.uniqueBrickSubdiv.TryGetValue(positions[i], out subdivLevel); + float brickSize = ProbeReferenceVolume.CellSize(subdivLevel); + float searchDistance = (brickSize * m_BakingProfile.minBrickSize) / ProbeBrickPool.kBrickCellCount; + + float scaleForSearchDist = voSettings.searchMultiplier; + Vector3 pushedPosition = PushPositionOutOfGeometry(positions[i], scaleForSearchDist * searchDistance, voSettings.outOfGeoOffset); + + offsets[i] = pushedPosition - positions[i]; + positions[i] = pushedPosition; + } + } + + static void AddOccluders() { addedOccluders = new List(); - for (int sceneIndex = 0; sceneIndex < UnityEngine.SceneManagement.SceneManager.sceneCount; ++sceneIndex) + for (int sceneIndex = 0; sceneIndex < SceneManagement.SceneManager.sceneCount; ++sceneIndex) { - UnityEngine.SceneManagement.Scene scene = UnityEngine.SceneManagement.SceneManager.GetSceneAt(sceneIndex); + SceneManagement.Scene scene = SceneManagement.SceneManager.GetSceneAt(sceneIndex); if (!scene.isLoaded) continue; @@ -27,10 +69,10 @@ private static void AddOccluders() MeshRenderer[] renderComponents = gameObject.GetComponentsInChildren(); foreach (MeshRenderer mr in renderComponents) { - if (!mr.gameObject.GetComponent() && (GameObjectUtility.GetStaticEditorFlags(mr.gameObject).HasFlag(StaticEditorFlags.ContributeGI))) + if ((GameObjectUtility.GetStaticEditorFlags(mr.gameObject) & StaticEditorFlags.ContributeGI) != 0 && !mr.gameObject.TryGetComponent(out _)) { var meshCollider = mr.gameObject.AddComponent(); - meshCollider.hideFlags |= (HideFlags.DontSaveInEditor | HideFlags.DontSaveInBuild); + meshCollider.hideFlags |= HideFlags.DontSaveInEditor | HideFlags.DontSaveInBuild; addedOccluders.Add(mr); } } @@ -38,9 +80,15 @@ private static void AddOccluders() } var autoSimState = Physics.autoSimulation; - Physics.autoSimulation = false; - Physics.Simulate(0.1f); - Physics.autoSimulation = autoSimState; + try + { + Physics.autoSimulation = false; + Physics.Simulate(0.1f); + } + finally + { + Physics.autoSimulation = autoSimState; + } } private static void CleanupOccluders() diff --git a/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.cs b/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.cs index c2053bb727d..72e23cf0770 100644 --- a/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.cs +++ b/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.cs @@ -26,6 +26,7 @@ class BakingBatch public Dictionary> cellIndex2SceneReferences = new Dictionary>(); public List cells = new List(); public Dictionary uniquePositions = new Dictionary(); + public Vector3[] virtualOffsets; // Allow to get a mapping to subdiv level with the unique positions. It stores the minimum subdiv level found for a given position. // Can be probably done cleaner. public Dictionary uniqueBrickSubdiv = new Dictionary(); @@ -201,9 +202,6 @@ static void OnBakeStarted() SetBakingContext(perSceneDataList); - if (m_BakingSettings.virtualOffsetSettings.useVirtualOffset) - AddOccluders(); - RunPlacement(); } @@ -462,6 +460,8 @@ static void OnAdditionalProbesBakeCompleted() onAdditionalProbesBakeCompletedCalled = true; var dilationSettings = m_BakingSettings.dilationSettings; + var virtualOffsets = m_BakingBatch.virtualOffsets; + // Fetch results of all cells for (int c = 0; c < numCells; ++c) { @@ -477,11 +477,16 @@ static void OnAdditionalProbesBakeCompleted() cell.sh = new SphericalHarmonicsL2[numProbes]; cell.validity = new float[numProbes]; + cell.offsetVectors = new Vector3[virtualOffsets != null ? numProbes : 0]; cell.minSubdiv = probeRefVolume.GetMaxSubdivision(); for (int i = 0; i < numProbes; ++i) { int j = bakingCells[c].probeIndices[i]; + + if (virtualOffsets != null) + cell.offsetVectors[i] = virtualOffsets[j]; + SphericalHarmonicsL2 shv = sh[j]; int brickIdx = i / 64; @@ -850,24 +855,9 @@ public static void ApplySubdivisionResults(ProbeSubdivisionResult results, Matri } } - - // Move positions before sending them + // Virtually offset positions before passing them to lightmapper var positions = m_BakingBatch.uniquePositions.Keys.ToArray(); - VirtualOffsetSettings voSettings = m_BakingSettings.virtualOffsetSettings; - if (voSettings.useVirtualOffset) - { - for (int i = 0; i < positions.Length; ++i) - { - int subdivLevel = 0; - m_BakingBatch.uniqueBrickSubdiv.TryGetValue(positions[i], out subdivLevel); - float brickSize = ProbeReferenceVolume.CellSize(subdivLevel); - float searchDistance = (brickSize * m_BakingProfile.minBrickSize) / ProbeBrickPool.kBrickCellCount; - - float scaleForSearchDist = voSettings.searchMultiplier; - positions[i] = PushPositionOutOfGeometry(positions[i], scaleForSearchDist * searchDistance, voSettings.outOfGeoOffset); - } - CleanupOccluders(); - } + ApplyVirtualOffsets(positions, out m_BakingBatch.virtualOffsets); UnityEditor.Experimental.Lightmapping.SetAdditionalBakedProbes(m_BakingBatch.index, positions); } diff --git a/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs b/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs index 5fd96bf719a..bc87e5101b6 100644 --- a/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs +++ b/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs @@ -7,6 +7,8 @@ namespace UnityEngine.Experimental.Rendering public enum DebugProbeShadingMode { SH, + SHL0, + SHL0L1, Validity, ValidityOverDilationThreshold, Size @@ -26,6 +28,8 @@ class ProbeVolumeDebug public float probeCullingDistance = 200.0f; public int maxSubdivToVisualize = ProbeBrickIndex.kMaxSubdivisionLevels; public float exposureCompensation; + public bool drawVirtualOffsetPush; + public float offsetSize = 0.1f; public bool freezeStreaming; } @@ -34,12 +38,13 @@ public partial class ProbeReferenceVolume class CellInstancedDebugProbes { public List probeBuffers; + public List offsetBuffers; public List props; public Hash128 cellHash; public Vector3 cellPosition; } - const int kProbesPerBatch = 1023; + const int kProbesPerBatch = 511; internal ProbeVolumeDebug debugDisplay { get; } = new ProbeVolumeDebug(); @@ -49,6 +54,8 @@ class CellInstancedDebugProbes DebugUI.Widget[] m_DebugItems; Mesh m_DebugMesh; Material m_DebugMaterial; + Mesh m_DebugOffsetMesh; + Material m_DebugOffsetMaterial; List m_CellDebugData = new List(); Plane[] m_DebugFrustumPlanes = new Plane[6]; @@ -64,19 +71,20 @@ public void RenderDebug(Camera camera) { if (camera.cameraType != CameraType.Reflection && camera.cameraType != CameraType.Preview) { - if (debugDisplay.drawProbes) - { - DrawProbeDebug(camera); - } + DrawProbeDebug(camera); } } - void InitializeDebug(Mesh debugProbeMesh, Shader debugProbeShader) + void InitializeDebug(Mesh debugProbeMesh, Shader debugProbeShader, Mesh debugOffsetMesh, Shader debugOffsetShader) { m_DebugMesh = debugProbeMesh; m_DebugMaterial = CoreUtils.CreateEngineMaterial(debugProbeShader); m_DebugMaterial.enableInstancing = true; + m_DebugOffsetMesh = debugOffsetMesh; + m_DebugOffsetMaterial = CoreUtils.CreateEngineMaterial(debugOffsetShader); + m_DebugOffsetMaterial.enableInstancing = true; + // Hard-coded colors for now. Debug.Assert(ProbeBrickIndex.kMaxSubdivisionLevels == 7); // Update list if this changes. subdivisionDebugColors[0] = new Color(1.0f, 0.0f, 0.0f); @@ -98,6 +106,7 @@ void CleanupDebug() { UnregisterDebug(true); CoreUtils.Destroy(m_DebugMaterial); + CoreUtils.Destroy(m_DebugOffsetMaterial); #if UNITY_EDITOR UnityEditor.Lightmapping.lightingDataCleared -= OnClearLightingdata; @@ -132,16 +141,14 @@ void RegisterDebug() } #endif - if (debugDisplay.drawCells || debugDisplay.drawBricks) - { - subdivContainer.children.Add(new DebugUI.FloatField { displayName = "Culling Distance", getter = () => debugDisplay.subdivisionViewCullingDistance, setter = value => debugDisplay.subdivisionViewCullingDistance = value, min = () => 0.0f }); - } + subdivContainer.children.Add(new DebugUI.FloatField { displayName = "Culling Distance", getter = () => debugDisplay.subdivisionViewCullingDistance, setter = value => debugDisplay.subdivisionViewCullingDistance = value, min = () => 0.0f }); var probeContainer = new DebugUI.Container() { displayName = "Probe Visualization" }; probeContainer.children.Add(new DebugUI.BoolField { displayName = "Display Probes", getter = () => debugDisplay.drawProbes, setter = value => debugDisplay.drawProbes = value, onValueChanged = RefreshDebug }); if (debugDisplay.drawProbes) { - probeContainer.children.Add(new DebugUI.EnumField + var probeContainerChildren = new DebugUI.Container(); + probeContainerChildren.children.Add(new DebugUI.EnumField { displayName = "Probe Shading Mode", getter = () => (int)debugDisplay.probeShading, @@ -151,13 +158,11 @@ void RegisterDebug() setIndex = value => debugDisplay.probeShading = (DebugProbeShadingMode)value, onValueChanged = RefreshDebug }); - probeContainer.children.Add(new DebugUI.FloatField { displayName = "Probe Size", getter = () => debugDisplay.probeSize, setter = value => debugDisplay.probeSize = value, min = () => 0.1f, max = () => 10.0f }); - if (debugDisplay.probeShading == DebugProbeShadingMode.SH) - probeContainer.children.Add(new DebugUI.FloatField { displayName = "Probe Exposure Compensation", getter = () => debugDisplay.exposureCompensation, setter = value => debugDisplay.exposureCompensation = value }); - - probeContainer.children.Add(new DebugUI.FloatField { displayName = "Culling Distance", getter = () => debugDisplay.probeCullingDistance, setter = value => debugDisplay.probeCullingDistance = value, min = () => 0.0f }); + probeContainerChildren.children.Add(new DebugUI.FloatField { displayName = "Probe Size", getter = () => debugDisplay.probeSize, setter = value => debugDisplay.probeSize = value, min = () => 0.1f, max = () => 10.0f }); + if (debugDisplay.probeShading == DebugProbeShadingMode.SH || debugDisplay.probeShading == DebugProbeShadingMode.SHL0 || debugDisplay.probeShading == DebugProbeShadingMode.SHL0L1) + probeContainerChildren.children.Add(new DebugUI.FloatField { displayName = "Probe Exposure Compensation", getter = () => debugDisplay.exposureCompensation, setter = value => debugDisplay.exposureCompensation = value }); - probeContainer.children.Add(new DebugUI.IntField + probeContainerChildren.children.Add(new DebugUI.IntField { displayName = "Max subdivision displayed", getter = () => debugDisplay.maxSubdivToVisualize, @@ -165,8 +170,19 @@ void RegisterDebug() min = () => 0, max = () => ProbeReferenceVolume.instance.GetMaxSubdivision(), }); + + probeContainer.children.Add(probeContainerChildren); } + probeContainer.children.Add(new DebugUI.BoolField { displayName = "Virtual Offset", getter = () => debugDisplay.drawVirtualOffsetPush, setter = value => debugDisplay.drawVirtualOffsetPush = value, onValueChanged = RefreshDebug }); + if (debugDisplay.drawVirtualOffsetPush) + { + var voOffset = new DebugUI.FloatField { displayName = "Offset Size", getter = () => debugDisplay.offsetSize, setter = value => debugDisplay.offsetSize = value, min = () => 0.001f, max = () => 0.1f }; + probeContainer.children.Add(new DebugUI.Container { children = { voOffset } }); + } + + probeContainer.children.Add(new DebugUI.FloatField { displayName = "Culling Distance", getter = () => debugDisplay.probeCullingDistance, setter = value => debugDisplay.probeCullingDistance = value, min = () => 0.0f }); + var streamingContainer = new DebugUI.Container() { displayName = "Streaming" }; streamingContainer.children.Add(new DebugUI.BoolField { displayName = "Freeze Streaming", getter = () => debugDisplay.freezeStreaming, setter = value => debugDisplay.freezeStreaming = value }); @@ -200,44 +216,53 @@ bool ShouldCullCell(Vector3 cellPosition, Transform cameraTransform, Plane[] fru return true; var volumeAABB = new Bounds(cellCenterWS, cellSize * Vector3.one); - return !GeometryUtility.TestPlanesAABB(frustumPlanes, volumeAABB); } void DrawProbeDebug(Camera camera) { - if (debugDisplay.drawProbes) - { - // TODO: Update data on ref vol changes - if (m_CellDebugData.Count == 0) - CreateInstancedProbes(); + if (!debugDisplay.drawProbes && !debugDisplay.drawVirtualOffsetPush) + return; - GeometryUtility.CalculateFrustumPlanes(camera, m_DebugFrustumPlanes); + // TODO: Update data on ref vol changes + if (m_CellDebugData.Count == 0) + CreateInstancedProbes(); - m_DebugMaterial.shaderKeywords = null; - if (m_SHBands == ProbeVolumeSHBands.SphericalHarmonicsL1) - m_DebugMaterial.EnableKeyword("PROBE_VOLUMES_L1"); - else if (m_SHBands == ProbeVolumeSHBands.SphericalHarmonicsL2) - m_DebugMaterial.EnableKeyword("PROBE_VOLUMES_L2"); + GeometryUtility.CalculateFrustumPlanes(camera, m_DebugFrustumPlanes); - foreach (var debug in m_CellDebugData) - { - if (ShouldCullCell(debug.cellPosition, camera.transform, m_DebugFrustumPlanes)) - continue; + m_DebugMaterial.shaderKeywords = null; + if (m_SHBands == ProbeVolumeSHBands.SphericalHarmonicsL1) + m_DebugMaterial.EnableKeyword("PROBE_VOLUMES_L1"); + else if (m_SHBands == ProbeVolumeSHBands.SphericalHarmonicsL2) + m_DebugMaterial.EnableKeyword("PROBE_VOLUMES_L2"); + + foreach (var debug in m_CellDebugData) + { + if (ShouldCullCell(debug.cellPosition, camera.transform, m_DebugFrustumPlanes)) + continue; - for (int i = 0; i < debug.probeBuffers.Count; ++i) + for (int i = 0; i < debug.probeBuffers.Count; ++i) + { + var props = debug.props[i]; + props.SetInt("_ShadingMode", (int)debugDisplay.probeShading); + props.SetFloat("_ExposureCompensation", debugDisplay.exposureCompensation); + props.SetFloat("_ProbeSize", debugDisplay.probeSize); + props.SetFloat("_CullDistance", debugDisplay.probeCullingDistance); + props.SetInt("_MaxAllowedSubdiv", debugDisplay.maxSubdivToVisualize); + props.SetFloat("_ValidityThreshold", dilationValidtyThreshold); + props.SetFloat("_OffsetSize", debugDisplay.offsetSize); + + if (debugDisplay.drawProbes) { var probeBuffer = debug.probeBuffers[i]; - var props = debug.props[i]; - props.SetInt("_ShadingMode", (int)debugDisplay.probeShading); - props.SetFloat("_ExposureCompensation", debugDisplay.exposureCompensation); - props.SetFloat("_ProbeSize", debugDisplay.probeSize); - props.SetFloat("_CullDistance", debugDisplay.probeCullingDistance); - props.SetInt("_MaxAllowedSubdiv", debugDisplay.maxSubdivToVisualize); - props.SetFloat("_ValidityThreshold", dilationValidtyThreshold); - Graphics.DrawMeshInstanced(m_DebugMesh, 0, m_DebugMaterial, probeBuffer, probeBuffer.Length, props, ShadowCastingMode.Off, false, 0, camera, LightProbeUsage.Off, null); } + + if (debugDisplay.drawVirtualOffsetPush) + { + var offsetBuffer = debug.offsetBuffers[i]; + Graphics.DrawMeshInstanced(m_DebugOffsetMesh, 0, m_DebugOffsetMaterial, offsetBuffer, offsetBuffer.Length, props, ShadowCastingMode.Off, false, 0, camera, LightProbeUsage.Off, null); + } } } } @@ -260,17 +285,21 @@ void CreateInstancedProbes() float largestBrickSize = cell.bricks.Count == 0 ? 0 : cell.bricks[0].subdivisionLevel; List probeBuffers = new List(); + List offsetBuffers = new List(); List props = new List(); var chunks = cellInfo.chunkList; Vector4[] texels = new Vector4[kProbesPerBatch]; float[] validity = new float[kProbesPerBatch]; float[] relativeSize = new float[kProbesPerBatch]; + Vector4[] offsets = cell.offsetVectors.Length > 0 ? new Vector4[kProbesPerBatch] : null; List probeBuffer = new List(); + List offsetBuffer = new List(); var debugData = new CellInstancedDebugProbes(); debugData.probeBuffers = probeBuffers; + debugData.offsetBuffers = offsetBuffers; debugData.props = props; debugData.cellPosition = cell.position; @@ -293,6 +322,25 @@ void CreateInstancedProbes() validity[idxInBatch] = cell.validity[i]; texels[idxInBatch] = new Vector4(texelLoc.x, texelLoc.y, texelLoc.z, brickSize); relativeSize[idxInBatch] = (float)brickSize / (float)maxSubdiv; + if (offsets != null) + { + const float kOffsetThresholdSqr = 1e-5f; + + var offset = cell.offsetVectors[i]; + offsets[idxInBatch] = offset; + + if (offset.sqrMagnitude < kOffsetThresholdSqr) + { + offsetBuffer.Add(Matrix4x4.identity); + } + else + { + var position = cell.probePositions[i] + offset; + var orientation = Quaternion.LookRotation(-offset); + var scale = new Vector3(0.5f, 0.5f, offset.magnitude); + offsetBuffer.Add(Matrix4x4.TRS(position, orientation, scale)); + } + } idxInBatch++; if (probeBuffer.Count >= kProbesPerBatch || i == cell.probePositions.Length - 1) @@ -304,10 +352,17 @@ void CreateInstancedProbes() prop.SetFloatArray("_RelativeSize", relativeSize); prop.SetVectorArray("_IndexInAtlas", texels); + if(offsets != null) + prop.SetVectorArray("_Offset", offsets); + props.Add(prop); probeBuffers.Add(probeBuffer.ToArray()); probeBuffer = new List(); + probeBuffer.Clear(); + + offsetBuffers.Add(offsetBuffer.ToArray()); + offsetBuffer.Clear(); } } diff --git a/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs.hlsl b/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs.hlsl index 9fcdecba00f..f222ba4eda8 100644 --- a/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs.hlsl +++ b/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs.hlsl @@ -8,9 +8,11 @@ // UnityEngine.Experimental.Rendering.DebugProbeShadingMode: static fields // #define DEBUGPROBESHADINGMODE_SH (0) -#define DEBUGPROBESHADINGMODE_VALIDITY (1) -#define DEBUGPROBESHADINGMODE_VALIDITY_OVER_DILATION_THRESHOLD (2) -#define DEBUGPROBESHADINGMODE_SIZE (3) +#define DEBUGPROBESHADINGMODE_SHL0 (1) +#define DEBUGPROBESHADINGMODE_SHL0L1 (2) +#define DEBUGPROBESHADINGMODE_VALIDITY (3) +#define DEBUGPROBESHADINGMODE_VALIDITY_OVER_DILATION_THRESHOLD (4) +#define DEBUGPROBESHADINGMODE_SIZE (5) #endif diff --git a/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.cs b/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.cs index 4c0fc793026..71bdba57d86 100644 --- a/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.cs +++ b/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.cs @@ -227,6 +227,14 @@ public struct ProbeVolumeSystemParameters /// The shader used to visualize the probes in the debug view. /// public Shader probeDebugShader; + /// + /// The debug mesh used to visualize probes virtual offset in the debug view. + /// + public Mesh offsetDebugMesh; + /// + /// The shader used to visualize probes virtual offset in the debug view. + /// + public Shader offsetDebugShader; public ProbeVolumeSceneData sceneData; public ProbeVolumeSHBands shBands; /// True if APV should support streaming of cell data. @@ -293,6 +301,7 @@ internal class Cell public Vector3Int position; public List bricks; public Vector3[] probePositions; + public Vector3[] offsetVectors; public SphericalHarmonicsL2[] sh; public float[] validity; public int minSubdiv; @@ -590,7 +599,7 @@ public void Initialize(in ProbeVolumeSystemParameters parameters) m_MemoryBudget = parameters.memoryBudget; m_SHBands = parameters.shBands; - InitializeDebug(parameters.probeDebugMesh, parameters.probeDebugShader); + InitializeDebug(parameters.probeDebugMesh, parameters.probeDebugShader, parameters.offsetDebugMesh, parameters.offsetDebugShader); InitProbeReferenceVolume(m_MemoryBudget, m_SHBands); m_IsInitialized = true; m_NeedsIndexRebuild = true; diff --git a/com.unity.render-pipelines.core/Runtime/Utilities/ResourceReloader.cs b/com.unity.render-pipelines.core/Runtime/Utilities/ResourceReloader.cs index f51f5a23511..fba907fb29c 100644 --- a/com.unity.render-pipelines.core/Runtime/Utilities/ResourceReloader.cs +++ b/com.unity.render-pipelines.core/Runtime/Utilities/ResourceReloader.cs @@ -191,9 +191,20 @@ static UnityEngine.Object Load(string path, Type type, bool builtin) // Else the path is good. Attempt loading resource if AssetDatabase available. UnityEngine.Object result; if (builtin && type == typeof(Shader)) + { result = Shader.Find(path); + } else + { result = AssetDatabase.LoadAssetAtPath(path, type); + + if (IsNull(result)) + result = Resources.GetBuiltinResource(type, path); + + if (IsNull(result)) + result = AssetDatabase.GetBuiltinExtraResource(type, path); + } + if (IsNull(result)) { var e = new Exception($"Cannot load. Path {path} is correct but AssetDatabase cannot load now."); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Debug/ProbeVolumeDebug.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Debug/ProbeVolumeDebug.hlsl new file mode 100644 index 00000000000..e6c99f9627a --- /dev/null +++ b/com.unity.render-pipelines.high-definition/Runtime/Debug/ProbeVolumeDebug.hlsl @@ -0,0 +1,118 @@ +#ifndef PROBEVOLUMEDEBUG_HLSL +#define PROBEVOLUMEDEBUG_HLSL + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonLighting.hlsl" +#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl" +#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinGIUtilities.hlsl" +#include "Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/DecodeSH.hlsl" +#include "Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolume.hlsl" +#include "Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs.hlsl" + +uniform int _ShadingMode; +uniform float _ExposureCompensation; +uniform float _ProbeSize; +uniform float4 _Color; +uniform int _SubdivLevel; +uniform float _CullDistance; +uniform int _MaxAllowedSubdiv; +uniform float _ValidityThreshold; +uniform float _OffsetSize; + +UNITY_INSTANCING_BUFFER_START(Props) + UNITY_DEFINE_INSTANCED_PROP(float, _Validity) + UNITY_DEFINE_INSTANCED_PROP(float4, _IndexInAtlas) + UNITY_DEFINE_INSTANCED_PROP(float4, _Offset) + UNITY_DEFINE_INSTANCED_PROP(float, _RelativeSize) +UNITY_INSTANCING_BUFFER_END(Props) + +struct appdata +{ + float4 vertex : POSITION; + float3 normal : NORMAL; + UNITY_VERTEX_INPUT_INSTANCE_ID +}; + +struct v2f +{ + float4 vertex : SV_POSITION; + float3 normal : TEXCOORD1; + UNITY_VERTEX_INPUT_INSTANCE_ID +}; + +void DoCull(inout v2f o) +{ + o.vertex = float4(0, 0, 0, 0); + o.normal = float3(0, 0, 0); +} + +// Finer culling, degenerate the vertices of the debug element if it lies over the max distance. +// Coarser culling has already happened on CPU. +bool ShouldCull(inout v2f o) +{ + float4 position = float4(UNITY_MATRIX_M._m03_m13_m23, 1); + int brickSize = UNITY_ACCESS_INSTANCED_PROP(Props, _IndexInAtlas).w; + + if(distance(position.xyz, GetCurrentViewPosition()) > _CullDistance || brickSize > _MaxAllowedSubdiv) + { + DoCull(o); + return true; + } + + return false; +} + +float3 EvalL1(float3 L0, float3 L1_R, float3 L1_G, float3 L1_B, float3 N) +{ + float3 outLighting = 0; + L1_R = DecodeSH(L0.r, L1_R); + L1_G = DecodeSH(L0.g, L1_G); + L1_B = DecodeSH(L0.b, L1_B); + outLighting += SHEvalLinearL1(N, L1_R, L1_G, L1_B); + + return outLighting; +} + +float3 EvalL2(inout float3 L0, float4 L2_R, float4 L2_G, float4 L2_B, float4 L2_C, float3 N) +{ + DecodeSH_L2(L0, L2_R, L2_G, L2_B, L2_C); + + return SHEvalLinearL2(N, L2_R, L2_G, L2_B, L2_C); +} + +float3 CalculateDiffuseLighting(v2f i) +{ + APVResources apvRes = FillAPVResources(); + int3 texLoc = UNITY_ACCESS_INSTANCED_PROP(Props, _IndexInAtlas).xyz; + float3 normal = normalize(i.normal); + + float4 L0_L1Rx = apvRes.L0_L1Rx[texLoc].rgba; + float3 L0 = L0_L1Rx.xyz; + + if (_ShadingMode == DEBUGPROBESHADINGMODE_SHL0) + return L0; + + float L1Rx = L0_L1Rx.w; + float4 L1G_L1Ry = apvRes.L1G_L1Ry[texLoc].rgba; + float4 L1B_L1Rz = apvRes.L1B_L1Rz[texLoc].rgba; + + float3 bakeDiffuseLighting = EvalL1(L0, float3(L1Rx, L1G_L1Ry.w, L1B_L1Rz.w), L1G_L1Ry.xyz, L1B_L1Rz.xyz, normal); + bakeDiffuseLighting += L0; + + if (_ShadingMode == DEBUGPROBESHADINGMODE_SHL0L1) + return bakeDiffuseLighting; + +#ifdef PROBE_VOLUMES_L2 + float4 L2_R = apvRes.L2_0[texLoc].rgba; + float4 L2_G = apvRes.L2_1[texLoc].rgba; + float4 L2_B = apvRes.L2_2[texLoc].rgba; + float4 L2_C = apvRes.L2_3[texLoc].rgba; + + bakeDiffuseLighting += EvalL2(L0, L2_R, L2_G, L2_B, L2_C, normal); +#endif + + return bakeDiffuseLighting; +} + +#endif //PROBEVOLUMEDEBUG_HLSL diff --git a/com.unity.render-pipelines.high-definition/Runtime/Debug/ProbeVolumeDebug.hlsl.meta b/com.unity.render-pipelines.high-definition/Runtime/Debug/ProbeVolumeDebug.hlsl.meta new file mode 100644 index 00000000000..dd811c03f8a --- /dev/null +++ b/com.unity.render-pipelines.high-definition/Runtime/Debug/ProbeVolumeDebug.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ccecfcbd852d8114fa00c7d48df8fb3c +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.render-pipelines.high-definition/Runtime/Debug/ProbeVolumeDebug.shader b/com.unity.render-pipelines.high-definition/Runtime/Debug/ProbeVolumeDebug.shader index 97ea26f53aa..eb06dedc8ab 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Debug/ProbeVolumeDebug.shader +++ b/com.unity.render-pipelines.high-definition/Runtime/Debug/ProbeVolumeDebug.shader @@ -1,9 +1,5 @@ Shader "Hidden/HDRP/ProbeVolumeDebug" { - Properties - { - } - SubShader { Tags{ "RenderPipeline" = "HDRenderPipeline" "RenderType" = "Opaque" } @@ -15,43 +11,7 @@ Shader "Hidden/HDRP/ProbeVolumeDebug" #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch #pragma multi_compile_fragment PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 - #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" - #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl" - #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonLighting.hlsl" - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl" - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinGIUtilities.hlsl" - #include "Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/DecodeSH.hlsl" - #include "Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolume.hlsl" - #include "Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs.hlsl" - - uniform int _ShadingMode; - uniform float _ExposureCompensation; - uniform float _ProbeSize; - uniform float4 _Color; - uniform int _SubdivLevel; - uniform float _CullDistance; - uniform int _MaxAllowedSubdiv; - uniform float _ValidityThreshold; - - struct appdata - { - float4 vertex : POSITION; - float3 normal : NORMAL; - UNITY_VERTEX_INPUT_INSTANCE_ID - }; - - struct v2f - { - float4 vertex : SV_POSITION; - float3 normal : TEXCOORD1; - UNITY_VERTEX_INPUT_INSTANCE_ID - }; - - UNITY_INSTANCING_BUFFER_START(Props) - UNITY_DEFINE_INSTANCED_PROP(float4, _IndexInAtlas) - UNITY_DEFINE_INSTANCED_PROP(float, _Validity) - UNITY_DEFINE_INSTANCED_PROP(float, _RelativeSize) - UNITY_INSTANCING_BUFFER_END(Props) + #include "ProbeVolumeDebug.hlsl" v2f vert(appdata v) { @@ -60,78 +20,23 @@ Shader "Hidden/HDRP/ProbeVolumeDebug" UNITY_SETUP_INSTANCE_ID(v); UNITY_TRANSFER_INSTANCE_ID(v, o); - - // Finer culling, degenerate the vertices of the sphere if it lies over the max distance. - // Coarser culling has already happened on CPU. - float4 position = float4(UNITY_MATRIX_M._m03_m13_m23, 1); - int brickSize = UNITY_ACCESS_INSTANCED_PROP(Props, _IndexInAtlas).w; - - if (distance(position.xyz, GetCurrentViewPosition()) > _CullDistance || - brickSize > _MaxAllowedSubdiv) - { - o.vertex = 0; - o.normal = 0; - } - else + if(!ShouldCull(o)) { float4 wsPos = mul(UNITY_MATRIX_M, float4(v.vertex.xyz * _ProbeSize, 1.0)); o.vertex = mul(UNITY_MATRIX_VP, wsPos); - o.normal = normalize(mul(v.normal, (float3x3)UNITY_MATRIX_M)); } return o; } - float3 EvalL1(float3 L0, float3 L1_R, float3 L1_G, float3 L1_B, float3 N) - { - float3 outLighting = 0; - L1_R = DecodeSH(L0.r, L1_R); - L1_G = DecodeSH(L0.g, L1_G); - L1_B = DecodeSH(L0.b, L1_B); - outLighting += SHEvalLinearL1(N, L1_R, L1_G, L1_B); - - return outLighting; - } - - float3 EvalL2(inout float3 L0, float4 L2_R, float4 L2_G, float4 L2_B, float4 L2_C, float3 N) - { - DecodeSH_L2(L0, L2_R, L2_G, L2_B, L2_C); - - return SHEvalLinearL2(N, L2_R, L2_G, L2_B, L2_C); - } - float4 frag(v2f i) : SV_Target { UNITY_SETUP_INSTANCE_ID(i); - if (_ShadingMode == DEBUGPROBESHADINGMODE_SH) + if (_ShadingMode >= DEBUGPROBESHADINGMODE_SH && _ShadingMode <= DEBUGPROBESHADINGMODE_SHL0L1) { - APVResources apvRes = FillAPVResources(); - int3 texLoc = UNITY_ACCESS_INSTANCED_PROP(Props, _IndexInAtlas).xyz; - float3 normal = normalize(i.normal); - - float3 bakeDiffuseLighting = float3(0.0, 0.0, 0.0); - float3 backBakeDiffuseLighting = float3(0.0, 0.0, 0.0); - - float4 L0_L1Rx = apvRes.L0_L1Rx[texLoc].rgba; - float3 L0 = L0_L1Rx.xyz; - float L1Rx = L0_L1Rx.w; - float4 L1G_L1Ry = apvRes.L1G_L1Ry[texLoc].rgba; - float4 L1B_L1Rz = apvRes.L1B_L1Rz[texLoc].rgba; - - bakeDiffuseLighting = EvalL1(L0, float3(L1Rx, L1G_L1Ry.w, L1B_L1Rz.w), L1G_L1Ry.xyz, L1B_L1Rz.xyz, normal); - - #ifdef PROBE_VOLUMES_L2 - float4 L2_R = apvRes.L2_0[texLoc].rgba; - float4 L2_G = apvRes.L2_1[texLoc].rgba; - float4 L2_B = apvRes.L2_2[texLoc].rgba; - float4 L2_C = apvRes.L2_3[texLoc].rgba; - - bakeDiffuseLighting += EvalL2(L0, L2_R, L2_G, L2_B, L2_C, normal); - #endif - bakeDiffuseLighting += L0; - return float4(bakeDiffuseLighting * exp2(_ExposureCompensation) * GetCurrentExposureMultiplier(), 1); + return float4(CalculateDiffuseLighting(i) * exp2(_ExposureCompensation) * GetCurrentExposureMultiplier(), 1); } else if (_ShadingMode == DEBUGPROBESHADINGMODE_VALIDITY) { diff --git a/com.unity.render-pipelines.high-definition/Runtime/Debug/ProbeVolumeOffsetDebug.shader b/com.unity.render-pipelines.high-definition/Runtime/Debug/ProbeVolumeOffsetDebug.shader new file mode 100644 index 00000000000..6a31119bb2c --- /dev/null +++ b/com.unity.render-pipelines.high-definition/Runtime/Debug/ProbeVolumeOffsetDebug.shader @@ -0,0 +1,74 @@ +Shader "Hidden/HDRP/ProbeVolumeOffsetDebug" +{ + SubShader + { + Tags{ "RenderPipeline" = "HDRenderPipeline" "RenderType" = "Opaque" } + LOD 100 + + HLSLINCLUDE + #pragma editor_sync_compilation + #pragma target 4.5 + #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch + #pragma multi_compile_fragment PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 + + #include "ProbeVolumeDebug.hlsl" + + v2f vert(appdata v) + { + v2f o; + + UNITY_SETUP_INSTANCE_ID(v); + UNITY_TRANSFER_INSTANCE_ID(v, o); + + float3 offset = UNITY_ACCESS_INSTANCED_PROP(Props, _Offset).xyz; + float offsetLenSqr = dot(offset, offset); + if(offsetLenSqr <= 1e-8f) + { + DoCull(o); + } + else if(!ShouldCull(o)) + { + float4 wsPos = mul(UNITY_MATRIX_M, float4(v.vertex.x * _OffsetSize, v.vertex.y * _OffsetSize, v.vertex.z, 1.f)); + o.vertex = mul(UNITY_MATRIX_VP, wsPos); + o.normal = normalize(mul(v.normal, (float3x3)UNITY_MATRIX_M)); + } + + return o; + } + + float4 frag(v2f i) : SV_Target + { + return float4(1, 0, 0, 1); + } + ENDHLSL + + Pass + { + Name "DepthForwardOnly" + Tags{ "LightMode" = "DepthForwardOnly" } + + ZWrite On + + HLSLPROGRAM + #pragma vertex vert + #pragma fragment frag + #pragma multi_compile_instancing + ENDHLSL + } + + Pass + { + Name "ForwardOnly" + Tags { "LightMode" = "ForwardOnly" } + + ZTest LEqual + ZWrite On + + HLSLPROGRAM + #pragma vertex vert + #pragma fragment frag + #pragma multi_compile_instancing + ENDHLSL + } + } +} diff --git a/com.unity.render-pipelines.high-definition/Runtime/Debug/ProbeVolumeOffsetDebug.shader.meta b/com.unity.render-pipelines.high-definition/Runtime/Debug/ProbeVolumeOffsetDebug.shader.meta new file mode 100644 index 00000000000..7aa906249f8 --- /dev/null +++ b/com.unity.render-pipelines.high-definition/Runtime/Debug/ProbeVolumeOffsetDebug.shader.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: db8bd7436dc2c5f4c92655307d198381 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + preprocessorOverride: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index 37ace55b3cb..182d76bcf62 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -376,11 +376,13 @@ public HDRenderPipeline(HDRenderPipelineAsset asset) if (IsAPVEnabled()) { var pvr = ProbeReferenceVolume.instance; - ProbeReferenceVolume.instance.Initialize(new ProbeVolumeSystemParameters() + ProbeReferenceVolume.instance.Initialize(new ProbeVolumeSystemParameters { memoryBudget = m_Asset.currentPlatformRenderPipelineSettings.probeVolumeMemoryBudget, probeDebugMesh = defaultResources.assets.probeDebugSphere, probeDebugShader = defaultResources.shaders.probeVolumeDebugShader, + offsetDebugMesh = defaultResources.assets.pyramidMesh, + offsetDebugShader = defaultResources.shaders.probeVolumeOffsetDebugShader, sceneData = m_GlobalSettings.GetOrCreateAPVSceneData(), shBands = m_Asset.currentPlatformRenderPipelineSettings.probeVolumeSHBands, supportStreaming = m_Asset.currentPlatformRenderPipelineSettings.supportProbeVolumeStreaming diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipelineRuntimeResources.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipelineRuntimeResources.cs index d3697c36efa..473879555f5 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipelineRuntimeResources.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipelineRuntimeResources.cs @@ -39,6 +39,8 @@ public sealed class ShaderResources public Shader materialError; [Reload("Runtime/Debug/ProbeVolumeDebug.shader")] public Shader probeVolumeDebugShader; + [Reload("Runtime/Debug/ProbeVolumeOffsetDebug.shader")] + public Shader probeVolumeOffsetDebugShader; // Lighting [Reload("Runtime/Lighting/Deferred.Shader")] @@ -481,6 +483,8 @@ public sealed class AssetResources public Mesh sphereMesh; [Reload("Runtime/RenderPipelineResources/Mesh/ProbeDebugSphere.fbx")] public Mesh probeDebugSphere; + [Reload("pyramid.fbx", ReloadAttribute.Package.Builtin)] + public Mesh pyramidMesh; } public ShaderResources shaders; diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/HDRenderPipelineRuntimeResources.asset b/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/HDRenderPipelineRuntimeResources.asset index 8ecefd75dc0..1351fc824db 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/HDRenderPipelineRuntimeResources.asset +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/HDRenderPipelineRuntimeResources.asset @@ -33,6 +33,8 @@ MonoBehaviour: materialError: {fileID: 4800000, guid: 79a966a5200a456188dec0d48d805614, type: 3} probeVolumeDebugShader: {fileID: 4800000, guid: 3b21275fd12d65f49babb5286f040f2d, type: 3} + probeVolumeOffsetDebugShader: {fileID: 4800000, guid: db8bd7436dc2c5f4c92655307d198381, + type: 3} deferredPS: {fileID: 4800000, guid: 00dd221e34a6ab349a1196b0f2fab693, type: 3} colorPyramidPS: {fileID: 4800000, guid: 2fcfb8d92f45e4549b3f0bad5d0654bf, type: 3} depthPyramidCS: {fileID: 7200000, guid: 64a553bb564274041906f78ffba955e4, type: 3} @@ -220,11 +222,16 @@ MonoBehaviour: finalPassPS: {fileID: 4800000, guid: 5ac9ef0c50282754b93c7692488e7ee7, type: 3} clearBlackPS: {fileID: 4800000, guid: 3330c1503ea8c6d4d9408df3f64227eb, type: 3} SMAAPS: {fileID: 4800000, guid: 9655f4aa89a469c49aceaceabf9bc77b, type: 3} - temporalAntialiasingPS: {fileID: 4800000, guid: 3dd9fd928fdb83743b1f27d15df22179, type: 3} - lensFlareDataDrivenPS: {fileID: 4800000, guid: 85330b3de0cfebc4ba78b2d61b1a2899, type: 3} - lensFlareMergeOcclusionCS: {fileID: 7200000, guid: 07492750f384d9a4da9aaf5d2feeed4a, type: 3} - DLSSBiasColorMaskPS: {fileID: 4800000, guid: 017a05924c0b0484ca29717ed0c60343, type: 3} - dofCircleOfConfusion: {fileID: 7200000, guid: 75332b7b315c80d4babe506820aa0bfd, type: 3} + temporalAntialiasingPS: {fileID: 4800000, guid: 3dd9fd928fdb83743b1f27d15df22179, + type: 3} + lensFlareDataDrivenPS: {fileID: 4800000, guid: 85330b3de0cfebc4ba78b2d61b1a2899, + type: 3} + lensFlareMergeOcclusionCS: {fileID: 7200000, guid: 07492750f384d9a4da9aaf5d2feeed4a, + type: 3} + DLSSBiasColorMaskPS: {fileID: 4800000, guid: 017a05924c0b0484ca29717ed0c60343, + type: 3} + dofCircleOfConfusion: {fileID: 7200000, guid: 75332b7b315c80d4babe506820aa0bfd, + type: 3} dofGatherCS: {fileID: 7200000, guid: 1e6b16a7970a1494db74b1d3d007d1cc, type: 3} dofCoCMinMaxCS: {fileID: 7200000, guid: c70dd492c3d2fe94589d6ca8d4e37915, type: 3} dofMinMaxDilateCS: {fileID: 7200000, guid: 757a3f81b35177b44b2b178909b49172, type: 3} @@ -329,8 +336,6 @@ MonoBehaviour: rankingTile256SPP: {fileID: 2800000, guid: 1e604a266c415cd46b36d97cd9220aa8, type: 3} scramblingTile256SPP: {fileID: 2800000, guid: 882fb55d7b3e7c94598a318df9376e32, type: 3} - preintegratedAzimuthalScattering: {fileID: 2800000, guid: 4f022cc0bdd8db4428a8faae60acb3dc, - type: 3} cloudLutRainAO: {fileID: 2800000, guid: e0bcfddf26ed5584ba3d8b94d3200114, type: 3} worleyNoise128RGBA: {fileID: 11700000, guid: 1fe54a721d0e2504e89f121c723404a8, type: 3} @@ -363,4 +368,5 @@ MonoBehaviour: sphereMesh: {fileID: 4300000, guid: 9e0af751bc36ea146940ba245193e28c, type: 3} probeDebugSphere: {fileID: 532591105809680800, guid: b979359990531a2489ebd7a0ef0f9f01, type: 3} + pyramidMesh: {fileID: 10213, guid: 0000000000000000e000000000000000, type: 0} m_Version: 4 From 9c7673ab3eb7545c2afb71c560273515ef68d625 Mon Sep 17 00:00:00 2001 From: Torbjorn Laedre <271210+tlaedre@users.noreply.github.com> Date: Fri, 29 Oct 2021 11:21:52 +0200 Subject: [PATCH 2/6] Tweak defaults and threshold values. --- .../Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs | 4 ++-- .../Runtime/Debug/ProbeVolumeOffsetDebug.shader | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs b/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs index bc87e5101b6..8078a5c6283 100644 --- a/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs +++ b/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs @@ -29,7 +29,7 @@ class ProbeVolumeDebug public int maxSubdivToVisualize = ProbeBrickIndex.kMaxSubdivisionLevels; public float exposureCompensation; public bool drawVirtualOffsetPush; - public float offsetSize = 0.1f; + public float offsetSize = 0.025f; public bool freezeStreaming; } @@ -324,7 +324,7 @@ void CreateInstancedProbes() relativeSize[idxInBatch] = (float)brickSize / (float)maxSubdiv; if (offsets != null) { - const float kOffsetThresholdSqr = 1e-5f; + const float kOffsetThresholdSqr = 1e-6f; var offset = cell.offsetVectors[i]; offsets[idxInBatch] = offset; diff --git a/com.unity.render-pipelines.high-definition/Runtime/Debug/ProbeVolumeOffsetDebug.shader b/com.unity.render-pipelines.high-definition/Runtime/Debug/ProbeVolumeOffsetDebug.shader index 6a31119bb2c..1d0e2b9723d 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Debug/ProbeVolumeOffsetDebug.shader +++ b/com.unity.render-pipelines.high-definition/Runtime/Debug/ProbeVolumeOffsetDebug.shader @@ -22,7 +22,7 @@ Shader "Hidden/HDRP/ProbeVolumeOffsetDebug" float3 offset = UNITY_ACCESS_INSTANCED_PROP(Props, _Offset).xyz; float offsetLenSqr = dot(offset, offset); - if(offsetLenSqr <= 1e-8f) + if(offsetLenSqr <= 1e-6f) { DoCull(o); } From f61e135d368a881b99c8e14a85c97d587d4f79ce Mon Sep 17 00:00:00 2001 From: Torbjorn Laedre <271210+tlaedre@users.noreply.github.com> Date: Wed, 8 Dec 2021 17:14:12 +0100 Subject: [PATCH 3/6] Account for null value when loading data baked before this revision. --- .../Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs b/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs index 1da6866d37b..129a5606784 100644 --- a/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs +++ b/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs @@ -314,7 +314,7 @@ void CreateInstancedProbes() Vector4[] texels = new Vector4[kProbesPerBatch]; float[] validity = new float[kProbesPerBatch]; float[] relativeSize = new float[kProbesPerBatch]; - Vector4[] offsets = cell.offsetVectors.Length > 0 ? new Vector4[kProbesPerBatch] : null; + Vector4[] offsets = cell.offsetVectors?.Length > 0 ? new Vector4[kProbesPerBatch] : null; List probeBuffer = new List(); List offsetBuffer = new List(); From ca5eab75b6242a7e30f1726b89c0e0086c6aafab Mon Sep 17 00:00:00 2001 From: "noreply@unity3d.com" Date: Thu, 9 Dec 2021 07:51:02 +0000 Subject: [PATCH 4/6] Apply formatting changes --- .../Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs b/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs index 129a5606784..d9d7646c55e 100644 --- a/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs +++ b/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs @@ -374,7 +374,7 @@ void CreateInstancedProbes() prop.SetFloatArray("_RelativeSize", relativeSize); prop.SetVectorArray("_IndexInAtlas", texels); - if(offsets != null) + if (offsets != null) prop.SetVectorArray("_Offset", offsets); props.Add(prop); From b676879e2291b18a214aaaf831ef56f5bec3a6ac Mon Sep 17 00:00:00 2001 From: Torbjorn Laedre <271210+tlaedre@users.noreply.github.com> Date: Fri, 17 Dec 2021 16:25:32 +0100 Subject: [PATCH 5/6] Automatically scale down debug probes when enabling virtual offset debug. --- .../ProbeVolume/ProbeReferenceVolume.Debug.cs | 27 +++++++++++++++---- .../ProbeVolume/ProbeVolumePerSceneData.cs | 2 +- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs b/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs index 3252769d398..f872c9e32b5 100644 --- a/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs +++ b/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs @@ -82,7 +82,7 @@ class CellInstancedDebugProbes List m_CellDebugData = new List(); Plane[] m_DebugFrustumPlanes = new Plane[6]; - internal float dilationValidtyThreshold = 0.25f; // We ned to store this here to access it + internal ProbeVolumeBakingProcessSettings bakingProcessSettings; /* DEFAULTS would be better but is implemented in PR#6174 = ProbeVolumeBakingProcessSettings.Defaults; */ // Field used for the realtime subdivision preview internal Dictionary> realtimeSubdivisionInfo = new Dictionary>(); @@ -150,6 +150,9 @@ void DebugCellIndexChanged(DebugUI.Field field, T value) void RegisterDebug() { + const float kProbeSizeMin = 0.05f, kProbeSizeMax = 10.0f; + const float kOffsetSizeMin = 0.001f, kOffsetSizeMax = 0.1f; + var widgetList = new List(); var subdivContainer = new DebugUI.Container() { displayName = "Subdivision Visualization" }; @@ -182,7 +185,7 @@ void RegisterDebug() setIndex = value => debugDisplay.probeShading = (DebugProbeShadingMode)value, onValueChanged = RefreshDebug }); - probeContainerChildren.children.Add(new DebugUI.FloatField { displayName = "Probe Size", getter = () => debugDisplay.probeSize, setter = value => debugDisplay.probeSize = value, min = () => 0.1f, max = () => 10.0f }); + probeContainerChildren.children.Add(new DebugUI.FloatField { displayName = "Probe Size", getter = () => debugDisplay.probeSize, setter = value => debugDisplay.probeSize = value, min = () => kProbeSizeMin, max = () => kProbeSizeMax }); if (debugDisplay.probeShading == DebugProbeShadingMode.SH || debugDisplay.probeShading == DebugProbeShadingMode.SHL0 || debugDisplay.probeShading == DebugProbeShadingMode.SHL0L1) probeContainerChildren.children.Add(new DebugUI.FloatField { displayName = "Probe Exposure Compensation", getter = () => debugDisplay.exposureCompensation, setter = value => debugDisplay.exposureCompensation = value }); @@ -198,10 +201,24 @@ void RegisterDebug() probeContainer.children.Add(probeContainerChildren); } - probeContainer.children.Add(new DebugUI.BoolField { displayName = "Virtual Offset", getter = () => debugDisplay.drawVirtualOffsetPush, setter = value => debugDisplay.drawVirtualOffsetPush = value, onValueChanged = RefreshDebug }); + probeContainer.children.Add(new DebugUI.BoolField { + displayName = "Virtual Offset", + getter = () => debugDisplay.drawVirtualOffsetPush, + setter = value => { + debugDisplay.drawVirtualOffsetPush = value; + + if (debugDisplay.drawVirtualOffsetPush && debugDisplay.drawProbes) + { + // If probes are being drawn when enabling offset, automatically scale them down to a reasonable size so the arrows aren't obscured by the probes. + var searchDistance = CellSize(0) * MinBrickSize() / ProbeBrickPool.kBrickCellCount * bakingProcessSettings.virtualOffsetSettings.searchMultiplier + bakingProcessSettings.virtualOffsetSettings.outOfGeoOffset; + debugDisplay.probeSize = Mathf.Min(debugDisplay.probeSize, Mathf.Clamp(searchDistance, kProbeSizeMin, kProbeSizeMax)); + } + }, + onValueChanged = RefreshDebug + }); if (debugDisplay.drawVirtualOffsetPush) { - var voOffset = new DebugUI.FloatField { displayName = "Offset Size", getter = () => debugDisplay.offsetSize, setter = value => debugDisplay.offsetSize = value, min = () => 0.001f, max = () => 0.1f }; + var voOffset = new DebugUI.FloatField { displayName = "Offset Size", getter = () => debugDisplay.offsetSize, setter = value => debugDisplay.offsetSize = value, min = () => kOffsetSizeMin, max = () => kOffsetSizeMax }; probeContainer.children.Add(new DebugUI.Container { children = { voOffset } }); } @@ -276,7 +293,7 @@ void DrawProbeDebug(Camera camera) props.SetFloat("_ProbeSize", debugDisplay.probeSize); props.SetFloat("_CullDistance", debugDisplay.probeCullingDistance); props.SetInt("_MaxAllowedSubdiv", debugDisplay.maxSubdivToVisualize); - props.SetFloat("_ValidityThreshold", dilationValidtyThreshold); + props.SetFloat("_ValidityThreshold", bakingProcessSettings.dilationSettings.dilationValidityThreshold); props.SetFloat("_OffsetSize", debugDisplay.offsetSize); if (debugDisplay.drawProbes) diff --git a/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumePerSceneData.cs b/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumePerSceneData.cs index f46fb3501c2..bc00a6a180d 100644 --- a/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumePerSceneData.cs +++ b/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumePerSceneData.cs @@ -98,7 +98,7 @@ internal void QueueAssetLoading() #if UNITY_EDITOR if (refVol.sceneData != null) { - refVol.dilationValidtyThreshold = refVol.sceneData.GetBakeSettingsForScene(gameObject.scene).dilationSettings.dilationValidityThreshold; + refVol.bakingProcessSettings = refVol.sceneData.GetBakeSettingsForScene(gameObject.scene); } #endif m_PreviousState = m_CurrentState; From 30057e0dea40f4f5786471ce7bea6cb964741147 Mon Sep 17 00:00:00 2001 From: "noreply@unity3d.com" Date: Sun, 9 Jan 2022 09:59:20 +0000 Subject: [PATCH 6/6] Apply formatting changes --- .../Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs b/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs index f872c9e32b5..3b6dfc785b4 100644 --- a/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs +++ b/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Debug.cs @@ -201,10 +201,12 @@ void RegisterDebug() probeContainer.children.Add(probeContainerChildren); } - probeContainer.children.Add(new DebugUI.BoolField { + probeContainer.children.Add(new DebugUI.BoolField + { displayName = "Virtual Offset", getter = () => debugDisplay.drawVirtualOffsetPush, - setter = value => { + setter = value => + { debugDisplay.drawVirtualOffsetPush = value; if (debugDisplay.drawVirtualOffsetPush && debugDisplay.drawProbes) @@ -262,7 +264,7 @@ bool ShouldCullCell(Vector3 cellPosition, Transform cameraTransform, Plane[] fru void DrawProbeDebug(Camera camera) { - if (!enabledBySRP || !isInitialized) + if (!enabledBySRP || !isInitialized) return; if (!debugDisplay.drawProbes && !debugDisplay.drawVirtualOffsetPush)