@woosh/meep-engine 3.61.0 → 3.61.2

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 (170) hide show
  1. package/package.json +1 -1
  2. package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
  3. package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +4 -0
  4. package/src/engine/graphics/ecs/decal/v2/Decal.d.ts +46 -2
  5. package/src/engine/graphics/ecs/decal/v2/Decal.d.ts.map +1 -1
  6. package/src/engine/graphics/ecs/decal/v2/Decal.js +74 -5
  7. package/src/engine/graphics/ecs/decal/v2/DecalSerializationAdapter.d.ts.map +1 -1
  8. package/src/engine/graphics/ecs/decal/v2/DecalSerializationAdapter.js +13 -1
  9. package/src/engine/graphics/ecs/decal/v2/DecalSerializationUpgrader_1_2.d.ts +9 -0
  10. package/src/engine/graphics/ecs/decal/v2/DecalSerializationUpgrader_1_2.d.ts.map +1 -0
  11. package/src/engine/graphics/ecs/decal/v2/DecalSerializationUpgrader_1_2.js +37 -0
  12. package/src/engine/graphics3/DecalSystem.d.ts.map +1 -1
  13. package/src/engine/graphics3/DecalSystem.js +462 -447
  14. package/src/engine/graphics3/decal/DECAL_GPU_RECORD.d.ts +14 -0
  15. package/src/engine/graphics3/decal/DECAL_GPU_RECORD.d.ts.map +1 -1
  16. package/src/engine/graphics3/decal/DECAL_GPU_RECORD.js +53 -13
  17. package/src/engine/graphics3/decal/chunk_decal_record.d.ts +6 -1
  18. package/src/engine/graphics3/decal/chunk_decal_record.d.ts.map +1 -1
  19. package/src/engine/graphics3/decal/chunk_decal_record.js +28 -9
  20. package/src/engine/graphics3/decal/decal_gpu_records.d.ts +2 -1
  21. package/src/engine/graphics3/decal/decal_gpu_records.d.ts.map +1 -1
  22. package/src/engine/graphics3/decal/decal_gpu_records.js +26 -5
  23. package/src/engine/graphics3/decal/decal_material_samplers.d.ts +6 -0
  24. package/src/engine/graphics3/decal/decal_material_samplers.d.ts.map +1 -1
  25. package/src/engine/graphics3/decal/decal_material_samplers.js +13 -0
  26. package/src/engine/graphics3/decal/shader_cluster_assign_decals.js +1 -1
  27. package/src/engine/graphics3/decal/shader_cull_decals_frustum.js +1 -1
  28. package/src/engine/graphics3/decal/shader_decal_composite.d.ts +5 -0
  29. package/src/engine/graphics3/decal/shader_decal_composite.d.ts.map +1 -1
  30. package/src/engine/graphics3/decal/shader_decal_composite.js +69 -28
  31. package/src/engine/network/sim/SimActionExecutor.d.ts +4 -0
  32. package/src/engine/network/sim/SimActionExecutor.d.ts.map +1 -1
  33. package/src/engine/network/sim/SimActionExecutor.js +4 -0
  34. package/src/generation/foliage/material/foliage_atlas_cutout.d.ts.map +1 -1
  35. package/src/generation/foliage/material/foliage_atlas_cutout.js +21 -5
  36. package/src/generation/foliage/mesh/tree_cluster_representatives.d.ts +8 -0
  37. package/src/generation/foliage/mesh/tree_cluster_representatives.d.ts.map +1 -1
  38. package/src/generation/foliage/mesh/tree_cluster_representatives.js +178 -78
  39. package/src/generation/foliage/mesh/tree_mesh_build_bark.d.ts.map +1 -1
  40. package/src/generation/foliage/mesh/tree_mesh_build_bark.js +178 -97
  41. package/src/generation/foliage/skeleton/ShootLightField.d.ts +1 -0
  42. package/src/generation/foliage/skeleton/ShootLightField.d.ts.map +1 -1
  43. package/src/generation/foliage/skeleton/ShootLightField.js +88 -17
  44. package/src/generation/foliage/skeleton/ShootWoodHash.d.ts +8 -4
  45. package/src/generation/foliage/skeleton/ShootWoodHash.d.ts.map +1 -1
  46. package/src/generation/foliage/skeleton/ShootWoodHash.js +216 -27
  47. package/src/shade/playground/probe_clipmap/main.d.ts.map +1 -1
  48. package/src/shade/playground/probe_clipmap/main.js +4 -0
  49. package/src/shade/playground/probe_clipmap_box/README.md +55 -0
  50. package/src/shade/playground/probe_clipmap_box/index.html +185 -0
  51. package/src/shade/playground/probe_clipmap_box/main.d.ts +8 -0
  52. package/src/shade/playground/probe_clipmap_box/main.d.ts.map +1 -0
  53. package/src/shade/playground/probe_clipmap_box/main.js +323 -0
  54. package/src/shade/playground/probe_clipmap_box/scene.d.ts +93 -0
  55. package/src/shade/playground/probe_clipmap_box/scene.d.ts.map +1 -0
  56. package/src/shade/playground/probe_clipmap_box/scene.js +256 -0
  57. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  58. package/src/shade/renderer/Renderer.js +6 -1
  59. package/src/shade/renderer/buffer/graph_read_buffer.d.ts +3 -1
  60. package/src/shade/renderer/buffer/graph_read_buffer.d.ts.map +1 -1
  61. package/src/shade/renderer/buffer/graph_read_buffer.js +9 -6
  62. package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_brick4_sh3_color_decode.d.ts +12 -0
  63. package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_brick4_sh3_color_decode.d.ts.map +1 -1
  64. package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_brick4_sh3_color_decode.js +49 -24
  65. package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_brick4_sh3_color_encode.d.ts +12 -0
  66. package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_brick4_sh3_color_encode.d.ts.map +1 -1
  67. package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_brick4_sh3_color_encode.js +50 -19
  68. package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_sh3_compress.d.ts.map +1 -1
  69. package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_sh3_compress.js +6 -2
  70. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts +5 -1
  71. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
  72. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +7 -3
  73. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +6 -4
  74. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
  75. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +10 -9
  76. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts +12 -0
  77. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts.map +1 -1
  78. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.js +14 -0
  79. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts +17 -22
  80. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts.map +1 -1
  81. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.js +53 -65
  82. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_pick.d.ts +2 -3
  83. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_pick.d.ts.map +1 -1
  84. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_pick.js +9 -20
  85. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts +2 -2
  86. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts.map +1 -1
  87. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.js +14 -19
  88. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts +1 -1
  89. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts.map +1 -1
  90. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.js +8 -4
  91. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_admit.js +1 -1
  92. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_bounce.d.ts +2 -1
  93. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_bounce.d.ts.map +1 -1
  94. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_bounce.js +13 -18
  95. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_candidate.d.ts +1 -1
  96. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_candidate.d.ts.map +1 -1
  97. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_candidate.js +4 -2
  98. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_diffuse.d.ts.map +1 -1
  99. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_diffuse.js +4 -6
  100. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_indirect_lighting.d.ts.map +1 -1
  101. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_indirect_lighting.js +4 -7
  102. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.d.ts +4 -3
  103. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.d.ts.map +1 -1
  104. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.js +14 -13
  105. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.d.ts +3 -4
  106. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.d.ts.map +1 -1
  107. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.js +7 -15
  108. package/src/shade/renderer/light/environment/shader_downsample_environment_map.d.ts.map +1 -1
  109. package/src/shade/renderer/light/environment/shader_downsample_environment_map.js +5 -1
  110. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  111. package/src/shade/renderer/particles/GPUParticleSystem.js +1 -7
  112. package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.d.ts +26 -8
  113. package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.d.ts.map +1 -1
  114. package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.js +170 -142
  115. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_probe_clipmap.d.ts +1 -1
  116. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_probe_clipmap.d.ts.map +1 -1
  117. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_probe_clipmap.js +5 -8
  118. package/src/shade/renderer/restir/di/chunk_restir_resolve.d.ts.map +1 -1
  119. package/src/shade/renderer/restir/di/chunk_restir_resolve.js +91 -94
  120. package/src/shade/renderer/restir/reservoir/chunk_rtxdi_stream_sample.js +1 -1
  121. package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_decode.d.ts +14 -0
  122. package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_decode.d.ts.map +1 -1
  123. package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_decode.js +36 -21
  124. package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_sample_gather.d.ts +22 -0
  125. package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_sample_gather.d.ts.map +1 -0
  126. package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_sample_gather.js +64 -0
  127. package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.d.ts +15 -4
  128. package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.d.ts.map +1 -1
  129. package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.js +33 -7
  130. package/src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_vertex_normal.d.ts.map +1 -1
  131. package/src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_vertex_normal.js +13 -18
  132. package/src/shade/renderer/shader/chunk/geometry/normal/chunk_encode_vertex_normal.d.ts.map +1 -1
  133. package/src/shade/renderer/shader/chunk/geometry/normal/chunk_encode_vertex_normal.js +28 -30
  134. package/src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_u32_to_vec2.d.ts.map +1 -1
  135. package/src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_u32_to_vec2.js +15 -16
  136. package/src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_vec2_to_u32.d.ts +0 -1
  137. package/src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_vec2_to_u32.d.ts.map +1 -1
  138. package/src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_vec2_to_u32.js +15 -18
  139. package/src/shade/renderer/shader/chunk/noise/chunk_sobol_sample_vec2.d.ts +40 -0
  140. package/src/shade/renderer/shader/chunk/noise/chunk_sobol_sample_vec2.d.ts.map +1 -0
  141. package/src/shade/renderer/shader/chunk/noise/chunk_sobol_sample_vec2.js +75 -0
  142. package/src/shade/renderer/shader/chunk/noise/chunk_vdc_radical_inverse.d.ts.map +1 -1
  143. package/src/shade/renderer/shader/chunk/noise/chunk_vdc_radical_inverse.js +3 -1
  144. package/src/shade/renderer/shader/chunk/random/chunk_hash_lk.d.ts +28 -0
  145. package/src/shade/renderer/shader/chunk/random/chunk_hash_lk.d.ts.map +1 -0
  146. package/src/shade/renderer/shader/chunk/random/chunk_hash_lk.js +41 -0
  147. package/src/shade/renderer/shader/chunk/spherical_harmonics/chunk_sh3_color_add_scaled.d.ts +12 -0
  148. package/src/shade/renderer/shader/chunk/spherical_harmonics/chunk_sh3_color_add_scaled.d.ts.map +1 -0
  149. package/src/shade/renderer/shader/chunk/spherical_harmonics/chunk_sh3_color_add_scaled.js +24 -0
  150. package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.d.ts +3 -2
  151. package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.d.ts.map +1 -1
  152. package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.js +4 -0
  153. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.d.ts +2 -5
  154. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.d.ts.map +1 -1
  155. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.js +3 -20
  156. package/src/shade/renderer/water/chunk_water_gi.d.ts +1 -1
  157. package/src/shade/renderer/water/chunk_water_gi.d.ts.map +1 -1
  158. package/src/shade/renderer/water/chunk_water_gi.js +6 -8
  159. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +8 -1
  160. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  161. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +79 -35
  162. package/src/core/math/hash/squirrel3.d.ts +0 -17
  163. package/src/core/math/hash/squirrel3.d.ts.map +0 -1
  164. package/src/core/math/hash/squirrel3.js +0 -30
  165. package/src/shade/renderer/global_illumination/brick4/cpu/brick4_sh3_color_encode.d.ts +0 -2
  166. package/src/shade/renderer/global_illumination/brick4/cpu/brick4_sh3_color_encode.d.ts.map +0 -1
  167. package/src/shade/renderer/global_illumination/brick4/cpu/brick4_sh3_color_encode.js +0 -6
  168. package/src/shade/renderer/shader/chunk/random/chunk_hash_squirrel3.d.ts +0 -12
  169. package/src/shade/renderer/shader/chunk/random/chunk_hash_squirrel3.d.ts.map +0 -1
  170. package/src/shade/renderer/shader/chunk/random/chunk_hash_squirrel3.js +0 -30
