From 5f24e4c27d1e72e3af522be7ba74123d72bc618a Mon Sep 17 00:00:00 2001 From: Misaki Date: Sat, 1 Mar 2025 16:58:26 +0900 Subject: [PATCH] Start working on Cluster; --- Runtime/CustomPass/AoVolumePass.cs | 69 ++++++++++--------- Runtime/Shader/HizCulling.compute | 19 ++--- Runtime/Shader/Includes/Common.hlsl | 31 +++++++++ .../Common.hlsl.meta} | 5 +- .../Shader/New Render Texture.renderTexture | 39 ----------- .../Shader/VolumeListBuild-Cluster.compute | 25 ++++--- 6 files changed, 90 insertions(+), 98 deletions(-) create mode 100644 Runtime/Shader/Includes/Common.hlsl rename Runtime/Shader/{New Render Texture.renderTexture.meta => Includes/Common.hlsl.meta} (52%) delete mode 100644 Runtime/Shader/New Render Texture.renderTexture diff --git a/Runtime/CustomPass/AoVolumePass.cs b/Runtime/CustomPass/AoVolumePass.cs index b3281e8..4d54a78 100644 --- a/Runtime/CustomPass/AoVolumePass.cs +++ b/Runtime/CustomPass/AoVolumePass.cs @@ -1,5 +1,6 @@ using Misaki.AoVolume; using System.Buffers; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Unity.Collections; using UnityEngine; @@ -23,10 +24,13 @@ internal class AoVolumePass : CustomPass [ResourcePath("Packages/com.misaki.ao-volume/Runtime/Shader/AoVolume.compute")] public ComputeShader renderingShader; - private void ClearVisibleVolumeCounter() + [Range(16, 256)] + public int maxVolumeOnScreen = 64; + + private void ClearCounterBuffer() { var zeroBuffer = new NativeArray(1, Allocator.Temp); - zeroBuffer[0] = 0; + zeroBuffer[0] = 0u; _visibleVolumeCountBuffer.SetData(zeroBuffer); zeroBuffer.Dispose(); } @@ -37,48 +41,24 @@ internal class AoVolumePass : CustomPass // The render pipeline will ensure target setup and clearing happens in an performance manner. protected override void Setup(ScriptableRenderContext renderContext, CommandBuffer cmd) { - _volumeBounds = new NativeArray(64, Allocator.Persistent); - _volumeBoundsBuffer = new ComputeBuffer(64, Marshal.SizeOf()); - _visibleIndicesBuffer = new ComputeBuffer(64, Marshal.SizeOf(), ComputeBufferType.Raw); + _volumeBounds = new NativeArray(maxVolumeOnScreen, Allocator.Persistent); + _volumeBoundsBuffer = new ComputeBuffer(maxVolumeOnScreen, Marshal.SizeOf()); + _visibleIndicesBuffer = new ComputeBuffer(maxVolumeOnScreen, Marshal.SizeOf(), ComputeBufferType.Raw); _visibleVolumeCountBuffer = new ComputeBuffer(1, Marshal.SizeOf(), ComputeBufferType.Counter); - _volumeDataBuffer = new ComputeBuffer(64, Marshal.SizeOf()); + _volumeDataBuffer = new ComputeBuffer(maxVolumeOnScreen, Marshal.SizeOf()); _volumeBuffer = RTHandles.Alloc(Vector2.one, useDynamicScale: true, dimension: TextureXR.dimension, enableRandomWrite: true, format: GraphicsFormat.R8_UNorm, name: "AO Volume Buffer"); - ClearVisibleVolumeCounter(); + ClearCounterBuffer(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int GetDepthPyramidMaxMipLevel(HDCamera hDCamera) { return Mathf.FloorToInt(Mathf.Log(Mathf.Min(hDCamera.actualWidth, hDCamera.actualHeight), 2)) - 1; } - protected override void Execute(CustomPassContext ctx) - { - if (cullingShader == null || renderingShader == null) - { - return; - } - - // Worth it to allocate a new buffer? - //if (Shader.GetGlobalTexture("_AmbientOcclusionTexture") is not RenderTexture gtaoBuffer) - //{ - // return; - //} - - var volumeCount = VolumeDatabase.Instance.EntityCount; - if (volumeCount <= 0) - { - return; - } - - HierarchicalZCulling(ctx, volumeCount); - RenderVisibleVolumes(ctx); - //DebugVisibleVolumes(); - ClearVisibleVolumeCounter(); - } - private void HierarchicalZCulling(CustomPassContext ctx, int volumeCount) { for (var i = 0; i < volumeCount; i++) @@ -141,6 +121,31 @@ internal class AoVolumePass : CustomPass ArrayPool.Shared.Return(visibleVolumeIndices); } + protected override void Execute(CustomPassContext ctx) + { + if (cullingShader == null || renderingShader == null) + { + return; + } + + // Worth it to allocate a new buffer? + //if (Shader.GetGlobalTexture("_AmbientOcclusionTexture") is not RenderTexture gtaoBuffer) + //{ + // return; + //} + + var volumeCount = VolumeDatabase.Instance.EntityCount; + if (volumeCount <= 0) + { + return; + } + + HierarchicalZCulling(ctx, volumeCount); + RenderVisibleVolumes(ctx); + //DebugVisibleVolumes(); + ClearCounterBuffer(); + } + protected override void Cleanup() { _volumeBounds.Dispose(); diff --git a/Runtime/Shader/HizCulling.compute b/Runtime/Shader/HizCulling.compute index 59b9785..855f50e 100644 --- a/Runtime/Shader/HizCulling.compute +++ b/Runtime/Shader/HizCulling.compute @@ -4,6 +4,7 @@ #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl" #include "Packages/com.misaki.ao-volume/Runtime/Shader/Includes/GeometryData.cs.hlsl" +#include "Packages/com.misaki.ao-volume/Runtime/Shader/Includes/Common.hlsl" #define _FLT_MIN 1.175494351e-38 // Minimum representable positive floating-point number #define _FLT_MAX 3.402823466e+38 // Maximum representable floating-point number @@ -19,16 +20,6 @@ StructuredBuffer _DepthPyramidMipLevelOffsets; RWByteAddressBuffer _VisibleVolumeCount : register(u0); RWByteAddressBuffer _VisibleVolumeIndices : register(u1); -RW_TEXTURE2D_X(float, _DebugTexture); - -float4 ComputeScreenPos(float4 pos, float projectionSign) -{ - float4 o = pos * 0.5f; - o.xy = float2(o.x, o.y * projectionSign) + o.w; - o.zw = pos.zw; - return o; -} - float SampleDepthLod(int2 uv, int lod) { int2 mipCoord = uv >> lod; @@ -80,13 +71,13 @@ void CSMain(uint3 dispatchThreadId : SV_DispatchThreadID) float4 positionCS = TransformWorldToHClip(cornerRWS); positionCS /= positionCS.w; - float2 screenPos = ComputeScreenPos(positionCS, _ProjectionParams.x).xy; + float2 positionNDC = ComputePositionNDC(positionCS, _ProjectionParams.x).xy; - screenMin = min(screenMin, screenPos); - screenMax = max(screenMax, screenPos); + screenMin = min(screenMin, positionNDC); + screenMax = max(screenMax, positionNDC); boxMaxDepth = max(boxMaxDepth, positionCS.z); - cornerPositionSS[i] = screenPos * _ScreenSize.xy; + cornerPositionSS[i] = positionNDC * _ScreenSize.xy; } float rectWidth = (screenMax.x - screenMin.x); diff --git a/Runtime/Shader/Includes/Common.hlsl b/Runtime/Shader/Includes/Common.hlsl new file mode 100644 index 0000000..f7df611 --- /dev/null +++ b/Runtime/Shader/Includes/Common.hlsl @@ -0,0 +1,31 @@ +#ifndef VOLUME_COMMON +#define VOLUME_COMMON + +#define _MAX_CLUSTER_COUNT 16 +#define _DEPTH_STEP (1.0 / _MAX_CLUSTER_COUNT) + +float4 ComputePositionNDC(float4 positionCS, float projectionSign) +{ + float4 positionNDC = positionCS * 0.5f; + positionNDC.xy = float2(positionNDC.x, positionNDC.y * projectionSign) + positionNDC.w; + positionNDC.zw = positionCS.zw; + return positionNDC; +} + +uint GetClusterIndex(float linearDepth) +{ + return (uint)clamp(floor(linearDepth / _DEPTH_STEP), 0.0, (float)_MAX_CLUSTER_COUNT - 1.0); +} + +void GetClusterVolumeCount(uint clusterIndex, out uint count) +{ + // TODO +} + +uint FetchVolumeIndex(uint clusterIndex, uint offset) +{ + // TODO + return 0; +} + +#endif \ No newline at end of file diff --git a/Runtime/Shader/New Render Texture.renderTexture.meta b/Runtime/Shader/Includes/Common.hlsl.meta similarity index 52% rename from Runtime/Shader/New Render Texture.renderTexture.meta rename to Runtime/Shader/Includes/Common.hlsl.meta index f7c9744..58c2fb9 100644 --- a/Runtime/Shader/New Render Texture.renderTexture.meta +++ b/Runtime/Shader/Includes/Common.hlsl.meta @@ -1,8 +1,7 @@ fileFormatVersion: 2 -guid: 3231123e01a82c04797c5cd8cb634e31 -NativeFormatImporter: +guid: 9733756ad1176ce4983ca1a172f79e15 +ShaderIncludeImporter: externalObjects: {} - mainObjectFileID: 8400000 userData: assetBundleName: assetBundleVariant: diff --git a/Runtime/Shader/New Render Texture.renderTexture b/Runtime/Shader/New Render Texture.renderTexture deleted file mode 100644 index 85a5592..0000000 --- a/Runtime/Shader/New Render Texture.renderTexture +++ /dev/null @@ -1,39 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!84 &8400000 -RenderTexture: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: New Render Texture - m_ImageContentsHash: - serializedVersion: 2 - Hash: 00000000000000000000000000000000 - m_IsAlphaChannelOptional: 0 - serializedVersion: 6 - m_Width: 256 - m_Height: 256 - m_AntiAliasing: 1 - m_MipCount: -1 - m_DepthStencilFormat: 94 - m_ColorFormat: 0 - m_MipMap: 0 - m_GenerateMips: 1 - m_SRGB: 0 - m_UseDynamicScale: 0 - m_UseDynamicScaleExplicit: 0 - m_BindMS: 0 - m_EnableCompatibleFormat: 1 - m_EnableRandomWrite: 0 - m_TextureSettings: - serializedVersion: 2 - m_FilterMode: 1 - m_Aniso: 0 - m_MipBias: 0 - m_WrapU: 1 - m_WrapV: 1 - m_WrapW: 1 - m_Dimension: 2 - m_VolumeDepth: 1 - m_ShadowSamplingMode: 2 diff --git a/Runtime/Shader/VolumeListBuild-Cluster.compute b/Runtime/Shader/VolumeListBuild-Cluster.compute index ad8fcb5..886ac61 100644 --- a/Runtime/Shader/VolumeListBuild-Cluster.compute +++ b/Runtime/Shader/VolumeListBuild-Cluster.compute @@ -1,14 +1,19 @@ -// Each #kernel tells which function to compile; you can have many kernels #pragma kernel CSMain -// Create a RenderTexture with enableRandomWrite flag and set it -// with cs.SetTexture -RWTexture2D Result; +#include "Packages/com.misaki.ao-volume/Runtime/Shader/Includes/GeometryData.cs.hlsl" -[numthreads(8,8,1)] -void CSMain (uint3 id : SV_DispatchThreadID) +StructuredBuffer _VolumeBounds; +ByteAddressBuffer _VisibleVolumeCount; +ByteAddressBuffer _VisibleVolumeIndices; + +// For the volume list buffer, we allocate a buffer with the size of "cluster count" * "max volume count on screen" / 4. +// The first slot of each cluster group is always reserved for the count of volumes in the cluster. +// The rest of the slots are used for the indices of the volumes in the cluster, each slot are packed with 2 16 bits indices. +// To total number of indices in each cluster is "max volume count on screen" / 4 - 1. +RWByteAddressBuffer _VolumeListCluster : register(u0); + +[numthreads(64,1,1)] +void CSMain(uint3 dispatchThreadId : SV_DispatchThreadID) { - // TODO: insert actual code here! - - Result[id.xy] = float4(id.x & id.y, (id.x & 15)/15.0, (id.y & 15)/15.0, 0.0); -} + +} \ No newline at end of file