blob: b2602297fc5c6a73bcfbe8dabb268b971d1cc2e4 [file] [log] [blame]
Ben Clayton73ced332022-01-21 22:38:16 +00001uint 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
7ByteAddressBuffer tables : register(t0, space0);
8
9RWByteAddressBuffer volume : register(u1, space0);
10
11RWByteAddressBuffer positionsOut : register(u2, space0);
12
13RWByteAddressBuffer normalsOut : register(u3, space0);
14
15RWByteAddressBuffer indicesOut : register(u4, space0);
16
17RWByteAddressBuffer drawOut : register(u5, space0);
18
19float 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
27float3 positionAt(uint3 index) {
28 return (asfloat(volume.Load3(0u)) + (asfloat(volume.Load3(32u)) * float3(index.xyz)));
29}
30
31float3 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
35static float3 positions[12] = (float3[12])0;
36static float3 normals[12] = (float3[12])0;
37static uint indices[12] = (uint[12])0;
38static uint cubeVerts = 0u;
39
40void 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
50void 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
60void 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
70struct tint_symbol_1 {
71 uint3 global_id : SV_DispatchThreadID;
72};
73
74void 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)]
182void computeMain(tint_symbol_1 tint_symbol) {
183 computeMain_inner(tint_symbol.global_id);
184 return;
185}