Update HzCulling
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using Misaki.AoVolume;
|
||||
using System.Buffers;
|
||||
using System.Runtime.InteropServices;
|
||||
using Unity.Collections;
|
||||
using UnityEngine;
|
||||
@@ -10,12 +11,27 @@ internal class AoVolumePass : CustomPass
|
||||
{
|
||||
private bool _initialized;
|
||||
|
||||
private NativeArray<VolumeData> _aoVolumeDatas;
|
||||
private ComputeBuffer _aoVolumeDataBuffer;
|
||||
private RTHandle _aoVolumeBuffer;
|
||||
private NativeArray<OrientedBoundingBox> _volumeBounds;
|
||||
private ComputeBuffer _volumeBoundsBuffer;
|
||||
private ComputeBuffer _visibleIndicesBuffer;
|
||||
private ComputeBuffer _visibleVolumeCountBuffer;
|
||||
|
||||
private ComputeBuffer _volumeDataBuffer;
|
||||
|
||||
private RTHandle _volumeBuffer;
|
||||
|
||||
[ResourcePath("Packages/com.misaki.ao-volume/Runtime/Shader/HzCulling.compute")]
|
||||
public ComputeShader cullingShader;
|
||||
[ResourcePath("Packages/com.misaki.ao-volume/Runtime/Shader/AoVolume.compute")]
|
||||
public ComputeShader shader;
|
||||
public ComputeShader renderingShader;
|
||||
|
||||
private void ClearVisibleVolumeCounter()
|
||||
{
|
||||
var zeroBuffer = new NativeArray<uint>(1, Allocator.Temp);
|
||||
zeroBuffer[0] = 0;
|
||||
_visibleVolumeCountBuffer.SetData(zeroBuffer);
|
||||
zeroBuffer.Dispose();
|
||||
}
|
||||
|
||||
// It can be used to configure render targets and their clear state. Also to create temporary render target textures.
|
||||
// When empty this render pass will render to the active camera render target.
|
||||
@@ -23,9 +39,21 @@ 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)
|
||||
{
|
||||
_aoVolumeDatas = new NativeArray<VolumeData>(64, Allocator.Persistent);
|
||||
_aoVolumeDataBuffer = new ComputeBuffer(64, Marshal.SizeOf<VolumeData>());
|
||||
_aoVolumeBuffer = RTHandles.Alloc(Vector2.one, useDynamicScale: true, dimension: TextureXR.dimension, enableRandomWrite: true, format: GraphicsFormat.R8_UNorm, name: "AO Volume Buffer");
|
||||
if (_initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_volumeBounds = new NativeArray<OrientedBoundingBox>(64, Allocator.Persistent);
|
||||
_volumeBoundsBuffer = new ComputeBuffer(64, Marshal.SizeOf<OrientedBoundingBox>());
|
||||
_visibleIndicesBuffer = new ComputeBuffer(64, Marshal.SizeOf<uint>(), ComputeBufferType.Raw);
|
||||
_visibleVolumeCountBuffer = new ComputeBuffer(1, Marshal.SizeOf<uint>(), ComputeBufferType.Counter);
|
||||
|
||||
_volumeDataBuffer = new ComputeBuffer(64, Marshal.SizeOf<VolumeData>());
|
||||
|
||||
_volumeBuffer = RTHandles.Alloc(Vector2.one, useDynamicScale: true, dimension: TextureXR.dimension, enableRandomWrite: true, format: GraphicsFormat.R8_UNorm, name: "AO Volume Buffer");
|
||||
|
||||
ClearVisibleVolumeCounter();
|
||||
|
||||
_initialized = true;
|
||||
}
|
||||
@@ -37,49 +65,88 @@ internal class AoVolumePass : CustomPass
|
||||
return;
|
||||
}
|
||||
|
||||
if (shader == null)
|
||||
if (cullingShader == null || renderingShader == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var volumeCount = VolumeDatabase.Instance.volumeObjects.Count;
|
||||
if (volumeCount <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < volumeCount; i++)
|
||||
{
|
||||
_aoVolumeDatas[i] = VolumeDatabase.Instance.volumeObjects[i].data;
|
||||
}
|
||||
_aoVolumeDataBuffer.SetData(_aoVolumeDatas);
|
||||
|
||||
// Worth it to allocate a new buffer?
|
||||
//if (Shader.GetGlobalTexture("_AmbientOcclusionTexture") is not RenderTexture gtaoBuffer)
|
||||
//{
|
||||
// return;
|
||||
//}
|
||||
|
||||
var kernelIndex = shader.FindKernel("CSMain");
|
||||
ctx.cmd.SetComputeBufferParam(shader, kernelIndex, "_VolumeDatas", _aoVolumeDataBuffer);
|
||||
ctx.cmd.SetComputeIntParam(shader, "_VolumeCount", volumeCount);
|
||||
ctx.cmd.SetComputeTextureParam(shader, kernelIndex, "_AOVolumeBuffer", _aoVolumeBuffer);
|
||||
var volumeCount = VolumeDatabase.Instance.EntityCount;
|
||||
if (volumeCount <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const int groupSizeX = 8;
|
||||
const int groupSizeY = 8;
|
||||
var threadGroupX = (ctx.hdCamera.actualWidth + (groupSizeX - 1)) / groupSizeX;
|
||||
var threadGroupY = (ctx.hdCamera.actualHeight + (groupSizeY - 1)) / groupSizeY;
|
||||
|
||||
ctx.cmd.DispatchCompute(shader, kernelIndex, threadGroupX, threadGroupY, _aoVolumeBuffer.rt.volumeDepth);
|
||||
for (var i = 0; i < volumeCount; i++)
|
||||
{
|
||||
_volumeBounds[i] = new OrientedBoundingBox(VolumeDatabase.Instance.VolumeDatas[i].worldMatrix);
|
||||
}
|
||||
_volumeBoundsBuffer.SetData(_volumeBounds);
|
||||
|
||||
ctx.cmd.SetGlobalTexture("_AmbientOcclusionTexture", _aoVolumeBuffer);
|
||||
ctx.cmd.SetComputeBufferParam(cullingShader, 0, "_VolumeBounds", _volumeBoundsBuffer);
|
||||
ctx.cmd.SetComputeIntParam(cullingShader, "_FullVolumeCount", volumeCount);
|
||||
ctx.cmd.SetComputeIntParam(cullingShader, "_DepthPyramidMaxMip", ctx.cameraDepthBuffer.rt.mipmapCount - 1);
|
||||
|
||||
ctx.cmd.SetComputeBufferParam(cullingShader, 0, "_VisibleVolumeIndices", _visibleIndicesBuffer);
|
||||
ctx.cmd.SetComputeBufferParam(cullingShader, 0, "_VisibleVolumeCount", _visibleVolumeCountBuffer);
|
||||
|
||||
const int groupSize = 64;
|
||||
var threadGroup = (volumeCount + (groupSize - 1)) / groupSize;
|
||||
ctx.cmd.DispatchCompute(cullingShader, 0, threadGroup, 1, 1);
|
||||
|
||||
// Debug
|
||||
var visibleVolumeCount = new int[1];
|
||||
_visibleVolumeCountBuffer.GetData(visibleVolumeCount);
|
||||
Debug.Log($"Visible Volume Count: {visibleVolumeCount[0]}");
|
||||
|
||||
var visibleVolumeIndices = ArrayPool<uint>.Shared.Rent(64);
|
||||
_visibleIndicesBuffer.GetData(visibleVolumeIndices);
|
||||
for (var i = 0; i < visibleVolumeCount[0]; i++)
|
||||
{
|
||||
if (i >= 64)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Debug.Log($"Visible Volume Index: {visibleVolumeIndices[i]}");
|
||||
}
|
||||
Debug.Log("End");
|
||||
ArrayPool<uint>.Shared.Return(visibleVolumeIndices);
|
||||
|
||||
ClearVisibleVolumeCounter();
|
||||
|
||||
//return;
|
||||
//_volumeDataBuffer.SetData(VolumeDatabase.Instance.VolumeDatas);
|
||||
|
||||
//ctx.cmd.SetComputeBufferParam(renderingShader, 0, "_VolumeDatas", _volumeDataBuffer);
|
||||
//ctx.cmd.SetComputeIntParam(renderingShader, "_VolumeCount", volumeCount);
|
||||
//ctx.cmd.SetComputeTextureParam(renderingShader, 0, "_AOVolumeBuffer", _volumeBuffer);
|
||||
|
||||
//ctx.cmd.DispatchCompute(renderingShader, 0, threadGroupX, threadGroupY, _volumeBuffer.rt.volumeDepth);
|
||||
|
||||
//ctx.cmd.SetGlobalTexture("_AmbientOcclusionTexture", _volumeBuffer);
|
||||
}
|
||||
|
||||
protected override void Cleanup()
|
||||
{
|
||||
_aoVolumeBuffer?.Release();
|
||||
_aoVolumeDatas.Dispose();
|
||||
_aoVolumeDataBuffer?.Release();
|
||||
_volumeBounds.Dispose();
|
||||
_volumeBoundsBuffer?.Dispose();
|
||||
_visibleIndicesBuffer?.Dispose();
|
||||
_visibleVolumeCountBuffer?.Dispose();
|
||||
|
||||
_volumeDataBuffer?.Dispose();
|
||||
|
||||
_volumeBuffer?.Release();
|
||||
|
||||
_initialized = false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user