At this point I’ve reached a dead end. I need to use the AppendStructuredBuffer as you can never be sure what index or how many triangles each thread will be adding. I have found no way of fixing this to far. Here is the rest of my code. I know its ugly and unclean, I’m just trying to see why this example doesn’t work.
Main Code
private void CreateBuffers() {
int numPoints = voxelResolution * voxelResolution;
int numVoxelsPerResolution = voxelResolution - 1;
int numVoxels = numVoxelsPerResolution * numVoxelsPerResolution;
int maxTriangleCount = numVoxels * 3;
Debug.Log(verticeBuffer);
if (!Application.isPlaying || (verticeBuffer == null || numPoints != verticeBuffer.count)) {
if (Application.isPlaying) {
ReleaseBuffers();
}
verticeBuffer = new ComputeBuffer(numPoints, sizeof(float) * 3);
triangleBuffer = new ComputeBuffer(maxTriangleCount, sizeof(float) * 2 * 3 * 2, ComputeBufferType.Append);
triCountBuffer = new ComputeBuffer(1, sizeof(int), ComputeBufferType.Raw);
stateBuffer = new ComputeBuffer(numPoints, sizeof(int));
}
}
public void TriangulateChunk(VoxelChunk chunk) {
chunk.mesh.Clear();
// Compute Shader Here
int numThreadsPerResolution = Mathf.CeilToInt(voxelResolution / threadSize);
triangleBuffer.SetCounterValue(0);
shader.SetBuffer(0, "_Vertices", verticeBuffer);
shader.SetBuffer(0, "_Triangles", triangleBuffer);
shader.SetBuffer(0, "_States", stateBuffer);
shader.SetInt("_Resolution", voxelResolution);
for (int i = 0; i < chunk.voxels.Length; i++) {
statePositions[i] = chunk.voxels[i].state ? 1 : 0;
}
stateBuffer.SetData(statePositions);
shader.Dispatch(0, numThreadsPerResolution, numThreadsPerResolution, 1);
ComputeBuffer.CopyCount(triangleBuffer, triCountBuffer, 0);
int[] triCountArray = { 0 };
triCountBuffer.GetData(triCountArray);
int numTris = triCountArray[0];
Triangle[] tris = new Triangle[numTris];
triangleBuffer.GetData(tris, 0, 0, numTris);
var vertices = new Vector3[numTris * 3];
var triangles = new int[numTris * 3];
for (int i = 0; i < numTris; i++) {
for (int j = 0; j < 3; j++) {
triangles[i * 3 + j] = i * 3 + j;
vertices[i * 3 + j] = tris[i][j];
}
}
chunk.mesh.vertices = vertices;
chunk.mesh.triangles = triangles;
chunk.mesh.RecalculateNormals();
}
Compute Shader
#pragma kernel CSMain
struct Triangle {
float2 vertexA;
float2 vertexB;
float2 vertexC;
};
int edges[16] = {
0x0,
0x3,
0x6,
0x5,
0x12,
0x15,
0x10,
0x9,
0x9,
0x10,
0x15,
0x12,
0x5,
0x6,
0x3,
0x0
};
int triangulation[16][9] = {
{-1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 1, 4, -1, -1, -1, -1, -1, -1},
{1, 2, 5, -1, -1, -1, -1, -1, -1},
{0, 2, 4, 4, 2, 5, -1, -1, -1},
{2, 3, 6, -1, -1, -1, -1, -1, -1},
{0, 1, 4, 2, 3, 6, -1, -1, -1},
{1, 3, 5, 5, 6, 3, -1, -1, -1},
{0, 4, 5, 0, 3, 5, 3, 5, 6},
{0, 3, 7, -1, -1, -1, -1, -1, -1},
{1, 3, 4, 4, 7, 3, -1, -1, -1},
{0, 3, 7, 1, 2, 5, -1, -1, -1},
{3, 7, 4, 3, 2, 4, 2, 5, 4},
{0, 2, 7, 7, 6, 2, -1, -1, -1},
{1, 2, 7, 1, 7, 4, 2, 7, 6},
{0, 1, 6, 0, 6, 7, 1, 6, 5},
{-1, -1, -1, -1, -1, -1, -1, -1, -1}
};
int relativeOffsets[8][2] = {
{0, 0},
{0, 1},
{1, 0},
{1, 1},
{0, 0.5},
{0.5, 0},
{1, 0.5},
{0.5, 1}
};
RWStructuredBuffer<float3> _Vertices;
AppendStructuredBuffer<Triangle> _Triangles;
RWStructuredBuffer<uint> _States;
uint _Resolution;
int2 GetUV (int3 id) {
return id.xy;
}
int indexFromCoord(int x, int y) {
return y * _Resolution + x;
}
void TriangulateCellRows(int2 uv) {
if (uv.x >= _Resolution-1 || uv.y >= _Resolution-1) {
return;
}
int squareCornerStates[4] = {
_States[indexFromCoord(uv.x, uv.y)],
_States[indexFromCoord(uv.x + 1, uv.y)],
_States[indexFromCoord(uv.x, uv.y + 1)],
_States[indexFromCoord(uv.x + 1, uv.y + 1)],
};
int cellType = 0;
if (squareCornerStates[0] == 1) cellType |= 1;
if (squareCornerStates[1] == 1) cellType |= 2;
if (squareCornerStates[2] == 1) cellType |= 4;
if (squareCornerStates[3] == 1) cellType |= 8;
for(int i = 0; triangulation[cellType][i] != -1; i +=3) {
Triangle tri;
tri.vertexA = float2(uv.x + relativeOffsets[triangulation[cellType][i]][0], uv.y + relativeOffsets[triangulation[cellType][i]][1]);
tri.vertexB = float2(uv.x + relativeOffsets[triangulation[cellType][i+1]][0], uv.y + relativeOffsets[triangulation[cellType][i+1]][1]);
tri.vertexC = float2(uv.x + relativeOffsets[triangulation[cellType][i+2]][0], uv.y + relativeOffsets[triangulation[cellType][i+2]][1]);
_Triangles.Append(tri);
}
}
[numthreads(8,8,1)]
void CSMain (int3 id : SV_DispatchThreadID)
{
int2 uv = GetUV(id);
TriangulateCellRows(uv);
}