@@ -23,25 +23,17 @@ describe('uniformity test example', () => {
2323 ) ;
2424
2525 expect ( shaderCodes ) . toMatchInlineSnapshot ( `
26- "struct fullScreenTriangle_Output {
27- @builtin(position) pos: vec4f,
28- @location(0) uv: vec2f,
29- }
30-
31- @vertex fn fullScreenTriangle(@builtin(vertex_index) vertexIndex: u32) -> fullScreenTriangle_Output {
32- const pos = array<vec2f, 3>(vec2f(-1, -1), vec2f(3, -1), vec2f(-1, 3));
33- const uv = array<vec2f, 3>(vec2f(0, 1), vec2f(2, 1), vec2f(0, -1));
26+ "@group(0) @binding(0) var<uniform> sizeUniform: vec3u;
3427
35- return fullScreenTriangle_Output(vec4f(pos[vertexIndex], 0, 1), uv[vertexIndex]);
36- }
37-
38- struct fragmentShader_Input {
39- @location(0) uv: vec2f,
28+ struct Config {
29+ gridSize: f32,
30+ canvasRatio: f32,
31+ useSeed2: u32,
32+ samplesPerThread: u32,
33+ takeAverage: u32,
4034 }
4135
42- @group(0) @binding(0) var<uniform> canvasRatioUniform: f32;
43-
44- @group(0) @binding(1) var<uniform> gridSizeUniform: f32;
36+ @group(0) @binding(1) var<uniform> configUniform: Config;
4537
4638 var<private> seed: vec2f;
4739
@@ -73,21 +65,35 @@ describe('uniformity test example', () => {
7365 return sample();
7466 }
7567
76- @fragment fn fragmentShader(_arg_0: fragmentShader_Input) -> @location(0) vec4f {
77- var uv = (((_arg_0.uv + 1f) / 2f) * vec2f(canvasRatioUniform, 1f));
78- var gridedUV = floor((uv * gridSizeUniform));
79- randSeed2(gridedUV);
80- return vec4f(vec3f(randFloat01()), 1f);
81- }
82-
83- struct fragmentShader_Input_1 {
84- @location(0) uv: vec2f,
68+ @group(1) @binding(0) var texture: texture_storage_2d<r32float, write>;
69+
70+ fn computeFn(x: u32, y: u32, _arg_2: u32) {
71+ let gridSize = configUniform.gridSize;
72+ if ((configUniform.useSeed2 == 1u)) {
73+ randSeed2((vec2f(f32(x), f32(y)) + 1f));
74+ }
75+ else {
76+ randSeed(((f32((x + 1u)) * gridSize) + f32((y + 1u))));
77+ }
78+ var i = 0u;
79+ let samplesPerThread = configUniform.samplesPerThread;
80+ var samples = 0f;
81+ while ((i < (samplesPerThread - 1u))) {
82+ samples += randFloat01();
83+ i += 1u;
84+ }
85+ var result = randFloat01();
86+ if ((configUniform.takeAverage == 1u)) {
87+ result = ((result + samples) / f32(samplesPerThread));
88+ }
89+ textureStore(texture, vec2u(x, y), vec4f(result, 0f, 0f, 0f));
8590 }
8691
87- var<private> seed_1: u32;
88-
89- fn seed2_1(value: vec2f) {
90- seed_1 = u32(((value.x * 32768f) + (value.y * 1024f)));
92+ @compute @workgroup_size(16, 16, 1) fn mainCompute(@builtin(global_invocation_id) id: vec3u) {
93+ if (any(id >= sizeUniform)) {
94+ return;
95+ }
96+ computeFn(id.x, id.y, id.z);
9197 }
9298
9399 @group(0) @binding(0) var<uniform> sizeUniform: vec3u;
@@ -106,8 +112,8 @@ describe('uniformity test example', () => {
106112
107113 }
108114
109- fn hash(v : u32) -> u32 {
110- var x = (v ^ (v >> 17u));
115+ fn hash(value : u32) -> u32 {
116+ var x = (value ^ (value >> 17u));
111117 x *= 3982152891u;
112118 x ^= (x >> 11u);
113119 x *= 2890668881u;
@@ -143,11 +149,262 @@ describe('uniformity test example', () => {
143149 return sample();
144150 }
145151
146- @fragment fn fragmentShader_1(_arg_0: fragmentShader_Input_1) -> @location(0) vec4f {
147- var uv = (((_arg_0.uv + 1f) / 2f) * vec2f(canvasRatioUniform, 1f));
148- var gridedUV = floor((uv * gridSizeUniform));
149- randSeed2_1(gridedUV);
150- return vec4f(vec3f(randFloat01_1()), 1f);
152+ @group(1) @binding(0) var texture: texture_storage_2d<r32float, write>;
153+
154+ fn computeFn(x: u32, y: u32, _arg_2: u32) {
155+ let gridSize = configUniform.gridSize;
156+ if ((configUniform.useSeed2 == 1u)) {
157+ randSeed2((vec2f(f32(x), f32(y)) + 1f));
158+ }
159+ else {
160+ randSeed(((f32((x + 1u)) * gridSize) + f32((y + 1u))));
161+ }
162+ var i = 0u;
163+ let samplesPerThread = configUniform.samplesPerThread;
164+ var samples = 0f;
165+ while ((i < (samplesPerThread - 1u))) {
166+ samples += randFloat01();
167+ i += 1u;
168+ }
169+ var result = randFloat01();
170+ if ((configUniform.takeAverage == 1u)) {
171+ result = ((result + samples) / f32(samplesPerThread));
172+ }
173+ textureStore(texture, vec2u(x, y), vec4f(result, 0f, 0f, 0f));
174+ }
175+
176+ @compute @workgroup_size(16, 16, 1) fn mainCompute(@builtin(global_invocation_id) id: vec3u) {
177+ if (any(id >= sizeUniform)) {
178+ return;
179+ }
180+ computeFn(id.x, id.y, id.z);
181+ }
182+
183+ @group(0) @binding(0) var<uniform> sizeUniform: vec3u;
184+
185+ struct Config {
186+ gridSize: f32,
187+ canvasRatio: f32,
188+ useSeed2: u32,
189+ samplesPerThread: u32,
190+ takeAverage: u32,
191+ }
192+
193+ @group(0) @binding(1) var<uniform> configUniform: Config;
194+
195+ fn hash(value: u32) -> u32 {
196+ var x = (value ^ (value >> 17u));
197+ x *= 3982152891u;
198+ x ^= (x >> 11u);
199+ x *= 2890668881u;
200+ x ^= (x >> 15u);
201+ x *= 830770091u;
202+ x ^= (x >> 14u);
203+ return x;
204+ }
205+
206+ fn rotl(x: u32, k: u32) -> u32 {
207+ return ((x << k) | (x >> (32u - k)));
208+ }
209+
210+ var<private> seed: vec2u;
211+
212+ fn seed2(value: vec2f) {
213+ let hx = hash((u32(value.x) ^ 2135587861u));
214+ let hy = hash((u32(value.y) ^ 2654435769u));
215+ seed = vec2u(hash((hx ^ hy)), hash((rotl(hx, 16u) ^ hy)));
216+ }
217+
218+ fn randSeed2(seed: vec2f) {
219+ seed2(seed);
220+ }
221+
222+ fn randSeed(seed_1: f32) {
223+
224+ }
225+
226+ fn u64Mul(a: vec2u, b: vec2u) -> vec2u {
227+ let all_1 = (a.x & 65535u);
228+ let alh = (a.x >> 16u);
229+ let ahl = (a.y & 65535u);
230+ let ahh = (a.y >> 16u);
231+ let bll = (b.x & 65535u);
232+ let blh = (b.x >> 16u);
233+ let bhl = (b.y & 65535u);
234+ let bhh = (b.y >> 16u);
235+ let row0_0 = (bll * all_1);
236+ let row0_1 = (bll * alh);
237+ let row0_2 = (bll * ahl);
238+ let row0_3 = (bll * ahh);
239+ let row1_0 = (blh * all_1);
240+ let row1_1 = (blh * alh);
241+ let row1_2 = (blh * ahl);
242+ let row2_0 = (bhl * all_1);
243+ let row2_1 = (bhl * alh);
244+ let row3_0 = (bhh * all_1);
245+ let r1 = (row0_0 & 65535u);
246+ var r2 = (((row0_0 >> 16u) + (row0_1 & 65535u)) + (row1_0 & 65535u));
247+ var r3 = (((((row0_1 >> 16u) + (row0_2 & 65535u)) + (row1_0 >> 16u)) + (row1_1 & 65535u)) + (row2_0 & 65535u));
248+ var r4 = (((((((row0_2 >> 16u) + (row0_3 & 65535u)) + (row1_1 >> 16u)) + (row1_2 & 65535u)) + (row2_0 >> 16u)) + (row2_1 & 65535u)) + (row3_0 & 65535u));
249+ r3 += (r2 >> 16u);
250+ r2 &= 65535u;
251+ r4 += (r3 >> 16u);
252+ r3 &= 65535u;
253+ r4 &= 65535u;
254+ return vec2u((r1 | (r2 << 16u)), (r3 | (r4 << 16u)));
255+ }
256+
257+ fn u64Add(a: vec2u, b: vec2u) -> vec2u {
258+ let rl = (a.x + b.x);
259+ let carry = u32(((rl < a.x) && (rl < b.x)));
260+ let rh = ((a.y + b.y) + carry);
261+ return vec2u(rl, rh);
262+ }
263+
264+ fn u32To01F32(value: u32) -> f32 {
265+ let mantissa = (value >> 9u);
266+ let bits = (1065353216u | mantissa);
267+ let f = bitcast<f32>(bits);
268+ return (f - 1f);
269+ }
270+
271+ fn sample() -> f32 {
272+ seed = u64Add(u64Mul(seed, vec2u(1284865837, 1481765933)), vec2u(1, 0));
273+ return u32To01F32(seed.y);
274+ }
275+
276+ fn randFloat01() -> f32 {
277+ return sample();
278+ }
279+
280+ @group(1) @binding(0) var texture: texture_storage_2d<r32float, write>;
281+
282+ fn computeFn(x: u32, y: u32, _arg_2: u32) {
283+ let gridSize = configUniform.gridSize;
284+ if ((configUniform.useSeed2 == 1u)) {
285+ randSeed2((vec2f(f32(x), f32(y)) + 1f));
286+ }
287+ else {
288+ randSeed(((f32((x + 1u)) * gridSize) + f32((y + 1u))));
289+ }
290+ var i = 0u;
291+ let samplesPerThread = configUniform.samplesPerThread;
292+ var samples = 0f;
293+ while ((i < (samplesPerThread - 1u))) {
294+ samples += randFloat01();
295+ i += 1u;
296+ }
297+ var result = randFloat01();
298+ if ((configUniform.takeAverage == 1u)) {
299+ result = ((result + samples) / f32(samplesPerThread));
300+ }
301+ textureStore(texture, vec2u(x, y), vec4f(result, 0f, 0f, 0f));
302+ }
303+
304+ @compute @workgroup_size(16, 16, 1) fn mainCompute(@builtin(global_invocation_id) id: vec3u) {
305+ if (any(id >= sizeUniform)) {
306+ return;
307+ }
308+ computeFn(id.x, id.y, id.z);
309+ }
310+
311+ @group(0) @binding(0) var<uniform> sizeUniform: vec3u;
312+
313+ struct Config {
314+ gridSize: f32,
315+ canvasRatio: f32,
316+ useSeed2: u32,
317+ samplesPerThread: u32,
318+ takeAverage: u32,
319+ }
320+
321+ @group(0) @binding(1) var<uniform> configUniform: Config;
322+
323+ fn hash(value: u32) -> u32 {
324+ var x = (value ^ (value >> 17u));
325+ x *= 3982152891u;
326+ x ^= (x >> 11u);
327+ x *= 2890668881u;
328+ x ^= (x >> 15u);
329+ x *= 830770091u;
330+ x ^= (x >> 14u);
331+ return x;
332+ }
333+
334+ fn rotl(x: u32, k: u32) -> u32 {
335+ return ((x << k) | (x >> (32u - k)));
336+ }
337+
338+ var<private> seed: vec2u;
339+
340+ fn seed2(value: vec2f) {
341+ let hx = hash((u32(value.x) ^ 2135587861u));
342+ let hy = hash((u32(value.y) ^ 2654435769u));
343+ seed = vec2u(hash((hx ^ hy)), hash((rotl(hx, 16u) ^ hy)));
344+ }
345+
346+ fn randSeed2(seed: vec2f) {
347+ seed2(seed);
348+ }
349+
350+ fn randSeed(seed_1: f32) {
351+
352+ }
353+
354+ fn next() -> u32 {
355+ let s0 = seed[0i];
356+ var s1 = seed[1i];
357+ s1 ^= s0;
358+ seed[0i] = ((rotl(s0, 26u) ^ s1) ^ (s1 << 9u));
359+ seed[1i] = rotl(s1, 13u);
360+ return (rotl((seed[0i] * 2654435771u), 5u) * 5u);
361+ }
362+
363+ fn u32To01F32(value: u32) -> f32 {
364+ let mantissa = (value >> 9u);
365+ let bits = (1065353216u | mantissa);
366+ let f = bitcast<f32>(bits);
367+ return (f - 1f);
368+ }
369+
370+ fn sample() -> f32 {
371+ let r = next();
372+ return u32To01F32(r);
373+ }
374+
375+ fn randFloat01() -> f32 {
376+ return sample();
377+ }
378+
379+ @group(1) @binding(0) var texture: texture_storage_2d<r32float, write>;
380+
381+ fn computeFn(x: u32, y: u32, _arg_2: u32) {
382+ let gridSize = configUniform.gridSize;
383+ if ((configUniform.useSeed2 == 1u)) {
384+ randSeed2((vec2f(f32(x), f32(y)) + 1f));
385+ }
386+ else {
387+ randSeed(((f32((x + 1u)) * gridSize) + f32((y + 1u))));
388+ }
389+ var i = 0u;
390+ let samplesPerThread = configUniform.samplesPerThread;
391+ var samples = 0f;
392+ while ((i < (samplesPerThread - 1u))) {
393+ samples += randFloat01();
394+ i += 1u;
395+ }
396+ var result = randFloat01();
397+ if ((configUniform.takeAverage == 1u)) {
398+ result = ((result + samples) / f32(samplesPerThread));
399+ }
400+ textureStore(texture, vec2u(x, y), vec4f(result, 0f, 0f, 0f));
401+ }
402+
403+ @compute @workgroup_size(16, 16, 1) fn mainCompute(@builtin(global_invocation_id) id: vec3u) {
404+ if (any(id >= sizeUniform)) {
405+ return;
406+ }
407+ computeFn(id.x, id.y, id.z);
151408 }"
152409 ` ) ;
153410 } ) ;
0 commit comments