Ben Clayton | 73ced33 | 2022-01-21 22:38:16 +0000 | [diff] [blame^] | 1 | uint atomicAdd_1(RWByteAddressBuffer buffer, uint offset, uint value) { |
| 2 | uint original_value = 0; |
| 3 | buffer.InterlockedAdd(offset, value, original_value); |
| 4 | return original_value; |
| 5 | } |
| 6 | |
| 7 | ByteAddressBuffer tables : register(t0, space0); |
| 8 | |
| 9 | RWByteAddressBuffer volume : register(u1, space0); |
| 10 | |
| 11 | RWByteAddressBuffer positionsOut : register(u2, space0); |
| 12 | |
| 13 | RWByteAddressBuffer normalsOut : register(u3, space0); |
| 14 | |
| 15 | RWByteAddressBuffer indicesOut : register(u4, space0); |
| 16 | |
| 17 | RWByteAddressBuffer drawOut : register(u5, space0); |
| 18 | |
| 19 | float valueAt(uint3 index) { |
| 20 | if (any((index >= volume.Load3(48u)))) { |
| 21 | return 0.0f; |
| 22 | } |
| 23 | const uint valueIndex = ((index.x + (index.y * volume.Load(48u))) + ((index.z * volume.Load(48u)) * volume.Load(52u))); |
| 24 | return asfloat(volume.Load((64u + (4u * valueIndex)))); |
| 25 | } |
| 26 | |
| 27 | float3 positionAt(uint3 index) { |
| 28 | return (asfloat(volume.Load3(0u)) + (asfloat(volume.Load3(32u)) * float3(index.xyz))); |
| 29 | } |
| 30 | |
| 31 | float3 normalAt(uint3 index) { |
| 32 | return float3((valueAt((index - uint3(1u, 0u, 0u))) - valueAt((index + uint3(1u, 0u, 0u)))), (valueAt((index - uint3(0u, 1u, 0u))) - valueAt((index + uint3(0u, 1u, 0u)))), (valueAt((index - uint3(0u, 0u, 1u))) - valueAt((index + uint3(0u, 0u, 1u))))); |
| 33 | } |
| 34 | |
| 35 | static float3 positions[12] = (float3[12])0; |
| 36 | static float3 normals[12] = (float3[12])0; |
| 37 | static uint indices[12] = (uint[12])0; |
| 38 | static uint cubeVerts = 0u; |
| 39 | |
| 40 | void interpX(uint index, uint3 i, float va, float vb) { |
| 41 | const float mu = ((asfloat(volume.Load(60u)) - va) / (vb - va)); |
| 42 | positions[cubeVerts] = (positionAt(i) + float3((asfloat(volume.Load(32u)) * mu), 0.0f, 0.0f)); |
| 43 | const float3 na = normalAt(i); |
| 44 | const float3 nb = normalAt((i + uint3(1u, 0u, 0u))); |
| 45 | normals[cubeVerts] = lerp(na, nb, float3(mu, mu, mu)); |
| 46 | indices[index] = cubeVerts; |
| 47 | cubeVerts = (cubeVerts + 1u); |
| 48 | } |
| 49 | |
| 50 | void interpY(uint index, uint3 i, float va, float vb) { |
| 51 | const float mu = ((asfloat(volume.Load(60u)) - va) / (vb - va)); |
| 52 | positions[cubeVerts] = (positionAt(i) + float3(0.0f, (asfloat(volume.Load(36u)) * mu), 0.0f)); |
| 53 | const float3 na = normalAt(i); |
| 54 | const float3 nb = normalAt((i + uint3(0u, 1u, 0u))); |
| 55 | normals[cubeVerts] = lerp(na, nb, float3(mu, mu, mu)); |
| 56 | indices[index] = cubeVerts; |
| 57 | cubeVerts = (cubeVerts + 1u); |
| 58 | } |
| 59 | |
| 60 | void interpZ(uint index, uint3 i, float va, float vb) { |
| 61 | const float mu = ((asfloat(volume.Load(60u)) - va) / (vb - va)); |
| 62 | positions[cubeVerts] = (positionAt(i) + float3(0.0f, 0.0f, (asfloat(volume.Load(40u)) * mu))); |
| 63 | const float3 na = normalAt(i); |
| 64 | const float3 nb = normalAt((i + uint3(0u, 0u, 1u))); |
| 65 | normals[cubeVerts] = lerp(na, nb, float3(mu, mu, mu)); |
| 66 | indices[index] = cubeVerts; |
| 67 | cubeVerts = (cubeVerts + 1u); |
| 68 | } |
| 69 | |
| 70 | struct tint_symbol_1 { |
| 71 | uint3 global_id : SV_DispatchThreadID; |
| 72 | }; |
| 73 | |
| 74 | void computeMain_inner(uint3 global_id) { |
| 75 | const uint3 i0 = global_id; |
| 76 | const uint3 i1 = (global_id + uint3(1u, 0u, 0u)); |
| 77 | const uint3 i2 = (global_id + uint3(1u, 1u, 0u)); |
| 78 | const uint3 i3 = (global_id + uint3(0u, 1u, 0u)); |
| 79 | const uint3 i4 = (global_id + uint3(0u, 0u, 1u)); |
| 80 | const uint3 i5 = (global_id + uint3(1u, 0u, 1u)); |
| 81 | const uint3 i6 = (global_id + uint3(1u, 1u, 1u)); |
| 82 | const uint3 i7 = (global_id + uint3(0u, 1u, 1u)); |
| 83 | const float v0 = valueAt(i0); |
| 84 | const float v1 = valueAt(i1); |
| 85 | const float v2 = valueAt(i2); |
| 86 | const float v3 = valueAt(i3); |
| 87 | const float v4 = valueAt(i4); |
| 88 | const float v5 = valueAt(i5); |
| 89 | const float v6 = valueAt(i6); |
| 90 | const float v7 = valueAt(i7); |
| 91 | uint cubeIndex = 0u; |
| 92 | if ((v0 < asfloat(volume.Load(60u)))) { |
| 93 | cubeIndex = (cubeIndex | 1u); |
| 94 | } |
| 95 | if ((v1 < asfloat(volume.Load(60u)))) { |
| 96 | cubeIndex = (cubeIndex | 2u); |
| 97 | } |
| 98 | if ((v2 < asfloat(volume.Load(60u)))) { |
| 99 | cubeIndex = (cubeIndex | 4u); |
| 100 | } |
| 101 | if ((v3 < asfloat(volume.Load(60u)))) { |
| 102 | cubeIndex = (cubeIndex | 8u); |
| 103 | } |
| 104 | if ((v4 < asfloat(volume.Load(60u)))) { |
| 105 | cubeIndex = (cubeIndex | 16u); |
| 106 | } |
| 107 | if ((v5 < asfloat(volume.Load(60u)))) { |
| 108 | cubeIndex = (cubeIndex | 32u); |
| 109 | } |
| 110 | if ((v6 < asfloat(volume.Load(60u)))) { |
| 111 | cubeIndex = (cubeIndex | 64u); |
| 112 | } |
| 113 | if ((v7 < asfloat(volume.Load(60u)))) { |
| 114 | cubeIndex = (cubeIndex | 128u); |
| 115 | } |
| 116 | const uint edges = tables.Load((4u * cubeIndex)); |
| 117 | if (((edges & 1u) != 0u)) { |
| 118 | interpX(0u, i0, v0, v1); |
| 119 | } |
| 120 | if (((edges & 2u) != 0u)) { |
| 121 | interpY(1u, i1, v1, v2); |
| 122 | } |
| 123 | if (((edges & 4u) != 0u)) { |
| 124 | interpX(2u, i3, v3, v2); |
| 125 | } |
| 126 | if (((edges & 8u) != 0u)) { |
| 127 | interpY(3u, i0, v0, v3); |
| 128 | } |
| 129 | if (((edges & 16u) != 0u)) { |
| 130 | interpX(4u, i4, v4, v5); |
| 131 | } |
| 132 | if (((edges & 32u) != 0u)) { |
| 133 | interpY(5u, i5, v5, v6); |
| 134 | } |
| 135 | if (((edges & 64u) != 0u)) { |
| 136 | interpX(6u, i7, v7, v6); |
| 137 | } |
| 138 | if (((edges & 128u) != 0u)) { |
| 139 | interpY(7u, i4, v4, v7); |
| 140 | } |
| 141 | if (((edges & 256u) != 0u)) { |
| 142 | interpZ(8u, i0, v0, v4); |
| 143 | } |
| 144 | if (((edges & 512u) != 0u)) { |
| 145 | interpZ(9u, i1, v1, v5); |
| 146 | } |
| 147 | if (((edges & 1024u) != 0u)) { |
| 148 | interpZ(10u, i2, v2, v6); |
| 149 | } |
| 150 | if (((edges & 2048u) != 0u)) { |
| 151 | interpZ(11u, i3, v3, v7); |
| 152 | } |
| 153 | const uint triTableOffset = ((cubeIndex << 4u) + 1u); |
| 154 | const uint indexCount = uint(asint(tables.Load((1024u + (4u * (triTableOffset - 1u)))))); |
| 155 | uint firstVertex = atomicAdd_1(drawOut, 4u, cubeVerts); |
| 156 | const uint bufferOffset = ((global_id.x + (global_id.y * volume.Load(48u))) + ((global_id.z * volume.Load(48u)) * volume.Load(52u))); |
| 157 | const uint firstIndex = (bufferOffset * 15u); |
| 158 | { |
| 159 | [loop] for(uint i = 0u; (i < cubeVerts); i = (i + 1u)) { |
| 160 | positionsOut.Store((4u * ((firstVertex * 3u) + (i * 3u))), asuint(positions[i].x)); |
| 161 | positionsOut.Store((4u * (((firstVertex * 3u) + (i * 3u)) + 1u)), asuint(positions[i].y)); |
| 162 | positionsOut.Store((4u * (((firstVertex * 3u) + (i * 3u)) + 2u)), asuint(positions[i].z)); |
| 163 | normalsOut.Store((4u * ((firstVertex * 3u) + (i * 3u))), asuint(normals[i].x)); |
| 164 | normalsOut.Store((4u * (((firstVertex * 3u) + (i * 3u)) + 1u)), asuint(normals[i].y)); |
| 165 | normalsOut.Store((4u * (((firstVertex * 3u) + (i * 3u)) + 2u)), asuint(normals[i].z)); |
| 166 | } |
| 167 | } |
| 168 | { |
| 169 | [loop] for(uint i = 0u; (i < indexCount); i = (i + 1u)) { |
| 170 | const int index = asint(tables.Load((1024u + (4u * (triTableOffset + i))))); |
| 171 | indicesOut.Store((4u * (firstIndex + i)), asuint((firstVertex + indices[index]))); |
| 172 | } |
| 173 | } |
| 174 | { |
| 175 | [loop] for(uint i = indexCount; (i < 15u); i = (i + 1u)) { |
| 176 | indicesOut.Store((4u * (firstIndex + i)), asuint(firstVertex)); |
| 177 | } |
| 178 | } |
| 179 | } |
| 180 | |
| 181 | [numthreads(4, 4, 4)] |
| 182 | void computeMain(tint_symbol_1 tint_symbol) { |
| 183 | computeMain_inner(tint_symbol.global_id); |
| 184 | return; |
| 185 | } |