Trying to add some optimization. Need to remove an intersection test now
This commit is contained in:
@ -262,30 +262,21 @@ void CSMain(uint3 id : SV_DispatchThreadID)
|
|||||||
// push children in reverse order (so the nearest is popped first) if stack has room
|
// push children in reverse order (so the nearest is popped first) if stack has room
|
||||||
for (int c = childCount - 1; c >= 0; --c)
|
for (int c = childCount - 1; c >= 0; --c)
|
||||||
{
|
{
|
||||||
//if (sp >= STACK_SIZE) break; // protect overflow
|
|
||||||
int cIndex = childIdx[c];
|
|
||||||
|
|
||||||
// compute child center (recompute bit pattern from cIndex relative? We need original i -> recompute mapping:
|
|
||||||
// We can recover i by searching bits in childMask; for clarity, recompute using same loop mapping: simpler: push center using known mapping
|
|
||||||
// But here we don't have i, so better to recompute using childIndex -> we need a deterministic mapping.
|
|
||||||
// For simplicity in this snippet, we recompute i by scanning parent children again — cost small (<=8), do it once:
|
|
||||||
// (implementation detail left to integrate carefully)
|
|
||||||
// --- simplified approach below assumes child center can be recomputed from cIndex via known ordering (keep same mapping as building)
|
|
||||||
// You must ensure mapping consistency between builder and shader.
|
|
||||||
|
|
||||||
// push
|
// push
|
||||||
childEntry.nodeIndex = cIndex;
|
childEntry.nodeIndex = childIdx[c];
|
||||||
// recompute center from index i -> omitted here; in your real shader compute the offsetVec same as above
|
childEntry.center = childCenter[c];
|
||||||
childEntry.center = childCenter[c]; // placeholder: replace with correct center compute
|
|
||||||
childEntry.halfSize = childHalf;
|
childEntry.halfSize = childHalf;
|
||||||
stack[sp++] = childEntry;
|
stack[sp++] = childEntry;
|
||||||
}
|
}
|
||||||
} // end while
|
}
|
||||||
|
|
||||||
if (hasHit)
|
if (hasHit)
|
||||||
{
|
{
|
||||||
// commit heavy ops only now
|
// commit heavy ops only now
|
||||||
float tHit = outHit.maxDistance;
|
float tHit = outHit.maxDistance;
|
||||||
|
|
||||||
|
if( tHit > 0 )
|
||||||
|
{
|
||||||
float3 hitPos = b.origin + r.direction * tHit;
|
float3 hitPos = b.origin + r.direction * tHit;
|
||||||
|
|
||||||
// closest point
|
// closest point
|
||||||
@ -297,3 +288,4 @@ void CSMain(uint3 id : SV_DispatchThreadID)
|
|||||||
hits.Append(outHit);
|
hits.Append(outHit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -180,8 +180,6 @@ MeshRenderer:
|
|||||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||||
m_RayTracingAccelStructBuildFlags: 1
|
m_RayTracingAccelStructBuildFlags: 1
|
||||||
m_SmallMeshCulling: 1
|
m_SmallMeshCulling: 1
|
||||||
m_ForceMeshLod: -1
|
|
||||||
m_MeshLodSelectionBias: 0
|
|
||||||
m_RenderingLayerMask: 1
|
m_RenderingLayerMask: 1
|
||||||
m_RendererPriority: 0
|
m_RendererPriority: 0
|
||||||
m_Materials:
|
m_Materials:
|
||||||
@ -203,7 +201,6 @@ MeshRenderer:
|
|||||||
m_AutoUVMaxDistance: 0.5
|
m_AutoUVMaxDistance: 0.5
|
||||||
m_AutoUVMaxAngle: 89
|
m_AutoUVMaxAngle: 89
|
||||||
m_LightmapParameters: {fileID: 0}
|
m_LightmapParameters: {fileID: 0}
|
||||||
m_GlobalIlluminationMeshLod: 0
|
|
||||||
m_SortingLayerID: 0
|
m_SortingLayerID: 0
|
||||||
m_SortingLayer: 0
|
m_SortingLayer: 0
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
@ -295,7 +292,7 @@ MonoBehaviour:
|
|||||||
m_Bits: 8
|
m_Bits: 8
|
||||||
voxelSize: 0.5
|
voxelSize: 0.5
|
||||||
maxDepth: 7
|
maxDepth: 7
|
||||||
boundsSize: 100
|
boundsSize: 200
|
||||||
computeShader: {fileID: 7200000, guid: beacc211952bec342847019386af6944, type: 3}
|
computeShader: {fileID: 7200000, guid: beacc211952bec342847019386af6944, type: 3}
|
||||||
clusteringShader: {fileID: 7200000, guid: 7b67ac486de90db48bc81c43fae83845, type: 3}
|
clusteringShader: {fileID: 7200000, guid: 7b67ac486de90db48bc81c43fae83845, type: 3}
|
||||||
--- !u!114 &464574967
|
--- !u!114 &464574967
|
||||||
@ -635,8 +632,6 @@ MeshRenderer:
|
|||||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||||
m_RayTracingAccelStructBuildFlags: 1
|
m_RayTracingAccelStructBuildFlags: 1
|
||||||
m_SmallMeshCulling: 1
|
m_SmallMeshCulling: 1
|
||||||
m_ForceMeshLod: -1
|
|
||||||
m_MeshLodSelectionBias: 0
|
|
||||||
m_RenderingLayerMask: 1
|
m_RenderingLayerMask: 1
|
||||||
m_RendererPriority: 0
|
m_RendererPriority: 0
|
||||||
m_Materials:
|
m_Materials:
|
||||||
@ -658,7 +653,6 @@ MeshRenderer:
|
|||||||
m_AutoUVMaxDistance: 0.5
|
m_AutoUVMaxDistance: 0.5
|
||||||
m_AutoUVMaxAngle: 89
|
m_AutoUVMaxAngle: 89
|
||||||
m_LightmapParameters: {fileID: 0}
|
m_LightmapParameters: {fileID: 0}
|
||||||
m_GlobalIlluminationMeshLod: 0
|
|
||||||
m_SortingLayerID: 0
|
m_SortingLayerID: 0
|
||||||
m_SortingLayer: 0
|
m_SortingLayer: 0
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
@ -680,7 +674,7 @@ Transform:
|
|||||||
m_GameObject: {fileID: 1273284503}
|
m_GameObject: {fileID: 1273284503}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
m_LocalPosition: {x: 18.52, y: 3.69, z: -9.47}
|
m_LocalPosition: {x: 24.81, y: 3.69, z: -4.07}
|
||||||
m_LocalScale: {x: 11.138, y: 11.138, z: 11.138}
|
m_LocalScale: {x: 11.138, y: 11.138, z: 11.138}
|
||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children: []
|
m_Children: []
|
||||||
@ -760,8 +754,6 @@ MeshRenderer:
|
|||||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||||
m_RayTracingAccelStructBuildFlags: 1
|
m_RayTracingAccelStructBuildFlags: 1
|
||||||
m_SmallMeshCulling: 1
|
m_SmallMeshCulling: 1
|
||||||
m_ForceMeshLod: -1
|
|
||||||
m_MeshLodSelectionBias: 0
|
|
||||||
m_RenderingLayerMask: 1
|
m_RenderingLayerMask: 1
|
||||||
m_RendererPriority: 0
|
m_RendererPriority: 0
|
||||||
m_Materials:
|
m_Materials:
|
||||||
@ -783,7 +775,6 @@ MeshRenderer:
|
|||||||
m_AutoUVMaxDistance: 0.5
|
m_AutoUVMaxDistance: 0.5
|
||||||
m_AutoUVMaxAngle: 89
|
m_AutoUVMaxAngle: 89
|
||||||
m_LightmapParameters: {fileID: 0}
|
m_LightmapParameters: {fileID: 0}
|
||||||
m_GlobalIlluminationMeshLod: 0
|
|
||||||
m_SortingLayerID: 0
|
m_SortingLayerID: 0
|
||||||
m_SortingLayer: 0
|
m_SortingLayer: 0
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
@ -885,8 +876,6 @@ MeshRenderer:
|
|||||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||||
m_RayTracingAccelStructBuildFlags: 1
|
m_RayTracingAccelStructBuildFlags: 1
|
||||||
m_SmallMeshCulling: 1
|
m_SmallMeshCulling: 1
|
||||||
m_ForceMeshLod: -1
|
|
||||||
m_MeshLodSelectionBias: 0
|
|
||||||
m_RenderingLayerMask: 1
|
m_RenderingLayerMask: 1
|
||||||
m_RendererPriority: 0
|
m_RendererPriority: 0
|
||||||
m_Materials:
|
m_Materials:
|
||||||
@ -908,7 +897,6 @@ MeshRenderer:
|
|||||||
m_AutoUVMaxDistance: 0.5
|
m_AutoUVMaxDistance: 0.5
|
||||||
m_AutoUVMaxAngle: 89
|
m_AutoUVMaxAngle: 89
|
||||||
m_LightmapParameters: {fileID: 0}
|
m_LightmapParameters: {fileID: 0}
|
||||||
m_GlobalIlluminationMeshLod: 0
|
|
||||||
m_SortingLayerID: 0
|
m_SortingLayerID: 0
|
||||||
m_SortingLayer: 0
|
m_SortingLayer: 0
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
|
|||||||
@ -24,7 +24,7 @@ public class Player : MonoBehaviour
|
|||||||
|
|
||||||
VoxelRaycastGPU.Ray[] rays = new VoxelRaycastGPU.Ray[rayCount];
|
VoxelRaycastGPU.Ray[] rays = new VoxelRaycastGPU.Ray[rayCount];
|
||||||
FillRaysArray(rays);
|
FillRaysArray(rays);
|
||||||
voxelManager.gpuRayCaster.Init(rayCount, rays);
|
voxelManager.gpuRayCaster.Init(rayCount, rays, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cast( ref VoxelRaycastGPU.BatchData[] batchData, int batchCount, int iIteration )
|
void Cast( ref VoxelRaycastGPU.BatchData[] batchData, int batchCount, int iIteration )
|
||||||
@ -142,7 +142,7 @@ public class Player : MonoBehaviour
|
|||||||
VoxelRaycastGPU.BatchData[] batchDatas = new VoxelRaycastGPU.BatchData[1];
|
VoxelRaycastGPU.BatchData[] batchDatas = new VoxelRaycastGPU.BatchData[1];
|
||||||
|
|
||||||
batchDatas[0].origin = origin;
|
batchDatas[0].origin = origin;
|
||||||
batchDatas[0].maxDistance = 100;
|
batchDatas[0].maxDistance = 300;
|
||||||
|
|
||||||
Cast(ref batchDatas, 1, 0);
|
Cast(ref batchDatas, 1, 0);
|
||||||
sw.Stop();
|
sw.Stop();
|
||||||
|
|||||||
@ -28,6 +28,7 @@ public class VoxelRaycastGpuManager
|
|||||||
int groupsX;
|
int groupsX;
|
||||||
|
|
||||||
int maxRaycastPerIteration;
|
int maxRaycastPerIteration;
|
||||||
|
int maxIterations = 3;
|
||||||
|
|
||||||
int threadsY = 8;
|
int threadsY = 8;
|
||||||
int maxGroupsY = 65535;
|
int maxGroupsY = 65535;
|
||||||
@ -59,25 +60,28 @@ public class VoxelRaycastGpuManager
|
|||||||
|
|
||||||
public VoxelRaycastGPU.BatchData[] Raycast(in VoxelRaycastGPU.BatchData[] batchData, int datasLenght)
|
public VoxelRaycastGPU.BatchData[] Raycast(in VoxelRaycastGPU.BatchData[] batchData, int datasLenght)
|
||||||
{
|
{
|
||||||
int iteration = 0;
|
int totalCastNumber = 0;
|
||||||
int currentCount = datasLenght;
|
|
||||||
int previousCount = datasLenght;
|
|
||||||
|
|
||||||
|
Stopwatch sw = Stopwatch.StartNew();
|
||||||
|
|
||||||
|
int iteration = 0;
|
||||||
|
int currentCount = batchData.Length;
|
||||||
|
int previousCount = currentCount;
|
||||||
|
|
||||||
|
datasBuffer.SetCounterValue(0);
|
||||||
datasBuffer.SetData(batchData, 0, 0, currentCount);
|
datasBuffer.SetData(batchData, 0, 0, currentCount);
|
||||||
|
|
||||||
while (iteration < 5 && currentCount > 0)
|
while (iteration < maxIterations && currentCount > 0)
|
||||||
{
|
{
|
||||||
|
totalCastNumber += currentCount;
|
||||||
previousCount = currentCount;
|
previousCount = currentCount;
|
||||||
|
|
||||||
hitBuffer.SetCounterValue(0);
|
hitBuffer.SetCounterValue(0);
|
||||||
|
datasBuffer.SetCounterValue(0);
|
||||||
|
|
||||||
raycastShader.SetBuffer(kernel, "batchDatas", datasBuffer );
|
raycastShader.SetBuffer(kernel, "batchDatas", datasBuffer );
|
||||||
raycastShader.SetBuffer(kernel, "hits", hitBuffer);
|
raycastShader.SetBuffer(kernel, "hits", hitBuffer);
|
||||||
|
|
||||||
/**
|
|
||||||
Stopwatch sw = Stopwatch.StartNew();
|
|
||||||
*/
|
|
||||||
|
|
||||||
for (int y = 0; y < currentCount; y += threadsY * maxGroupsY)
|
for (int y = 0; y < currentCount; y += threadsY * maxGroupsY)
|
||||||
{
|
{
|
||||||
int remaining = currentCount - y;
|
int remaining = currentCount - y;
|
||||||
@ -86,14 +90,13 @@ public class VoxelRaycastGpuManager
|
|||||||
raycastShader.Dispatch(kernel, groupsX, dispatchGroupsY, 1);
|
raycastShader.Dispatch(kernel, groupsX, dispatchGroupsY, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ComputeBuffer.CopyCount(hitBuffer, countBuffer, 0);
|
ComputeBuffer.CopyCount(hitBuffer, countBuffer, 0);
|
||||||
int[] countArr = new int[1];
|
int[] countArr = new int[1];
|
||||||
countBuffer.GetData(countArr);
|
countBuffer.GetData(countArr);
|
||||||
currentCount = countArr[0];
|
currentCount = countArr[0];
|
||||||
|
|
||||||
|
sw.Stop();
|
||||||
|
|
||||||
/**
|
|
||||||
VoxelRaycastGPU.BatchData[] hits = new VoxelRaycastGPU.BatchData[currentCount];
|
VoxelRaycastGPU.BatchData[] hits = new VoxelRaycastGPU.BatchData[currentCount];
|
||||||
hitBuffer.GetData(hits, 0, 0, currentCount);
|
hitBuffer.GetData(hits, 0, 0, currentCount);
|
||||||
for( int i = 0; i < hits.Length; i++ )
|
for( int i = 0; i < hits.Length; i++ )
|
||||||
@ -102,53 +105,33 @@ public class VoxelRaycastGpuManager
|
|||||||
sphere.transform.position = hits[i].origin;
|
sphere.transform.position = hits[i].origin;
|
||||||
sphere.transform.localScale = Vector3.one * 0.5f;
|
sphere.transform.localScale = Vector3.one * 0.5f;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
|
sw.Start();
|
||||||
/**
|
|
||||||
sw.Stop();
|
|
||||||
UnityEngine.Debug.Log($"Dispatch done in {sw.Elapsed.TotalMilliseconds}ms for {previousCount*raysPerBatch} casts retrieving {currentCount} hits");
|
|
||||||
*/
|
|
||||||
|
|
||||||
iteration++;
|
iteration++;
|
||||||
|
|
||||||
if (currentCount > 0 && iteration < 5)
|
if (currentCount > 0 && iteration < maxIterations )
|
||||||
{
|
{
|
||||||
datasBuffer = hitBuffer;
|
(datasBuffer,hitBuffer) = (hitBuffer,datasBuffer);
|
||||||
/**
|
}
|
||||||
if (currentCount * raysPerBatch > maxRaycastPerIteration && iteration < 5)
|
|
||||||
{
|
}
|
||||||
sw = Stopwatch.StartNew();
|
|
||||||
currentCount = Clustering( maxRaycastPerIteration / raysPerBatch);
|
|
||||||
sw.Stop();
|
sw.Stop();
|
||||||
|
|
||||||
UnityEngine.Debug.Log($"Clustering done in {sw.Elapsed.TotalMilliseconds}ms for {currentCount} casts");
|
|
||||||
|
|
||||||
VoxelRaycastGPU.BatchData[] hits = new VoxelRaycastGPU.BatchData[currentCount];
|
|
||||||
datasBuffer.GetData(hits, 0, 0, currentCount);
|
|
||||||
|
|
||||||
for (int i = 0; i < currentCount; i++)
|
|
||||||
{
|
|
||||||
GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
|
|
||||||
sphere.transform.position = hits[i].origin;
|
|
||||||
sphere.transform.localScale = Vector3.one * 0.5f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
VoxelRaycastGPU.BatchData[] result = new VoxelRaycastGPU.BatchData[previousCount];
|
VoxelRaycastGPU.BatchData[] result = new VoxelRaycastGPU.BatchData[previousCount];
|
||||||
hitBuffer.GetData(result, 0, 0, previousCount);
|
hitBuffer.GetData(result, 0, 0, previousCount);
|
||||||
|
|
||||||
|
|
||||||
|
UnityEngine.Debug.Log($"Raycast done in {sw.Elapsed.TotalMilliseconds}ms for a total of {totalCastNumber} raycasts");
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Init(int nbRaysPerBatch, in VoxelRaycastGPU.Ray[] rays)
|
public void Init(int nbRaysPerBatch, in VoxelRaycastGPU.Ray[] rays, int maxIterations)
|
||||||
{
|
{
|
||||||
maxRaycastPerIteration = 1000000;
|
maxRaycastPerIteration = 1000000;
|
||||||
raysPerBatch = nbRaysPerBatch;
|
raysPerBatch = nbRaysPerBatch;
|
||||||
|
this.maxIterations = maxIterations;
|
||||||
|
|
||||||
countBuffer = new ComputeBuffer(1, sizeof(int), ComputeBufferType.Raw);
|
countBuffer = new ComputeBuffer(1, sizeof(int), ComputeBufferType.Raw);
|
||||||
|
|
||||||
@ -157,7 +140,7 @@ public class VoxelRaycastGpuManager
|
|||||||
int nodeStride = Marshal.SizeOf(typeof(LinearNode)); // should be 64
|
int nodeStride = Marshal.SizeOf(typeof(LinearNode)); // should be 64
|
||||||
|
|
||||||
hitBuffer = new ComputeBuffer(maxRaycastPerIteration * raysPerBatch, batchDataClassSize, ComputeBufferType.Append);
|
hitBuffer = new ComputeBuffer(maxRaycastPerIteration * raysPerBatch, batchDataClassSize, ComputeBufferType.Append);
|
||||||
datasBuffer = new ComputeBuffer(maxRaycastPerIteration, batchDataClassSize, ComputeBufferType.Default);
|
datasBuffer = new ComputeBuffer(maxRaycastPerIteration, batchDataClassSize, ComputeBufferType.Append);
|
||||||
|
|
||||||
rayBuffer = new ComputeBuffer(rays.Length, Marshal.SizeOf(typeof(VoxelRaycastGPU.Ray)), ComputeBufferType.Default);
|
rayBuffer = new ComputeBuffer(rays.Length, Marshal.SizeOf(typeof(VoxelRaycastGPU.Ray)), ComputeBufferType.Default);
|
||||||
rayBuffer.SetData(rays, 0, 0, rays.Length);
|
rayBuffer.SetData(rays, 0, 0, rays.Length);
|
||||||
|
|||||||
Reference in New Issue
Block a user