HATEBIN
>
// Each #kernel tells which function to compile; you can have many kernels #pragma kernel VoxelMesh struct Triangle { float3 p0; float3 p1; float3 p2; }; // Create a RenderTexture with enableRandomWrite flag and set it // with cs.SetTexture RWTexture3D
InputVolume; AppendStructuredBuffer
triangleBuffer; float3 Resolution = float3(32, 32, 32); float3 areaSize = float3(1, 1, 1); float3 getPos(uint3 id) { float3 pos = (float3)id; pos /= Resolution; pos -= 0.5f; pos *= areaSize; return pos; } bool isSolid(uint3 id) { return InputVolume[id].x < 0; } bool IsTopSolid(uint3 id) { uint3 pos = id + uint3(0, 1, 0); return isSolid(pos); } bool IsBottomSolid(uint3 id) { uint3 pos = id + uint3(0, -1, 0); return isSolid(pos); } bool IsLeftSolid(uint3 id) { uint3 pos = id + uint3(-1, 0, 0); return isSolid(pos); } bool IsRightSolid(uint3 id) { uint3 pos = id + uint3(1, 0, 0); return isSolid(pos); } bool IsFrontSolid(uint3 id) { uint3 pos = id + uint3(0, 0, 1); return isSolid(pos); } bool IsBackSolid(uint3 id) { uint3 pos = id + uint3(0, 0, -1); return isSolid(pos); } [numthreads(8,8,8)] void VoxelMesh(uint3 id : SV_DispatchThreadID) { float3 pos = getPos(id); float3 offset = areaSize / Resolution; if (!isSolid(id)) { return; } //top face, clockwise winding order if (!IsTopSolid(id)) { Triangle topTriangle1; topTriangle1.p0 = pos + (float3(0, 1, 0) * offset); topTriangle1.p1 = pos + (float3(1, 1, 1) * offset); topTriangle1.p2 = pos + (float3(1, 1, 0) * offset); triangleBuffer.Append(topTriangle1); Triangle topTriangle2; topTriangle2.p0 = pos + (float3(0, 1, 0) * offset); topTriangle2.p1 = pos + (float3(0, 1, 1) * offset); topTriangle2.p2 = pos + (float3(1, 1, 1) * offset); triangleBuffer.Append(topTriangle2); } //bottom face, clockwise winding order if (!IsBottomSolid(id)) { Triangle bottomTriangle1; bottomTriangle1.p0 = pos + (float3(0, 0, 0) * offset); bottomTriangle1.p1 = pos + (float3(1, 0, 0) * offset); bottomTriangle1.p2 = pos + (float3(1, 0, 1) * offset); triangleBuffer.Append(bottomTriangle1); Triangle bottomTriangle2; bottomTriangle2.p0 = pos + (float3(0, 0, 0) * offset); bottomTriangle2.p1 = pos + (float3(1, 0, 1) * offset); bottomTriangle2.p2 = pos + (float3(0, 0, 1) * offset); triangleBuffer.Append(bottomTriangle2); } //left face, clockwise winding order if(!IsLeftSolid(id)) { Triangle leftTriangle1; leftTriangle1.p0 = pos + (float3(0, 0, 0) * offset); leftTriangle1.p1 = pos + (float3(0, 0, 1) * offset); leftTriangle1.p2 = pos + (float3(0, 1, 1) * offset); triangleBuffer.Append(leftTriangle1); Triangle leftTriangle2; leftTriangle2.p0 = pos + (float3(0, 0, 0) * offset); leftTriangle2.p1 = pos + (float3(0, 1, 1) * offset); leftTriangle2.p2 = pos + (float3(0, 1, 0) * offset); triangleBuffer.Append(leftTriangle2); } //right face, clockwise winding order if(!IsRightSolid(id)) { Triangle rightTriangle1; rightTriangle1.p0 = pos + (float3(1, 0, 0) * offset); rightTriangle1.p1 = pos + (float3(1, 1, 0) * offset); rightTriangle1.p2 = pos + (float3(1, 1, 1) * offset); triangleBuffer.Append(rightTriangle1); Triangle rightTriangle2; rightTriangle2.p0 = pos + (float3(1, 0, 0) * offset); rightTriangle2.p1 = pos + (float3(1, 1, 1) * offset); rightTriangle2.p2 = pos + (float3(1, 0, 1) * offset); triangleBuffer.Append(rightTriangle2); } //front face, clockwise winding order if(!IsFrontSolid(id)) { Triangle frontTriangle1; frontTriangle1.p0 = pos + (float3(0, 0, 1) * offset); frontTriangle1.p1 = pos + (float3(1, 0, 1) * offset); frontTriangle1.p2 = pos + (float3(1, 1, 1) * offset); triangleBuffer.Append(frontTriangle1); Triangle frontTriangle2; frontTriangle2.p0 = pos + (float3(0, 0, 1) * offset); frontTriangle2.p1 = pos + (float3(1, 1, 1) * offset); frontTriangle2.p2 = pos + (float3(0, 1, 1) * offset); triangleBuffer.Append(frontTriangle2); } //back face, clockwise winding order if(!IsBackSolid(id)) { Triangle backTriangle1; backTriangle1.p0 = pos + (float3(0, 0, 0) * offset); backTriangle1.p1 = pos + (float3(1, 1, 0) * offset); backTriangle1.p2 = pos + (float3(1, 0, 0) * offset); triangleBuffer.Append(backTriangle1); Triangle backTriangle2; backTriangle2.p0 = pos + (float3(0, 0, 0) * offset); backTriangle2.p1 = pos + (float3(0, 1, 0) * offset); backTriangle2.p2 = pos + (float3(1, 1, 0) * offset); triangleBuffer.Append(backTriangle2); } }