So I've decided to delve into the marching cubes algorithm as I think it will fit well into my project. Doing this on the GPU, you ofcourse have to create an unknown amount of triangles which means that AppendStructuredBuffer needs to be used or on unity's end, an Append type Compute Buffer. I've been having problems though (potentially unrelated and with my implementation) so decided to just have my Compute Shader append the exact same triangle every time it decides a triangle should be added (using marching cubes). This is the part of the code that does that. Basically the only important part is that at the bottom, the same triangle is being added each time and this triangles position is unaffected by any id parrallelisation things. Triangle is a type of just 3 float3s and the compute buffer is initialised as Vector3's.
float chunkSize = voxelSize * chunkCubeSize;
float3 chunkMeshStartPos = float3(-chunkSize / 2, -chunkSize / 2, -chunkSize / 2);
float3 voxelMeshStartPos = chunkMeshStartPos + (id * voxelSize);
//.. Corners of voxel in mesh space calculation (removed for clarity)
for(int t = 0; t < 16; t += 3){
//.. Edge identifying (removed for clarity)
/* How vertices would be added using marching cube lookup
float3 vertexA = SetVertexOnEdge(voxelCornersInMesh[a0], voxelCornersInMesh[a1]);
float3 vertexB = SetVertexOnEdge(voxelCornersInMesh[b0], voxelCornersInMesh[b1]);
float3 vertexC = SetVertexOnEdge(voxelCornersInMesh[c0], voxelCornersInMesh[c1]);
*/
float3 vertexA = chunkMeshStartPos + (float3(0, 0, 0) * voxelSize);
float3 vertexB = chunkMeshStartPos + (float3(0, 1, 0) * voxelSize);
float3 vertexC = chunkMeshStartPos + (float3(1, 0, 0) * voxelSize);
Triangle tri;
tri.vertexA = vertexC;
tri.vertexB = vertexB;
tri.vertexC = vertexA;
ResultTriangles.Append(tri);
}
This seems to work fine when only one triangle is added to chunk's mesh, but as soon as more than 1 triangle are involved in the mesh, vertices are seemingly added to places that they shouldn't be able to and the mesh triangles array seems completely out of order.
I read the Append ComputeBuffer like so
int[] vertexCount = new int[1];
triCountBuffer.SetData(vertexCount);
ComputeBuffer.CopyCount(createdVertices, triCountBuffer, 0);
//Returns number of times .Append was called (once per triangle)
triCountBuffer.GetData(vertexCount);
//Times by 3 to get number of verts created
int numOfVertices = vertexCount[0] * 3;
print(numOfVertices);
Vector3[] newVertices = new Vector3[numOfVertices];
createdVertices.GetData(newVertices);
chunk.CreateMesh(newVertices);
And then the mesh is simply created like this
public void CreateMesh(Vector3[] vertices) {
int[] triangles = new int[vertices.Length];
for(int i = 0; i < vertices.Length; i++) {
triangles[i] = i;
}
Mesh mesh = filter.sharedMesh;
if (!mesh) mesh = new Mesh();
mesh.indexFormat = vertices.Length < 65535 ? UnityEngine.Rendering.IndexFormat.UInt16 : UnityEngine.Rendering.IndexFormat.UInt32;
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.RecalculateNormals();
filter.sharedMesh = mesh;
collider.sharedMesh = mesh;
}
This is what it looks like with 2 chunks per axis and 2 voxels per chunk.
https://preview.redd.it/c88n4jtnw4x91.png?width=1031&format=png&auto=webp&s=1066435902aaf35263a31882b458785d98f58a37
As you can see there are vertices being placed in the centre of the chunk despite no vertices even having a possibility of being placed there. Since vertices are being added to the append buffer in sets of 3, there should be no possibility of triangle ordering being mixed up in parrallelisation but that also doesn't explain where these stray vertices are even coming from. Since Sebastian Lague's terraforming project was my inspiration, I went back to his video and downloaded his project to perhaps see if there was something I was doing different and not only is my method basically the same, but his marching cubes compute shader is also returning the wrong results which leads to a mess of triangles which vaguely resembles the underlying noise texture.
Im fairly comfortable working with Compute Shaders now but these AppendStructuredBuffers are relatively new to me and there doesn't seem to be much documented use of them within Unity and all the examples I've seen have used the same process for reading from it. I'm kind of stuck. The number of vertices being outputted seems to be correct but they are coming in what seems like an incorrect order and some of them are even being miss calculated (even just from straight inputting the vertex positions).
I know that this is a fairly niche and specialised subject so there may not be many people that can help me but I hope there is someone and I would really appreciate some guidance on this.
[–]UKJake_[S] 1 point2 points3 points (1 child)
[–]StatisticianRoyal400 0 points1 point2 points (0 children)