From 3a68dfd78326d7cb1f31b4b7f2b04021d077f8b8 Mon Sep 17 00:00:00 2001 From: StarBeats <977663818@qq.com> Date: Mon, 23 Jun 2025 19:18:41 +0800 Subject: [PATCH] add hi-z occlusion culling.culling --- Assets/Scenes/Garden/GardenScene.unity | 91 +++++ Assets/Settings/Mobile/Mobile_High.asset | 2 +- .../Mobile/Mobile_High_Renderer.asset | 27 +- .../Runtime/OcclusionCulling/CullDebug.cs | 4 + ...s => HierarchicalZOcclusionCullFeature.cs} | 220 ++++++++++-- ...HierarchicalZOcclusionCullFeature.cs.meta} | 0 .../Runtime/OcclusionCulling/HizObject.cs | 19 + ...llingFeature.cs.meta => HizObject.cs.meta} | 2 +- .../OcclusionCulling/HizObjectsManager.cs | 231 ++++++++++++ .../HizObjectsManager.cs.meta | 11 + .../OcclusionCulling/HziCullingFeature.cs | 334 ------------------ .../OcclusionCulling/Shaders/CopyDepth.shader | 3 + .../OcclusionCulling/Shaders/HizCull.shader | 100 +++--- 13 files changed, 631 insertions(+), 413 deletions(-) rename Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/{HierarchicalZFeature.cs => HierarchicalZOcclusionCullFeature.cs} (69%) rename Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/{HierarchicalZFeature.cs.meta => HierarchicalZOcclusionCullFeature.cs.meta} (100%) create mode 100644 Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HizObject.cs rename Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/{HziCullingFeature.cs.meta => HizObject.cs.meta} (83%) create mode 100644 Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HizObjectsManager.cs create mode 100644 Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HizObjectsManager.cs.meta delete mode 100644 Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HziCullingFeature.cs diff --git a/Assets/Scenes/Garden/GardenScene.unity b/Assets/Scenes/Garden/GardenScene.unity index b30e084..d5efba7 100644 --- a/Assets/Scenes/Garden/GardenScene.unity +++ b/Assets/Scenes/Garden/GardenScene.unity @@ -44066,6 +44066,10 @@ PrefabInstance: serializedVersion: 3 m_TransformParent: {fileID: 87142414} m_Modifications: + - target: {fileID: 204879369288025, guid: f3465f68f6d568d498c6301e743eae85, type: 3} + propertyPath: m_RenderingLayerMask + value: 1 + objectReference: {fileID: 0} - target: {fileID: 2921625138699678336, guid: f3465f68f6d568d498c6301e743eae85, type: 3} propertyPath: m_Name value: LanternStone_01_Prefab (2) @@ -44074,6 +44078,10 @@ PrefabInstance: propertyPath: m_IsActive value: 1 objectReference: {fileID: 0} + - target: {fileID: 5230092601067906215, guid: f3465f68f6d568d498c6301e743eae85, type: 3} + propertyPath: m_RenderingLayerMask + value: 1 + objectReference: {fileID: 0} - target: {fileID: 5402048836714850101, guid: f3465f68f6d568d498c6301e743eae85, type: 3} propertyPath: maxDisplayDistance value: 26 @@ -44122,6 +44130,10 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 8869709827930661810, guid: f3465f68f6d568d498c6301e743eae85, type: 3} + propertyPath: m_RenderingLayerMask + value: 1 + objectReference: {fileID: 0} - target: {fileID: 9056249284700800750, guid: f3465f68f6d568d498c6301e743eae85, type: 3} propertyPath: m_IsActive value: 1 @@ -47362,6 +47374,10 @@ PrefabInstance: propertyPath: m_IsActive value: 1 objectReference: {fileID: 0} + - target: {fileID: 141850471471409436, guid: 8e5bed6b8dcfed240a38affefd9c58f6, type: 3} + propertyPath: m_Enabled + value: 1 + objectReference: {fileID: 0} - target: {fileID: 141850471471409437, guid: 8e5bed6b8dcfed240a38affefd9c58f6, type: 3} propertyPath: m_LocalPosition.x value: 0 @@ -65894,6 +65910,10 @@ PrefabInstance: serializedVersion: 3 m_TransformParent: {fileID: 87142414} m_Modifications: + - target: {fileID: 204879369288025, guid: f3465f68f6d568d498c6301e743eae85, type: 3} + propertyPath: m_RenderingLayerMask + value: 1 + objectReference: {fileID: 0} - target: {fileID: 2921625138699678336, guid: f3465f68f6d568d498c6301e743eae85, type: 3} propertyPath: m_Name value: LanternStone_01_Prefab (3) @@ -65906,6 +65926,10 @@ PrefabInstance: propertyPath: m_BoundingSphereOverride.x value: -0.125 objectReference: {fileID: 0} + - target: {fileID: 5230092601067906215, guid: f3465f68f6d568d498c6301e743eae85, type: 3} + propertyPath: m_RenderingLayerMask + value: 1 + objectReference: {fileID: 0} - target: {fileID: 6614022729291184415, guid: f3465f68f6d568d498c6301e743eae85, type: 3} propertyPath: m_RootOrder value: 0 @@ -65950,6 +65974,10 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 8869709827930661810, guid: f3465f68f6d568d498c6301e743eae85, type: 3} + propertyPath: m_RenderingLayerMask + value: 1 + objectReference: {fileID: 0} m_RemovedComponents: - {fileID: 8762647674606602420, guid: f3465f68f6d568d498c6301e743eae85, type: 3} m_RemovedGameObjects: [] @@ -73681,6 +73709,10 @@ PrefabInstance: serializedVersion: 3 m_TransformParent: {fileID: 87142414} m_Modifications: + - target: {fileID: 204879369288025, guid: f3465f68f6d568d498c6301e743eae85, type: 3} + propertyPath: m_RenderingLayerMask + value: 1 + objectReference: {fileID: 0} - target: {fileID: 2921625138699678336, guid: f3465f68f6d568d498c6301e743eae85, type: 3} propertyPath: m_Name value: LanternStone_01_Prefab (8) @@ -73689,6 +73721,10 @@ PrefabInstance: propertyPath: m_IsActive value: 1 objectReference: {fileID: 0} + - target: {fileID: 5230092601067906215, guid: f3465f68f6d568d498c6301e743eae85, type: 3} + propertyPath: m_RenderingLayerMask + value: 1 + objectReference: {fileID: 0} - target: {fileID: 6614022729291184415, guid: f3465f68f6d568d498c6301e743eae85, type: 3} propertyPath: m_RootOrder value: 0 @@ -73733,6 +73769,10 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 8869709827930661810, guid: f3465f68f6d568d498c6301e743eae85, type: 3} + propertyPath: m_RenderingLayerMask + value: 1 + objectReference: {fileID: 0} m_RemovedComponents: - {fileID: 8762647674606602420, guid: f3465f68f6d568d498c6301e743eae85, type: 3} m_RemovedGameObjects: [] @@ -74798,6 +74838,10 @@ PrefabInstance: serializedVersion: 3 m_TransformParent: {fileID: 87142414} m_Modifications: + - target: {fileID: 204879369288025, guid: f3465f68f6d568d498c6301e743eae85, type: 3} + propertyPath: m_RenderingLayerMask + value: 1 + objectReference: {fileID: 0} - target: {fileID: 2921625138699678336, guid: f3465f68f6d568d498c6301e743eae85, type: 3} propertyPath: m_Name value: LanternStone_01_Prefab (1) @@ -74806,6 +74850,10 @@ PrefabInstance: propertyPath: m_IsActive value: 1 objectReference: {fileID: 0} + - target: {fileID: 5230092601067906215, guid: f3465f68f6d568d498c6301e743eae85, type: 3} + propertyPath: m_RenderingLayerMask + value: 1 + objectReference: {fileID: 0} - target: {fileID: 6614022729291184415, guid: f3465f68f6d568d498c6301e743eae85, type: 3} propertyPath: m_RootOrder value: 1 @@ -74850,6 +74898,10 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 8869709827930661810, guid: f3465f68f6d568d498c6301e743eae85, type: 3} + propertyPath: m_RenderingLayerMask + value: 1 + objectReference: {fileID: 0} m_RemovedComponents: - {fileID: 8762647674606602420, guid: f3465f68f6d568d498c6301e743eae85, type: 3} m_RemovedGameObjects: [] @@ -113304,6 +113356,10 @@ PrefabInstance: serializedVersion: 3 m_TransformParent: {fileID: 87142414} m_Modifications: + - target: {fileID: 204879369288025, guid: f3465f68f6d568d498c6301e743eae85, type: 3} + propertyPath: m_RenderingLayerMask + value: 1 + objectReference: {fileID: 0} - target: {fileID: 2921625138699678336, guid: f3465f68f6d568d498c6301e743eae85, type: 3} propertyPath: m_Name value: LanternStone_01_Prefab (5) @@ -113312,6 +113368,10 @@ PrefabInstance: propertyPath: m_IsActive value: 1 objectReference: {fileID: 0} + - target: {fileID: 5230092601067906215, guid: f3465f68f6d568d498c6301e743eae85, type: 3} + propertyPath: m_RenderingLayerMask + value: 1 + objectReference: {fileID: 0} - target: {fileID: 6614022729291184415, guid: f3465f68f6d568d498c6301e743eae85, type: 3} propertyPath: m_RootOrder value: 0 @@ -113356,6 +113416,10 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 8869709827930661810, guid: f3465f68f6d568d498c6301e743eae85, type: 3} + propertyPath: m_RenderingLayerMask + value: 1 + objectReference: {fileID: 0} m_RemovedComponents: - {fileID: 8762647674606602420, guid: f3465f68f6d568d498c6301e743eae85, type: 3} m_RemovedGameObjects: [] @@ -115248,6 +115312,10 @@ PrefabInstance: serializedVersion: 3 m_TransformParent: {fileID: 87142414} m_Modifications: + - target: {fileID: 204879369288025, guid: f3465f68f6d568d498c6301e743eae85, type: 3} + propertyPath: m_RenderingLayerMask + value: 1 + objectReference: {fileID: 0} - target: {fileID: 2921625138699678336, guid: f3465f68f6d568d498c6301e743eae85, type: 3} propertyPath: m_Name value: LanternStone_01_Prefab (6) @@ -115256,6 +115324,10 @@ PrefabInstance: propertyPath: m_IsActive value: 1 objectReference: {fileID: 0} + - target: {fileID: 5230092601067906215, guid: f3465f68f6d568d498c6301e743eae85, type: 3} + propertyPath: m_RenderingLayerMask + value: 1 + objectReference: {fileID: 0} - target: {fileID: 5402048836714850101, guid: f3465f68f6d568d498c6301e743eae85, type: 3} propertyPath: maxDisplayDistance value: 23 @@ -115304,6 +115376,10 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 8869709827930661810, guid: f3465f68f6d568d498c6301e743eae85, type: 3} + propertyPath: m_RenderingLayerMask + value: 1 + objectReference: {fileID: 0} m_RemovedComponents: - {fileID: 8762647674606602420, guid: f3465f68f6d568d498c6301e743eae85, type: 3} m_RemovedGameObjects: [] @@ -117817,6 +117893,7 @@ GameObject: - component: {fileID: 966895463892816108} - component: {fileID: 966895463892816109} - component: {fileID: 966895463892816115} + - component: {fileID: 966895463892816116} m_Layer: 0 m_Name: SceneSetup m_TagString: Untagged @@ -117837,6 +117914,20 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: transform: {fileID: 0} +--- !u!114 &966895463892816116 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 966895463892816114} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 86f2125f6a508374c89fea25b64ef353, type: 3} + m_Name: + m_EditorClassIdentifier: + ShowDebug: 0 + culledCnt: 0 --- !u!33 &966895463987172997 MeshFilter: m_ObjectHideFlags: 0 diff --git a/Assets/Settings/Mobile/Mobile_High.asset b/Assets/Settings/Mobile/Mobile_High.asset index 8e18294..a6f760e 100644 --- a/Assets/Settings/Mobile/Mobile_High.asset +++ b/Assets/Settings/Mobile/Mobile_High.asset @@ -114,5 +114,5 @@ MonoBehaviour: m_PrefilterNativeRenderPass: 1 m_ShaderVariantLogLevel: 0 m_ShadowCascades: 0 - superResolution: 3 + superResolution: 0 vrsRate: 0 diff --git a/Assets/Settings/Mobile/Mobile_High_Renderer.asset b/Assets/Settings/Mobile/Mobile_High_Renderer.asset index 0cdc1ce..3f1c041 100644 --- a/Assets/Settings/Mobile/Mobile_High_Renderer.asset +++ b/Assets/Settings/Mobile/Mobile_High_Renderer.asset @@ -43,7 +43,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 386e439eeef2849448d91896c74ff1d5, type: 3} m_Name: FSR m_EditorClassIdentifier: - m_Active: 1 + m_Active: 0 Quality: 0 v1setting: EasuCompute: {fileID: 7200000, guid: 787b0c165dad9074e9489817de945916, type: 3} @@ -146,6 +146,20 @@ MonoBehaviour: CullShader: {fileID: 7200000, guid: 029fde5b4200eeb4e919fe924f26fdd8, type: 3} CullTextureSize: 64 UseThreeFrameReadback: 1 +--- !u!114 &-3660967294238269343 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a5c181080479e2b4cbb22ad7fc3fa4d4, type: 3} + m_Name: HizCullingFeature1 + m_EditorClassIdentifier: + m_Active: 0 + _material: {fileID: 0} --- !u!114 &-2621301742936824463 MonoBehaviour: m_ObjectHideFlags: 0 @@ -223,11 +237,15 @@ MonoBehaviour: m_Active: 1 settings: PyramidFunc: 0 - SkipThreeMip: 0 - UseThreeFrameReadback: 0 + SkipThreeMip: 1 + UseThreeFrameReadback: 1 ComputeShader: {fileID: 7200000, guid: b10c09f63c5a5864ca12e07b1b361d56, type: 3} Spd: {fileID: 7200000, guid: 2c0519b45f80f5c47b4ee3edb2e7931b, type: 3} CopyDepth: {fileID: 2100000, guid: 5f8ec7ea87b60a1448091fade6a0e68f, type: 2} + UseTowCullPass: 0 + UseCompute: 0 + CullMat: {fileID: 2100000, guid: ce13e27ede10980489261083a699b449, type: 2} + CullShader: {fileID: 7200000, guid: 029fde5b4200eeb4e919fe924f26fdd8, type: 3} --- !u!114 &-1133205096357012623 MonoBehaviour: m_ObjectHideFlags: 0 @@ -293,8 +311,7 @@ MonoBehaviour: - {fileID: 4071882023117421450} - {fileID: -7284859345190182597} - {fileID: -1629415145513658388} - - {fileID: -4150689035588204578} - m_RendererFeatureMap: bc3f630842f2e70dd6a559c442a94bfd4529d15534f2d3de228858dca8d12222716523fbf3439fdb7a327b7bff4bdd446ac59dfa966ffa88ca6373cd5da9013d6cff55ca297e5e908a7b3653203b82383b2141bb05fbe69aec5704e48e2763e9de07a83c50ca65c6 + m_RendererFeatureMap: bc3f630842f2e70dd6a559c442a94bfd4529d15534f2d3de228858dca8d12222716523fbf3439fdb7a327b7bff4bdd446ac59dfa966ffa88ca6373cd5da9013d6cff55ca297e5e908a7b3653203b82383b2141bb05fbe69aec5704e48e2763e9 m_UseNativeRenderPass: 0 postProcessData: {fileID: 11400000, guid: 41439944d30ece34e96484bdb6645b55, type: 2} shaders: diff --git a/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/CullDebug.cs b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/CullDebug.cs index 72b5e6c..f33637d 100644 --- a/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/CullDebug.cs +++ b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/CullDebug.cs @@ -14,4 +14,8 @@ public class CullDebug : MonoBehaviour Gizmos.DrawWireCube(Position, Size); Gizmos.color = col; } + + private void LateUpdate() + { + } } diff --git a/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HierarchicalZFeature.cs b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HierarchicalZOcclusionCullFeature.cs similarity index 69% rename from Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HierarchicalZFeature.cs rename to Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HierarchicalZOcclusionCullFeature.cs index 81e5790..38f06c7 100644 --- a/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HierarchicalZFeature.cs +++ b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HierarchicalZOcclusionCullFeature.cs @@ -1,4 +1,6 @@ using System; +using Unity.Collections; +using Unity.Mathematics; using UnityEngine; using UnityEngine.Experimental.Rendering; using UnityEngine.Rendering; @@ -6,7 +8,62 @@ using UnityEngine.Rendering.Universal; namespace X.Rendering.Feature { - public class HierarchicalZFeature : ScriptableRendererFeature + internal class CullResult : IDisposable + { + public RenderTexture ResultTex; + public NativeArray ResultArray; + public bool ReadDone = false; + public bool DataReady = false; + public Action ReadBackAction; + + private void ReadBack(AsyncGPUReadbackRequest readback) + { + if (readback.done && !readback.hasError) + { + var data = readback.GetData(); + if (ResultArray.IsCreated) + { + ResultArray.CopyFrom(data); + } + ReadDone = true; + } + else + { + ReadDone = false; + } + + DataReady = true; + } + + public CullResult CreateResources(int texSize) + { + ResultArray.Dispose(); + ResultArray = new(texSize * texSize, Allocator.Persistent); + if (ResultTex != null) + { + ResultTex.Release(); + } + + ResultTex = new RenderTexture(texSize, texSize, 0, RenderTextureFormat.RHalf); + ResultTex.filterMode = FilterMode.Point; + ResultTex.enableRandomWrite = true; + ResultTex.Create(); + ReadBackAction = ReadBack; + return this; + } + + public void Dispose() + { + if (ResultTex != null) + { + ResultTex.Release(); + } + ResultTex = null; + ResultArray.Dispose(); + } + } + + public class HierarchicalZOcclusionCullFeature : ScriptableRendererFeature { public enum EDepthPyramidFunc { @@ -21,20 +78,28 @@ namespace X.Rendering.Feature public EDepthPyramidFunc PyramidFunc = EDepthPyramidFunc.CopyDepth; public bool SkipThreeMip; // 留历史 depth,做 tow pass cull - public bool UseThreeFrameReadback; + public bool UseThreeFrameReadback = true; public ComputeShader ComputeShader; public ComputeShader Spd; public Material CopyDepth; + + //TODO: 通过使用上一帧的摄像机位置(包括矩阵)和上一帧的深度图做剔除,储存已经被剔除的物体和未被剔除的物体,然后绘制未被剔除的物体到GBuffer(包含深度图), + //再二次生成HiZ DepthTexture,并对已经被剔除的物体使用一遍新的深度和当前摄像机的位置做一次剔除判断 + public bool UseTowCullPass; + public bool UseCompute; + public Material CullMat; + public ComputeShader CullShader; } [SerializeField] private Settings settings; - private HizPass hizPass; + private HizOcclusionCullPass hizPass; + private static HierarchicalZOcclusionCullFeature instance; public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) { - if (renderingData.cameraData.cameraType == UnityEngine.CameraType.Game) + if ((renderingData.cameraData.cameraType == CameraType.Game)) { renderer.EnqueuePass(hizPass); } @@ -43,6 +108,7 @@ namespace X.Rendering.Feature public override void Create() { hizPass = new(settings); + instance = this; } protected override void Dispose(bool disposing) @@ -54,9 +120,15 @@ namespace X.Rendering.Feature } } - internal class HizPass : ScriptableRenderPass, IDisposable + internal static CullResult GetCullResult() + { + return instance.hizPass.GetCullResult(); + } + + internal class HizOcclusionCullPass : ScriptableRenderPass, IDisposable { private readonly Settings settings; + private ProfilingSampler profiler; private Vector2Int cachedHardwareTextureSize; @@ -73,15 +145,29 @@ namespace X.Rendering.Feature RenderTexture SpdAtomicCounter; - public HizPass(Settings settings) + + CullResult[] cullResults; + HizOcclusionCullPass instance; + + public HizOcclusionCullPass(Settings settings) { + profiler = new ProfilingSampler(nameof(HizOcclusionCullPass)); + renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing; - profiler = new("DepthPyramid"); this.settings = settings; mipLevelOffsets = new Vector2Int[16]; mipLevelSizes = new Vector2Int[16]; SpdAtomicCounter = new RenderTexture(1, 1, 0, GraphicsFormat.R32_UInt) { name = "FSR2_SpdAtomicCounter", enableRandomWrite = true }; SpdAtomicCounter.Create(); + + int texSize = 64; + + cullResults = new CullResult[3] + { + new CullResult().CreateResources(texSize), + new CullResult().CreateResources(texSize), + new CullResult().CreateResources(texSize), + }; } public static int HizIndex { get; private set; } @@ -100,6 +186,12 @@ namespace X.Rendering.Feature return HizIndex; } + public CullResult GetCullResult() + { + var hizIndex = GetHizIndex(); + return cullResults[GetLastCullIndex(hizIndex)]; + } + public void ComputePackedMipChainInfo(Vector2Int viewportSize) { if (cachedHardwareTextureSize == viewportSize && cachedSkipThreeMip == settings.SkipThreeMip) @@ -111,20 +203,25 @@ namespace X.Rendering.Feature cachedSkipThreeMip = settings.SkipThreeMip; mip0SizeNOP = viewportSize; - // PowerOfTwo 不会留缝隙 - int resizeX = settings.PyramidFunc == EDepthPyramidFunc.SPD || Mathf.IsPowerOfTwo(viewportSize.x) ? viewportSize.x : Mathf.NextPowerOfTwo(viewportSize.x); - int resizeY = settings.PyramidFunc == EDepthPyramidFunc.SPD || Mathf.IsPowerOfTwo(viewportSize.y) ? viewportSize.y : Mathf.NextPowerOfTwo(viewportSize.y); + int resizeX = viewportSize.x; + int resizeY = viewportSize.y; + + resizeX = Mathf.IsPowerOfTwo(viewportSize.x) ? viewportSize.x : Mathf.NextPowerOfTwo(viewportSize.x); + resizeY = Mathf.IsPowerOfTwo(viewportSize.y) ? viewportSize.y : Mathf.NextPowerOfTwo(viewportSize.y); + if (resizeX > viewportSize.x) + resizeX /= 2; + if (resizeY > viewportSize.y) + resizeY /= 2; + Vector2Int hardwareTextureSize = new Vector2Int(resizeX, resizeY); mipLevelOffsets[0] = Vector2Int.zero; mipLevelSizes[0] = Vector2Int.zero; - int mipLevel = 0; Vector2Int mipSize = hardwareTextureSize; Vector2Int texSize = Vector2Int.zero; - do + mipLevelCount = 1 + (int)math.floor(math.log2(math.max(resizeX, resizeY))); + + for (int mipLevel = 1; mipLevel < mipLevelCount; mipLevel++) { - mipLevel++; - - // Round up. mipSize.x = System.Math.Max(1, (mipSize.x + 1) >> 1); mipSize.y = System.Math.Max(1, (mipSize.y + 1) >> 1); @@ -156,11 +253,16 @@ namespace X.Rendering.Feature texSize.x = System.Math.Max(texSize.x, mipBegin.x + mipSize.x); texSize.y = System.Math.Max(texSize.y, mipBegin.y + mipSize.y); } - while ((mipSize.x > 1) || (mipSize.y > 1)); + mipLevelSizes[0] = hardwareTextureSize; //RT实际大小 depthPyramidTextureSize = new Vector2Int((int)Mathf.Ceil((float)texSize.x), (int)Mathf.Ceil((float)texSize.y)); - mipLevelCount = mipLevel + 1; + + for (int i = 0;i < mipLevelSizes.Length; i++) + { + mipOffsetAndSizes[i] = new Vector4(mipLevelOffsets[i].x, mipLevelOffsets[i].y, mipLevelSizes[i].x, + mipLevelSizes[i].y); + } } private static int[] depthMipId = null; @@ -180,20 +282,20 @@ namespace X.Rendering.Feature cmd.BeginSample(sampleName); cmd.SetViewProjectionMatrices(Matrix4x4.identity, Matrix4x4.identity); cmd.SetGlobalTexture(HizShaderIds.DepthInputId, depthTex); - for (int i = 1; i < mipLevelCount; i++) + for (int i = 0; i < mipLevelCount; i++) { var index = i; - if (settings.SkipThreeMip && i < 3 + 1) + if (settings.SkipThreeMip && i < 3) { continue; } - else if (settings.SkipThreeMip && i == 3 + 1) + else if (settings.SkipThreeMip && i == 3) { - index = 1; + index = 0; } var mipSize = mipLevelSizes[i]; - var inputMipSize = index == 1 ? mip0SizeNOP : mipLevelSizes[i - 1]; + var inputMipSize = index == 0 ? mip0SizeNOP : mipLevelSizes[i - 1]; var texId = depthMipId[i]; cmd.SetGlobalVector(HizShaderIds.InputScaleAndMaxIndexId, new Vector4(inputMipSize.x / (float)mipSize.x, inputMipSize.y / (float)mipSize.y, inputMipSize.x - 1, inputMipSize.y - 1)); cmd.GetTemporaryRT(texId, mipSize.x, mipSize.y, 0, FilterMode.Point, RenderTextureFormat.RFloat); @@ -231,7 +333,6 @@ namespace X.Rendering.Feature cmd.SetGlobalTexture(HizShaderIds.DepthInputId, texId); var mipSize = mipLevelSizes[i]; var mipOffset = mipLevelOffsets[i]; - mipOffsetAndSizes[i] = new (mipOffset.x, mipOffset.y, mipSize.x, mipSize.y); cmd.SetViewport(new Rect(mipOffset.x, mipOffset.y, mipSize.x, mipSize.y)); cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, settings.CopyDepth, 0, 1); } @@ -342,12 +443,7 @@ namespace X.Rendering.Feature cmd.SetComputeIntParam(settings.Spd, "mips", mipLevelCount); cmd.SetComputeIntParam(settings.Spd, "numWorkGroups", dispatchX); - for (int i = 0; i < mipLevelCount; i++) - { - var mipSize = mipLevelSizes[i]; - var mipOffset = mipLevelOffsets[i]; - mipOffsetAndSizes[i] = new(mipOffset.x, mipOffset.y, mipSize.x, mipSize.y); - } + cmd.SetComputeVectorArrayParam(settings.Spd, "_MipOffsetAndSizeArray", mipOffsetAndSizes); cmd.SetComputeTextureParam(settings.Spd, 0, "_InputDepth", depthTex); @@ -358,16 +454,40 @@ namespace X.Rendering.Feature cmd.SetGlobalTexture(HizShaderIds.DepthPyramidTexId, hizBuffer); } + private void DoCulling(ScriptableRenderContext context, ref RenderingData renderingData) + { + var cmd = renderingData.commandBuffer;; + cmd.BeginSample("Hiz-Culling"); + var hizIndex = GetHizIndex(); + var cullResult = cullResults[hizIndex]; + var world2Project = renderingData.cameraData.GetGPUProjectionMatrix() * + renderingData.cameraData.GetViewMatrix(); + if (settings.UseCompute) + { + + } + else + { + cmd.SetGlobalMatrix(HizShaderIds.GPUCullingVPId, world2Project); + + cmd.SetRenderTarget(cullResult.ResultTex, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store); + cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, settings.CullMat, 0, 0); + cmd.RequestAsyncReadback(cullResult.ResultTex, 0, cullResult.ReadBackAction); + //cmd.RequestAsyncReadbackIntoNativeArray(ref cullResult.ResultArray, cullResult.ResultTex, 0, cullResult.ReadBackAction); + cullResult.DataReady = false; + } + cmd.EndSample("Hiz-Culling"); + } + public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) { var cmd = renderingData.commandBuffer; - using var soc = new ProfilingScope(cmd, profiler); Texture depthTex = Shader.GetGlobalTexture(HizShaderIds.CameraDepthTextureId); if(depthTex == null) { return; } - + using var scp = new ProfilingScope(cmd, profiler); ComputePackedMipChainInfo(new Vector2Int(depthTex.width, depthTex.height)); switch (settings.PyramidFunc) @@ -386,10 +506,41 @@ namespace X.Rendering.Feature } cmd.SetGlobalVector(HizShaderIds.Mip0SizeId, new Vector4(mip0SizeNOP.x, mip0SizeNOP.y, 0, 0)); - cmd.SetGlobalVector(HizShaderIds.MipmapLevelMinMaxIndexId, new Vector4(1, mipLevelCount, 0, 0)); + if (settings.SkipThreeMip) + { + cmd.SetGlobalVector(HizShaderIds.MipmapLevelMinMaxIndexId, new Vector4(4, mipLevelCount - 1, 0, 0)); + } + else + { + cmd.SetGlobalVector(HizShaderIds.MipmapLevelMinMaxIndexId, new Vector4(1, mipLevelCount - 1, 0, 0)); + } cmd.SetGlobalVectorArray(HizShaderIds.MipOffsetAndSizeArrayId, mipOffsetAndSizes); + DoCulling(context, ref renderingData); } + + + private int GetLastCullIndex(int hizIndex) + { + if (!settings.UseThreeFrameReadback) + { + return 0; + } + + switch (hizIndex) + { + case 0: + return 1; + case 1: + return 2; + case 2: + return 0; + default: + throw new ArgumentException("参数错误 hizIndex:" + hizIndex); + } + } + + public void Dispose() { if (SpdAtomicCounter != null) @@ -403,6 +554,11 @@ namespace X.Rendering.Feature var rt = depthPyramidTexs[i]; rt?.Release(); } + + for (int i = 0; i < cullResults.Length; i++) + { + cullResults[i]?.Dispose(); + } } } } diff --git a/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HierarchicalZFeature.cs.meta b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HierarchicalZOcclusionCullFeature.cs.meta similarity index 100% rename from Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HierarchicalZFeature.cs.meta rename to Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HierarchicalZOcclusionCullFeature.cs.meta diff --git a/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HizObject.cs b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HizObject.cs new file mode 100644 index 0000000..fd56763 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HizObject.cs @@ -0,0 +1,19 @@ +using UnityEngine; + +namespace X.Rendering.Feature +{ + [RequireComponent(typeof(Renderer))] + public class HizObject : MonoBehaviour + { + + private void OnEnable() + { + HizObjectsManager.Instance.Register(GetComponent()); + } + + private void OnDisable() + { + HizObjectsManager.Instance.UnRegister(GetComponent()); + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HziCullingFeature.cs.meta b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HizObject.cs.meta similarity index 83% rename from Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HziCullingFeature.cs.meta rename to Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HizObject.cs.meta index dddfd52..637545b 100644 --- a/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HziCullingFeature.cs.meta +++ b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HizObject.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: a0b8751ae563c82438124306d98fffd5 +guid: 1ff7514cf209ebe4eb6d41ea454b721c MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HizObjectsManager.cs b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HizObjectsManager.cs new file mode 100644 index 0000000..c3f8156 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HizObjectsManager.cs @@ -0,0 +1,231 @@ +using System.Collections.Generic; +using Unity.Mathematics; +using UnityEngine; +using UnityEngine.Experimental.Rendering; + +namespace X.Rendering.Feature +{ + public class HizObjectsManager : MonoBehaviour + { + public bool ShowDebug = false; + Texture2D centerTex; + Texture2D sizeTex; + + private static HizObjectsManager intstance; + public static HizObjectsManager Instance => intstance; + + private float4[] centers; + private float4[] extents; + + private float3x2[] aabbs; + + private List renderers = new(); + private bool[] cullResults; + private bool needUpdateAABB = true; + + public int culledCnt = 0; + + private void Awake() + { + intstance = new(); + } + + void Start() + { + int texSize = 64; + centerTex = new Texture2D(texSize, texSize, TextureFormat.RGBAFloat, 0, true); + centerTex.filterMode = FilterMode.Point; + sizeTex = new Texture2D(texSize, texSize, TextureFormat.RGBAFloat, 0, true); + sizeTex.filterMode = FilterMode.Point; + Shader.SetGlobalTexture(HizShaderIds.ObjectAABBCenterId, centerTex); + Shader.SetGlobalTexture(HizShaderIds.ObjectAABBSizeId, sizeTex); + } + + void Update() + { + if (needUpdateAABB) + { + needUpdateAABB = false; + UpdateAABB(centerTex, sizeTex); + } + } + + private void OnDestroy() + { + Texture.DestroyImmediate(centerTex); + Texture.DestroyImmediate(sizeTex); + } + + private void LateUpdate() + { + ApplyCull(HierarchicalZOcclusionCullFeature.GetCullResult()); + } + + public void Register(MeshRenderer renderer) + { + if (!renderers.Contains(renderer)) + { + renderers.Add(renderer); + needUpdateAABB = true; + } + } + + public void UnRegister(MeshRenderer renderer) + { + if(renderers.Remove(renderer)) + { + needUpdateAABB = true; + } + } + + public void UpdateAABB(ComputeBuffer aabbBuffer) + { + if (aabbBuffer == null || aabbs.Length != renderers.Count) + { + aabbs = new float3x2[renderers.Count]; + } + for (int i = 0; i < renderers.Count; i++) + { + var rdr = renderers[i]; + if (rdr != null) + { + Bounds bounds = rdr.bounds; + aabbs[i] = new float3x2(bounds.center, bounds.size); + } + else + { + aabbs[i] = float3x2.zero; + } + } + + aabbBuffer.SetData(aabbs); + } + + public void UpdateAABB(Texture2D centerTex, Texture2D sizeTex) + { + if (centers == null || centers.Length != centerTex.width * centerTex.height) + { + centers = new float4[centerTex.width * centerTex.height]; + extents = new float4[centerTex.width * centerTex.height]; + } + + if (renderers.Count == 0) + { + foreach (var item in GameObject.FindObjectsOfType()) + { + if (item.gameObject.isStatic) + { + Register(item); + } + } + } + if (cullResults == null || cullResults.Length != renderers.Count) + { + cullResults = new bool[renderers.Count]; + } + + int nullCnt = 0; + for (int i = 0; i < renderers.Count; i++) + { + var rdr = renderers[i]; + if (rdr != null) + { + Bounds bounds = rdr.bounds; + centers[i] = new float4(bounds.center, 1); + extents[i] = new float4(bounds.extents, 1); + } + else + { + nullCnt++; + centers[i] = float4.zero; + extents[i] = float4.zero; + } + } + + if (nullCnt == renderers.Count) + { + renderers.Clear(); + } + + centerTex.SetPixelData(centers, 0); + centerTex.Apply(); + sizeTex.SetPixelData(extents, 0); + sizeTex.Apply(); + Shader.SetGlobalTexture(HizShaderIds.ObjectAABBCenterId, centerTex); + Shader.SetGlobalTexture(HizShaderIds.ObjectAABBSizeId, sizeTex); + } + + private void ApplyCull(CullResult cullResult) + { + if (cullResult.ReadDone) + { + culledCnt = 0; + for (var i = 0; i < renderers.Count; i++) + { + var rdr = renderers[i]; + if (rdr) + { + bool needCull = cullResult.ResultArray[i] > 0; +#if UNITY_EDITOR + if (ShowDebug && rdr.GetComponent() is CullDebug cullDebug && cullDebug) + { + cullDebug.Index = i; + cullDebug.IsCulled = needCull; + cullDebug.Position = centers[i].xyz; + cullDebug.Size = extents[i].xyz; + } + +#endif + if (needCull) + { + culledCnt++; + } + + if (cullResults[i] != needCull) + { + if (needCull) + { + culledCnt++; + rdr.renderingLayerMask = 0; + } + else + { + rdr.renderingLayerMask = 1; + } + cullResults[i] = needCull; + } + + } + } + + //Debug.Log("frameCount: " + Time.frameCount + " Buffer index " + Time.frameCount % 3 + " : cullcount = " + culledCnt); + } + + else + { + ResetRenderer(); + } + } + + private void ResetRenderer() + { + for (var i = 0; i < renderers.Count; i++) + { + var rdr = renderers[i]; + if (rdr) + { + if (cullResults[i]) + { + rdr.renderingLayerMask = 1; + cullResults[i] = false; + } + } + } + } + + private void OnDisable() + { + ResetRenderer(); + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HizObjectsManager.cs.meta b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HizObjectsManager.cs.meta new file mode 100644 index 0000000..41ba058 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HizObjectsManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 86f2125f6a508374c89fea25b64ef353 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HziCullingFeature.cs b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HziCullingFeature.cs deleted file mode 100644 index 398aa04..0000000 --- a/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HziCullingFeature.cs +++ /dev/null @@ -1,334 +0,0 @@ -using System; -using System.Collections.Generic; -using Unity.Collections; -using Unity.Mathematics; -using UnityEngine; -using UnityEngine.Experimental.Rendering; -using UnityEngine.Rendering; -using UnityEngine.Rendering.Universal; -using static X.Rendering.Feature.HziCullingFeature; - -namespace X.Rendering.Feature -{ - public class SceneRenderObjects - { - private static SceneRenderObjects intstance; - public static SceneRenderObjects Instance => intstance; - - private float4[] centers; - private float4[] sizes; - - private float3x2[] aabbs; - - List renderers = new(); - - static SceneRenderObjects() - { - intstance = new SceneRenderObjects(); - } - - public void Register(Renderer renderer) - { - if(!renderers.Contains(renderer)) - { - renderers.Add(renderer); - } - } - - public void UnRegister(Renderer renderer) - { - renderers.Remove(renderer); - } - - public void UpdateAABB(ComputeBuffer aabbBuffer) - { - if(aabbBuffer == null || aabbs.Length != renderers.Count) - { - aabbs = new float3x2[renderers.Count]; - } - for (int i = 0; i < renderers.Count; i++) - { - var rdr = renderers[i]; - if (rdr != null) - { - Bounds bounds = rdr.bounds; - aabbs[i] = new float3x2(bounds.center,bounds.size); - } - else - { - aabbs[i] = float3x2.zero; - } - } - - aabbBuffer.SetData(aabbs); - } - - public void UpdateAABB(Texture2D centerTex, Texture2D sizeTex) - { - if (centers == null || centers.Length != centerTex.width * centerTex.height) - { - centers = new float4[centerTex.width * centerTex.height]; - sizes = new float4[centerTex.width * centerTex.height]; - } - - if (renderers.Count == 0) - { - foreach (var item in GameObject.FindObjectsOfType()) - { - Register(item); - } - } - - int nullCnt = 0; - for (int i = 0; i < renderers.Count; i++) - { - var rdr = renderers[i]; - if (rdr != null) - { - Bounds bounds = rdr.bounds; - centers[i] = new float4(bounds.center, 1); - sizes[i] = new float4(bounds.size, 1); - } - else - { - nullCnt++; - centers[i] = float4.zero; - sizes[i] = float4.zero; - } - } - - if (nullCnt == renderers.Count) - { - renderers.Clear(); - } - - centerTex.SetPixelData(centers, 0); - centerTex.Apply(); - sizeTex.SetPixelData(sizes, 0); - sizeTex.Apply(); - } - - internal void ApplyCull(CullResult cullResult) - { - if (cullResult.ReadDone) - { - for (var i = 0; i < renderers.Count; i++) - { - var rdr = renderers[i]; - if (rdr) - { -#if UNITY_EDITOR - if(rdr.GetComponent() is CullDebug cullDebug && cullDebug) - { - cullDebug.Index = i; - cullDebug.IsCulled = cullResult.ResultArray[i] > 0; - cullDebug.Position = centers[i].xyz; - cullDebug.Size = sizes[i].xyz; - } - -#endif - //if (cullResult.ResultArray[i] > 0) - //{ - // rdr.renderingLayerMask = 0; - //} - //else - { - rdr.renderingLayerMask = 1; - } - } - } - } - } - } - - public class HziCullingFeature : ScriptableRendererFeature - { - [Serializable] - public class Settings - { - //TODO: 通过使用上一帧的摄像机位置(包括矩阵)和上一帧的深度图做剔除,储存已经被剔除的物体和未被剔除的物体,然后绘制未被剔除的物体到GBuffer(包含深度图), - //再二次生成HiZ DepthTexture,并对已经被剔除的物体使用一遍新的深度和当前摄像机的位置做一次剔除判断 - public bool UseTowCullPass; - public bool UseTextureAABB = true; - public bool UseCompute; - public Material CullMat; - public ComputeShader CullShader; - [Range(32, 128)] - public int CullTextureSize = 64; - public bool UseThreeFrameReadback = true; - } - - [SerializeField] - private Settings settings; - - private CullPass cullPass; - public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) - { - if (renderingData.cameraData.cameraType == CameraType.Game) - { - renderer.EnqueuePass(cullPass); - } - } - - public override void Create() - { - cullPass = new(settings); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - cullPass.Dispose(); - } - - internal class CullResult : IDisposable - { - public RenderTexture ResultTex; - public NativeArray ResultArray; - public bool ReadDone = false; - public Action ReadBackAction; - - private void ReadBack(AsyncGPUReadbackRequest readback) - { - if (readback.done && !readback.hasError) - { - var data = readback.GetData(); - if (ResultArray.IsCreated) - { - ResultArray.CopyFrom(data); - } - ReadDone = true; - } - else - { - ReadDone = false; - } - } - - public CullResult CreateResources(int texSize) - { - ResultArray.Dispose(); - ResultArray = new NativeArray(texSize * texSize, Allocator.Persistent); - if(ResultTex != null) - { - ResultTex.Release(); - } - - ResultTex = new(texSize, texSize, 0, GraphicsFormat.R16_SFloat); - ResultTex.filterMode = FilterMode.Point; - ReadBackAction = ReadBack; - return this; - } - - public void Dispose() - { - if (ResultTex != null) - { - ResultTex.Release(); - } - ResultTex = null; - ResultArray.Dispose(); - } - } - - internal class CullPass : ScriptableRenderPass, IDisposable - { - private Settings settings; - private ProfilingSampler profiler; - Texture2D centerTex; - Texture2D sizeTex; - CullResult[] cullResults; - public CullPass(Settings settings) - { - profiler = new("Hi-Z Culling"); - this.settings = settings; - int texSize = settings.CullTextureSize; - centerTex = new Texture2D(texSize, texSize, GraphicsFormat.R32G32B32A32_SFloat, TextureCreationFlags.None); - centerTex.filterMode = FilterMode.Point; - sizeTex = new Texture2D(texSize, texSize, GraphicsFormat.R32G32B32A32_SFloat, TextureCreationFlags.None); - sizeTex.filterMode = FilterMode.Point; - cullResults = new CullResult[3] - { - new CullResult().CreateResources(texSize), - new CullResult().CreateResources(texSize), - new CullResult().CreateResources(texSize), - }; - - renderPassEvent = RenderPassEvent.AfterRendering; - } - - public void Dispose() - { - Texture.DestroyImmediate(centerTex); - Texture.DestroyImmediate(sizeTex); - for (int i = 0; i < cullResults.Length; i++) - { - cullResults[i]?.Dispose(); - } - } - - private int GetHizIndex() - { - if (settings.UseThreeFrameReadback) - { - return Time.frameCount % 3; - } - - return 0; - } - - private int GetLastCullIndex(int hizIndex) - { - switch (hizIndex) - { - case 0: - return 1; - case 1: - return 2; - case 2: - return 0; - default: - throw new ArgumentException("参数错误 hizIndex:" + hizIndex); - } - } - - public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) - { - var cmd = CommandBufferPool.Get("HizBuf"); - using var soc = new ProfilingScope(cmd, profiler); - cmd.Clear(); - if (settings.UseTextureAABB) - { - SceneRenderObjects.Instance.UpdateAABB(centerTex, sizeTex); - } - var hizIndex = GetHizIndex(); - var cullResult = cullResults[hizIndex]; - SceneRenderObjects.Instance.ApplyCull(cullResults[GetLastCullIndex(hizIndex)]); - cullResult.ReadDone = false; - var world2Project = renderingData.cameraData.GetGPUProjectionMatrix() * renderingData.cameraData.GetViewMatrix(); - if(settings.UseCompute) - { - - } - else - { - world2Project.m11 *= -1; - world2Project.m13 *= -1; - - cmd.SetGlobalMatrix(HizShaderIds.GPUCullingVPId, world2Project); - cmd.SetGlobalTexture(HizShaderIds.ObjectAABBCenterId, centerTex); - cmd.SetGlobalTexture(HizShaderIds.ObjectAABBSizeId, sizeTex); - cmd.SetRenderTarget(cullResult.ResultTex, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store); - cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, settings.CullMat, 0, 0); - var temp = new NativeArray(centerTex.width * sizeTex.height, Allocator.Persistent); - cmd.RequestAsyncReadbackIntoNativeArray(ref temp, cullResult.ResultTex, 0, cullResult.ReadBackAction); - //cmd.RequestAsyncReadbackIntoNativeArray(ref cullResult.ResultArray, cullResult.ResultTex, 0, cullResult.ReadBackAction); - } - context.ExecuteCommandBuffer(cmd); - CommandBufferPool.Release(cmd); - } - - - } - } -} diff --git a/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/Shaders/CopyDepth.shader b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/Shaders/CopyDepth.shader index 6c7b408..783bd91 100644 --- a/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/Shaders/CopyDepth.shader +++ b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/Shaders/CopyDepth.shader @@ -2,6 +2,9 @@ Shader "Hidden/CopyDepth" { SubShader { + ZTest Off + ZWrite Off + Pass { HLSLPROGRAM diff --git a/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/Shaders/HizCull.shader b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/Shaders/HizCull.shader index fe1cfe2..68438cb 100644 --- a/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/Shaders/HizCull.shader +++ b/Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/Shaders/HizCull.shader @@ -2,6 +2,9 @@ { SubShader { + ZTest Off + ZWrite Off + Pass { HLSLPROGRAM @@ -13,14 +16,14 @@ struct Attributes { - float4 positionOS : POSITION; - float2 texcoord : TEXCOORD0; + float4 positionOS : POSITION; + float2 texcoord : TEXCOORD0; }; struct Varyings { - float2 uv : TEXCOORD0; - float4 positionCS : SV_POSITION; + float2 uv : TEXCOORD0; + float4 positionCS : SV_POSITION; }; Varyings Vertex(Attributes input) @@ -30,20 +33,20 @@ output.uv = input.texcoord; return output; } - + TEXTURE2D(_ObjectAABBTexture0); SAMPLER(sampler_ObjectAABBTexture0); TEXTURE2D(_ObjectAABBTexture1); SAMPLER(sampler_ObjectAABBTexture1); - - + + TEXTURE2D(_DepthPyramidTexture); SAMPLER(sampler_DepthPyramidTexture); float4x4 _GPUCullingVP; float2 _MipmapLevelMinMaxIndex; float2 _Mip0Size; float4 _MipOffsetAndSize[16]; - + static const float3 aggressiveExtentArray[8] = { float3(1, 1, 1), @@ -55,19 +58,27 @@ float3(-1, -1, 1), float3(-1, -1, -1) }; - + float3 TransferNDC(float3 pos) + { + float4 ndc = mul(_GPUCullingVP, float4(pos, 1.0)); + ndc.xyz /= ndc.w; + ndc.xy = ndc.xy * 0.5f + 0.5f; + ndc.y = 1 - ndc.y; + return ndc.xyz; + } + half CullFrag(Varyings input) : SV_Target { float2 uv = input.uv; - float4 aabbCenter = SAMPLE_TEXTURE2D_LOD(_ObjectAABBTexture0, sampler_ObjectAABBTexture0, uv,0.0); + float4 aabbCenter = SAMPLE_TEXTURE2D_LOD(_ObjectAABBTexture0, sampler_ObjectAABBTexture0, uv, 0.0); float4 aabbSize = SAMPLE_TEXTURE2D_LOD(_ObjectAABBTexture1, sampler_ObjectAABBTexture1, uv, 0.0); - float3 aabbExtent = aabbSize.xyz * 0.5;//贴图可以直接存extent + float3 aabbExtent = aabbSize.xyz; UNITY_BRANCH - if (aabbCenter.a == 0.0) + if (aabbCenter.a == 0.0) { return 1; } - + #ifdef UNITY_REVERSED_Z float minZ = 0; #else @@ -76,28 +87,38 @@ float2 maxXY = 0; float2 minXY = 1; - for(uint i = 0; i < 8; ++i) + for (uint i = 0; i < 8; ++i) { - float3 boxCorner = aabbCenter + aabbExtent * aggressiveExtentArray[i]; - float4 clipPos = mul(_GPUCullingVP, float4(boxCorner, 1)); - clipPos /= clipPos.w; - minXY = min(clipPos.xy, minXY); - maxXY = max(clipPos.xy, maxXY); - #ifdef UNITY_REVERSED_Z - minZ = max(minZ, clipPos.z); - #else - minZ = min(minZ, clipPos.z); - #endif + float3 boxCorner = aabbCenter + aabbExtent * aggressiveExtentArray[i]; + float4 clipPos = mul(_GPUCullingVP, float4(boxCorner, 1)); + clipPos /= clipPos.w; + clipPos.xy = clipPos.xy * 0.5f + 0.5f; + #if UNITY_UV_STARTS_AT_TOP + clipPos.y = 1 - clipPos.y; + #endif + + minXY = min(clipPos.xy, minXY); + maxXY = max(clipPos.xy, maxXY); + #ifdef UNITY_REVERSED_Z + minZ = max(minZ, clipPos.z); + #else + minZ = min(minZ, clipPos.z); + #endif } float4 boxUVs = float4(minXY, maxXY); - boxUVs = saturate(boxUVs * 0.5 + 0.5); + + // if( boxUVs.x < 0 || boxUVs.y < 0 || boxUVs.x > 1 || boxUVs.y > 1 || boxUVs.z >1 || boxUVs.z<0) + // { + // return 1; + // } + float2 size = (boxUVs.zw - boxUVs.xy) * _Mip0Size.xy; - float mip = (log2(max(size.x, size.y) / 2.0f)); - - mip = ceil(mip); + float mip = (log2(max(size.x, size.y))); + + mip = ceil(mip) ; mip = clamp(mip, _MipmapLevelMinMaxIndex.x, _MipmapLevelMinMaxIndex.y); - + // float level_lower = max(mip - 1, 0); // float2 scale = exp2(-level_lower) / _Mip0Size.xy; // float2 a = floor(boxUVs.xy*scale); @@ -107,29 +128,28 @@ // // Use the lower level if we only touch <= 2 texels in both dimensions // if (dims.x <= 2 && dims.y <= 2) // mip = level_lower; - + float4 offsetAndSize = _MipOffsetAndSize[mip]; int4 pxMinMax = boxUVs * offsetAndSize.zwzw + offsetAndSize.xyxy; - - float4 depth = float4(LOAD_TEXTURE2D_LOD(_DepthPyramidTexture, pxMinMax.xy,0).r, - LOAD_TEXTURE2D_LOD(_DepthPyramidTexture, pxMinMax.zy,0).r, - LOAD_TEXTURE2D_LOD(_DepthPyramidTexture, pxMinMax.xw,0).r, - LOAD_TEXTURE2D_LOD(_DepthPyramidTexture, pxMinMax.zw,0).r + + float4 depth = float4(LOAD_TEXTURE2D_LOD(_DepthPyramidTexture, pxMinMax.xy, 0).r, + LOAD_TEXTURE2D_LOD(_DepthPyramidTexture, pxMinMax.zy, 0).r, + LOAD_TEXTURE2D_LOD(_DepthPyramidTexture, pxMinMax.xw, 0).r, + LOAD_TEXTURE2D_LOD(_DepthPyramidTexture, pxMinMax.zw, 0).r ); - + #ifdef UNITY_REVERSED_Z depth.xy = min(depth.xy, depth.zw); depth.x = min(depth.x, depth.y); - return minZ >= depth.x ? 0 : 1; + return minZ > depth.x ? 0 : 1; #else depth.xy = max(depth.xy, depth.zw); depth.x = max(depth.x, depth.y); - return minZ <= depth.x ? 1 : 0; + return minZ < depth.x ? 1 : 0; #endif } - ENDHLSL } } -} +} \ No newline at end of file