@woosh/meep-engine 3.18.0 → 3.19.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 (120) hide show
  1. package/build/bundle-worker-image-decoder.js +1 -1
  2. package/editor/view/particles/effect/ParticleCurveEditorView.d.ts.map +1 -1
  3. package/editor/view/particles/effect/ParticleCurveEditorView.js +303 -120
  4. package/editor/view/particles/effect/ParticleGradientEditorView.d.ts.map +1 -1
  5. package/editor/view/particles/effect/ParticleGradientEditorView.js +108 -63
  6. package/editor/view/particles/effect/ParticleGraphEditorView.js +1 -1
  7. package/editor/view/particles/effect/ParticleNodeParametersView.d.ts.map +1 -1
  8. package/editor/view/particles/effect/ParticleNodeParametersView.js +3 -1
  9. package/editor/view/particles/effect/particle-editor.css +60 -30
  10. package/package.json +1 -2
  11. package/samples/engine/README.md +1 -1
  12. package/src/core/binary/compression/decompress_bytes.d.ts +13 -0
  13. package/src/core/binary/compression/decompress_bytes.d.ts.map +1 -0
  14. package/src/core/binary/compression/decompress_bytes.js +28 -0
  15. package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.js +67 -22
  16. package/src/engine/asset/loaders/image/ImageDecoderWorker.js +12 -27
  17. package/src/engine/asset/loaders/image/prototypePNG.js +8 -7
  18. package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
  19. package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +4 -0
  20. package/src/engine/graphics/ecs/particles/ParticleEffect.d.ts +266 -0
  21. package/src/engine/graphics/ecs/particles/ParticleEffect.d.ts.map +1 -0
  22. package/src/engine/graphics/ecs/particles/ParticleEffect.js +455 -0
  23. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.d.ts +58 -0
  24. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.d.ts.map +1 -0
  25. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.js +219 -0
  26. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts +178 -25
  27. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts.map +1 -1
  28. package/src/engine/graphics3/GPUParticleEmitterSystem.js +809 -310
  29. package/src/format/image/png/PNGReader.d.ts +7 -6
  30. package/src/format/image/png/PNGReader.d.ts.map +1 -1
  31. package/src/format/image/png/PNGReader.js +13 -12
  32. package/src/format/image/png/chunk/png_chunk_decode_iTXt.d.ts +3 -2
  33. package/src/format/image/png/chunk/png_chunk_decode_iTXt.d.ts.map +1 -1
  34. package/src/format/image/png/chunk/png_chunk_decode_iTXt.js +5 -4
  35. package/src/format/image/png/chunk/png_chunk_decode_zTXt.d.ts +3 -2
  36. package/src/format/image/png/chunk/png_chunk_decode_zTXt.d.ts.map +1 -1
  37. package/src/format/image/png/chunk/png_chunk_decode_zTXt.js +5 -4
  38. package/src/format/image/png/png_inflate.d.ts +3 -3
  39. package/src/format/image/png/png_inflate.d.ts.map +1 -1
  40. package/src/format/image/png/png_inflate.js +29 -39
  41. package/src/format/texture/ktx2/ktx2_read.d.ts +4 -4
  42. package/src/format/texture/ktx2/ktx2_read.d.ts.map +1 -1
  43. package/src/format/texture/ktx2/ktx2_read.js +18 -21
  44. package/src/shade/playground/particle_ecs/README.md +203 -0
  45. package/src/shade/playground/particle_ecs/bonfire_editor.d.ts +39 -0
  46. package/src/shade/playground/particle_ecs/bonfire_editor.d.ts.map +1 -0
  47. package/src/shade/playground/particle_ecs/bonfire_editor.js +315 -0
  48. package/src/shade/playground/particle_ecs/bonfire_effects.d.ts +145 -0
  49. package/src/shade/playground/particle_ecs/bonfire_effects.d.ts.map +1 -0
  50. package/src/shade/playground/particle_ecs/bonfire_effects.js +202 -0
  51. package/src/shade/playground/particle_ecs/bonfire_sprites.d.ts +23 -0
  52. package/src/shade/playground/particle_ecs/bonfire_sprites.d.ts.map +1 -0
  53. package/src/shade/playground/particle_ecs/bonfire_sprites.js +315 -0
  54. package/src/shade/playground/particle_ecs/bonfire_world.d.ts +86 -0
  55. package/src/shade/playground/particle_ecs/bonfire_world.d.ts.map +1 -0
  56. package/src/shade/playground/particle_ecs/bonfire_world.js +303 -0
  57. package/src/shade/playground/particle_ecs/effects/embers.json +1634 -0
  58. package/src/shade/playground/particle_ecs/effects/flame.json +1882 -0
  59. package/src/shade/playground/particle_ecs/effects/smoke.json +1860 -0
  60. package/src/shade/playground/particle_ecs/effects/soot.json +1606 -0
  61. package/src/shade/playground/particle_ecs/index.html +330 -0
  62. package/src/shade/playground/particle_ecs/main.d.ts +2 -0
  63. package/src/shade/playground/particle_ecs/main.d.ts.map +1 -0
  64. package/src/shade/playground/particle_ecs/main.js +566 -0
  65. package/src/shade/playground/particle_ecs/moonlit_environment.d.ts +16 -0
  66. package/src/shade/playground/particle_ecs/moonlit_environment.d.ts.map +1 -0
  67. package/src/shade/playground/particle_ecs/moonlit_environment.js +144 -0
  68. package/src/shade/playground/particle_editor/README.md +5 -4
  69. package/src/shade/playground/profile_hotkey.d.ts +58 -0
  70. package/src/shade/playground/profile_hotkey.d.ts.map +1 -0
  71. package/src/shade/playground/profile_hotkey.js +325 -0
  72. package/src/shade/playground/ssr_variance/README.md +105 -0
  73. package/src/shade/playground/ssr_variance/capture.d.ts +16 -0
  74. package/src/shade/playground/ssr_variance/capture.d.ts.map +1 -0
  75. package/src/shade/playground/ssr_variance/capture.js +96 -0
  76. package/src/shade/playground/ssr_variance/index.html +22 -0
  77. package/src/shade/playground/ssr_variance/main.d.ts +2 -0
  78. package/src/shade/playground/ssr_variance/main.d.ts.map +1 -0
  79. package/src/shade/playground/ssr_variance/main.js +246 -0
  80. package/src/shade/playground/ssr_variance/reference.d.ts +18 -0
  81. package/src/shade/playground/ssr_variance/reference.d.ts.map +1 -0
  82. package/src/shade/playground/ssr_variance/reference.js +78 -0
  83. package/src/shade/playground/ssr_variance/scene.d.ts +11 -0
  84. package/src/shade/playground/ssr_variance/scene.d.ts.map +1 -0
  85. package/src/shade/playground/ssr_variance/scene.js +61 -0
  86. package/src/shade/playground/ssr_variance/statistics.d.ts +44 -0
  87. package/src/shade/playground/ssr_variance/statistics.d.ts.map +1 -0
  88. package/src/shade/playground/ssr_variance/statistics.js +51 -0
  89. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts.map +1 -1
  90. package/src/shade/renderer/loader/gltf/tiny-gltf.js +9 -3
  91. package/src/shade/renderer/loader/usd/usd_decode_image.d.ts +4 -4
  92. package/src/shade/renderer/loader/usd/usd_decode_image.d.ts.map +1 -1
  93. package/src/shade/renderer/loader/usd/usd_decode_image.js +4 -4
  94. package/src/shade/renderer/particles/DESIGN.md +748 -703
  95. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +11 -4
  96. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -1
  97. package/src/shade/renderer/particles/runtime/ParticleEmitter.js +431 -424
  98. package/src/shade/renderer/postprocess/ssr/SSR.d.ts.map +1 -1
  99. package/src/shade/renderer/postprocess/ssr/SSR.js +2 -1
  100. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_reprojection.d.ts.map +1 -1
  101. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_reprojection.js +0 -6
  102. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_sample_history.d.ts.map +1 -1
  103. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_sample_history.js +19 -5
  104. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.d.ts +4 -0
  105. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.d.ts.map +1 -0
  106. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.js +133 -0
  107. package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.d.ts +0 -8
  108. package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.d.ts.map +1 -1
  109. package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.js +16 -113
  110. package/src/shade/renderer/texture/source/texel_data_from_ktx2.d.ts +2 -2
  111. package/src/shade/renderer/texture/source/texel_data_from_ktx2.d.ts.map +1 -1
  112. package/src/shade/renderer/texture/source/texel_data_from_ktx2.js +3 -3
  113. package/src/shade/renderer/particles/shaders/chunk_particle_emitter_warmup.d.ts +0 -20
  114. package/src/shade/renderer/particles/shaders/chunk_particle_emitter_warmup.d.ts.map +0 -1
  115. package/src/shade/renderer/particles/shaders/chunk_particle_emitter_world_sphere.d.ts +0 -14
  116. package/src/shade/renderer/particles/shaders/chunk_particle_emitter_world_sphere.d.ts.map +0 -1
  117. package/src/shade/renderer/particles/shaders/shader_particle_reclaim.d.ts +0 -50
  118. package/src/shade/renderer/particles/shaders/shader_particle_reclaim.d.ts.map +0 -1
  119. package/src/shade/renderer/postprocess/ssr/reproject/shader_ffx_denoiser_reflections_reproject.d.ts +0 -17
  120. package/src/shade/renderer/postprocess/ssr/reproject/shader_ffx_denoiser_reflections_reproject.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"SSR.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/postprocess/ssr/SSR.js"],"names":[],"mappings":"AAiBA;IAyDI;;;OAGG;IACH,sBAFW,OAAO,0BAA0B,EAAE,eAAe,EAiB5D;IA1DD,oBAAgB;IAMhB,4CAOC;IATD,iGAAiG;IACjG,yCAA2E;IA0B3E,gCAMC;IAZD;;;;OAIG;IACH,6BAAmD;IAbnD,mCAMC;IARD,qCAAqC;IACrC,gCAA2D;IA4C3D;;;;OAIG;IACH,UAHW,MAAM,KACN,MAAM,QAUhB;IAED;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH;QAtBsG,KAAK,EAAhG,OAAO,8DAA8D,EAAE,UAAU;QACjE,WAAW,EAA3B,MAAM;QACW,oBAAoB,GAArC,MAAM;QACU,SAAS,EAAzB,MAAM;QACU,iBAAiB,EAAjC,MAAM;QACU,YAAY,EAA5B,MAAM;QACU,SAAS,EAAzB,MAAM;QACU,YAAY,EAA5B,MAAM;QACU,cAAc,EAA9B,MAAM;QACU,eAAe,EAA/B,MAAM;QACW,iBAAiB,GAAlC,MAAM;QACqB,UAAU,EAArC,UAAU,MAAM,CAAC;QACD,cAAc,EAA9B,MAAM;QACU,eAAe,EAA/B,MAAM;QAC8B,sBAAsB,GAA1D,yBAAyB;QAC6D,MAAM,GAA5F,OAAO,oDAAoD,EAAE,cAAc;QACkB,GAAG,GAAhG,OAAO,sDAAsD,EAAE,mBAAmB;QAClB,QAAQ,GAAxE,OAAO,8BAA8B,EAAE,cAAc;QACzB,MAAM,GAAlC,UAAU,MAAM,CAAC;QACA,GAAG,GAApB,MAAM;;eACG,MAAM;eAAQ,MAAM;qBAAc,MAAM;kBAAW,MAAM;oBAAa,MAAM;MAkQ/F;;CACJ;0CAxYyC,oCAAoC"}
