Removing clustering. Replaced by separation of axes
This commit is contained in:
@ -1,81 +1,91 @@
|
||||
// VoxelBatchCluster.compute
|
||||
#pragma kernel AccumulateHits
|
||||
#pragma kernel ComputeMeans
|
||||
// SpatialGridCluster.compute
|
||||
#pragma kernel Accumulate
|
||||
#pragma kernel Reduce
|
||||
|
||||
// ---- Structures ----
|
||||
struct BatchData
|
||||
{
|
||||
float3 position;
|
||||
float3 origin;
|
||||
float maxDistance;
|
||||
};
|
||||
|
||||
// ---- Constantes ----
|
||||
#define GRID_SIZE 8192 // nombre total de cellules max
|
||||
#define GRID_PRIME1 73856093 // pour hash
|
||||
#define GRID_PRIME2 19349663
|
||||
#define GRID_PRIME3 83492791
|
||||
#define SCALE 1000.0
|
||||
StructuredBuffer<BatchData> batchDatas;
|
||||
RWStructuredBuffer<uint> cellCount;
|
||||
RWStructuredBuffer<uint> cellDistanceSum;
|
||||
AppendStructuredBuffer<BatchData> clusteredBatches;
|
||||
|
||||
// ---- Buffers ----
|
||||
StructuredBuffer<BatchData> inputHits;
|
||||
float3 gridMin;
|
||||
float3 gridMax;
|
||||
int3 gridResolution;
|
||||
float3 cellSize;
|
||||
int startIndex;
|
||||
|
||||
RWStructuredBuffer<int4> cellSums; // xyz = somme positions, w = somme maxDistance
|
||||
RWStructuredBuffer<uint> cellCounts; // nombre d'éléments par cellule
|
||||
AppendStructuredBuffer<BatchData> clusteredHits;
|
||||
#define DIST_SCALE 100.0
|
||||
#define THREADS 64
|
||||
|
||||
// ---- Params ----
|
||||
float cellSize; // taille d'une cellule (distance seuil)
|
||||
uint inputCount; // nombre d'éléments d'entrée
|
||||
float3 gridOrigin; // origine du monde pour le hash
|
||||
// ----------------------
|
||||
// === KERNEL 1 : ACCUMULATION OPTIMISÉE ===
|
||||
// ----------------------
|
||||
groupshared uint localCellCount[THREADS];
|
||||
groupshared uint localCellSum[THREADS];
|
||||
|
||||
// ---- Utilitaires ----
|
||||
uint HashCell(int3 cell)
|
||||
[numthreads(THREADS, 1, 1)]
|
||||
void Accumulate(uint3 id : SV_DispatchThreadID, uint3 groupId : SV_GroupID, uint3 localId : SV_GroupThreadID)
|
||||
{
|
||||
uint h = (uint)((cell.x * GRID_PRIME1) ^ (cell.y * GRID_PRIME2) ^ (cell.z * GRID_PRIME3));
|
||||
return h % GRID_SIZE;
|
||||
uint index = id.x + startIndex;
|
||||
if (index >= batchDatas.Length) return;
|
||||
|
||||
BatchData b = batchDatas[index];
|
||||
|
||||
// Position relative dans la grille
|
||||
float3 rel = (b.origin - gridMin) / (gridMax - gridMin);
|
||||
int3 cell = clamp(int3(rel * gridResolution), 0, gridResolution - 1);
|
||||
|
||||
// Index 1D de la cellule
|
||||
uint cellIndex = cell.x + cell.y * gridResolution.x + cell.z * gridResolution.x * gridResolution.y;
|
||||
|
||||
// Initialiser le groupe partagé pour ce thread
|
||||
localCellCount[localId.x] = 0;
|
||||
localCellSum[localId.x] = 0;
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
// Accumulation locale
|
||||
localCellCount[localId.x] += 1;
|
||||
localCellSum[localId.x] += (uint)(b.maxDistance * DIST_SCALE + 0.5);
|
||||
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
// Écriture atomique unique par thread vers le buffer global
|
||||
InterlockedAdd(cellCount[cellIndex], localCellCount[localId.x]);
|
||||
InterlockedAdd(cellDistanceSum[cellIndex], localCellSum[localId.x]);
|
||||
}
|
||||
|
||||
// ---- Kernel 1 : Accumulation ----
|
||||
// Constante d’échelle
|
||||
|
||||
[numthreads(64,1,1)]
|
||||
void AccumulateHits(uint3 id : SV_DispatchThreadID)
|
||||
// ----------------------
|
||||
// === KERNEL 2 : REDUCTION ===
|
||||
// ----------------------
|
||||
[numthreads(THREADS, 1, 1)]
|
||||
void Reduce(uint3 id : SV_DispatchThreadID)
|
||||
{
|
||||
uint i = id.x;
|
||||
if (i >= inputCount) return;
|
||||
uint index = id.x;
|
||||
uint totalCells = gridResolution.x * gridResolution.y * gridResolution.z;
|
||||
|
||||
BatchData b = inputHits[i];
|
||||
if (index >= totalCells) return;
|
||||
|
||||
int3 cell = int3(floor((b.position - gridOrigin) / cellSize));
|
||||
uint hash = HashCell(cell);
|
||||
|
||||
// Conversion float -> int
|
||||
int3 posInt = int3(b.position * SCALE);
|
||||
int maxDistInt = (int)(b.maxDistance * SCALE);
|
||||
|
||||
// Ajout atomique
|
||||
InterlockedAdd(cellSums[hash].x, posInt.x);
|
||||
InterlockedAdd(cellSums[hash].y, posInt.y);
|
||||
InterlockedAdd(cellSums[hash].z, posInt.z);
|
||||
InterlockedAdd(cellSums[hash].w, maxDistInt);
|
||||
InterlockedAdd(cellCounts[hash], 1);
|
||||
}
|
||||
|
||||
// ---- Kernel 2 : Calcul des moyennes ----
|
||||
[numthreads(64,1,1)]
|
||||
void ComputeMeans(uint3 id : SV_DispatchThreadID)
|
||||
{
|
||||
uint i = id.x;
|
||||
if (i >= GRID_SIZE) return;
|
||||
|
||||
uint count = cellCounts[i];
|
||||
uint count = cellCount[index];
|
||||
if (count == 0) return;
|
||||
|
||||
int4 sum = cellSums[i];
|
||||
uint sumScaled = cellDistanceSum[index];
|
||||
float avgDistance = (float(sumScaled) / float(count)) / DIST_SCALE;
|
||||
|
||||
BatchData outB;
|
||||
outB.position = (float3(sum.xyz) / SCALE) / count;
|
||||
outB.maxDistance = (float(sum.w) / SCALE) / count;
|
||||
uint3 coord;
|
||||
coord.x = index % gridResolution.x;
|
||||
coord.y = (index / gridResolution.x) % gridResolution.y;
|
||||
coord.z = index / (gridResolution.x * gridResolution.y);
|
||||
|
||||
clusteredHits.Append(outB);
|
||||
float3 center = gridMin + (float3(coord) + 0.5) * cellSize;
|
||||
|
||||
BatchData b;
|
||||
b.origin = center;
|
||||
b.maxDistance = avgDistance;
|
||||
|
||||
clusteredBatches.Append(b);
|
||||
}
|
||||
@ -69,6 +69,8 @@ float3 rootCenter;
|
||||
float rootHalfSize;
|
||||
int rootIndex;
|
||||
|
||||
int startIndexY;
|
||||
|
||||
float3 ClosestPointOnAABB(float3 hitPos, float3 boxCenter, float halfSize)
|
||||
{
|
||||
float3 minB = boxCenter - halfSize;
|
||||
@ -139,7 +141,7 @@ inline bool IntersectAABB_fast(
|
||||
void CSMain(uint3 id : SV_DispatchThreadID)
|
||||
{
|
||||
uint rayIndex = id.x;
|
||||
uint batchIndex = id.y;
|
||||
uint batchIndex = id.y + startIndexY;
|
||||
if (rayIndex >= rays.Length || batchIndex >= batchDatas.Length) return;
|
||||
|
||||
RayData r = rays[rayIndex];
|
||||
|
||||
@ -244,228 +244,6 @@ MonoBehaviour:
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::AudioObject
|
||||
audioMaterialSettings: {fileID: 11400000, guid: 58ebbfa597f7b56499162cc5660da3ba, type: 2}
|
||||
--- !u!1 &428183757
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 428183761}
|
||||
- component: {fileID: 428183760}
|
||||
- component: {fileID: 428183759}
|
||||
- component: {fileID: 428183758}
|
||||
m_Layer: 0
|
||||
m_Name: Cube (2)
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!65 &428183758
|
||||
BoxCollider:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 428183757}
|
||||
m_Material: {fileID: 0}
|
||||
m_IncludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_ExcludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_LayerOverridePriority: 0
|
||||
m_IsTrigger: 0
|
||||
m_ProvidesContacts: 0
|
||||
m_Enabled: 1
|
||||
serializedVersion: 3
|
||||
m_Size: {x: 1, y: 1, z: 1}
|
||||
m_Center: {x: 0, y: 0, z: 0}
|
||||
--- !u!23 &428183759
|
||||
MeshRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 428183757}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 1
|
||||
m_ReceiveShadows: 1
|
||||
m_DynamicOccludee: 1
|
||||
m_StaticShadowCaster: 0
|
||||
m_MotionVectors: 1
|
||||
m_LightProbeUsage: 1
|
||||
m_ReflectionProbeUsage: 1
|
||||
m_RayTracingMode: 2
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
m_StaticBatchRoot: {fileID: 0}
|
||||
m_ProbeAnchor: {fileID: 0}
|
||||
m_LightProbeVolumeOverride: {fileID: 0}
|
||||
m_ScaleInLightmap: 1
|
||||
m_ReceiveGI: 1
|
||||
m_PreserveUVs: 0
|
||||
m_IgnoreNormalsForChartDetection: 0
|
||||
m_ImportantGI: 0
|
||||
m_StitchLightmapSeams: 1
|
||||
m_SelectedEditorRenderState: 3
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_AdditionalVertexStreams: {fileID: 0}
|
||||
--- !u!33 &428183760
|
||||
MeshFilter:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 428183757}
|
||||
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
|
||||
--- !u!4 &428183761
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 428183757}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 19.35913, y: 9.19515, z: 43.9}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &450236051
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 450236055}
|
||||
- component: {fileID: 450236054}
|
||||
- component: {fileID: 450236053}
|
||||
- component: {fileID: 450236052}
|
||||
m_Layer: 0
|
||||
m_Name: Cube (5)
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!65 &450236052
|
||||
BoxCollider:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 450236051}
|
||||
m_Material: {fileID: 0}
|
||||
m_IncludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_ExcludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_LayerOverridePriority: 0
|
||||
m_IsTrigger: 0
|
||||
m_ProvidesContacts: 0
|
||||
m_Enabled: 1
|
||||
serializedVersion: 3
|
||||
m_Size: {x: 1, y: 1, z: 1}
|
||||
m_Center: {x: 0, y: 0, z: 0}
|
||||
--- !u!23 &450236053
|
||||
MeshRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 450236051}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 1
|
||||
m_ReceiveShadows: 1
|
||||
m_DynamicOccludee: 1
|
||||
m_StaticShadowCaster: 0
|
||||
m_MotionVectors: 1
|
||||
m_LightProbeUsage: 1
|
||||
m_ReflectionProbeUsage: 1
|
||||
m_RayTracingMode: 2
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
m_StaticBatchRoot: {fileID: 0}
|
||||
m_ProbeAnchor: {fileID: 0}
|
||||
m_LightProbeVolumeOverride: {fileID: 0}
|
||||
m_ScaleInLightmap: 1
|
||||
m_ReceiveGI: 1
|
||||
m_PreserveUVs: 0
|
||||
m_IgnoreNormalsForChartDetection: 0
|
||||
m_ImportantGI: 0
|
||||
m_StitchLightmapSeams: 1
|
||||
m_SelectedEditorRenderState: 3
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_AdditionalVertexStreams: {fileID: 0}
|
||||
--- !u!33 &450236054
|
||||
MeshFilter:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 450236051}
|
||||
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
|
||||
--- !u!4 &450236055
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 450236051}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 20.352, y: 9.19515, z: 44.904}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &464574962
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -560,117 +338,6 @@ MonoBehaviour:
|
||||
emptyColor: {r: 0, g: 0.5, b: 1, a: 0.2}
|
||||
solidColor: {r: 1, g: 0, b: 0, a: 0.5}
|
||||
mixedColor: {r: 1, g: 1, b: 0, a: 0.4}
|
||||
--- !u!1 &612412859
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 612412863}
|
||||
- component: {fileID: 612412862}
|
||||
- component: {fileID: 612412861}
|
||||
- component: {fileID: 612412860}
|
||||
m_Layer: 0
|
||||
m_Name: Cube (6)
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!65 &612412860
|
||||
BoxCollider:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 612412859}
|
||||
m_Material: {fileID: 0}
|
||||
m_IncludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_ExcludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_LayerOverridePriority: 0
|
||||
m_IsTrigger: 0
|
||||
m_ProvidesContacts: 0
|
||||
m_Enabled: 1
|
||||
serializedVersion: 3
|
||||
m_Size: {x: 1, y: 1, z: 1}
|
||||
m_Center: {x: 0, y: 0, z: 0}
|
||||
--- !u!23 &612412861
|
||||
MeshRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 612412859}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 1
|
||||
m_ReceiveShadows: 1
|
||||
m_DynamicOccludee: 1
|
||||
m_StaticShadowCaster: 0
|
||||
m_MotionVectors: 1
|
||||
m_LightProbeUsage: 1
|
||||
m_ReflectionProbeUsage: 1
|
||||
m_RayTracingMode: 2
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
m_StaticBatchRoot: {fileID: 0}
|
||||
m_ProbeAnchor: {fileID: 0}
|
||||
m_LightProbeVolumeOverride: {fileID: 0}
|
||||
m_ScaleInLightmap: 1
|
||||
m_ReceiveGI: 1
|
||||
m_PreserveUVs: 0
|
||||
m_IgnoreNormalsForChartDetection: 0
|
||||
m_ImportantGI: 0
|
||||
m_StitchLightmapSeams: 1
|
||||
m_SelectedEditorRenderState: 3
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_AdditionalVertexStreams: {fileID: 0}
|
||||
--- !u!33 &612412862
|
||||
MeshFilter:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 612412859}
|
||||
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
|
||||
--- !u!4 &612412863
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 612412859}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 18.363, y: 9.19515, z: 41.884}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &705507993
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -768,7 +435,7 @@ Transform:
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
|
||||
--- !u!1 &864920249
|
||||
--- !u!1 &711765669
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
@ -776,104 +443,24 @@ GameObject:
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 864920253}
|
||||
- component: {fileID: 864920252}
|
||||
- component: {fileID: 864920251}
|
||||
- component: {fileID: 864920250}
|
||||
- component: {fileID: 711765670}
|
||||
m_Layer: 0
|
||||
m_Name: Cube (3)
|
||||
m_Name: GameObject
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!65 &864920250
|
||||
BoxCollider:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 864920249}
|
||||
m_Material: {fileID: 0}
|
||||
m_IncludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_ExcludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_LayerOverridePriority: 0
|
||||
m_IsTrigger: 0
|
||||
m_ProvidesContacts: 0
|
||||
m_Enabled: 1
|
||||
serializedVersion: 3
|
||||
m_Size: {x: 1, y: 1, z: 1}
|
||||
m_Center: {x: 0, y: 0, z: 0}
|
||||
--- !u!23 &864920251
|
||||
MeshRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 864920249}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 1
|
||||
m_ReceiveShadows: 1
|
||||
m_DynamicOccludee: 1
|
||||
m_StaticShadowCaster: 0
|
||||
m_MotionVectors: 1
|
||||
m_LightProbeUsage: 1
|
||||
m_ReflectionProbeUsage: 1
|
||||
m_RayTracingMode: 2
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
m_StaticBatchRoot: {fileID: 0}
|
||||
m_ProbeAnchor: {fileID: 0}
|
||||
m_LightProbeVolumeOverride: {fileID: 0}
|
||||
m_ScaleInLightmap: 1
|
||||
m_ReceiveGI: 1
|
||||
m_PreserveUVs: 0
|
||||
m_IgnoreNormalsForChartDetection: 0
|
||||
m_ImportantGI: 0
|
||||
m_StitchLightmapSeams: 1
|
||||
m_SelectedEditorRenderState: 3
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_AdditionalVertexStreams: {fileID: 0}
|
||||
--- !u!33 &864920252
|
||||
MeshFilter:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 864920249}
|
||||
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
|
||||
--- !u!4 &864920253
|
||||
--- !u!4 &711765670
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 864920249}
|
||||
m_GameObject: {fileID: 711765669}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 18.363, y: 9.19515, z: 42.918}
|
||||
m_LocalPosition: {x: 50, y: 50, z: 50}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
@ -1349,117 +936,6 @@ Transform:
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: -53.013, z: 0}
|
||||
--- !u!1 &2077705879
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 2077705883}
|
||||
- component: {fileID: 2077705882}
|
||||
- component: {fileID: 2077705881}
|
||||
- component: {fileID: 2077705880}
|
||||
m_Layer: 0
|
||||
m_Name: Cube (4)
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!65 &2077705880
|
||||
BoxCollider:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2077705879}
|
||||
m_Material: {fileID: 0}
|
||||
m_IncludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_ExcludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_LayerOverridePriority: 0
|
||||
m_IsTrigger: 0
|
||||
m_ProvidesContacts: 0
|
||||
m_Enabled: 1
|
||||
serializedVersion: 3
|
||||
m_Size: {x: 1, y: 1, z: 1}
|
||||
m_Center: {x: 0, y: 0, z: 0}
|
||||
--- !u!23 &2077705881
|
||||
MeshRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2077705879}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 1
|
||||
m_ReceiveShadows: 1
|
||||
m_DynamicOccludee: 1
|
||||
m_StaticShadowCaster: 0
|
||||
m_MotionVectors: 1
|
||||
m_LightProbeUsage: 1
|
||||
m_ReflectionProbeUsage: 1
|
||||
m_RayTracingMode: 2
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
m_StaticBatchRoot: {fileID: 0}
|
||||
m_ProbeAnchor: {fileID: 0}
|
||||
m_LightProbeVolumeOverride: {fileID: 0}
|
||||
m_ScaleInLightmap: 1
|
||||
m_ReceiveGI: 1
|
||||
m_PreserveUVs: 0
|
||||
m_IgnoreNormalsForChartDetection: 0
|
||||
m_ImportantGI: 0
|
||||
m_StitchLightmapSeams: 1
|
||||
m_SelectedEditorRenderState: 3
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_AdditionalVertexStreams: {fileID: 0}
|
||||
--- !u!33 &2077705882
|
||||
MeshFilter:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2077705879}
|
||||
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
|
||||
--- !u!4 &2077705883
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2077705879}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 21.35913, y: 9.19515, z: 45.902}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1660057539 &9223372036854775807
|
||||
SceneRoots:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -1470,9 +946,5 @@ SceneRoots:
|
||||
- {fileID: 1376698039}
|
||||
- {fileID: 1629958729}
|
||||
- {fileID: 464574964}
|
||||
- {fileID: 428183761}
|
||||
- {fileID: 864920253}
|
||||
- {fileID: 612412863}
|
||||
- {fileID: 2077705883}
|
||||
- {fileID: 450236055}
|
||||
- {fileID: 1273284507}
|
||||
- {fileID: 711765670}
|
||||
|
||||
@ -29,18 +29,18 @@ public class Player : MonoBehaviour
|
||||
|
||||
void Cast( ref VoxelRaycastGPU.BatchData[] batchData, int batchCount, int iIteration )
|
||||
{
|
||||
ComputeBuffer hitBuffer = new ComputeBuffer(rayCount * batchCount, Marshal.SizeOf(typeof(VoxelRaycastGPU.Hit)), ComputeBufferType.Append);
|
||||
|
||||
Stopwatch sw = Stopwatch.StartNew();
|
||||
totalCastDone += batchCount * rayCount;
|
||||
VoxelRaycastGPU.BatchData[] hits = voxelManager.CastGpuRay(in batchData, batchCount);
|
||||
|
||||
/*for( int i = 0; i < hits.Length; i++ )
|
||||
/**
|
||||
for( int i = 0; i < hits.Length; i++ )
|
||||
{
|
||||
GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
|
||||
sphere.transform.position = hits[i].origin;
|
||||
sphere.transform.localScale = Vector3.one * 0.5f;
|
||||
}*/
|
||||
}
|
||||
*/
|
||||
|
||||
sw.Stop();
|
||||
}
|
||||
|
||||
@ -15,10 +15,11 @@ public class VoxelRaycastGpuManager
|
||||
//--------------- RayCasts ------------------------------------------------------
|
||||
int kernel;
|
||||
|
||||
ComputeBuffer datasBuffer;
|
||||
ComputeBuffer datasBuffer = null;
|
||||
ComputeBuffer hitCounterBuffer = null;
|
||||
ComputeBuffer rayBuffer = null;
|
||||
ComputeBuffer hitBuffer;
|
||||
ComputeBuffer hitBuffer = null;
|
||||
ComputeBuffer countBuffer = null;
|
||||
|
||||
int raysPerBatch;
|
||||
|
||||
@ -28,11 +29,15 @@ public class VoxelRaycastGpuManager
|
||||
|
||||
int maxRaycastPerIteration;
|
||||
|
||||
int threadsY = 8;
|
||||
int maxGroupsY = 65535;
|
||||
|
||||
|
||||
//--------------- Clustering ------------------------------------------------------
|
||||
|
||||
ComputeShader clusteringShader;
|
||||
|
||||
int accumulationKernel;
|
||||
int reductionKernel;
|
||||
int gridSize;
|
||||
int threadCount = 64;
|
||||
int groupCountHits;
|
||||
@ -54,8 +59,6 @@ public class VoxelRaycastGpuManager
|
||||
|
||||
public VoxelRaycastGPU.BatchData[] Raycast(in VoxelRaycastGPU.BatchData[] batchData, int datasLenght)
|
||||
{
|
||||
ComputeBuffer countBuffer = new ComputeBuffer(1, sizeof(int), ComputeBufferType.Raw);
|
||||
|
||||
int iteration = 0;
|
||||
int currentCount = datasLenght;
|
||||
int previousCount = datasLenght;
|
||||
@ -71,27 +74,52 @@ public class VoxelRaycastGpuManager
|
||||
raycastShader.SetBuffer(kernel, "batchDatas", datasBuffer );
|
||||
raycastShader.SetBuffer(kernel, "hits", hitBuffer);
|
||||
|
||||
int threadsY = 8;
|
||||
|
||||
int groupsY = Mathf.CeilToInt((float)currentCount / threadsY);
|
||||
|
||||
/**
|
||||
Stopwatch sw = Stopwatch.StartNew();
|
||||
raycastShader.Dispatch(kernel, groupsX, groupsY, 1);
|
||||
*/
|
||||
|
||||
for (int y = 0; y < currentCount; y += threadsY * maxGroupsY)
|
||||
{
|
||||
int remaining = currentCount - y;
|
||||
int dispatchGroupsY = Mathf.CeilToInt(Mathf.Min(remaining / (float)threadsY, maxGroupsY));
|
||||
raycastShader.SetInt("startIndexY", y);
|
||||
raycastShader.Dispatch(kernel, groupsX, dispatchGroupsY, 1);
|
||||
}
|
||||
|
||||
|
||||
ComputeBuffer.CopyCount(hitBuffer, countBuffer, 0);
|
||||
int[] countArr = new int[1];
|
||||
countBuffer.GetData(countArr);
|
||||
currentCount = countArr[0];
|
||||
|
||||
|
||||
/**
|
||||
VoxelRaycastGPU.BatchData[] hits = new VoxelRaycastGPU.BatchData[currentCount];
|
||||
hitBuffer.GetData(hits, 0, 0, currentCount);
|
||||
for( int i = 0; i < hits.Length; i++ )
|
||||
{
|
||||
GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
|
||||
sphere.transform.position = hits[i].origin;
|
||||
sphere.transform.localScale = Vector3.one * 0.5f;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
sw.Stop();
|
||||
UnityEngine.Debug.Log($"Dispatch done in {sw.Elapsed.TotalMilliseconds}ms for {previousCount*raysPerBatch} casts retrieving {currentCount} hits");
|
||||
*/
|
||||
|
||||
if (currentCount > 0)
|
||||
iteration++;
|
||||
|
||||
if (currentCount > 0 && iteration < 5)
|
||||
{
|
||||
datasBuffer = hitBuffer;
|
||||
/**
|
||||
if (currentCount * raysPerBatch > maxRaycastPerIteration && iteration < 5)
|
||||
{
|
||||
sw = Stopwatch.StartNew();
|
||||
currentCount = Clustering(currentCount);
|
||||
currentCount = Clustering( maxRaycastPerIteration / raysPerBatch);
|
||||
sw.Stop();
|
||||
|
||||
UnityEngine.Debug.Log($"Clustering done in {sw.Elapsed.TotalMilliseconds}ms for {currentCount} casts");
|
||||
@ -105,27 +133,15 @@ public class VoxelRaycastGpuManager
|
||||
sphere.transform.position = hits[i].origin;
|
||||
sphere.transform.localScale = Vector3.one * 0.5f;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
datasBuffer = hitBuffer;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
iteration++;
|
||||
}
|
||||
|
||||
VoxelRaycastGPU.BatchData[] result = new VoxelRaycastGPU.BatchData[previousCount];
|
||||
if (currentCount == 0)
|
||||
datasBuffer.GetData(result, 0, 0, previousCount);
|
||||
else
|
||||
hitBuffer.GetData(result, 0, 0, previousCount);
|
||||
|
||||
|
||||
countBuffer.Release();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -134,6 +150,8 @@ public class VoxelRaycastGpuManager
|
||||
maxRaycastPerIteration = 1000000;
|
||||
raysPerBatch = nbRaysPerBatch;
|
||||
|
||||
countBuffer = new ComputeBuffer(1, sizeof(int), ComputeBufferType.Raw);
|
||||
|
||||
// Flatten octree
|
||||
linearTree = OctreeGpuHelpers.FlattenOctree(root);
|
||||
int nodeStride = Marshal.SizeOf(typeof(LinearNode)); // should be 64
|
||||
@ -152,7 +170,6 @@ public class VoxelRaycastGpuManager
|
||||
uint[] counterInit = { 0 };
|
||||
counterInit[0] = 0;
|
||||
hitCounterBuffer.SetData(counterInit);
|
||||
|
||||
kernel = raycastShader.FindKernel("CSMain");
|
||||
|
||||
raycastShader.SetBuffer(kernel, "nodes", nodeBuffer);
|
||||
@ -174,46 +191,72 @@ public class VoxelRaycastGpuManager
|
||||
cellClusteringSums = new ComputeBuffer(gridSize, sizeof(float) * 4);
|
||||
cellClusteringCounts = new ComputeBuffer(gridSize, sizeof(uint));
|
||||
clustered = new ComputeBuffer(gridSize, Marshal.SizeOf(typeof(VoxelRaycastGPU.BatchData)), ComputeBufferType.Append);
|
||||
|
||||
accumulationKernel = clusteringShader.FindKernel("Accumulate");
|
||||
reductionKernel = clusteringShader.FindKernel("Reduce");
|
||||
}
|
||||
|
||||
public int Clustering( int inputCount )
|
||||
public int Clustering( int targetGroupCount )
|
||||
{
|
||||
groupCountHits = Mathf.CeilToInt((float)inputCount / threadCount);
|
||||
int count = datasBuffer.count;
|
||||
|
||||
clustered.SetCounterValue(0);
|
||||
float[] zero4 = new float[gridSize * 4];
|
||||
uint[] zeroU = new uint[gridSize];
|
||||
cellClusteringSums.SetData(zero4);
|
||||
cellClusteringCounts.SetData(zeroU);
|
||||
// 1️⃣ Définir la résolution de la grille
|
||||
int cellsPerAxis = Mathf.CeilToInt(Mathf.Pow(targetGroupCount, 1f / 3f));
|
||||
Vector3 gridMin = new Vector3(-50, -50, -50);
|
||||
Vector3 gridMax = new Vector3(50, 50, 50);
|
||||
Vector3 cellSize = (gridMax - gridMin) / cellsPerAxis;
|
||||
|
||||
// Shader
|
||||
int kernelAcc = clusteringShader.FindKernel("AccumulateHits");
|
||||
int kernelMean = clusteringShader.FindKernel("ComputeMeans");
|
||||
int totalCells = cellsPerAxis * cellsPerAxis * cellsPerAxis;
|
||||
|
||||
clusteringShader.SetInt("inputCount", inputCount);
|
||||
clusteringShader.SetFloat("cellSize", 1.0f); // taille des cellules
|
||||
clusteringShader.SetVector("gridOrigin", Vector3.zero);
|
||||
// 2️⃣ Créer les buffers
|
||||
ComputeBuffer cellCount = new ComputeBuffer(totalCells, sizeof(uint));
|
||||
ComputeBuffer cellDistanceSum = new ComputeBuffer(totalCells, sizeof(float));
|
||||
ComputeBuffer resultBuffer = new ComputeBuffer(totalCells, sizeof(float) * 4, ComputeBufferType.Append);
|
||||
resultBuffer.SetCounterValue(0);
|
||||
|
||||
clusteringShader.SetBuffer(kernelAcc, "inputHits", hitBuffer);
|
||||
clusteringShader.SetBuffer(kernelAcc, "cellSums", cellClusteringSums);
|
||||
clusteringShader.SetBuffer(kernelAcc, "cellCounts", cellClusteringCounts);
|
||||
clusteringShader.Dispatch(kernelAcc, groupCountHits, 1, 1);
|
||||
clusteringShader.SetBuffer(accumulationKernel, "batchDatas", datasBuffer);
|
||||
clusteringShader.SetBuffer(accumulationKernel, "cellCount", cellCount);
|
||||
clusteringShader.SetBuffer(accumulationKernel, "cellDistanceSum", cellDistanceSum);
|
||||
|
||||
clusteringShader.SetBuffer(kernelMean, "cellSums", cellClusteringSums);
|
||||
clusteringShader.SetBuffer(kernelMean, "cellCounts", cellClusteringCounts);
|
||||
clusteringShader.SetBuffer(kernelMean, "clusteredHits", clustered);
|
||||
clusteringShader.Dispatch(kernelMean, groupCountGrid, 1, 1);
|
||||
clusteringShader.SetVector("gridMin", gridMin);
|
||||
clusteringShader.SetVector("gridMax", gridMax);
|
||||
clusteringShader.SetInts("gridResolution", cellsPerAxis, cellsPerAxis, cellsPerAxis);
|
||||
clusteringShader.SetVector("cellSize", cellSize);
|
||||
|
||||
// Lecture du résultat
|
||||
ComputeBuffer countBuffer = new ComputeBuffer(1, sizeof(int), ComputeBufferType.Raw);
|
||||
ComputeBuffer.CopyCount(clustered, countBuffer, 0);
|
||||
int[] countArr = new int[1];
|
||||
countBuffer.GetData(countArr);
|
||||
int clusterCount = countArr[0];
|
||||
int threadsPerGroup = 64;
|
||||
int maxThreadGroups = 65535;
|
||||
|
||||
datasBuffer = clustered;
|
||||
for (int i = 0; i < count; i += threadsPerGroup * maxThreadGroups)
|
||||
{
|
||||
int remaining = count - i;
|
||||
int groups = Mathf.CeilToInt(Mathf.Min(remaining / (float)threadsPerGroup, maxThreadGroups));
|
||||
clusteringShader.SetInt("startIndex", i);
|
||||
clusteringShader.Dispatch(accumulationKernel, groups, 1, 1);
|
||||
}
|
||||
|
||||
return clusterCount;
|
||||
// 4️⃣ Dispatch reduce
|
||||
clusteringShader.SetBuffer(reductionKernel, "cellCount", cellCount);
|
||||
clusteringShader.SetBuffer(reductionKernel, "cellDistanceSum", cellDistanceSum);
|
||||
clusteringShader.SetBuffer(reductionKernel, "clusteredBatches", resultBuffer);
|
||||
|
||||
int reduceGroups = Mathf.CeilToInt(totalCells / 64);
|
||||
clusteringShader.Dispatch(reductionKernel, reduceGroups, 1, 1);
|
||||
|
||||
// 5️⃣ Lire le résultat
|
||||
ComputeBuffer.CopyCount(resultBuffer, countBuffer, 0);
|
||||
int[] countArray = new int[1];
|
||||
countBuffer.GetData(countArray);
|
||||
int outputCount = countArray[0];
|
||||
|
||||
VoxelRaycastGPU.BatchData[] finalBatches = new VoxelRaycastGPU.BatchData[outputCount];
|
||||
resultBuffer.GetData(finalBatches, 0, 0, outputCount);
|
||||
|
||||
// 🔚 Cleanup
|
||||
cellCount.Release();
|
||||
cellDistanceSum.Release();
|
||||
resultBuffer.Release();
|
||||
|
||||
return outputCount;
|
||||
}
|
||||
|
||||
~VoxelRaycastGpuManager()
|
||||
@ -224,8 +267,14 @@ public class VoxelRaycastGpuManager
|
||||
if (rayBuffer != null)
|
||||
rayBuffer.Release();
|
||||
|
||||
if (hitBuffer != null)
|
||||
hitBuffer.Release();
|
||||
|
||||
if (datasBuffer != null)
|
||||
datasBuffer.Release();
|
||||
|
||||
if( countBuffer != null )
|
||||
countBuffer.Release();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user