#pragma kernel BuildMesh #include "MathUtils.cginc" struct RendererData { float4 color; float radiusScale; }; StructuredBuffer particleIndices; StructuredBuffer positions; StructuredBuffer orientations; StructuredBuffer radii; StructuredBuffer colors; StructuredBuffer rendererIndices; StructuredBuffer rendererData; RWByteAddressBuffer vertices; RWByteAddressBuffer indices; uint firstParticle; uint particleCount; [numthreads(128, 1, 1)] void BuildMesh (uint3 id : SV_DispatchThreadID) { unsigned int i = id.x; if (i >= particleCount) return; int p = particleIndices[firstParticle + i]; int r = rendererIndices[firstParticle + i]; // <<2 = multiply by 4 to get byte address, since a float/int is 4 bytes in size. // particle data is the same for all 4 vertices: for (uint v = i*4; v < i*4 + 4; ++v) { int base = v*23; // pos vertices.Store4(base<<2, asuint(float4(positions[p].xyz, 1))); // color: vertices.Store4((base+7)<<2, asuint(colors[p] * rendererData[r].color)); // b1, b2, b3: vertices.Store4((base+11)<<2, asuint( float4(rotate_vector(orientations[p],float3(1,0,0)),radii[p].x * radii[p].w * rendererData[r].radiusScale) )); vertices.Store4((base+15)<<2, asuint( float4(rotate_vector(orientations[p],float3(0,1,0)),radii[p].y * radii[p].w * rendererData[r].radiusScale) )); vertices.Store4((base+19)<<2, asuint( float4(rotate_vector(orientations[p],float3(0,0,1)),radii[p].z * radii[p].w * rendererData[r].radiusScale) )); } //different offset for each vertex: int base = i*4; vertices.Store3((base*23 + 4)<<2, asuint(float3(1,1,0))); vertices.Store3(((base+1)*23 + 4)<<2, asuint(float3(-1,1,0))); vertices.Store3(((base+2)*23 + 4)<<2, asuint(float3(-1,-1,0))); vertices.Store3(((base+3)*23 + 4)<<2, asuint(float3(1,-1,0))); // indices: indices.Store((i*6)<<2, asuint(i*4+2)); indices.Store((i*6+1)<<2, asuint(i*4+1)); indices.Store((i*6+2)<<2, asuint(i*4)); indices.Store((i*6+3)<<2, asuint(i*4+3)); indices.Store((i*6+4)<<2, asuint(i*4+2)); indices.Store((i*6+5)<<2, asuint(i*4)); }