1
+ {"version":3,"file":"SSR.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/postprocess/ssr/SSR.js"],"names":[],"mappings":"AAiBA;IAyDI;;;OAGG;IACH,sBAFW,OAAO,0BAA0B,EAAE,eAAe,EAkB5D;IA3DD,oBAAgB;IAMhB,4CAOC;IATD,iGAAiG;IACjG,yCAA2E;IA0B3E,gCAMC;IAZD;;;;OAIG;IACH,6BAAmD;IAbnD,mCAMC;IARD,qCAAqC;IACrC,gCAA2D;IA6C3D;;;;OAIG;IACH,UAHW,MAAM,KACN,MAAM,QAUhB;IAED;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH;QAtBsG,KAAK,EAAhG,OAAO,8DAA8D,EAAE,UAAU;QACjE,WAAW,EAA3B,MAAM;QACW,oBAAoB,GAArC,MAAM;QACU,SAAS,EAAzB,MAAM;QACU,iBAAiB,EAAjC,MAAM;QACU,YAAY,EAA5B,MAAM;QACU,SAAS,EAAzB,MAAM;QACU,YAAY,EAA5B,MAAM;QACU,cAAc,EAA9B,MAAM;QACU,eAAe,EAA/B,MAAM;QACW,iBAAiB,GAAlC,MAAM;QACqB,UAAU,EAArC,UAAU,MAAM,CAAC;QACD,cAAc,EAA9B,MAAM;QACU,eAAe,EAA/B,MAAM;QAC8B,sBAAsB,GAA1D,yBAAyB;QAC6D,MAAM,GAA5F,OAAO,oDAAoD,EAAE,cAAc;QACkB,GAAG,GAAhG,OAAO,sDAAsD,EAAE,mBAAmB;QAClB,QAAQ,GAAxE,OAAO,8BAA8B,EAAE,cAAc;QACzB,MAAM,GAAlC,UAAU,MAAM,CAAC;QACA,GAAG,GAApB,MAAM;;eACG,MAAM;eAAQ,MAAM;qBAAc,MAAM;kBAAW,MAAM;oBAAa,MAAM;MAkQ/F;;CACJ;0CAzYyC,oCAAoC"}
@@ -80,7 +80,8 @@ export class SSR {
80
80
 
81
81
  for (const [history, format, label] of [
82
82
  [this.#history, "rgba16float", "radiance"],
83
- [this.#metadata, "rg32float", "metadata"],
83
+ // xy: reflected distance/support, z: history age, w: short-term luminance.
84
+ [this.#metadata, "rgba32float", "metadata"],
84
85
  [this.#geometry, "rgba16float", "geometry"],
85
86
  ]) {
86
87
  for (let i = 0; i < 2; i++) {
@@ -1 +1 @@
1
- {"version":3,"file":"chunk_ssr_reprojection.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_reprojection.js"],"names":[],"mappings":"AAIA,+CAyBuC;0BA7Bb,uCAAuC"}
1
+ {"version":3,"file":"chunk_ssr_reprojection.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_reprojection.js"],"names":[],"mappings":"AAIA,+CAmBuC;0BAvBb,uCAAuC"}
@@ -21,10 +21,4 @@ fn ssr_surface_history_uv(pixel: vec2f, velocity: vec2f, jitter_delta: vec2f, si
21
21
  return (pixel - velocity + jitter_delta) / size;
22
22
  }
23
23
 
24
- // Apply confidence LAST. Variance and clamp heuristics cannot resurrect rejected history.
25
- fn ssr_history_weight(current_variance: f32, history_variance: f32, current_blend: f32, confidence: f32) -> f32 {
26
- let c = current_blend / (1.0 + max(current_variance, 0.0));
27
- let h = (1.0 - current_blend) / (1.0 + max(history_variance, 0.0));
28
- return h / max(c + h, 1e-20) * saturate(confidence);
29
- }
30
24
  `, [chunk_ndc_to_uv, chunk_is_finite]);
@@ -1 +1 @@
1
- {"version":3,"file":"chunk_ssr_sample_history.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_sample_history.js"],"names":[],"mappings":"AAUA,8FAA8F;AAC9F,iDA0DkD;0BArExB,uCAAuC"}
1
+ {"version":3,"file":"chunk_ssr_sample_history.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_sample_history.js"],"names":[],"mappings":"AAUA,8FAA8F;AAC9F,iDAwEkD;0BAnFxB,uCAAuC"}
@@ -13,6 +13,8 @@ export const chunk_ssr_sample_history = CodeChunk.from(/* language=WGSL */ `
13
13
  struct SSRHistorySample {
14
14
  radiance: vec4f,
15
15
  confidence: f32,
16
+ age: f32,
17
+ short_luma: f32,
16
18
  }
17
19
 
18
20
  fn ssr_sample_history(
@@ -43,10 +45,12 @@ fn ssr_sample_history(
43
45
  texel_coordinate_to_uv(vec2f(coord), size), depth, camera_previous.view_projection_matrix_inverse);
44
46
  let plane_distance = abs(point_distance_above_plane(previous_position, plane));
45
47
  if (!is_finite(plane_distance) || plane_distance > plane_tolerance) { continue; }
46
- let previous_metadata = textureLoad(tHistoryMetadata, coord, 0).rg;
48
+ let previous_metadata = textureLoad(tHistoryMetadata, coord, 0);
47
49
  if (!is_finite(previous_metadata.x) || !is_finite(previous_metadata.y)) { continue; }
48
- // A source/support transition must not preserve the previous, unrelated reflection.
49
- if (abs(previous_metadata.y - metadata.y) > 0.25) { continue; }
50
+ if (!is_finite(previous_metadata.z) || !is_finite(previous_metadata.w)) { continue; }
51
+ // On a rough reflector, hit/miss support is itself a stochastic sample. It is
52
+ // not evidence that the receiving surface or the reflected scene has moved.
53
+ if (roughness <= 0.2 && abs(previous_metadata.y - metadata.y) > 0.25) { continue; }
50
54
  var support = 1.0;
51
55
  if (virtual_candidate) {
52
56
  if (previous_metadata.y < 0.5 || previous_metadata.x <= 0.0) { continue; }
@@ -59,10 +63,20 @@ fn ssr_sample_history(
59
63
  let radiance = textureLoad(tHistory, coord, 0);
60
64
  if (!is_finite(radiance.x) || !is_finite(radiance.y) || !is_finite(radiance.z) || !is_finite(radiance.w)) { continue; }
61
65
  let w = weights[i] * support;
62
- result.radiance += max(radiance, vec4f(0.0)) * w;
66
+ let age = clamp(previous_metadata.z, 1.0, 128.0);
67
+ // Reconstruct each tap's distribution variance BEFORE interpolation.
68
+ // E[variance/age] * E[age] can wildly inflate noise at an age boundary.
69
+ result.radiance += max(radiance, vec4f(0.0)) * vec4f(w,w,w,w*age);
70
+ result.age += age * w;
71
+ result.short_luma += previous_metadata.w * w;
63
72
  result.confidence += w;
64
73
  }
65
- if (result.confidence > 1e-6) { result.radiance /= result.confidence; }
74
+ if (result.confidence > 1e-6) {
75
+ result.radiance /= result.confidence;
76
+ result.age /= result.confidence;
77
+ result.radiance.w /= result.age;
78
+ result.short_luma /= result.confidence;
79
+ }
66
80
  return result;
67
81
  }
68
82
  `, [chunk_project_position_from_depth, chunk_is_background, chunk_plane_from_normal_and_point,
@@ -0,0 +1,4 @@
1
+ /** Linear radiance accumulation. Spatial contrast and single stochastic hits are not motion. */
2
+ export const chunk_ssr_temporal_accumulate: CodeChunk;
3
+ import { CodeChunk } from "../../../shader/compiler/CodeChunk.js";
4
+ //# sourceMappingURL=chunk_ssr_temporal_accumulate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk_ssr_temporal_accumulate.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.js"],"names":[],"mappings":"AAUA,gGAAgG;AAChG,sDAyHuH;0BApI7F,uCAAuC"}
@@ -0,0 +1,133 @@
1
+ import { CodeChunk } from "../../../shader/compiler/CodeChunk.js";
2
+ import { chunk_rgb_to_luminance } from "../../../shader/chunk/color/chunk_rgb_to_luminance.js";
3
+ import { chunk_decode_g_buffer_normal } from "../../../shader/chunk/geometry/normal/chunk_decode_g_buffer_normal.js";
4
+ import { chunk_is_finite } from "../../../shader/chunk/math/chunk_is_finite.js";
5
+ import { chunk_decode_g_buffer_roughness } from "../../../shader/chunk/material/chunk_decode_g_buffer_roughness.js";
6
+ import { chunk_project_position_from_depth } from "../../../shader/chunk/camera/chunk_project_position_from_depth.js";
7
+ import { chunk_texel_coordinate_to_uv } from "../../../shader/chunk/texture/chunk_texel_coordinate_to_uv.js";
8
+ import { chunk_get_view_space_depth } from "../../../shader/chunk/depth/chunk_get_view_space_depth.js";
9
+ import { chunk_is_background } from "../../../shader/chunk/depth/chunk_is_background.js";
10
+
11
+ /** Linear radiance accumulation. Spatial contrast and single stochastic hits are not motion. */
12
+ export const chunk_ssr_temporal_accumulate = CodeChunk.from(/* language=WGSL */ `
13
+ const SSR_SHORT_BLEND = 0.25;
14
+ const SSR_SHORT_VARIANCE_SCALE = SSR_SHORT_BLEND / (2.0-SSR_SHORT_BLEND);
15
+
16
+ struct SSRAccumulation {
17
+ radiance: vec4f,
18
+ age: f32,
19
+ short_luma: f32,
20
+ }
21
+
22
+ fn ssr_temporal_accumulate(current: vec4f, previous: vec4f, previous_age: f32,
23
+ previous_short_luma: f32, confidence: f32, motion_confidence: f32, st: vec2i, history_uv: vec2f) -> SSRAccumulation {
24
+ let old_age = clamp(previous_age, 1.0, 128.0);
25
+ let current_luma = rgb_to_luminance(current.rgb);
26
+ let previous_luma = rgb_to_luminance(previous.rgb);
27
+ // Alpha describes uncertainty in the accumulated mean. Recover the estimated
28
+ // distribution variance before judging whether a new sample is surprising.
29
+ let previous_variance = max(0.0, previous.w) * old_age;
30
+ let short_luma = mix(previous_short_luma, current_luma, SSR_SHORT_BLEND);
31
+ let short_delta = current_luma - previous_short_luma;
32
+ // Noise statistics need a short window too: long-lived variance would hide a
33
+ // real transition from a noisy bright reflection to a steady dark surface.
34
+ let sample_variance = (1.0-SSR_SHORT_BLEND) * (previous_variance + SSR_SHORT_BLEND * short_delta * short_delta);
35
+ // Compare two means at different time scales, normalized by sampling noise.
36
+ // The previous implementation compared the mean with ONE noisy sample and
37
+ // discarded useful history on almost every bright ray hit.
38
+ let short_sigma = sqrt(max(1e-6, sample_variance * SSR_SHORT_VARIANCE_SCALE));
39
+ let inconsistency = abs(short_luma - previous_luma) / short_sigma;
40
+ var reactive = smoothstep(3.0, 6.0, inconsistency);
41
+
42
+ // A 5x5 neighbourhood sees beyond the small prefilter. Persistent temporal
43
+ // uncertainty keeps a chance cluster of misses from clipping a valid mean to
44
+ // black. Real geometry and coherent lighting changes can still rectify it.
45
+ let size = vec2i(textureDimensions(tInput));
46
+ let center_normal = decode_g_buffer_normal(textureLoad(tNormal, st, 0).xy);
47
+ let center_depth = textureLoad(tDepth, st, 0).r;
48
+ let center_roughness = decode_g_buffer_roughness(textureLoad(tPBR, st, 0));
49
+ var first = vec3f(0.0);
50
+ var second = vec3f(0.0);
51
+ var count = 0.0;
52
+ var history_mean = 0.0;
53
+ var short_mean = 0.0;
54
+ var noise_sum = 0.0;
55
+ var history_count = 0.0;
56
+ let history_st = vec2i(history_uv * vec2f(size));
57
+ for (var y = -2; y <= 2; y++) {
58
+ for (var x = -2; x <= 2; x++) {
59
+ let p = st + vec2i(x,y);
60
+ if (any(p < vec2i(0)) || any(p >= size)) { continue; }
61
+ let normal = decode_g_buffer_normal(textureLoad(tNormal, p, 0).xy);
62
+ let depth = textureLoad(tDepth, p, 0).r;
63
+ if (is_background(depth)) { continue; }
64
+ let roughness = decode_g_buffer_roughness(textureLoad(tPBR, p, 0));
65
+ if (!(abs(roughness-center_roughness) <= 0.08)) { continue; }
66
+ if (dot(normal,center_normal) < 0.9 || abs(depth-center_depth) > max(1e-4, center_depth*0.02)) { continue; }
67
+ let c = textureLoad(tInput, p, 0).rgb;
68
+ first += c;
69
+ second += c*c;
70
+ count += 1.0;
71
+ // Compare local short- and long-term means. A moving rough reflection
72
+ // can change many individually low-SNR pixels coherently. One noisy
73
+ // pixel cannot establish that, but a matched patch can.
74
+ let h = history_st + vec2i(x,y);
75
+ if (any(h < vec2i(0)) || any(h >= size)) { continue; }
76
+ let old_geometry = textureLoad(tHistoryGeometry,h,0);
77
+ if (!(dot(old_geometry.xyz,normal) >= 0.9)) { continue; }
78
+ if (!(abs(old_geometry.w-roughness) <= 0.08)) { continue; }
79
+ // Device depths belong to different cameras. Validate the old point
80
+ // against the current surface in world space, as the history gather does.
81
+ let old_depth = textureLoad(tPreviousDepth,h,0).r;
82
+ if (is_background(old_depth)) { continue; }
83
+ let position = project_position_from_depth(texel_coordinate_to_uv(vec2f(p),vec2u(size)),depth,camera_current.view_projection_matrix_inverse);
84
+ let old_position = project_position_from_depth(texel_coordinate_to_uv(vec2f(h),vec2u(size)),old_depth,camera_previous.view_projection_matrix_inverse);
85
+ let plane_distance = abs(dot(normal,old_position-position));
86
+ let tolerance = max(1e-4,0.002*get_view_space_depth(depth,camera_current));
87
+ if (!(plane_distance <= tolerance)) { continue; }
88
+ let old = textureLoad(tHistory,h,0);
89
+ let old_metadata = textureLoad(tHistoryMetadata,h,0);
90
+ if (!is_finite(old.x) || !is_finite(old.y) || !is_finite(old.z) || !is_finite(old.w)
91
+ || !is_finite(old_metadata.z) || !is_finite(old_metadata.w)) { continue; }
92
+ let luma = rgb_to_luminance(c);
93
+ let d = luma-old_metadata.w;
94
+ history_mean += rgb_to_luminance(old.rgb);
95
+ short_mean += mix(old_metadata.w,luma,SSR_SHORT_BLEND);
96
+ noise_sum += (1.0-SSR_SHORT_BLEND) * (max(0.0,old.w)*clamp(old_metadata.z,1.0,128.0) + SSR_SHORT_BLEND*d*d);
97
+ history_count += 1.0;
98
+ }
99
+ }
100
+ if (history_count >= 9.0) {
101
+ // The 3x3 prefilter correlates adjacent samples: use a conservative nine
102
+ // taps per independent observation instead of claiming 25 independent rays.
103
+ let sigma = sqrt(max(1e-6,noise_sum*SSR_SHORT_VARIANCE_SCALE*9.0));
104
+ reactive = max(reactive,smoothstep(3.0,6.0,abs(short_mean-history_mean)/sigma));
105
+ }
106
+ // Blend update rates, not history lengths: halfway from 128 to two frames
107
+ // would still retain ~98% history and barely respond to a detected change.
108
+ let mature_age = min(128.0, old_age * confidence + 1.0);
109
+ var age = 1.0 / mix(1.0/mature_age, 0.5, reactive);
110
+ let mean = first / max(1.0,count);
111
+ // The carried variance is in luminance units. Expand RGB bounds along the
112
+ // history color, otherwise saturated blue gets only 7.22% of its RGB sigma
113
+ // and a normal stochastic miss can erase an already converged reflection.
114
+ let noise_color = select(vec3f(1.0),previous.rgb/max(previous_luma,1e-6),previous_luma > 1e-6);
115
+ let deviation = sqrt(max(noise_color*noise_color*previous_variance, second / max(1.0,count) - mean*mean));
116
+ let gamma = mix(1.5, 4.0, motion_confidence);
117
+ let clipped = clamp(previous.rgb, max(vec3f(0.0),mean-gamma*deviation), mean+gamma*deviation);
118
+ // Once history is outside even the noise-expanded box, it is no longer a
119
+ // well-supported long-term estimate. Do not leave it pinned to a clipped edge.
120
+ let rectified = any(abs(previous.rgb-clipped) > vec3f(1e-5));
121
+ if (rectified) { age = min(age, 2.0); }
122
+ let weight = min(saturate(confidence), 1.0 - 1.0/age);
123
+ let color = mix(current.rgb, clipped, weight);
124
+ var result: SSRAccumulation;
125
+ // Post-spatial passes receive uncertainty of the mean, rather than the raw
126
+ // sample distribution or the resolve pass's within-ray variance.
127
+ result.radiance = vec4f(color, min(65504.0,sample_variance/age));
128
+ result.age = age;
129
+ result.short_luma = select(short_luma, rgb_to_luminance(color), rectified);
130
+ return result;
131
+ }
132
+ `, [chunk_rgb_to_luminance, chunk_decode_g_buffer_normal, chunk_is_finite, chunk_decode_g_buffer_roughness,
133
+ chunk_project_position_from_depth, chunk_texel_coordinate_to_uv, chunk_get_view_space_depth, chunk_is_background]);
@@ -1,11 +1,3 @@
1
- /**
2
- * Note: result will be in YCoCg color space
3
- * @see https://projects.blender.org/blender/blender/src/commit/866ef5b468589587395b1ee7480ea75b4c0fbc26/source/blender/draw/engines/eevee_next/shaders/eevee_film_lib.glsl#L340
4
- * @see https://github.com/GameTechDev/TAA/blob/39786709cf70a1e0906196c600f6079571a33ceb/MiniEngine/Core/Shaders/TAAResolve.hlsl#L472
5
- * @type {CodeChunk}
6
- */
7
- export const chunk_ssr_history_color_bounding_box_YCoCg: CodeChunk;
8
1
  export const ssr_reproject_shader: ImageShader;
9
- import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
10
2
  import { ImageShader } from "../../shader/ImageShader.js";
11
3
  //# sourceMappingURL=ssr_reproject_shader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ssr_reproject_shader.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/postprocess/ssr/ssr_reproject_shader.js"],"names":[],"mappings":"AAuCA;;;;;GAKG;AACH,yDAFU,SAAS,CA+ElB;AA2ED,+CAGG;0BAjMuB,oCAAoC;4BAClC,6BAA6B"}
1
+ {"version":3,"file":"ssr_reproject_shader.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/postprocess/ssr/ssr_reproject_shader.js"],"names":[],"mappings":"AAoGA,+CAGG;4BAjGyB,6BAA6B"}
@@ -1,6 +1,4 @@
1
1
  import { CAMERA_UNIFORM_STRUCT } from "../../camera/CAMERA_UNIFORM_STRUCT.js";
2
- import { chunk_aabb3_normalized_dist } from "../../shader/chunk/geometry/aabb3/chunk_line_aabb3_clipping_distance.js";
3
- import { chunk_get_std_dev3 } from "../../shader/chunk/math/statistics/chunk_get_std_dev3.js";
4
2
  import { chunk_screen_coordinate_to_world } from "../../shader/chunk/camera/chunk_screen_coordinate_to_world.js";
5
3
  import { chunk_get_view_space_depth } from "../../shader/chunk/depth/chunk_get_view_space_depth.js";
6
4
  import { chunk_decode_g_buffer_normal } from "../../shader/chunk/geometry/normal/chunk_decode_g_buffer_normal.js";
@@ -11,13 +9,12 @@ import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourc
11
9
  import { ShaderDescriptor } from "../../shader/ShaderDescriptor.js";
12
10
  import { WebGPUStruct } from "../../shader/type/WebGPUStruct.js";
13
11
  import { f32, u32, vec2f } from "../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
14
- import { chunk_color_clip_to_aabb3 } from "../taa/chunk_color_clip_to_aabb3.js";
15
- import { chunk_taa_decode_color } from "../taa/chunk_taa_decode_color.js";
16
- import { chunk_taa_encode_color } from "../taa/chunk_taa_encode_color.js";
17
- import { chunk_taa_velocity_confidence, chunk_taa_velocity_variance_scale } from "../taa/shader_taa.js";
12
+ import { chunk_taa_velocity_confidence } from "../taa/shader_taa.js";
18
13
  import { chunk_depth_clip_offset_codec } from "../taa/chunk_depth_clip_offset_codec.js";
19
14
  import { chunk_ssr_reprojection } from "./reproject/chunk_ssr_reprojection.js";
20
15
  import { chunk_ssr_sample_history } from "./reproject/chunk_ssr_sample_history.js";
16
+ import { chunk_ssr_temporal_accumulate } from "./reproject/chunk_ssr_temporal_accumulate.js";
17
+ import { chunk_rgb_to_luminance } from "../../shader/chunk/color/chunk_rgb_to_luminance.js";
21
18
 
22
19
  const settings = WebGPUStruct.from({ history_validity: f32, reprojection_mode: u32, jitter_delta: vec2f });
23
20
  const resources = new ShaderResourceSetDescriptor();
@@ -37,96 +34,10 @@ resources.createGroup()
37
34
  .addUniform("camera_current", CAMERA_UNIFORM_STRUCT)
38
35
  .addUniform("camera_previous", CAMERA_UNIFORM_STRUCT);
39
36
 
40
- /**
41
- * Note: result will be in YCoCg color space
42
- * @see https://projects.blender.org/blender/blender/src/commit/866ef5b468589587395b1ee7480ea75b4c0fbc26/source/blender/draw/engines/eevee_next/shaders/eevee_film_lib.glsl#L340
43
- * @see https://github.com/GameTechDev/TAA/blob/39786709cf70a1e0906196c600f6079571a33ceb/MiniEngine/Core/Shaders/TAAResolve.hlsl#L472
44
- * @type {CodeChunk}
45
- */
46
- export const chunk_ssr_history_color_bounding_box_YCoCg = CodeChunk.from(
47
- //language=WGSL
48
- `
49
- fn ssr_history_color_bounding_box_YCoCg(
50
- current_color_texture: texture_2d<f32>,
51
- in_current_colour_variance:vec4<f32>,
52
- in_screen_st:vec2<i32>,
53
-
54
- in_variance_gamma: f32,
55
-
56
- out_min_c: ptr< function, vec3<f32> >,
57
- out_max_c: ptr< function, vec3<f32> >,
58
- ) {
59
-
60
- const offsets = array< vec2<i32>,8>(
61
- vec2( -1, -1 ),
62
- vec2( 0, -1 ),
63
- vec2( 1, -1 ),
64
-
65
- vec2( -1, 0 ),
66
- vec2( 1, 0 ),
67
-
68
- vec2( -1, 1 ),
69
- vec2( 0, 1 ),
70
- vec2( 1, 1 ),
71
- );
72
-
73
- const iteratorMax = 8;
74
- const rcp_divider = 1.f / 9.f;
75
-
76
- // calcluate mean value (mean) and standard deviation (variance)
77
-
78
- var moment1 = in_current_colour_variance.rgb;
79
- var moment2 = moment1*moment1;
80
- var source_variance = in_current_colour_variance.w;
81
-
82
- for (var i = 0; i < iteratorMax; i++ ) {
83
- let new_st = clamp(in_screen_st + offsets[i], vec2i(0), vec2i(textureDimensions(current_color_texture)) - 1);
84
-
85
- let texel = textureLoad( current_color_texture, new_st, 0 );
86
- let new_colour = taa_encode_color( texel.rgb );
87
-
88
- moment1 += new_colour;
89
- moment2 += new_colour*new_colour;
90
-
91
- source_variance += texel.w;
92
- }
93
-
94
- source_variance *= rcp_divider;
95
-
96
- // get resolve-stage standard deviation
97
- let source_std_dev = sqrt(source_variance);
98
-
99
- // Apply perceptual weighting to variance.
100
- // Y (Luma) is critical for structural sharpness -> Keep strict (1.0x).
101
- // Co/Cg (Chroma) is less noticeable to human perception -> Relax to prevent color flickering/desaturation.
102
- // Cg (green) has stronger visual response than Co (orange) to human perception
103
- const variance_scale = vec3(1.0, 1.4, 1.2);
104
-
105
- // Apply the base gamma to the perceptual scale
106
- let final_sigma = variance_scale * in_variance_gamma * (1 + source_std_dev);
107
-
108
- let mean = moment1 * rcp_divider;
109
- let std_dev = get_std_dev3(mean, moment2 * rcp_divider );
110
-
111
- let sigma = std_dev * final_sigma;
112
-
113
- *out_min_c = mean - sigma;
114
- *out_max_c = mean + sigma;
115
-
116
- }
117
- `,
118
- [
119
- chunk_get_std_dev3,
120
- chunk_taa_decode_color,
121
- chunk_taa_encode_color,
122
- ]
123
- )
124
-
125
-
126
37
  const body = CodeChunk.from(/* language=WGSL */ `
127
38
  struct SSRTemporalOutput {
128
39
  @location(0) radiance: vec4f,
129
- @location(1) metadata: vec2f,
40
+ @location(1) metadata: vec4f,
130
41
  @location(2) geometry: vec4f,
131
42
  }
132
43
 
@@ -139,7 +50,7 @@ fn main(@builtin(position) coord: vec4f) -> SSRTemporalOutput {
139
50
  let roughness = decode_g_buffer_roughness(textureLoad(tPBR, st, 0));
140
51
  var output: SSRTemporalOutput;
141
52
  output.radiance = current;
142
- output.metadata = metadata;
53
+ output.metadata = vec4f(metadata, 1.0, rgb_to_luminance(current.rgb));
143
54
  output.geometry = vec4f(normal, roughness);
144
55
  let depth = textureLoad(tDepth, st, 0).r;
145
56
  // A reset must never read history, even when stale textures contain non-finite values.
@@ -153,9 +64,11 @@ fn main(@builtin(position) coord: vec4f) -> SSRTemporalOutput {
153
64
  var history: SSRHistorySample;
154
65
  var confidence = 0.0;
155
66
  var motion_confidence = 1.0;
67
+ var history_uv = vec2f(0.0);
156
68
  let virtual_eligible = settings.reprojection_mode != 1u && metadata.y >= 0.75 && metadata.x > 0.0 && is_finite(metadata.x) && roughness <= 0.2;
157
69
  if (virtual_eligible) {
158
70
  let uv = ssr_history_uv(virtual_position, camera_previous.view_projection_matrix);
71
+ history_uv = uv;
159
72
  history = ssr_sample_history(uv, position, normal, roughness, metadata, virtual_position, true, plane_tolerance);
160
73
  confidence = history.confidence;
161
74
  }
@@ -165,6 +78,7 @@ fn main(@builtin(position) coord: vec4f) -> SSRTemporalOutput {
165
78
  let surface_confidence = textureLoad(tOcclusion, st, 0).r * motion_confidence;
166
79
  if (surface_confidence <= 0.001) { return output; }
167
80
  let uv = ssr_surface_history_uv(coord.xy, velocity, settings.jitter_delta, size);
81
+ history_uv = uv;
168
82
  history = ssr_sample_history(uv, position, normal, roughness, metadata, virtual_position, false, plane_tolerance);
169
83
  confidence = history.confidence * surface_confidence;
170
84
  // Surface correspondence alone cannot justify a long history for a smooth finite reflection.
@@ -172,30 +86,19 @@ fn main(@builtin(position) coord: vec4f) -> SSRTemporalOutput {
172
86
  }
173
87
  if (confidence <= 0.001) { return output; }
174
88
 
175
- let current_color = taa_encode_color(current.rgb);
176
- let history_color = taa_encode_color(history.radiance.rgb);
177
- var min_c: vec3f;
178
- var max_c: vec3f;
179
- ssr_history_color_bounding_box_YCoCg(tInput, vec4f(current_color, current.w), st,
180
- 2.0 * taa_velocity_variance_scale(motion_confidence), &min_c, &max_c);
181
- let clipped = color_clip_to_aabb3(history_color, current_color, min_c, max_c);
182
- let tension = saturate(aabb3_normalized_dist_from_center(current_color, clipped, min_c, max_c));
183
- let blend = 0.05 * mix(0.2, 1.0, tension * tension);
184
- // Geometry cannot see motion of the reflected object. Respond to radiance disagreement too.
185
- let difference = length(history_color - current_color);
186
- let reactive = 1.0 / (1.0 + 16.0 * difference);
187
- let weight = ssr_history_weight(current.w, history.radiance.w, blend, confidence * reactive);
188
- output.radiance = vec4f(taa_decode_color(mix(current_color, clipped, weight)),
189
- mix(current.w, history.radiance.w, weight));
89
+ let accumulated = ssr_temporal_accumulate(current, history.radiance, history.age,
90
+ history.short_luma, confidence, motion_confidence, st, history_uv);
91
+ output.radiance = accumulated.radiance;
92
+ output.metadata.z = accumulated.age;
93
+ output.metadata.w = accumulated.short_luma;
190
94
  return output;
191
95
  }
192
96
  `, [chunk_ssr_reprojection, chunk_ssr_sample_history, chunk_screen_coordinate_to_world,
193
97
  chunk_get_view_space_depth, chunk_decode_g_buffer_normal, chunk_decode_g_buffer_roughness,
194
- chunk_depth_clip_offset_codec, chunk_taa_encode_color, chunk_taa_decode_color,
195
- chunk_ssr_history_color_bounding_box_YCoCg, chunk_color_clip_to_aabb3,
196
- chunk_aabb3_normalized_dist, chunk_taa_velocity_confidence, chunk_taa_velocity_variance_scale]);
98
+ chunk_depth_clip_offset_codec, chunk_taa_velocity_confidence,
99
+ chunk_ssr_temporal_accumulate, chunk_rgb_to_luminance]);
197
100
 
198
101
  export const ssr_reproject_shader = new ImageShader({
199
102
  descriptor: ShaderDescriptor.from({ label: "SSR Reproject", body, resources }),
200
- targets: [{ format: "rgba16float" }, { format: "rg32float" }, { format: "rgba16float" }],
103
+ targets: [{ format: "rgba16float" }, { format: "rgba32float" }, { format: "rgba16float" }],
201
104
  });
@@ -21,12 +21,12 @@
21
21
  * @param {ArrayBuffer|Uint8Array} bytes the whole file
22
22
  * @param {TextureFormat|TextureFormat[]} [transcode_target] what a Basis payload should become — see
23
23
  * {@link ktx2_read}, which owns the rules
24
- * @returns {ShadeTexelData}
24
+ * @returns {Promise<ShadeTexelData>}
25
25
  * @throws {Error} everything {@link ktx2_read} throws, a partial mip chain, and an array or cube map
26
26
  *
27
27
  * @author Alex Goldring
28
28
  * @copyright Company Named Limited (c) 2026
29
29
  */
30
- export function texel_data_from_ktx2(bytes: ArrayBuffer | Uint8Array, transcode_target?: TextureFormat | TextureFormat[]): ShadeTexelData;
30
+ export function texel_data_from_ktx2(bytes: ArrayBuffer | Uint8Array, transcode_target?: TextureFormat | TextureFormat[]): Promise<ShadeTexelData>;
31
31
  import { ShadeTexelData } from "./ShadeTexelData.js";
32
32
  //# sourceMappingURL=texel_data_from_ktx2.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"texel_data_from_ktx2.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/texture/source/texel_data_from_ktx2.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,4CATW,WAAW,GAAC,UAAU,qBACtB,gBAAc,eAAe,GAE3B,cAAc,CAqB1B;+BA9C8B,qBAAqB"}
1
+ {"version":3,"file":"texel_data_from_ktx2.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/texture/source/texel_data_from_ktx2.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,4CATW,WAAW,GAAC,UAAU,qBACtB,gBAAc,eAAe,GAE3B,QAAQ,cAAc,CAAC,CAqBnC;+BA9C8B,qBAAqB"}
@@ -24,14 +24,14 @@ import { ShadeTexelData } from "./ShadeTexelData.js";
24
24
  * @param {ArrayBuffer|Uint8Array} bytes the whole file
25
25
  * @param {TextureFormat|TextureFormat[]} [transcode_target] what a Basis payload should become — see
26
26
  * {@link ktx2_read}, which owns the rules
27
- * @returns {ShadeTexelData}
27
+ * @returns {Promise<ShadeTexelData>}
28
28
  * @throws {Error} everything {@link ktx2_read} throws, a partial mip chain, and an array or cube map
29
29
  *
30
30
  * @author Alex Goldring
31
31
  * @copyright Company Named Limited (c) 2026
32
32
  */
33
- export function texel_data_from_ktx2(bytes, transcode_target = undefined) {
34
- const payload = ktx2_read(bytes, transcode_target);
33
+ export async function texel_data_from_ktx2(bytes, transcode_target = undefined) {
34
+ const payload = await ktx2_read(bytes, transcode_target);
35
35
 
36
36
  if (payload.layers > 1 || payload.faces > 1) {
37
37
  throw new Error(
@@ -1,20 +0,0 @@
1
- /**
2
- * How many seconds of simulation this frame's newborns of an emitter owe before they may be shown,
3
- * as the tick pass left it this frame.
4
- *
5
- * Zero on all but one frame of an emitter's life. The tick writes the emitter's `prewarm` here on
6
- * the row's first tick and zero on every tick after, so a newborn asks this rather than asking the
7
- * record's `prewarm` directly: the record says how long the emitter wants pre-warming *for*, and
8
- * only the tick knows *whether this is that frame* — it is the generation comparison, and by the
9
- * time the emit pass runs the tick has already made the two generations agree.
10
- *
11
- * Read off the `emitter_state` table of the same database the emitter record came from
12
- * ({@link ../data/PARTICLE_EMITTER_STATE.js}), through the table's single-field reader, exactly as
13
- * {@link ./chunk_particle_emitter_age.js} reads the age beside it — one binding for both, and no
14
- * second copy of the row layout here to drift from the table's.
15
- *
16
- * @type {CodeChunk}
17
- */
18
- export const chunk_particle_emitter_warmup: CodeChunk;
19
- import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
20
- //# sourceMappingURL=chunk_particle_emitter_warmup.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"chunk_particle_emitter_warmup.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/shaders/chunk_particle_emitter_warmup.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;GAgBG;AACH,4CAFU,SAAS,CAMgD;0BAxBzC,oCAAoC"}
@@ -1,14 +0,0 @@
1
- /**
2
- * An emitter's bounds sphere in world space: the centre through the node's matrix, the radius
3
- * scaled by the largest axis scale the matrix carries.
4
- *
5
- * The axes are read as transformed unit vectors rather than as matrix columns — the same numbers,
6
- * in a form the WGSL emulator also evaluates. Shared by the tick pass (frustum culling of spawning)
7
- * and the AVBOIT occupancy pass (which depth slices the emitter's particles can reach), so both
8
- * test the same sphere.
9
- *
10
- * @type {CodeChunk}
11
- */
12
- export const chunk_particle_emitter_world_sphere: CodeChunk;
13
- import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
14
- //# sourceMappingURL=chunk_particle_emitter_world_sphere.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"chunk_particle_emitter_world_sphere.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/shaders/chunk_particle_emitter_world_sphere.js"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AACH,kDAFU,SAAS,CAUU;0BAtBH,oCAAoC"}
@@ -1,50 +0,0 @@
1
- /**
2
- * Return to the free list the slots the emit pass's pre-warm killed.
3
- *
4
- * A newborn of a pre-warming emitter runs its UPDATE program forward before it is shown
5
- * ({@link ./chunk_particle_emit_step.js}), and one whose life runs out during that never belongs on
6
- * the alive list. Its slot has to go back to the free list, and this pass is where that happens.
7
- *
8
- * ## Why it is a pass of its own
9
- *
10
- * Because emit is the one pass that POPS the free list, and a push racing a pop on an array stack
11
- * hands one slot to two particles.
12
- *
13
- * The pop is `old = atomicSub(DEAD, 1)` followed by a read of `dead[old - 1]`; a push would be
14
- * `d = atomicAdd(DEAD, 1)` followed by a write to `dead[d]`. Order one thread's `atomicSub` before
15
- * another's `atomicAdd` and the two name the same index, with nothing between the atomic and the
16
- * plain access to order them. If the write lands first, the popper takes the pushed slot AND leaves
17
- * it on the stack under a count that now includes it — so the next popper takes it again, and two
18
- * live particles share one record. That is precisely the failure the build-indirect pass warns about
19
- * for a different reason, and it is why the emit pass writes to `dead` nowhere: even its
20
- * pool-exhaustion path only ever puts the counter back.
21
- *
22
- * Between two dispatches there is no such race. This pass only pushes; nothing in it pops.
23
- *
24
- * ## Where the slots are between the two
25
- *
26
- * At the far end of `alive_out`, growing down from `capacity`, counted by
27
- * {@link PARTICLE_COUNTER.STILLBORN}. A region of a buffer emit already binds, rather than a list of
28
- * its own: emit binds exactly the eight storage buffers a compute stage gets by default, and a ninth
29
- * for a list that is empty on all but a handful of frames is not what the ninth is for.
30
- *
31
- * The park cannot collide with the alive list growing up from zero. Every entry in either is a
32
- * distinct pool slot and a parked one is by definition not alive, so the two lengths sum to at most
33
- * the `capacity` entries between them.
34
- *
35
- * ## Sizing
36
- *
37
- * A bounded launch with a grid-stride loop, the shape the wide interpreter uses and for the same
38
- * reason: the length it walks is a GPU-side count. Nothing about it is sized from the host, and the
39
- * dispatch costs one atomic load and an exit on the frames — nearly all of them — where nothing was
40
- * parked.
41
- *
42
- * @type {ComputeShader}
43
- */
44
- /** Workgroups this pass dispatches. Constant: the launch does not depend on how many slots were parked. */
45
- export const PARTICLE_RECLAIM_WORKGROUP_COUNT: number;
46
- export const shader_particle_reclaim: ComputeShader;
47
- export { PARTICLE_RECLAIM_WORKGROUP_SIZE };
48
- import { ComputeShader } from "../../shader/ComputeShader.js";
49
- import { PARTICLE_RECLAIM_WORKGROUP_SIZE } from "../ParticleConstants.js";
50
- //# sourceMappingURL=shader_particle_reclaim.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"shader_particle_reclaim.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/shaders/shader_particle_reclaim.js"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH,2GAA2G;AAC3G,sDAAyG;AAWzG,oDAqBG;;8BAnF2B,+BAA+B;gDAGW,yBAAyB"}
@@ -1,17 +0,0 @@
1
- /**
2
- * An unfinished translation of the FidelityFX reflection denoiser's reprojection pass.
3
- *
4
- * Not yet a shader, and not yet valid WGSL: the body still carries HLSL spellings the port has not
5
- * reached (`FfxFloat16x4`, `FfxInt32x2`, `FFX_GROUP_MEMORY_BARRIER`), and `main` is an empty stub
6
- * with no `@compute` and no `@workgroup_size`. It was a `ComputeShader` here until the workgroup
7
- * size started being read out of the WGSL, which is a question this source cannot answer; it stays
8
- * a chunk until someone finishes the port and writes the entry point.
9
- *
10
- * The bindings it will want are one texture, `tRadiance`.
11
- *
12
- * @see https://github.com/GPUOpen-LibrariesAndSDKs/FidelityFX-SDK/blob/1bbe66e7ea0d358e84af4471a90aa9c35b583de0/sdk/include/FidelityFX/gpu/denoiser/ffx_denoiser_reflections_reproject.h
13
- * @type {CodeChunk}
14
- */
15
- export const chunk_ffx_denoiser_reflections_reproject: CodeChunk;
16
- import { CodeChunk } from "../../../shader/compiler/CodeChunk.js";
17
- //# sourceMappingURL=shader_ffx_denoiser_reflections_reproject.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"shader_ffx_denoiser_reflections_reproject.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/postprocess/ssr/reproject/shader_ffx_denoiser_reflections_reproject.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;GAaG;AACH,uDAFU,SAAS,CAubjB;0BArcwB,uCAAuC"}