add hi-z occlusion culling.culling
This commit is contained in:
parent
20c56fed0a
commit
3a68dfd783
@ -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
|
||||
|
||||
@ -114,5 +114,5 @@ MonoBehaviour:
|
||||
m_PrefilterNativeRenderPass: 1
|
||||
m_ShaderVariantLogLevel: 0
|
||||
m_ShadowCascades: 0
|
||||
superResolution: 3
|
||||
superResolution: 0
|
||||
vrsRate: 0
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -14,4 +14,8 @@ public class CullDebug : MonoBehaviour
|
||||
Gizmos.DrawWireCube(Position, Size);
|
||||
Gizmos.color = col;
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<half> ResultArray;
|
||||
public bool ReadDone = false;
|
||||
public bool DataReady = false;
|
||||
public Action<AsyncGPUReadbackRequest> ReadBackAction;
|
||||
|
||||
private void ReadBack(AsyncGPUReadbackRequest readback)
|
||||
{
|
||||
if (readback.done && !readback.hasError)
|
||||
{
|
||||
var data = readback.GetData<half>();
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
19
Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HizObject.cs
vendored
Normal file
19
Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HizObject.cs
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace X.Rendering.Feature
|
||||
{
|
||||
[RequireComponent(typeof(Renderer))]
|
||||
public class HizObject : MonoBehaviour
|
||||
{
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
HizObjectsManager.Instance.Register(GetComponent<MeshRenderer>());
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
HizObjectsManager.Instance.UnRegister(GetComponent<MeshRenderer>());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a0b8751ae563c82438124306d98fffd5
|
||||
guid: 1ff7514cf209ebe4eb6d41ea454b721c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
231
Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HizObjectsManager.cs
vendored
Normal file
231
Packages/com.unity.render-pipelines.universal@14.0.11/Runtime/OcclusionCulling/HizObjectsManager.cs
vendored
Normal file
@ -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<MeshRenderer> 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<MeshRenderer>())
|
||||
{
|
||||
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<CullDebug>() 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86f2125f6a508374c89fea25b64ef353
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -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<Renderer> 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<MeshRenderer>())
|
||||
{
|
||||
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<CullDebug>() 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<half> ResultArray;
|
||||
public bool ReadDone = false;
|
||||
public Action<AsyncGPUReadbackRequest> ReadBackAction;
|
||||
|
||||
private void ReadBack(AsyncGPUReadbackRequest readback)
|
||||
{
|
||||
if (readback.done && !readback.hasError)
|
||||
{
|
||||
var data = readback.GetData<half>();
|
||||
if (ResultArray.IsCreated)
|
||||
{
|
||||
ResultArray.CopyFrom(data);
|
||||
}
|
||||
ReadDone = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ReadDone = false;
|
||||
}
|
||||
}
|
||||
|
||||
public CullResult CreateResources(int texSize)
|
||||
{
|
||||
ResultArray.Dispose();
|
||||
ResultArray = new NativeArray<half>(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<half>(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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,9 @@ Shader "Hidden/CopyDepth"
|
||||
{
|
||||
SubShader
|
||||
{
|
||||
ZTest Off
|
||||
ZWrite Off
|
||||
|
||||
Pass
|
||||
{
|
||||
HLSLPROGRAM
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user