@@ -36,7 +36,7 @@ fn rtxdi_stream_sample(
36
36
  if (selectSample)
37
37
  {
38
38
  reservoir.lightData = lightIndex | RTXDI_Reservoir_LightValidBit;
39
- reservoir.uvData = u32(saturate(uv.x) * 0xffff) | (u32(saturate(uv.y) * 0xffff) << 16);
39
+ reservoir.uvData = pack2x16unorm(uv);
40
40
  reservoir.targetPdf = targetPdf;
41
41
  }
42
42
 
@@ -1,4 +1,18 @@
1
1
  /**
2
+ * Decodes a packed RGBE 9-9-9-5 (`u32`) word into linear RGB (`vec3<f32>`).
3
+ *
4
+ * Bit layout:
5
+ * - `[0..8]`: 9-bit R mantissa
6
+ * - `[9..17]`: 9-bit G mantissa
7
+ * - `[18..26]`: 9-bit B mantissa
8
+ * - `[27..31]`: 5-bit biased exponent E (bias = 15, mantissa bits = 9)
9
+ *
10
+ * Rather than evaluating a transcendental `exp2(E - 24.0)` on the SFU, `2^(E - 24)` is
11
+ * constructed directly in IEEE-754 binary32 bits: shifting E from `[27..31]` down to the
12
+ * float exponent field `[23..27]` and adding the combined exponent bias `(127 - 24) << 23 = 0x33800000u`.
13
+ * Because `E` is in `[0, 31]`, the biased IEEE-754 exponent `E + 103` is in `[103, 134]`,
14
+ * which is always a normal positive float.
15
+ *
2
16
  * @see https://en.wikipedia.org/wiki/RGBE_image_format
3
17
  * @see https://github.com/zhangjiangen11/godot/blob/b64ac6341347906dacdda712dc78b574334ff4af/servers/rendering/renderer_rd/shaders/environment/hddagi_direct_light.glsl#L331
4
18
  * @type {CodeChunk}
@@ -1 +1 @@
1
- {"version":3,"file":"chunk_rgbe9995_decode.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_decode.js"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,oCAFU,SAAS,CAejB;0BApBwB,gCAAgC"}
1
+ {"version":3,"file":"chunk_rgbe9995_decode.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_decode.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AACH,oCAFU,SAAS,CAgBjB;0BAnCwB,gCAAgC"}
@@ -1,21 +1,36 @@
1
- import { CodeChunk } from "../../../compiler/CodeChunk.js";
2
-
3
- /**
4
- * @see https://en.wikipedia.org/wiki/RGBE_image_format
5
- * @see https://github.com/zhangjiangen11/godot/blob/b64ac6341347906dacdda712dc78b574334ff4af/servers/rendering/renderer_rd/shaders/environment/hddagi_direct_light.glsl#L331
6
- * @type {CodeChunk}
7
- */
8
- export const chunk_rgbe9995_decode = CodeChunk.from(
9
- //language=WGSL
10
- `
11
- fn rgbe9995_decode(p_rgbe:u32) -> vec3<f32>{
12
- // shift and mask
13
- let rgbef = vec4<f32>(
14
- (vec4(p_rgbe) >> vec4<u32>(0, 9, 18, 27))
15
- & vec4<u32>(0x1FF, 0x1FF, 0x1FF, 0x1F)
16
- );
17
-
18
- return rgbef.rgb * exp2(rgbef.a - 15.0 - 9.0);
19
- }
20
- `
21
- );
1
+ import { CodeChunk } from "../../../compiler/CodeChunk.js";
2
+
3
+ /**
4
+ * Decodes a packed RGBE 9-9-9-5 (`u32`) word into linear RGB (`vec3<f32>`).
5
+ *
6
+ * Bit layout:
7
+ * - `[0..8]`: 9-bit R mantissa
8
+ * - `[9..17]`: 9-bit G mantissa
9
+ * - `[18..26]`: 9-bit B mantissa
10
+ * - `[27..31]`: 5-bit biased exponent E (bias = 15, mantissa bits = 9)
11
+ *
12
+ * Rather than evaluating a transcendental `exp2(E - 24.0)` on the SFU, `2^(E - 24)` is
13
+ * constructed directly in IEEE-754 binary32 bits: shifting E from `[27..31]` down to the
14
+ * float exponent field `[23..27]` and adding the combined exponent bias `(127 - 24) << 23 = 0x33800000u`.
15
+ * Because `E` is in `[0, 31]`, the biased IEEE-754 exponent `E + 103` is in `[103, 134]`,
16
+ * which is always a normal positive float.
17
+ *
18
+ * @see https://en.wikipedia.org/wiki/RGBE_image_format
19
+ * @see https://github.com/zhangjiangen11/godot/blob/b64ac6341347906dacdda712dc78b574334ff4af/servers/rendering/renderer_rd/shaders/environment/hddagi_direct_light.glsl#L331
20
+ * @type {CodeChunk}
21
+ */
22
+ export const chunk_rgbe9995_decode = CodeChunk.from(
23
+ //language=WGSL
24
+ `
25
+ fn rgbe9995_decode(p_rgbe: u32) -> vec3<f32> {
26
+ let rgb = vec3<f32>(
27
+ (vec3<u32>(p_rgbe) >> vec3<u32>(0u, 9u, 18u))
28
+ & vec3<u32>(0x1FFu)
29
+ );
30
+ let exp_bits = ((p_rgbe >> 4u) & 0x0F800000u) + 0x33800000u;
31
+ let scale = bitcast<f32>(exp_bits);
32
+
33
+ return rgb * scale;
34
+ }
35
+ `
36
+ );
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Software-bilinear sample of an RGBE 9-9-9-5 (`r32uint`) 2D texture using a single `textureGather`.
3
+ *
4
+ * WebGPU's `rgb9e5ufloat` format is hardware-filterable, but cannot be written as a storage texture
5
+ * (`STORAGE_BINDING`) or render attachment, nor view-aliased with `r32uint`. When an HDR texture is
6
+ * produced on the GPU via `textureStore` into `r32uint`, this function performs a 4-texel bilinear
7
+ * tap using one `textureGather`:
8
+ *
9
+ * 1. Snaps the gather UV to `(floor(uv * tex_size - 0.5) + 1.0) * inv_tex_size` (dead-center
10
+ * between the 4 texels) so the TMU's 16.8 fixed-point floor never disagrees with the ALU's
11
+ * `f32` fractional weights near half-texel boundaries.
12
+ * 2. Constructs the four `2^(E - 24)` scale factors directly in IEEE-754 float bits via shift,
13
+ * mask, bias addition (`103 << 23 = 0x33800000u`), and `bitcast<vec4<f32>>`, avoiding 4 SFU
14
+ * `exp2` instructions.
15
+ * 3. Folds the 4 shared-exponent scales into the 4 bilinear weights (`w = bilinear * scale`) and
16
+ * evaluates each RGB channel as a single `dot(mantissa, w)`.
17
+ *
18
+ * @type {CodeChunk}
19
+ */
20
+ export const chunk_rgbe9995_sample_gather: CodeChunk;
21
+ import { CodeChunk } from "../../../compiler/CodeChunk.js";
22
+ //# sourceMappingURL=chunk_rgbe9995_sample_gather.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk_rgbe9995_sample_gather.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_sample_gather.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AACH,2CAFU,SAAS,CA4CjB;0BA/DwB,gCAAgC"}
@@ -0,0 +1,64 @@
1
+ import { CodeChunk } from "../../../compiler/CodeChunk.js";
2
+
3
+ /**
4
+ * Software-bilinear sample of an RGBE 9-9-9-5 (`r32uint`) 2D texture using a single `textureGather`.
5
+ *
6
+ * WebGPU's `rgb9e5ufloat` format is hardware-filterable, but cannot be written as a storage texture
7
+ * (`STORAGE_BINDING`) or render attachment, nor view-aliased with `r32uint`. When an HDR texture is
8
+ * produced on the GPU via `textureStore` into `r32uint`, this function performs a 4-texel bilinear
9
+ * tap using one `textureGather`:
10
+ *
11
+ * 1. Snaps the gather UV to `(floor(uv * tex_size - 0.5) + 1.0) * inv_tex_size` (dead-center
12
+ * between the 4 texels) so the TMU's 16.8 fixed-point floor never disagrees with the ALU's
13
+ * `f32` fractional weights near half-texel boundaries.
14
+ * 2. Constructs the four `2^(E - 24)` scale factors directly in IEEE-754 float bits via shift,
15
+ * mask, bias addition (`103 << 23 = 0x33800000u`), and `bitcast<vec4<f32>>`, avoiding 4 SFU
16
+ * `exp2` instructions.
17
+ * 3. Folds the 4 shared-exponent scales into the 4 bilinear weights (`w = bilinear * scale`) and
18
+ * evaluates each RGB channel as a single `dot(mantissa, w)`.
19
+ *
20
+ * @type {CodeChunk}
21
+ */
22
+ export const chunk_rgbe9995_sample_gather = CodeChunk.from(
23
+ //language=WGSL
24
+ `
25
+ fn rgbe9995_sample_gather(
26
+ tex: texture_2d<u32>,
27
+ samp: sampler,
28
+ uv: vec2<f32>,
29
+ tex_size: vec2<f32>,
30
+ inv_tex_size: vec2<f32>
31
+ ) -> vec3<f32> {
32
+ // 1. Align UV to prevent 16.8 fixed-point TMU vs f32 ALU boundary mismatch
33
+ let coord = uv * tex_size - 0.5;
34
+ let base = floor(coord);
35
+ let f = coord - base;
36
+ let gather_uv = (base + 1.0) * inv_tex_size;
37
+
38
+ // WebGPU textureGather component order:
39
+ // .x = (u0, v1) [bottom-left], .y = (u1, v1) [bottom-right]
40
+ // .z = (u1, v0) [top-right], .w = (u0, v0) [top-left]
41
+ let raw: vec4<u32> = textureGather(0, tex, samp, gather_uv);
42
+
43
+ // 2. Construct 2^(E - 24) directly in IEEE-754 float bits:
44
+ // Shift E from [27..31] to [23..27] and add bias (103 << 23 = 0x33800000u)
45
+ let exp_bits = ((raw >> vec4<u32>(4u)) & vec4<u32>(0x0F800000u)) + vec4<u32>(0x33800000u);
46
+ let scale = bitcast<vec4<f32>>(exp_bits);
47
+
48
+ // 3. Fold bilinear weights and shared-exponent scales into a single vec4 weight
49
+ let w = vec4<f32>(
50
+ (1.0 - f.x) * f.y, // .x: (u0, v1)
51
+ f.x * f.y, // .y: (u1, v1)
52
+ f.x * (1.0 - f.y), // .z: (u1, v0)
53
+ (1.0 - f.x) * (1.0 - f.y)// .w: (u0, v0)
54
+ ) * scale;
55
+
56
+ // 4. Extract 9-bit mantissas and dot with combined weights
57
+ let r = vec4<f32>(raw & vec4<u32>(0x1FFu));
58
+ let g = vec4<f32>((raw >> vec4<u32>(9u)) & vec4<u32>(0x1FFu));
59
+ let b = vec4<f32>((raw >> vec4<u32>(18u)) & vec4<u32>(0x1FFu));
60
+
61
+ return vec3<f32>(dot(r, w), dot(g, w), dot(b, w));
62
+ }
63
+ `
64
+ );
@@ -6,16 +6,27 @@
6
6
  *
7
7
  * ```wgsl
8
8
  * fn multiscale_mean_seed(sample: vec3f) -> MultiscaleMean
9
- * fn multiscale_mean_add(e: MultiscaleMean, sample: vec3f, short_blend: f32, variance_blend: f32, mean_blend_min: f32, clip: bool) -> MultiscaleMean
9
+ * fn multiscale_mean_add(e: MultiscaleMean, sample: vec3f, short_blend: f32, variance_blend: f32, mean_blend_min: f32, clip: bool, exposure: f32) -> MultiscaleMean
10
+ * fn multiscale_mean_deviation_floor(short_mean: vec3f, exposure: f32) -> vec3f
10
11
  * ```
11
12
  *
12
13
  * `MultiscaleMean` is {@link MULTISCALE_MEAN_STRUCT}.
13
14
  *
15
+ * - **Exposure**: the factor the display multiplies the samples by ahead of its tone curve, Unreal Engine's
16
+ * `View.PreExposure`. The reference's two absolute constants, its variance floor of 1e-5 and its firefly offset
17
+ * of 0.1, are in exposed units, as Unreal states its world caches' thresholds (`MaxRayIntensity ·
18
+ * OneOverPreExposure`): over a stream scaled by 1/E at an exposure of E the estimator does what it does over
19
+ * the stream at an exposure of one, so it tells a change from noise as far as the display shows it. Held to the
20
+ * positive normal f32 range, where neither constant overflows or vanishes.
21
+ * - **Deviation floor**: the least deviation the estimator divides by, √1e-5 / exposure, and never under one
22
+ * half-float step of the short mean, `max(|short_mean|·2⁻¹⁰, 2⁻²⁴)`: the state is stored in halves, so a
23
+ * smaller gap between the means is their rounding, and the floor stays above zero at any exposure. Taken as
24
+ * `max(floor, √variance)`, the reference's `√max(floor², variance)` without squaring the floor.
14
25
  * - **Seed**: both means at the first sample, nothing of variance, no blend reduction, an inconsistency of one,
15
26
  * as WickedEngine's surfels seed it.
16
- * - **Clip**: a sample past `0.1 + short_mean + 8·deviation` a channel is held there, a firefly. The 0.1 is
17
- * the reference's, in the radiance's own units. A caller whose variance does not yet rest on a window of
18
- * samples passes `clip` false: there is no spread to clip to.
27
+ * - **Clip**: a sample past `0.1 / exposure + short_mean + 8·deviation` a channel is held there, a firefly. A
28
+ * caller whose variance does not yet rest on a window of samples passes `clip` false: there is no spread to clip
29
+ * to.
19
30
  * - **Short mean**: blended by `short_blend`; the variance by `variance_blend`, the reference's half of it, so
20
31
  * that its window outlasts the short mean's.
21
32
  * - **Long mean**: blended by the catch-up, `smoothstep(relative · max(0.02, inconsistency − 0.2))` held to
@@ -1 +1 @@
1
- {"version":3,"file":"chunk_multiscale_mean.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.js"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,oCAFU,SAAS,CA4CZ;0BAtFmB,6BAA6B"}
1
+ {"version":3,"file":"chunk_multiscale_mean.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.js"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,oCAFU,SAAS,CAuDZ;0BAhHmB,6BAA6B"}
@@ -2,6 +2,10 @@ import { CodeChunk } from "../../compiler/CodeChunk.js";
2
2
  import { chunk_rgb_to_luminance } from "../color/chunk_rgb_to_luminance.js";
3
3
  import { MULTISCALE_MEAN_STRUCT } from "./MULTISCALE_MEAN_STRUCT.js";
4
4
 
5
+ /** 2⁻¹²⁶ and 2¹²⁷, the positive normal f32 range's ends */
6
+ const EXPOSURE_MIN = '1.17549435e-38';
7
+ const EXPOSURE_MAX = '1.70141183e38';
8
+
5
9
  /**
6
10
  * The multi-scale mean estimator (MSME) of a stream of RGB samples: a long mean that blends slowly while the
7
11
  * stream is steady and noisy, and catches up with a short mean once the two disagree by more than the stream's
@@ -10,16 +14,27 @@ import { MULTISCALE_MEAN_STRUCT } from "./MULTISCALE_MEAN_STRUCT.js";
10
14
  *
11
15
  * ```wgsl
12
16
  * fn multiscale_mean_seed(sample: vec3f) -> MultiscaleMean
13
- * fn multiscale_mean_add(e: MultiscaleMean, sample: vec3f, short_blend: f32, variance_blend: f32, mean_blend_min: f32, clip: bool) -> MultiscaleMean
17
+ * fn multiscale_mean_add(e: MultiscaleMean, sample: vec3f, short_blend: f32, variance_blend: f32, mean_blend_min: f32, clip: bool, exposure: f32) -> MultiscaleMean
18
+ * fn multiscale_mean_deviation_floor(short_mean: vec3f, exposure: f32) -> vec3f
14
19
  * ```
15
20
  *
16
21
  * `MultiscaleMean` is {@link MULTISCALE_MEAN_STRUCT}.
17
22
  *
23
+ * - **Exposure**: the factor the display multiplies the samples by ahead of its tone curve, Unreal Engine's
24
+ * `View.PreExposure`. The reference's two absolute constants, its variance floor of 1e-5 and its firefly offset
25
+ * of 0.1, are in exposed units, as Unreal states its world caches' thresholds (`MaxRayIntensity ·
26
+ * OneOverPreExposure`): over a stream scaled by 1/E at an exposure of E the estimator does what it does over
27
+ * the stream at an exposure of one, so it tells a change from noise as far as the display shows it. Held to the
28
+ * positive normal f32 range, where neither constant overflows or vanishes.
29
+ * - **Deviation floor**: the least deviation the estimator divides by, √1e-5 / exposure, and never under one
30
+ * half-float step of the short mean, `max(|short_mean|·2⁻¹⁰, 2⁻²⁴)`: the state is stored in halves, so a
31
+ * smaller gap between the means is their rounding, and the floor stays above zero at any exposure. Taken as
32
+ * `max(floor, √variance)`, the reference's `√max(floor², variance)` without squaring the floor.
18
33
  * - **Seed**: both means at the first sample, nothing of variance, no blend reduction, an inconsistency of one,
19
34
  * as WickedEngine's surfels seed it.
20
- * - **Clip**: a sample past `0.1 + short_mean + 8·deviation` a channel is held there, a firefly. The 0.1 is
21
- * the reference's, in the radiance's own units. A caller whose variance does not yet rest on a window of
22
- * samples passes `clip` false: there is no spread to clip to.
35
+ * - **Clip**: a sample past `0.1 / exposure + short_mean + 8·deviation` a channel is held there, a firefly. A
36
+ * caller whose variance does not yet rest on a window of samples passes `clip` false: there is no spread to clip
37
+ * to.
23
38
  * - **Short mean**: blended by `short_blend`; the variance by `variance_blend`, the reference's half of it, so
24
39
  * that its window outlasts the short mean's.
25
40
  * - **Long mean**: blended by the catch-up, `smoothstep(relative · max(0.02, inconsistency − 0.2))` held to
@@ -55,17 +70,28 @@ fn multiscale_mean_seed(sample: vec3f) -> ${MULTISCALE_MEAN_STRUCT.wgsl_ref} {
55
70
  })};
56
71
  }
57
72
 
58
- fn multiscale_mean_add(e: ${MULTISCALE_MEAN_STRUCT.wgsl_ref}, sample: vec3f, short_blend: f32, variance_blend: f32, mean_blend_min: f32, clip: bool) -> ${MULTISCALE_MEAN_STRUCT.wgsl_ref} {
73
+ // the exposure, held to the positive normal f32 range
74
+ fn multiscale_mean_exposure(exposure: f32) -> f32 {
75
+ return clamp(exposure, ${EXPOSURE_MIN}, ${EXPOSURE_MAX});
76
+ }
77
+
78
+ fn multiscale_mean_deviation_floor(short_mean: vec3f, exposure: f32) -> vec3f {
79
+ return max(vec3f(sqrt(1e-5) / multiscale_mean_exposure(exposure)), max(abs(short_mean) * exp2(-10.0), vec3f(exp2(-24.0))));
80
+ }
81
+
82
+ fn multiscale_mean_add(e: ${MULTISCALE_MEAN_STRUCT.wgsl_ref}, sample: vec3f, short_blend: f32, variance_blend: f32, mean_blend_min: f32, clip: bool, exposure: f32) -> ${MULTISCALE_MEAN_STRUCT.wgsl_ref} {
59
83
  var y = sample;
60
84
 
61
85
  if (clip) {
62
- y = min(y, 0.1 + e.short_mean + 8.0 * sqrt(max(vec3f(1e-5), e.variance)));
86
+ let spread = max(multiscale_mean_deviation_floor(e.short_mean, exposure), sqrt(max(vec3f(0.0), e.variance)));
87
+
88
+ y = min(y, 0.1 / multiscale_mean_exposure(exposure) + e.short_mean + 8.0 * spread);
63
89
  }
64
90
 
65
91
  let delta = y - e.short_mean;
66
92
  let short_mean = mix(e.short_mean, y, short_blend);
67
93
  let variance = mix(e.variance, delta * (y - short_mean), variance_blend);
68
- let deviation = sqrt(max(vec3f(1e-5), variance));
94
+ let deviation = max(multiscale_mean_deviation_floor(short_mean, exposure), sqrt(max(vec3f(0.0), variance)));
69
95
 
70
96
  let relative = rgb_to_luminance(abs(e.mean - short_mean) / deviation);
71
97
  let inconsistency = mix(e.inconsistency, relative, short_blend);
@@ -1 +1 @@
1
- {"version":3,"file":"chunk_decode_vertex_normal.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_vertex_normal.js"],"names":[],"mappings":"AAGA,mDAcE;0BAjBwB,gCAAgC"}
1
+ {"version":3,"file":"chunk_decode_vertex_normal.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_vertex_normal.js"],"names":[],"mappings":"AAGA,mDASE;0BAZwB,gCAAgC"}
@@ -1,18 +1,13 @@
1
- import { CodeChunk } from "../../../compiler/CodeChunk.js";
2
- import { chunk_uv_octahedral_unit_decode } from "../octahedron/chunk_uv_octahedral_unit_decode.js";
3
-
4
- export const chunk_decode_vertex_normal = CodeChunk.from(
5
- //language=WGSL
6
- `
7
- fn decode_vertex_normal(base: u32) -> vec3<f32>{
8
-
9
- let decode = (vec2(base) >> vec2(0u, 16u)) & vec2(0xFFFFu, 0xFFFFu);
10
-
11
- let norm = vec2<f32>(decode) / vec2(65535.0, 65535.0);
12
-
13
- return uv_octahedral_unit_decode(norm);
14
- }
15
- `, [
16
- chunk_uv_octahedral_unit_decode,
17
- ]
18
- );
1
+ import { CodeChunk } from "../../../compiler/CodeChunk.js";
2
+ import { chunk_uv_octahedral_unit_decode } from "../octahedron/chunk_uv_octahedral_unit_decode.js";
3
+
4
+ export const chunk_decode_vertex_normal = CodeChunk.from(
5
+ //language=WGSL
6
+ `
7
+ fn decode_vertex_normal(base: u32) -> vec3<f32>{
8
+ return uv_octahedral_unit_decode(unpack2x16unorm(base));
9
+ }
10
+ `, [
11
+ chunk_uv_octahedral_unit_decode,
12
+ ]
13
+ );
@@ -1 +1 @@
1
- {"version":3,"file":"chunk_encode_vertex_normal.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/geometry/normal/chunk_encode_vertex_normal.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;GAcG;AACH,yCAFU,SAAS,CAajB;0BA7BwB,gCAAgC"}
1
+ {"version":3,"file":"chunk_encode_vertex_normal.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/geometry/normal/chunk_encode_vertex_normal.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;GAcG;AACH,yCAFU,SAAS,CAWjB;0BA3BwB,gCAAgC"}
@@ -1,30 +1,28 @@
1
- import { CodeChunk } from "../../../compiler/CodeChunk.js";
2
- import { chunk_uv_octahedral_unit_encode } from "../octahedron/chunk_uv_octahedral_unit_encode.js";
3
-
4
- /**
5
- * Inverse of `decode_vertex_normal` — packs a unit normal into a single
6
- * `u32` via octahedral-unit encoding into two 16-bit u-norms (one per
7
- * u32 half).
8
- *
9
- * Layout matches the decoder:
10
- * - bits [0, 15]: oct.x (16-bit u-norm of `uv_octahedral_unit_encode(n).x`)
11
- * - bits [16, 31]: oct.y
12
- *
13
- * Round-trips lossily — the 16-bit quantization gives ~1.5° worst-case
14
- * angular error, which is what the format buys us in exchange for the
15
- * 4-byte stride.
16
- *
17
- * @type {CodeChunk}
18
- */
19
- export const chunk_encode_vertex_normal = CodeChunk.from(
20
- //language=WGSL
21
- `
22
- fn encode_vertex_normal(n: vec3<f32>) -> u32 {
23
- let oct = uv_octahedral_unit_encode(n);
24
- let q = vec2<u32>(oct * 65535.0) & vec2<u32>(0xFFFFu, 0xFFFFu);
25
- return q.x | (q.y << 16u);
26
- }
27
- `, [
28
- chunk_uv_octahedral_unit_encode,
29
- ]
30
- );
1
+ import { CodeChunk } from "../../../compiler/CodeChunk.js";
2
+ import { chunk_uv_octahedral_unit_encode } from "../octahedron/chunk_uv_octahedral_unit_encode.js";
3
+
4
+ /**
5
+ * Inverse of `decode_vertex_normal` — packs a unit normal into a single
6
+ * `u32` via octahedral-unit encoding into two 16-bit u-norms (one per
7
+ * u32 half).
8
+ *
9
+ * Layout matches the decoder:
10
+ * - bits [0, 15]: oct.x (16-bit u-norm of `uv_octahedral_unit_encode(n).x`)
11
+ * - bits [16, 31]: oct.y
12
+ *
13
+ * Round-trips lossily — the 16-bit quantization gives ~1.5° worst-case
14
+ * angular error, which is what the format buys us in exchange for the
15
+ * 4-byte stride.
16
+ *
17
+ * @type {CodeChunk}
18
+ */
19
+ export const chunk_encode_vertex_normal = CodeChunk.from(
20
+ //language=WGSL
21
+ `
22
+ fn encode_vertex_normal(n: vec3<f32>) -> u32 {
23
+ return pack2x16unorm(uv_octahedral_unit_encode(n));
24
+ }
25
+ `, [
26
+ chunk_uv_octahedral_unit_encode,
27
+ ]
28
+ );
@@ -1 +1 @@
1
- {"version":3,"file":"chunk_unit_u32_to_vec2.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_u32_to_vec2.js"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,qCAFU,SAAS,CAUlB;0BAfyB,gCAAgC"}
1
+ {"version":3,"file":"chunk_unit_u32_to_vec2.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_u32_to_vec2.js"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,qCAFU,SAAS,CASlB;0BAdyB,gCAAgC"}
@@ -1,16 +1,15 @@
1
- import { CodeChunk } from "../../../compiler/CodeChunk.js";
2
-
3
- /**
4
- * Quantized vec2 decoding, vector values must be in [0..1] range
5
- * @see https://github.com/zhangjiangen11/godot/blob/b64ac6341347906dacdda712dc78b574334ff4af/servers/rendering/renderer_rd/shaders/skeleton.glsl#L66
6
- * @type {CodeChunk}
7
- */
8
- export const chunk_unit_u32_to_vec2 = CodeChunk.from(
9
- //language=WGSL
10
- `
11
- fn unit_u32_to_vec2(base: u32) -> vec2<f32>{
12
- let decode = (vec2(base) >> vec2(0u, 16u)) & vec2(0xFFFFu, 0xFFFFu);
13
- return vec2<f32>(decode) / vec2(65535.0, 65535.0) * 2.0 - 1.0;
14
- }
15
- `
16
- )
1
+ import { CodeChunk } from "../../../compiler/CodeChunk.js";
2
+
3
+ /**
4
+ * Quantized vec2 decoding, vector values must be in [0..1] range
5
+ * @see https://github.com/zhangjiangen11/godot/blob/b64ac6341347906dacdda712dc78b574334ff4af/servers/rendering/renderer_rd/shaders/skeleton.glsl#L66
6
+ * @type {CodeChunk}
7
+ */
8
+ export const chunk_unit_u32_to_vec2 = CodeChunk.from(
9
+ //language=WGSL
10
+ `
11
+ fn unit_u32_to_vec2(base: u32) -> vec2<f32>{
12
+ return unpack2x16unorm(base) * 2.0 - 1.0;
13
+ }
14
+ `
15
+ )
@@ -1,5 +1,4 @@
1
1
  /**
2
- * TODO consider pack2x16unorm instead
3
2
  * Quantized vec2 encoding, values must be in [0..1] range
4
3
  * @see https://github.com/zhangjiangen11/godot/blob/b64ac6341347906dacdda712dc78b574334ff4af/servers/rendering/renderer_rd/shaders/skeleton.glsl#L93
5
4
  * @type {CodeChunk}
@@ -1 +1 @@
1
- {"version":3,"file":"chunk_unit_vec2_to_u32.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_vec2_to_u32.js"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,qCAFU,SAAS,CAUjB;0BAhBwB,gCAAgC"}
1
+ {"version":3,"file":"chunk_unit_vec2_to_u32.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_vec2_to_u32.js"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,qCAFU,SAAS,CASjB;0BAdwB,gCAAgC"}
@@ -1,18 +1,15 @@
1
- import { CodeChunk } from "../../../compiler/CodeChunk.js";
2
-
3
- /**
4
- * TODO consider pack2x16unorm instead
5
- * Quantized vec2 encoding, values must be in [0..1] range
6
- * @see https://github.com/zhangjiangen11/godot/blob/b64ac6341347906dacdda712dc78b574334ff4af/servers/rendering/renderer_rd/shaders/skeleton.glsl#L93
7
- * @type {CodeChunk}
8
- */
9
- export const chunk_unit_vec2_to_u32 = CodeChunk.from(
10
- //language=WGSL
11
- `
12
- fn unit_vec2_to_u32(base:vec2<f32>) -> u32{
13
- let enc = vec2<u32>(clamp(vec2<i32>(base * vec2(65535, 65535)), vec2(0), vec2(0xFFFF, 0xFFFF))) << vec2(0u, 16u);
14
- return enc.x | enc.y;
15
- }
16
- `
17
- );
18
-
1
+ import { CodeChunk } from "../../../compiler/CodeChunk.js";
2
+
3
+ /**
4
+ * Quantized vec2 encoding, values must be in [0..1] range
5
+ * @see https://github.com/zhangjiangen11/godot/blob/b64ac6341347906dacdda712dc78b574334ff4af/servers/rendering/renderer_rd/shaders/skeleton.glsl#L93
6
+ * @type {CodeChunk}
7
+ */
8
+ export const chunk_unit_vec2_to_u32 = CodeChunk.from(
9
+ //language=WGSL
10
+ `
11
+ fn unit_vec2_to_u32(base:vec2<f32>) -> u32{
12
+ return pack2x16unorm(base);
13
+ }
14
+ `
15
+ );
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Evaluates a 2D shuffled, Owen-scrambled Sobol (0, 2)-sequence point in [0, 1)^2
3
+ * entirely in registers with zero lookup tables.
4
+ *
5
+ * Every power-of-two prefix of 2^m samples forms a fully stratified (0, m, 2)-net
6
+ * across all elementary dyadic rectangles of area 2^-m, while per-pixel seeding
7
+ * decorrelates sample sets across pixels and bounce dimensions:
8
+ *
9
+ * 1. **Index shuffling (MSB-to-LSB):** `sample_idx` is Owen-scrambled top-down via
10
+ * `reverseBits(hash_lk(reverseBits(sample_idx), ...))`. This maps every aligned
11
+ * block of 2^m contiguous indices `[k * 2^m, (k + 1) * 2^m)` bijectively onto
12
+ * another aligned 2^m block, randomizing traversal order per pixel while keeping
13
+ * bits `i_31..i_m` constant across the block so prefix stratification holds.
14
+ * 2. **Dimension 0 (Van der Corput):** Prior to radical inversion, the base-2
15
+ * Van der Corput sequence is the identity on `i`. Because bit 0 of `i` (`i_0`)
16
+ * already represents the geometric MSB (2^-1), `hash_lk` is applied directly
17
+ * followed by a single `reverseBits`.
18
+ * 3. **Dimension 1 (Sobol D1):** Computed without direction-number tables by
19
+ * multiplying `i` by the 32x32 upper-triangular Pascal matrix over GF(2)
20
+ * (`P_{k,j} = C(j, k) mod 2`, the 5-fold Kronecker power of `[1 1; 0 1]`) using
21
+ * 5 logarithmic butterfly shift-XOR stages before coordinate scrambling.
22
+ *
23
+ * For multi-bounce path tracing, pass a combined hash of `(pixel_coord, bounce_dim_pair)`
24
+ * as `pixel_seed` to construct padded 2D (0, 2)-sequences without high-dimensional
25
+ * direction tables.
26
+ *
27
+ * @see Brent Burley, "Practical Hash-based Owen Scrambling", Journal of Computer
28
+ * Graphics Techniques (JCGT), vol. 9, no. 4, pp. 1-20, 2020.
29
+ * http://jcgt.org/published/0009/04/01/
30
+ * @see Nathan Vegdahl, "Building a Better LK Hash", 2021.
31
+ * https://psychopath.io/post/2021_01_30_building_a_better_lk_hash
32
+ * @see Ilya M. Sobol', "On the distribution of points in a cube and the approximate
33
+ * evaluation of integrals", USSR Computational Mathematics and Mathematical
34
+ * Physics, vol. 7, no. 4, pp. 86-112, 1967.
35
+ *
36
+ * @type {CodeChunk}
37
+ */
38
+ export const chunk_sobol_sample_vec2: CodeChunk;
39
+ import { CodeChunk } from "../../compiler/CodeChunk.js";
40
+ //# sourceMappingURL=chunk_sobol_sample_vec2.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk_sobol_sample_vec2.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/shader/chunk/noise/chunk_sobol_sample_vec2.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,sCAFU,SAAS,CAkClB;0BA1EyB,6BAA6B"}
@@ -0,0 +1,75 @@
1
+ import { CodeChunk } from "../../compiler/CodeChunk.js";
2
+ import { chunk_hash_lk } from "../random/chunk_hash_lk.js";
3
+ import { chunk_hash_to_float01 } from "../random/chunk_hash_to_float01.js";
4
+
5
+
6
+ /**
7
+ * Evaluates a 2D shuffled, Owen-scrambled Sobol (0, 2)-sequence point in [0, 1)^2
8
+ * entirely in registers with zero lookup tables.
9
+ *
10
+ * Every power-of-two prefix of 2^m samples forms a fully stratified (0, m, 2)-net
11
+ * across all elementary dyadic rectangles of area 2^-m, while per-pixel seeding
12
+ * decorrelates sample sets across pixels and bounce dimensions:
13
+ *
14
+ * 1. **Index shuffling (MSB-to-LSB):** `sample_idx` is Owen-scrambled top-down via
15
+ * `reverseBits(hash_lk(reverseBits(sample_idx), ...))`. This maps every aligned
16
+ * block of 2^m contiguous indices `[k * 2^m, (k + 1) * 2^m)` bijectively onto
17
+ * another aligned 2^m block, randomizing traversal order per pixel while keeping
18
+ * bits `i_31..i_m` constant across the block so prefix stratification holds.
19
+ * 2. **Dimension 0 (Van der Corput):** Prior to radical inversion, the base-2
20
+ * Van der Corput sequence is the identity on `i`. Because bit 0 of `i` (`i_0`)
21
+ * already represents the geometric MSB (2^-1), `hash_lk` is applied directly
22
+ * followed by a single `reverseBits`.
23
+ * 3. **Dimension 1 (Sobol D1):** Computed without direction-number tables by
24
+ * multiplying `i` by the 32x32 upper-triangular Pascal matrix over GF(2)
25
+ * (`P_{k,j} = C(j, k) mod 2`, the 5-fold Kronecker power of `[1 1; 0 1]`) using
26
+ * 5 logarithmic butterfly shift-XOR stages before coordinate scrambling.
27
+ *
28
+ * For multi-bounce path tracing, pass a combined hash of `(pixel_coord, bounce_dim_pair)`
29
+ * as `pixel_seed` to construct padded 2D (0, 2)-sequences without high-dimensional
30
+ * direction tables.
31
+ *
32
+ * @see Brent Burley, "Practical Hash-based Owen Scrambling", Journal of Computer
33
+ * Graphics Techniques (JCGT), vol. 9, no. 4, pp. 1-20, 2020.
34
+ * http://jcgt.org/published/0009/04/01/
35
+ * @see Nathan Vegdahl, "Building a Better LK Hash", 2021.
36
+ * https://psychopath.io/post/2021_01_30_building_a_better_lk_hash
37
+ * @see Ilya M. Sobol', "On the distribution of points in a cube and the approximate
38
+ * evaluation of integrals", USSR Computational Mathematics and Mathematical
39
+ * Physics, vol. 7, no. 4, pp. 86-112, 1967.
40
+ *
41
+ * @type {CodeChunk}
42
+ */
43
+ export const chunk_sobol_sample_vec2 = CodeChunk.from(
44
+ //language=WGSL
45
+ `
46
+ fn sample_sobol_2d(sample_idx: u32, pixel_seed: u32) -> vec2<f32> {
47
+ // 1. Shuffle index (MSB -> LSB):
48
+ // Reverse sample_idx so s_31 is at bit 0, run LSB->MSB hash,
49
+ // then reverse back so i_0 is at bit 0 for Sobol generation.
50
+ let idx_seed = pixel_seed ^ 0x79c68e4au;
51
+ let i = reverseBits(hash_lk(reverseBits(sample_idx), idx_seed));
52
+
53
+ // 2. Dimension 0 (Van der Corput):
54
+ // i_0 (geometric MSB) is already at bit 0. Hash LSB->MSB, then
55
+ // reverse once so the geometric MSB sits at bit 31.
56
+ let u0 = reverseBits(hash_lk(i, pixel_seed ^ 0x9e3779b9u));
57
+
58
+ // 3. Dimension 1 (Sobol D1 via upper-triangular Pascal matrix):
59
+ // Requires i_0 at bit 0 so high bits (i_31..i_m, which are constant
60
+ // across 2^m-aligned blocks) shift down into low bits.
61
+ var b = i;
62
+ b ^= b >> 16u;
63
+ b ^= (b & 0xff00ff00u) >> 8u;
64
+ b ^= (b & 0xf0f0f0f0u) >> 4u;
65
+ b ^= (b & 0xccccccccu) >> 2u;
66
+ b ^= (b & 0xaaaaaaaau) >> 1u;
67
+ let u1 = reverseBits(hash_lk(b, pixel_seed ^ 0xbb67ae85u));
68
+
69
+ return vec2<f32>(hash_to_float01(u0), hash_to_float01(u1));
70
+ }
71
+ `,[
72
+ chunk_hash_lk,
73
+ chunk_hash_to_float01
74
+ ]
75
+ )
@@ -1 +1 @@
1
- {"version":3,"file":"chunk_vdc_radical_inverse.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/shader/chunk/noise/chunk_vdc_radical_inverse.js"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wCAFU,SAAS,CAYlB;0BAlByB,6BAA6B"}
1
+ {"version":3,"file":"chunk_vdc_radical_inverse.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/shader/chunk/noise/chunk_vdc_radical_inverse.js"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,wCAFU,SAAS,CAalB;0BApByB,6BAA6B"}
@@ -1,4 +1,5 @@
1
1
  import { CodeChunk } from "../../compiler/CodeChunk.js";
2
+ import { chunk_hash_to_float01 } from "../random/chunk_hash_to_float01.js";
2
3
 
3
4
  /**
4
5
  *
@@ -12,8 +13,9 @@ export const chunk_vdc_radical_inverse = CodeChunk.from(
12
13
  fn vdc_radical_inverse(bits:u32) -> f32{
13
14
  let b = reverseBits(bits);
14
15
 
15
- return f32(b) * 2.3283064365386963e-10;
16
+ return hash_to_float01(b);
16
17
  }
17
18
  `, [
19
+ chunk_hash_to_float01
18
20
  ]
19
21
  )