@woosh/meep-engine 3.7.0 → 3.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/package.json +1 -1
  2. package/src/engine/physics/ccd/linear_sweep.d.ts +19 -4
  3. package/src/engine/physics/ccd/linear_sweep.d.ts.map +1 -1
  4. package/src/engine/physics/ccd/linear_sweep.js +214 -6
  5. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  6. package/src/engine/physics/ecs/PhysicsSystem.js +2277 -2266
  7. package/src/shade/renderer/rasterize/native/oit/shader_oit_blend.d.ts.map +1 -1
  8. package/src/shade/renderer/rasterize/native/oit/shader_oit_blend.js +5 -4
  9. package/src/shade/renderer/shader/chunk/math/chunk_magnitude_floor.d.ts +9 -0
  10. package/src/shade/renderer/shader/chunk/math/chunk_magnitude_floor.d.ts.map +1 -0
  11. package/src/shade/renderer/shader/chunk/math/chunk_magnitude_floor.js +16 -0
  12. package/src/shade/renderer/shader/chunk/math/complex/chunk_complex_magnitude_floor.d.ts +10 -0
  13. package/src/shade/renderer/shader/chunk/math/complex/chunk_complex_magnitude_floor.d.ts.map +1 -0
  14. package/src/shade/renderer/shader/chunk/math/complex/chunk_complex_magnitude_floor.js +17 -0
  15. package/src/shade/renderer/shader/chunk/math/complex/chunk_complex_solve_cubic_blinn.d.ts.map +1 -1
  16. package/src/shade/renderer/shader/chunk/math/complex/chunk_complex_solve_cubic_blinn.js +7 -1
  17. package/src/shade/renderer/shader/chunk/math/complex/chunk_complex_square_root.d.ts.map +1 -1
  18. package/src/shade/renderer/shader/chunk/math/complex/chunk_complex_square_root.js +9 -3
  19. package/src/shade/renderer/shader/chunk/math/polynomial/chunk_solve_cubic.d.ts.map +1 -1
  20. package/src/shade/renderer/shader/chunk/math/polynomial/chunk_solve_cubic.js +13 -7
  21. package/src/shade/renderer/shader/chunk/math/polynomial/chunk_solve_cubic_blinn_smallest.d.ts.map +1 -1
  22. package/src/shade/renderer/shader/chunk/math/polynomial/chunk_solve_cubic_blinn_smallest.js +13 -4
  23. package/src/shade/renderer/shader/chunk/math/polynomial/chunk_solve_quadratic.d.ts.map +1 -1
  24. package/src/shade/renderer/shader/chunk/math/polynomial/chunk_solve_quadratic.js +20 -13
  25. package/src/shade/renderer/shader/chunk/math/polynomial/chunk_solve_quartic_neumark.d.ts.map +1 -1
  26. package/src/shade/renderer/shader/chunk/math/polynomial/chunk_solve_quartic_neumark.js +8 -4
  27. package/src/shade/renderer/shader/chunk/mboit/NOTES.md +35 -1
  28. package/src/shade/renderer/shader/chunk/mboit/moments/geometric/chunk_compute_transmittance_from_2_trigonometric_moments.d.ts.map +1 -1
  29. package/src/shade/renderer/shader/chunk/mboit/moments/geometric/chunk_compute_transmittance_from_2_trigonometric_moments.js +18 -5
  30. package/src/shade/renderer/shader/chunk/mboit/moments/geometric/chunk_compute_transmittance_from_3_trigonometric_moments.d.ts.map +1 -1
  31. package/src/shade/renderer/shader/chunk/mboit/moments/geometric/chunk_compute_transmittance_from_3_trigonometric_moments.js +21 -8
  32. package/src/shade/renderer/shader/chunk/mboit/moments/geometric/chunk_compute_transmittance_from_4_trigonometric_moments.d.ts.map +1 -1
  33. package/src/shade/renderer/shader/chunk/mboit/moments/geometric/chunk_compute_transmittance_from_4_trigonometric_moments.js +25 -12
  34. package/src/shade/renderer/shader/chunk/mboit/moments/geometric/chunk_generate_trigonometric_moments_4.d.ts +6 -2
  35. package/src/shade/renderer/shader/chunk/mboit/moments/geometric/chunk_generate_trigonometric_moments_4.d.ts.map +1 -1
  36. package/src/shade/renderer/shader/chunk/mboit/moments/geometric/chunk_generate_trigonometric_moments_4.js +42 -35
  37. package/src/shade/renderer/shader/chunk/mboit/moments/power/chunk_compute_transmittance_from_4_power_moments.d.ts.map +1 -1
  38. package/src/shade/renderer/shader/chunk/mboit/moments/power/chunk_compute_transmittance_from_4_power_moments.js +18 -5
  39. package/src/shade/renderer/shader/chunk/mboit/moments/power/chunk_compute_transmittance_from_6_power_moments.d.ts.map +1 -1
  40. package/src/shade/renderer/shader/chunk/mboit/moments/power/chunk_compute_transmittance_from_6_power_moments.js +24 -9
  41. package/src/shade/renderer/shader/chunk/mboit/moments/power/chunk_compute_transmittance_from_8_power_moments.d.ts.map +1 -1
  42. package/src/shade/renderer/shader/chunk/mboit/moments/power/chunk_compute_transmittance_from_8_power_moments.js +29 -13
  43. package/src/shade/renderer/shader/chunk/mboit/moments/power/chunk_generate_power_moments_4.d.ts +12 -0
  44. package/src/shade/renderer/shader/chunk/mboit/moments/power/chunk_generate_power_moments_4.d.ts.map +1 -1
  45. package/src/shade/renderer/shader/chunk/mboit/moments/power/chunk_generate_power_moments_4.js +38 -48
@@ -1,35 +1,42 @@
1
- import { CodeChunk } from "../../../../compiler/CodeChunk.js";
2
- import { chunk_complex_multiply } from "../../../math/complex/chunk_complex_multiply.js";
3
-
4
- /**
5
- * This function handles the actual computation of the new vector of
6
- * trigonometric moments for NUM_MOMENTS = 4 with SINGLE_PRECISION = true.
7
- * @see https://github.com/AlicesoftHumika/UnityOIT/blob/612c3c04263acb22980f33fa3cb2d3653ed389ff/Assets/Shader/MBOIT/MomentOIT.hlsli#L123
8
- * @type {CodeChunk}
9
- */
10
- export const chunk_generate_trigonometric_moments_4 = CodeChunk.from(
11
- //language=WGSL
12
- `
13
- fn generate_trigonometric_moments_4(
14
- b_0: ptr<function, f32>,
15
- b_12: ptr<function, vec4<f32>>,
16
- depth: f32,
17
- transmittance: f32,
18
- wrapping_zone_parameters: vec4<f32>
19
- ) {
20
- let absorbance = -log(transmittance);
21
-
22
- let phase = depth * wrapping_zone_parameters.y + wrapping_zone_parameters.y;
23
- let circle_point = vec2<f32>(cos(phase), sin(phase));
24
- let circle_point_pow2 = complex_multiply(circle_point, circle_point);
25
-
26
- let b_12_new = vec4<f32>(circle_point.x, circle_point.y, circle_point_pow2.x, circle_point_pow2.y) * absorbance;
27
-
28
- // SINGLE_PRECISION = true case
29
- (*b_0) += absorbance;
30
- (*b_12) += b_12_new;
31
- }
32
- `, [
33
- chunk_complex_multiply,
34
- ]
35
- );
1
+ import { CodeChunk } from "../../../../compiler/CodeChunk.js";
2
+ import { chunk_complex_multiply } from "../../../math/complex/chunk_complex_multiply.js";
3
+
4
+ /**
5
+ * This function computes one fragment's contribution to the vector of
6
+ * trigonometric moments, for NUM_MOMENTS = 4 with SINGLE_PRECISION = true.
7
+ * b_12 packs the two complex moments as (re_1, im_1, re_2, im_2). The
8
+ * contribution is returned raw; summing across fragments is the caller's
9
+ * business (additive blending into float render targets, or component-wise
10
+ * addition in a loop).
11
+ * @see https://github.com/AlicesoftHumika/UnityOIT/blob/612c3c04263acb22980f33fa3cb2d3653ed389ff/Assets/Shader/MBOIT/MomentOIT.hlsli#L123
12
+ * @type {CodeChunk}
13
+ */
14
+ export const chunk_generate_trigonometric_moments_4 = CodeChunk.from(
15
+ //language=WGSL
16
+ `
17
+ struct TrigonometricMoments4 {
18
+ b_0: f32,
19
+ b_12: vec4<f32>
20
+ }
21
+
22
+ fn generate_trigonometric_moments_4(
23
+ depth: f32,
24
+ transmittance: f32,
25
+ wrapping_zone_parameters: vec4<f32>
26
+ ) -> TrigonometricMoments4 {
27
+ let absorbance = -log(transmittance);
28
+
29
+ let phase = depth * wrapping_zone_parameters.y + wrapping_zone_parameters.y;
30
+ let circle_point = vec2<f32>(cos(phase), sin(phase));
31
+ let circle_point_pow2 = complex_multiply(circle_point, circle_point);
32
+
33
+ // SINGLE_PRECISION = true case
34
+ return TrigonometricMoments4(
35
+ absorbance,
36
+ vec4<f32>(circle_point.x, circle_point.y, circle_point_pow2.x, circle_point_pow2.y) * absorbance
37
+ );
38
+ }
39
+ `, [
40
+ chunk_complex_multiply,
41
+ ]
42
+ );
@@ -1 +1 @@
1
- {"version":3,"file":"chunk_compute_transmittance_from_4_power_moments.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/shade/renderer/shader/chunk/mboit/moments/power/chunk_compute_transmittance_from_4_power_moments.js"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,+DAFU,SAAS,CAsFjB;0BA5FwB,mCAAmC"}
1
+ {"version":3,"file":"chunk_compute_transmittance_from_4_power_moments.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/shade/renderer/shader/chunk/mboit/moments/power/chunk_compute_transmittance_from_4_power_moments.js"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,+DAFU,SAAS,CAmGjB;0BAzGwB,mCAAmC"}
@@ -50,14 +50,27 @@ fn compute_transmittance_from_4_power_moments(
50
50
  c[1] -= l21 * c[2];
51
51
  c[0] -= dot(c.yz, b.xy);
52
52
 
53
- // Solve the quadratic equation c[0]+c[1]*z+c[2]*z^2 to obtain solutions z[1] and z[2]
54
- let inv_c2 = 1.0 / c[2];
53
+ // Solve the quadratic equation c[0]+c[1]*z+c[2]*z^2 to obtain solutions z[1] and z[2].
54
+ // c[2] crosses 0 where the third support point of the canonical distribution passes
55
+ // through infinity (its weight is 0 there), and the cancellation computing it snaps it
56
+ // to exactly 0.0 over a whole band of depths around the crossing — for a single layer
57
+ // the band sits at warp depth sqrt(0.375), from the bias vector. Unguarded, 1/0 turns
58
+ // the discriminant into inf - inf = NaN, knocking the pixel out of the composite as a
59
+ // camera-locked stripe. The magnitude clamp keeps the vanishing root huge-but-finite
60
+ // (its weight is negligible there); the discriminant floor keeps the roots distinct.
61
+ let c2_safe = select(min(c[2], -1e-10), max(c[2], 1e-10), c[2] >= 0.0);
62
+ let inv_c2 = 1.0 / c2_safe;
55
63
  let p = c[1] * inv_c2;
56
64
  let q = c[0] * inv_c2;
57
- let d = (p * p * 0.25) - q;
65
+ let d = max((p * p * 0.25) - q, 1e-20);
58
66
  let r = sqrt(d);
59
- z[1] = -p * 0.5 - r;
60
- z[2] = -p * 0.5 + r;
67
+ // Citardauq form: the far root is computed additively (no cancellation) and the near
68
+ // root recovered via Vieta (z1*z2 = q) — the classic -p/2 ± r loses every significant
69
+ // digit of the near root when the clamp above makes |p| huge.
70
+ let z_far = -p * 0.5 - select(-r, r, p >= 0.0);
71
+ let z_near = q / z_far;
72
+ z[1] = min(z_far, z_near);
73
+ z[2] = max(z_far, z_near);
61
74
 
62
75
  // Compute the absorbance by summing the appropriate weights
63
76
 
@@ -1 +1 @@
1
- {"version":3,"file":"chunk_compute_transmittance_from_6_power_moments.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/shade/renderer/shader/chunk/mboit/moments/power/chunk_compute_transmittance_from_6_power_moments.js"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,+DAFU,SAAS,CAqGjB;0BA5GwB,mCAAmC"}
1
+ {"version":3,"file":"chunk_compute_transmittance_from_6_power_moments.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/shade/renderer/shader/chunk/mboit/moments/power/chunk_compute_transmittance_from_6_power_moments.js"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,+DAFU,SAAS,CAmHjB;0BA3HwB,mCAAmC"}
@@ -1,4 +1,5 @@
1
1
  import { CodeChunk } from "../../../../compiler/CodeChunk.js";
2
+ import { chunk_magnitude_floor } from "../../../math/chunk_magnitude_floor.js";
2
3
  import { chunk_solve_cubic } from "../../../math/polynomial/chunk_solve_cubic.js";
3
4
 
4
5
  /**
@@ -61,8 +62,17 @@ fn compute_transmittance_from_6_power_moments(
61
62
  c[1] -= dot(vec2<f32>(l21, l31), c.zw);
62
63
  c[0] -= dot(vec3<f32>(b[0], b[1], b[2]), c.yzw);
63
64
 
64
- // Solve the cubic equation
65
- let cubic_roots = solve_cubic(c);
65
+ // Solve the cubic equation.
66
+ // c[3] -> 0 where the fourth support point of the canonical distribution escapes to
67
+ // infinity (its weight vanishes there), and the cancellation computing it snaps it to
68
+ // exactly 0.0 over a whole band of depths around the crossing; the solver normalizes
69
+ // by it, which unguarded turns every root into inf/NaN and poisons the interpolation
70
+ // below. The floor keeps the escaped root huge-but-finite. It is relative to the
71
+ // largest lower coefficient — the pivot scaling above can amplify the whole vector —
72
+ // so the solver-normalized coefficients stay <= ~1e4: every solver intermediate then
73
+ // fits f32, while a root out at ~1e4 carries negligible weight in the reconstruction.
74
+ let c_scale = max(1.0, max(abs(c[0]), max(abs(c[1]), abs(c[2]))));
75
+ let cubic_roots = solve_cubic(vec4<f32>(c.xyz, magnitude_floor(c[3], 1e-4 * c_scale)));
66
76
  z[1] = cubic_roots.x;
67
77
  z[2] = cubic_roots.y;
68
78
  z[3] = cubic_roots.z;
@@ -80,12 +90,16 @@ fn compute_transmittance_from_6_power_moments(
80
90
  let f1 = weight_factor[1];
81
91
  let f2 = weight_factor[2];
82
92
  let f3 = weight_factor[3];
83
- let f01 = (f1 - f0) / (z[1] - z[0]);
84
- let f12 = (f2 - f1) / (z[2] - z[1]);
85
- let f23 = (f3 - f2) / (z[3] - z[2]);
86
- let f012 = (f12 - f01) / (z[2] - z[0]);
87
- let f123 = (f23 - f12) / (z[3] - z[1]);
88
- let f0123 = (f123 - f012) / (z[3] - z[0]);
93
+ // Coincident support points (or a root landing exactly on the query depth) zero
94
+ // these separations: equal weights then make the division 0/0 = NaN, unequal ones an
95
+ // inf that meets another inf two lines later. Floored, a merged pair contributes one
96
+ // bounded term instead.
97
+ let f01 = (f1 - f0) / magnitude_floor(z[1] - z[0], 1e-4);
98
+ let f12 = (f2 - f1) / magnitude_floor(z[2] - z[1], 1e-4);
99
+ let f23 = (f3 - f2) / magnitude_floor(z[3] - z[2], 1e-4);
100
+ let f012 = (f12 - f01) / magnitude_floor(z[2] - z[0], 1e-4);
101
+ let f123 = (f23 - f12) / magnitude_floor(z[3] - z[1], 1e-4);
102
+ let f0123 = (f123 - f012) / magnitude_floor(z[3] - z[0], 1e-4);
89
103
  var polynomial = vec4<f32>();
90
104
  // f012+f0123 *(z-z2)
91
105
  polynomial[0] = f0123 * (-z[2]) + f012;
@@ -104,6 +118,7 @@ fn compute_transmittance_from_6_power_moments(
104
118
  return saturate(exp(-b_0 * absorbance));
105
119
  }
106
120
  `, [
107
- chunk_solve_cubic
121
+ chunk_solve_cubic,
122
+ chunk_magnitude_floor
108
123
  ]
109
124
  );
@@ -1 +1 @@
1
- {"version":3,"file":"chunk_compute_transmittance_from_8_power_moments.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/shade/renderer/shader/chunk/mboit/moments/power/chunk_compute_transmittance_from_8_power_moments.js"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,+DAFU,SAAS,CAiIjB;0BAxIwB,mCAAmC"}
1
+ {"version":3,"file":"chunk_compute_transmittance_from_8_power_moments.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/shade/renderer/shader/chunk/mboit/moments/power/chunk_compute_transmittance_from_8_power_moments.js"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,+DAFU,SAAS,CAgJjB;0BAxJwB,mCAAmC"}
@@ -1,4 +1,5 @@
1
1
  import { CodeChunk } from "../../../../compiler/CodeChunk.js";
2
+ import { chunk_magnitude_floor } from "../../../math/chunk_magnitude_floor.js";
2
3
  import { chunk_solve_quartic_neumark } from "../../../math/polynomial/chunk_solve_quartic_neumark.js";
3
4
 
4
5
  /**
@@ -81,8 +82,18 @@ fn compute_transmittance_from_8_power_moments(
81
82
  c[1] -= dot(vec3<f32>(l52, l42, l32), vec3<f32>(c[4], c[3], c[2]));
82
83
  c[0] -= dot(vec4<f32>(b[3], b[2], b[1], b[0]), vec4<f32>(c[4], c[3], c[2], c[1]));
83
84
 
84
- // Solve the quartic equation
85
- let quartic_roots = solve_quartic_neumark(c);
85
+ // Solve the quartic equation.
86
+ // c[4] -> 0 where the fifth support point of the canonical distribution escapes to
87
+ // infinity (its weight vanishes there), and the cancellation computing it snaps it to
88
+ // exactly 0.0 over a whole band of depths around the crossing; the solver normalizes
89
+ // by it, which unguarded turns every root into inf/NaN and poisons the interpolation
90
+ // below. The floor keeps the escaped root huge-but-finite. It is relative to the
91
+ // largest lower coefficient — the pivot scaling above can amplify the whole vector —
92
+ // so the solver-normalized coefficients stay <= ~1e4: every resolvent intermediate
93
+ // then fits f32, while a root out at ~1e4 carries negligible weight in the
94
+ // reconstruction.
95
+ let c_scale = max(1.0, max(max(abs(c[0]), abs(c[1])), max(abs(c[2]), abs(c[3]))));
96
+ let quartic_roots = solve_quartic_neumark(array<f32, 5>(c[0], c[1], c[2], c[3], magnitude_floor(c[4], 1e-4 * c_scale)));
86
97
  z[1] = quartic_roots[0];
87
98
  z[2] = quartic_roots[1];
88
99
  z[3] = quartic_roots[2];
@@ -96,16 +107,20 @@ fn compute_transmittance_from_8_power_moments(
96
107
  let f2 = weight_factor[1];
97
108
  let f3 = weight_factor[2];
98
109
  let f4 = weight_factor[3];
99
- let f01 = (f1 - f0) / (z[1] - z[0]);
100
- let f12 = (f2 - f1) / (z[2] - z[1]);
101
- let f23 = (f3 - f2) / (z[3] - z[2]);
102
- let f34 = (f4 - f3) / (z[4] - z[3]);
103
- let f012 = (f12 - f01) / (z[2] - z[0]);
104
- let f123 = (f23 - f12) / (z[3] - z[1]);
105
- let f234 = (f34 - f23) / (z[4] - z[2]);
106
- let f0123 = (f123 - f012) / (z[3] - z[0]);
107
- let f1234 = (f234 - f123) / (z[4] - z[1]);
108
- let f01234 = (f1234 - f0123) / (z[4] - z[0]);
110
+ // Coincident support points (or a root landing exactly on the query depth) zero
111
+ // these separations: equal weights then make the division 0/0 = NaN, unequal ones an
112
+ // inf that meets another inf further down the table. Floored, a merged pair
113
+ // contributes one bounded term instead.
114
+ let f01 = (f1 - f0) / magnitude_floor(z[1] - z[0], 1e-4);
115
+ let f12 = (f2 - f1) / magnitude_floor(z[2] - z[1], 1e-4);
116
+ let f23 = (f3 - f2) / magnitude_floor(z[3] - z[2], 1e-4);
117
+ let f34 = (f4 - f3) / magnitude_floor(z[4] - z[3], 1e-4);
118
+ let f012 = (f12 - f01) / magnitude_floor(z[2] - z[0], 1e-4);
119
+ let f123 = (f23 - f12) / magnitude_floor(z[3] - z[1], 1e-4);
120
+ let f234 = (f34 - f23) / magnitude_floor(z[4] - z[2], 1e-4);
121
+ let f0123 = (f123 - f012) / magnitude_floor(z[3] - z[0], 1e-4);
122
+ let f1234 = (f234 - f123) / magnitude_floor(z[4] - z[1], 1e-4);
123
+ let f01234 = (f1234 - f0123) / magnitude_floor(z[4] - z[0], 1e-4);
109
124
 
110
125
  var polynomial_0: f32;
111
126
  var polynomial = vec4<f32>();
@@ -132,6 +147,7 @@ fn compute_transmittance_from_8_power_moments(
132
147
  return saturate(exp(-b_0 * absorbance));
133
148
  }
134
149
  `, [
135
- chunk_solve_quartic_neumark
150
+ chunk_solve_quartic_neumark,
151
+ chunk_magnitude_floor
136
152
  ]
137
153
  );
@@ -1,3 +1,15 @@
1
+ /**
2
+ * This function computes one fragment's contribution to the vector of power
3
+ * moments, for NUM_MOMENTS = 4 with SINGLE_PRECISION = true. The contribution
4
+ * is returned raw; summing across fragments is the caller's business (additive
5
+ * blending into float render targets, or component-wise addition in a loop).
6
+ * Quantization, normalization by b_0 and the [0, 1] offset belong to the
7
+ * quantized-storage path, which needs read-modify-write access to the already
8
+ * accumulated moments (an ROV in the reference) and cannot be expressed
9
+ * through additive blending.
10
+ * @see https://github.com/AlicesoftHumika/UnityOIT/blob/612c3c04263acb22980f33fa3cb2d3653ed389ff/Assets/Shader/MBOIT/MomentOIT.hlsli#L123
11
+ * @type {CodeChunk}
12
+ */
1
13
  export const chunk_generate_power_moments_4: CodeChunk;
2
14
  import { CodeChunk } from "../../../../compiler/CodeChunk.js";
3
15
  //# sourceMappingURL=chunk_generate_power_moments_4.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chunk_generate_power_moments_4.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/shade/renderer/shader/chunk/mboit/moments/power/chunk_generate_power_moments_4.js"],"names":[],"mappings":"AAIA,uDA2CC;0BA/CyB,mCAAmC"}
1
+ {"version":3,"file":"chunk_generate_power_moments_4.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/shade/renderer/shader/chunk/mboit/moments/power/chunk_generate_power_moments_4.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AACH,6CAFU,SAAS,CAyBjB;0BArCwB,mCAAmC"}
@@ -1,48 +1,38 @@
1
- import { CodeChunk } from "../../../../compiler/CodeChunk.js";
2
- import { chunk_offset_moments_2 } from "../chunk_offset_moments_2.js";
3
- import { chunk_quantize_moments_2 } from "../chunk_quantize_moments_2.js";
4
-
5
- export const chunk_generate_power_moments_4 = CodeChunk.from(
6
- //language=WGSL
7
- `
8
- fn generate_power_moments_4(
9
- b_0: ptr<function, f32>,
10
- b_even: ptr<function, vec2<f32>>,
11
- b_odd: ptr<function, vec2<f32>>,
12
- depth: f32,
13
- transmittance: f32,
14
- ) {
15
-
16
- let absorbance = -log(transmittance);
17
- let depth_pow2 = depth * depth;
18
- let depth_pow4 = depth_pow2 * depth_pow2;
19
-
20
- *b_0 += absorbance;
21
- *b_even += vec2(depth_pow2, depth_pow4) * absorbance;
22
- *b_odd += vec2(depth, depth_pow2 * depth) * absorbance;
23
-
24
- var b_even_new = vec2(depth_pow2, depth_pow4);
25
- var b_odd_new = vec2(depth, depth_pow2 * depth);
26
-
27
- var b_even_new_q:vec2f;
28
- var b_odd_new_q:vec2f;
29
-
30
- quantize_moments_2(b_even_new, b_odd_new, &b_even_new_q, &b_odd_new_q);
31
-
32
- // Combine Moments
33
- *b_0 += absorbance;
34
- *b_even += b_even_new_q * absorbance;
35
- *b_odd += b_odd_new_q * absorbance;
36
-
37
- // Go back to interval [0, 1]
38
- *b_even /= *b_0;
39
- *b_odd /= *b_0;
40
-
41
- offset_moments_2(b_even, b_odd, 1.0);
42
-
43
- }
44
- `, [
45
- chunk_quantize_moments_2,
46
- chunk_offset_moments_2
47
- ]
48
- )
1
+ import { CodeChunk } from "../../../../compiler/CodeChunk.js";
2
+
3
+ /**
4
+ * This function computes one fragment's contribution to the vector of power
5
+ * moments, for NUM_MOMENTS = 4 with SINGLE_PRECISION = true. The contribution
6
+ * is returned raw; summing across fragments is the caller's business (additive
7
+ * blending into float render targets, or component-wise addition in a loop).
8
+ * Quantization, normalization by b_0 and the [0, 1] offset belong to the
9
+ * quantized-storage path, which needs read-modify-write access to the already
10
+ * accumulated moments (an ROV in the reference) and cannot be expressed
11
+ * through additive blending.
12
+ * @see https://github.com/AlicesoftHumika/UnityOIT/blob/612c3c04263acb22980f33fa3cb2d3653ed389ff/Assets/Shader/MBOIT/MomentOIT.hlsli#L123
13
+ * @type {CodeChunk}
14
+ */
15
+ export const chunk_generate_power_moments_4 = CodeChunk.from(
16
+ //language=WGSL
17
+ `
18
+ struct PowerMoments4 {
19
+ b_0: f32,
20
+ b_even: vec2<f32>,
21
+ b_odd: vec2<f32>
22
+ }
23
+
24
+ fn generate_power_moments_4(depth: f32, transmittance: f32) -> PowerMoments4 {
25
+ let absorbance = -log(transmittance);
26
+
27
+ let depth_pow2 = depth * depth;
28
+ let depth_pow4 = depth_pow2 * depth_pow2;
29
+
30
+ // SINGLE_PRECISION = true case
31
+ return PowerMoments4(
32
+ absorbance,
33
+ vec2(depth_pow2, depth_pow4) * absorbance,
34
+ vec2(depth, depth_pow2 * depth) * absorbance
35
+ );
36
+ }
37
+ `
38
+ );