@woosh/meep-engine 3.18.0 → 3.20.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 (228) hide show
  1. package/build/bundle-worker-image-decoder.js +1 -1
  2. package/build/bundle-worker-terrain.js +1 -1
  3. package/editor/view/particles/effect/ParticleCurveEditorView.d.ts.map +1 -1
  4. package/editor/view/particles/effect/ParticleCurveEditorView.js +303 -120
  5. package/editor/view/particles/effect/ParticleGradientEditorView.d.ts.map +1 -1
  6. package/editor/view/particles/effect/ParticleGradientEditorView.js +108 -63
  7. package/editor/view/particles/effect/ParticleGraphEditorView.js +2 -2
  8. package/editor/view/particles/effect/ParticleNodeParametersView.d.ts.map +1 -1
  9. package/editor/view/particles/effect/ParticleNodeParametersView.js +7 -46
  10. package/editor/view/particles/effect/particle-editor.css +60 -30
  11. package/package.json +1 -2
  12. package/samples/engine/README.md +1 -1
  13. package/src/core/binary/compression/decompress_bytes.d.ts +13 -0
  14. package/src/core/binary/compression/decompress_bytes.d.ts.map +1 -0
  15. package/src/core/binary/compression/decompress_bytes.js +28 -0
  16. package/src/core/collection/array/array_group_by.d.ts.map +1 -1
  17. package/src/core/collection/array/array_group_by.js +2 -11
  18. package/src/core/geom/3d/shape/HeightMapShape3D.d.ts.map +1 -1
  19. package/src/core/geom/3d/shape/HeightMapShape3D.js +4 -9
  20. package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.js +67 -22
  21. package/src/core/model/object/optional_clone.d.ts +7 -0
  22. package/src/core/model/object/optional_clone.d.ts.map +1 -0
  23. package/src/core/model/object/optional_equality.d.ts +10 -0
  24. package/src/core/model/object/optional_equality.d.ts.map +1 -0
  25. package/src/{shade/descriptor/util → core/model/object}/optional_equality.js +2 -2
  26. package/src/core/model/object/optional_hash.d.ts +9 -0
  27. package/src/core/model/object/optional_hash.d.ts.map +1 -0
  28. package/src/{shade/descriptor/util → core/model/object}/optional_hash.js +3 -3
  29. package/src/engine/asset/Asset.d.ts +1 -1
  30. package/src/engine/asset/Asset.d.ts.map +1 -1
  31. package/src/engine/asset/Asset.js +3 -1
  32. package/src/engine/asset/loaders/image/ImageDecoderWorker.js +12 -27
  33. package/src/engine/asset/loaders/image/prototypePNG.js +8 -7
  34. package/src/engine/ecs/gui/hud/HeadsUpDisplaySystem.d.ts.map +1 -1
  35. package/src/engine/ecs/gui/hud/HeadsUpDisplaySystem.js +9 -10
  36. package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
  37. package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +4 -0
  38. package/src/engine/graphics/ecs/particles/ParticleEffect.d.ts +266 -0
  39. package/src/engine/graphics/ecs/particles/ParticleEffect.d.ts.map +1 -0
  40. package/src/engine/graphics/ecs/particles/ParticleEffect.js +439 -0
  41. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.d.ts +58 -0
  42. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.d.ts.map +1 -0
  43. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.js +219 -0
  44. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts +178 -25
  45. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts.map +1 -1
  46. package/src/engine/graphics3/GPUParticleEmitterSystem.js +809 -310
  47. package/src/format/image/png/PNGReader.d.ts +7 -6
  48. package/src/format/image/png/PNGReader.d.ts.map +1 -1
  49. package/src/format/image/png/PNGReader.js +13 -12
  50. package/src/format/image/png/chunk/png_chunk_decode_iTXt.d.ts +3 -2
  51. package/src/format/image/png/chunk/png_chunk_decode_iTXt.d.ts.map +1 -1
  52. package/src/format/image/png/chunk/png_chunk_decode_iTXt.js +5 -4
  53. package/src/format/image/png/chunk/png_chunk_decode_zTXt.d.ts +3 -2
  54. package/src/format/image/png/chunk/png_chunk_decode_zTXt.d.ts.map +1 -1
  55. package/src/format/image/png/chunk/png_chunk_decode_zTXt.js +5 -4
  56. package/src/format/image/png/png_inflate.d.ts +3 -3
  57. package/src/format/image/png/png_inflate.d.ts.map +1 -1
  58. package/src/format/image/png/png_inflate.js +29 -39
  59. package/src/format/texture/ktx2/ktx2_read.d.ts +4 -4
  60. package/src/format/texture/ktx2/ktx2_read.d.ts.map +1 -1
  61. package/src/format/texture/ktx2/ktx2_read.js +18 -21
  62. package/src/shade/descriptor/binding/BindGroupLayoutDescriptor.js +1 -1
  63. package/src/shade/descriptor/binding/BindGroupLayoutEntry.js +3 -3
  64. package/src/shade/descriptor/pipeline/PipelineDescriptorBase.js +1 -1
  65. package/src/shade/descriptor/pipeline/PipelineLayoutDescriptor.js +1 -1
  66. package/src/shade/descriptor/pipeline/render/ColorTargetState.js +3 -3
  67. package/src/shade/descriptor/pipeline/render/FragmentState.js +1 -1
  68. package/src/shade/descriptor/pipeline/render/RenderPipelineDescriptor.js +3 -3
  69. package/src/shade/playground/particle_ecs/README.md +203 -0
  70. package/src/shade/playground/particle_ecs/bonfire_editor.d.ts +39 -0
  71. package/src/shade/playground/particle_ecs/bonfire_editor.d.ts.map +1 -0
  72. package/src/shade/playground/particle_ecs/bonfire_editor.js +315 -0
  73. package/src/shade/playground/particle_ecs/bonfire_effects.d.ts +145 -0
  74. package/src/shade/playground/particle_ecs/bonfire_effects.d.ts.map +1 -0
  75. package/src/shade/playground/particle_ecs/bonfire_effects.js +202 -0
  76. package/src/shade/playground/particle_ecs/bonfire_sprites.d.ts +23 -0
  77. package/src/shade/playground/particle_ecs/bonfire_sprites.d.ts.map +1 -0
  78. package/src/shade/playground/particle_ecs/bonfire_sprites.js +315 -0
  79. package/src/shade/playground/particle_ecs/bonfire_world.d.ts +86 -0
  80. package/src/shade/playground/particle_ecs/bonfire_world.d.ts.map +1 -0
  81. package/src/shade/playground/particle_ecs/bonfire_world.js +303 -0
  82. package/src/shade/playground/particle_ecs/effects/embers.json +1634 -0
  83. package/src/shade/playground/particle_ecs/effects/flame.json +1882 -0
  84. package/src/shade/playground/particle_ecs/effects/smoke.json +1860 -0
  85. package/src/shade/playground/particle_ecs/effects/soot.json +1606 -0
  86. package/src/shade/playground/particle_ecs/index.html +330 -0
  87. package/src/shade/playground/particle_ecs/main.d.ts +2 -0
  88. package/src/shade/playground/particle_ecs/main.d.ts.map +1 -0
  89. package/src/shade/playground/particle_ecs/main.js +566 -0
  90. package/src/shade/playground/particle_ecs/moonlit_environment.d.ts +16 -0
  91. package/src/shade/playground/particle_ecs/moonlit_environment.d.ts.map +1 -0
  92. package/src/shade/playground/particle_ecs/moonlit_environment.js +144 -0
  93. package/src/shade/playground/particle_editor/README.md +5 -4
  94. package/src/shade/playground/particle_system/particle_prototype.d.ts +7 -9
  95. package/src/shade/playground/particle_system/particle_prototype.d.ts.map +1 -1
  96. package/src/shade/playground/particle_system/particle_prototype.js +7 -9
  97. package/src/shade/playground/profile_hotkey.d.ts +58 -0
  98. package/src/shade/playground/profile_hotkey.d.ts.map +1 -0
  99. package/src/shade/playground/profile_hotkey.js +325 -0
  100. package/src/shade/playground/ssr_motion/README.md +22 -0
  101. package/src/shade/playground/ssr_motion/index.html +18 -0
  102. package/src/shade/playground/ssr_motion/main.d.ts +2 -0
  103. package/src/shade/playground/ssr_motion/main.d.ts.map +1 -0
  104. package/src/shade/playground/ssr_motion/main.js +149 -0
  105. package/src/shade/playground/ssr_variance/README.md +105 -0
  106. package/src/shade/playground/ssr_variance/capture.d.ts +16 -0
  107. package/src/shade/playground/ssr_variance/capture.d.ts.map +1 -0
  108. package/src/shade/playground/ssr_variance/capture.js +96 -0
  109. package/src/shade/playground/ssr_variance/index.html +23 -0
  110. package/src/shade/playground/ssr_variance/main.d.ts +2 -0
  111. package/src/shade/playground/ssr_variance/main.d.ts.map +1 -0
  112. package/src/shade/playground/ssr_variance/main.js +246 -0
  113. package/src/shade/playground/ssr_variance/reference.d.ts +18 -0
  114. package/src/shade/playground/ssr_variance/reference.d.ts.map +1 -0
  115. package/src/shade/playground/ssr_variance/reference.js +78 -0
  116. package/src/shade/playground/ssr_variance/scene.d.ts +11 -0
  117. package/src/shade/playground/ssr_variance/scene.d.ts.map +1 -0
  118. package/src/shade/playground/ssr_variance/scene.js +61 -0
  119. package/src/shade/playground/ssr_variance/statistics.d.ts +44 -0
  120. package/src/shade/playground/ssr_variance/statistics.d.ts.map +1 -0
  121. package/src/shade/playground/ssr_variance/statistics.js +51 -0
  122. package/src/shade/renderer/geometry/Geometry.d.ts.map +1 -1
  123. package/src/shade/renderer/geometry/Geometry.js +4 -7
  124. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts.map +1 -1
  125. package/src/shade/renderer/loader/gltf/tiny-gltf.js +9 -3
  126. package/src/shade/renderer/loader/usd/usd_decode_image.d.ts +4 -4
  127. package/src/shade/renderer/loader/usd/usd_decode_image.d.ts.map +1 -1
  128. package/src/shade/renderer/loader/usd/usd_decode_image.js +4 -4
  129. package/src/shade/renderer/material/StandardShadeMaterial.js +2 -2
  130. package/src/shade/renderer/particles/DESIGN.md +745 -702
  131. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  132. package/src/shade/renderer/particles/GPUParticleSystem.js +3 -1
  133. package/src/shade/renderer/particles/graph/ParticleGroupBuilder.d.ts +1 -1
  134. package/src/shade/renderer/particles/graph/ParticleGroupBuilder.js +1 -1
  135. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts.map +1 -1
  136. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.js +9 -15
  137. package/src/shade/renderer/particles/graph/particle_group_library.d.ts.map +1 -1
  138. package/src/shade/renderer/particles/graph/particle_group_library.js +8 -3
  139. package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts +0 -2
  140. package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts.map +1 -1
  141. package/src/shade/renderer/particles/graph/particle_node_parameters.js +0 -9
  142. package/src/shade/renderer/particles/graph/particle_node_presentation.d.ts.map +1 -1
  143. package/src/shade/renderer/particles/graph/particle_node_presentation.js +0 -10
  144. package/src/shade/renderer/particles/graph/particle_ramp.d.ts +2 -8
  145. package/src/shade/renderer/particles/graph/particle_ramp.d.ts.map +1 -1
  146. package/src/shade/renderer/particles/graph/particle_ramp.js +2 -8
  147. package/src/shade/renderer/particles/graph/validate_particle_graph.js +0 -6
  148. package/src/shade/renderer/particles/graph_particles_avboit.d.ts.map +1 -1
  149. package/src/shade/renderer/particles/graph_particles_avboit.js +13 -4
  150. package/src/shade/renderer/particles/isa/InstructionStream.d.ts +1 -12
  151. package/src/shade/renderer/particles/isa/InstructionStream.d.ts.map +1 -1
  152. package/src/shade/renderer/particles/isa/InstructionStream.js +1 -12
  153. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts +54 -60
  154. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts.map +1 -1
  155. package/src/shade/renderer/particles/isa/ParticleVMISA.js +9 -17
  156. package/src/shade/renderer/particles/isa/particle_assembly.d.ts +0 -1
  157. package/src/shade/renderer/particles/isa/particle_assembly.d.ts.map +1 -1
  158. package/src/shade/renderer/particles/isa/particle_assembly.js +2 -16
  159. package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.d.ts +1 -1
  160. package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.js +1 -1
  161. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.js +0 -14
  162. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.js +3 -17
  163. package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts.map +1 -1
  164. package/src/shade/renderer/particles/optimizer/particle_program_analysis.js +15 -36
  165. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts.map +1 -1
  166. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.js +1 -5
  167. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts.map +1 -1
  168. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.js +1 -8
  169. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts +2 -11
  170. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts.map +1 -1
  171. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.js +2 -11
  172. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +11 -4
  173. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -1
  174. package/src/shade/renderer/particles/runtime/ParticleEmitter.js +431 -424
  175. package/src/shade/renderer/particles/shaders/chunk_particle_avboit_contribution.d.ts.map +1 -1
  176. package/src/shade/renderer/particles/shaders/chunk_particle_avboit_contribution.js +13 -0
  177. package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.d.ts +3 -6
  178. package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.d.ts.map +1 -1
  179. package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.js +49 -17
  180. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  181. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +0 -2
  182. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.d.ts.map +1 -1
  183. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.js +0 -2
  184. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  185. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +1 -5
  186. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.d.ts.map +1 -1
  187. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.js +0 -2
  188. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts +1 -3
  189. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts.map +1 -1
  190. package/src/shade/renderer/particles/vm/ParticleVMReference.js +4 -20
  191. package/src/shade/renderer/particles/vm/chunk_particle_vm.d.ts.map +1 -1
  192. package/src/shade/renderer/particles/vm/chunk_particle_vm.js +2 -5
  193. package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance.d.ts.map +1 -1
  194. package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance.js +0 -2
  195. package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance_wide.d.ts.map +1 -1
  196. package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance_wide.js +0 -2
  197. package/src/shade/renderer/postprocess/ssr/SSR.d.ts.map +1 -1
  198. package/src/shade/renderer/postprocess/ssr/SSR.js +2 -1
  199. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_reprojection.d.ts.map +1 -1
  200. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_reprojection.js +20 -5
  201. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_sample_history.d.ts.map +1 -1
  202. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_sample_history.js +19 -5
  203. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.d.ts +4 -0
  204. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.d.ts.map +1 -0
  205. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.js +137 -0
  206. package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.d.ts +0 -8
  207. package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.d.ts.map +1 -1
  208. package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.js +18 -114
  209. package/src/shade/renderer/scene/Mesh.js +1 -1
  210. package/src/shade/renderer/texture/ShadeTexture.js +1 -1
  211. package/src/shade/renderer/texture/source/texel_data_from_ktx2.d.ts +2 -2
  212. package/src/shade/renderer/texture/source/texel_data_from_ktx2.d.ts.map +1 -1
  213. package/src/shade/renderer/texture/source/texel_data_from_ktx2.js +3 -3
  214. package/src/shade/renderer/particles/shaders/chunk_particle_curve_animation.d.ts +0 -19
  215. package/src/shade/renderer/particles/shaders/chunk_particle_curve_animation.d.ts.map +0 -1
  216. package/src/shade/renderer/particles/shaders/chunk_particle_curve_animation.js +0 -30
  217. package/src/shade/renderer/particles/shaders/chunk_particle_curve_disabled.d.ts +0 -11
  218. package/src/shade/renderer/particles/shaders/chunk_particle_curve_disabled.d.ts.map +0 -1
  219. package/src/shade/renderer/particles/shaders/chunk_particle_curve_disabled.js +0 -13
  220. package/src/shade/renderer/particles/shaders/chunk_particle_emitter_warmup.d.ts +0 -20
  221. package/src/shade/renderer/particles/shaders/chunk_particle_emitter_warmup.d.ts.map +0 -1
  222. package/src/shade/renderer/particles/shaders/chunk_particle_emitter_world_sphere.d.ts +0 -14
  223. package/src/shade/renderer/particles/shaders/chunk_particle_emitter_world_sphere.d.ts.map +0 -1
  224. package/src/shade/renderer/particles/shaders/shader_particle_reclaim.d.ts +0 -50
  225. package/src/shade/renderer/particles/shaders/shader_particle_reclaim.d.ts.map +0 -1
  226. package/src/shade/renderer/postprocess/ssr/reproject/shader_ffx_denoiser_reflections_reproject.d.ts +0 -17
  227. package/src/shade/renderer/postprocess/ssr/reproject/shader_ffx_denoiser_reflections_reproject.d.ts.map +0 -1
  228. /package/src/{shade/descriptor/util → core/model/object}/optional_clone.js +0 -0
@@ -0,0 +1,137 @@
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
+ // Confidence can force a much larger current contribution than 1/age.
123
+ // Carry that actual update rate into the age/variance pair too; otherwise a
124
+ // half-current blend can claim the uncertainty of a 65-frame accumulation.
125
+ age = min(age, 1.0 / max(1e-6, 1.0-saturate(confidence)));
126
+ let weight = min(saturate(confidence), 1.0 - 1.0/age);
127
+ let color = mix(current.rgb, clipped, weight);
128
+ var result: SSRAccumulation;
129
+ // Post-spatial passes receive uncertainty of the mean, rather than the raw
130
+ // sample distribution or the resolve pass's within-ray variance.
131
+ result.radiance = vec4f(color, min(65504.0,sample_variance/age));
132
+ result.age = age;
133
+ result.short_luma = select(short_luma, rgb_to_luminance(color), rectified);
134
+ return result;
135
+ }
136
+ `, [chunk_rgb_to_luminance, chunk_decode_g_buffer_normal, chunk_is_finite, chunk_decode_g_buffer_roughness,
137
+ 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":"AAqGA,+CAGG;4BAlGyB,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;
156
- let virtual_eligible = settings.reprojection_mode != 1u && metadata.y >= 0.75 && metadata.x > 0.0 && is_finite(metadata.x) && roughness <= 0.2;
67
+ var history_uv = vec2f(0.0);
68
+ let virtual_eligible = settings.reprojection_mode != 1u && metadata.y >= 0.5 && 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,37 +78,28 @@ 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;
84
+ confidence *= ssr_surface_parallax_confidence(camera_position,position,metadata.x,camera_previous.view_projection_matrix,size);
170
85
  // Surface correspondence alone cannot justify a long history for a smooth finite reflection.
171
86
  if (virtual_eligible) { confidence *= 0.25; }
172
87
  }
173
88
  if (confidence <= 0.001) { return output; }
174
89
 
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));
90
+ let accumulated = ssr_temporal_accumulate(current, history.radiance, history.age,
91
+ history.short_luma, confidence, motion_confidence, st, history_uv);
92
+ output.radiance = accumulated.radiance;
93
+ output.metadata.z = accumulated.age;
94
+ output.metadata.w = accumulated.short_luma;
190
95
  return output;
191
96
  }
192
97
  `, [chunk_ssr_reprojection, chunk_ssr_sample_history, chunk_screen_coordinate_to_world,
193
98
  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]);
99
+ chunk_depth_clip_offset_codec, chunk_taa_velocity_confidence,
100
+ chunk_ssr_temporal_accumulate, chunk_rgb_to_luminance]);
197
101
 
198
102
  export const ssr_reproject_shader = new ImageShader({
199
103
  descriptor: ShaderDescriptor.from({ label: "SSR Reproject", body, resources }),
200
- targets: [{ format: "rgba16float" }, { format: "rg32float" }, { format: "rgba16float" }],
104
+ targets: [{ format: "rgba16float" }, { format: "rgba32float" }, { format: "rgba16float" }],
201
105
  });
@@ -4,7 +4,7 @@ import { aabb3_from_v3_array_transformed } from "../../../core/geom/3d/aabb/aabb
4
4
  import { aabb3_matrix4_project } from "../../../core/geom/3d/aabb/aabb3_matrix4_project.js";
5
5
  import { sphere_matrix4_transform } from "../../../core/geom/3d/sphere/sphere_matrix4_transform.js";
6
6
  import { epsilonEquals } from "../../../core/math/epsilonEquals.js";
7
- import { optional_equality } from "../../descriptor/util/optional_equality.js";
7
+ import { optional_equality } from "../../../core/model/object/optional_equality.js";
8
8
  import { StandardAttributes } from "../geometry/StandardAttributes.js";
9
9
  import { Node3D } from "./Node3D.js";
10
10
 
@@ -1,6 +1,6 @@
1
1
  import { assert } from "../../../core/assert.js";
2
2
  import { combine_hash } from "../../../core/collection/array/combine_hash.js";
3
- import { optional_hash } from "../../descriptor/util/optional_hash.js";
3
+ import { optional_hash } from "../../../core/model/object/optional_hash.js";
4
4
  import { ShadeTextureFlags } from "./ShadeTextureFlags.js";
5
5
  import { TextureFilterType } from "./TextureFilterType.js";
6
6
  import { TextureWrapType } from "./TextureWrapType.js";
@@ -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,19 +0,0 @@
1
- /**
2
- * Production implementation of the VM `CURVE` opcode's `particle_vm_sample_curve(handle, t)`, backed
3
- * by the engine's existing AnimationCurve GPU path — no reinvention. It reads the curve header from
4
- * the `animation_curves` GPUDatabase table by handle and evaluates it with the same
5
- * `animation_curve_evaluate` cubic-Hermite chunk the skeletal animation system uses.
6
- *
7
- * This is the "reuse meep's AnimationCurve" + "GPUDatabase where relevant" integration: an effect
8
- * author registers a curve via `GPUAnimationManager.register_curve(curve)` (or `add_curve`), gets a
9
- * handle, references it from a `curve` node, and the simulation samples it on the GPU.
10
- *
11
- * The simulate shader that includes this chunk must also bind `particle_curve_database :
12
- * array<u32>` to `GPUAnimationManager.database.buffer` (in place of the no-op
13
- * {@link ./chunk_particle_curve_disabled.js} provider used when no effect uses curves).
14
- *
15
- * @type {CodeChunk}
16
- */
17
- export const chunk_particle_curve_animation: CodeChunk;
18
- import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
19
- //# sourceMappingURL=chunk_particle_curve_animation.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"chunk_particle_curve_animation.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/shaders/chunk_particle_curve_animation.js"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;GAeG;AACH,6CAFU,SAAS,CAS0C;0BA3BnC,oCAAoC"}
@@ -1,30 +0,0 @@
1
- import { ANIMATION_DATABASE_SPEC } from "../../animation/ANIMATION_DATABASE_SPEC.js";
2
- import { chunk_animation_curve_evaluate } from "../../animation/chunk_animation_curve_evaluate.js";
3
- import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
4
-
5
- const CURVE_TABLE = ANIMATION_DATABASE_SPEC.get("animation_curves");
6
-
7
- /**
8
- * Production implementation of the VM `CURVE` opcode's `particle_vm_sample_curve(handle, t)`, backed
9
- * by the engine's existing AnimationCurve GPU path — no reinvention. It reads the curve header from
10
- * the `animation_curves` GPUDatabase table by handle and evaluates it with the same
11
- * `animation_curve_evaluate` cubic-Hermite chunk the skeletal animation system uses.
12
- *
13
- * This is the "reuse meep's AnimationCurve" + "GPUDatabase where relevant" integration: an effect
14
- * author registers a curve via `GPUAnimationManager.register_curve(curve)` (or `add_curve`), gets a
15
- * handle, references it from a `curve` node, and the simulation samples it on the GPU.
16
- *
17
- * The simulate shader that includes this chunk must also bind `particle_curve_database :
18
- * array<u32>` to `GPUAnimationManager.database.buffer` (in place of the no-op
19
- * {@link ./chunk_particle_curve_disabled.js} provider used when no effect uses curves).
20
- *
21
- * @type {CodeChunk}
22
- */
23
- export const chunk_particle_curve_animation = CodeChunk.from(
24
- /* language=wgsl */
25
- `
26
- fn particle_vm_sample_curve(handle : u32, t : f32) -> f32 {
27
- let header = ${CURVE_TABLE.marshalling_method_read}(&particle_curve_database, handle);
28
- return animation_curve_evaluate(t, &particle_curve_database, header);
29
- }
30
- `, [CURVE_TABLE.chunk_read, chunk_animation_curve_evaluate]);
@@ -1,11 +0,0 @@
1
- /**
2
- * Default curve provider: no curves bound, `CURVE` opcodes evaluate to 0. The production feature
3
- * swaps this for an animation-database-backed provider
4
- * ({@link ./chunk_particle_curve_animation.js}). Kept separate so an effect that uses no curves
5
- * compiles without any animation bindings.
6
- *
7
- * @type {CodeChunk}
8
- */
9
- export const chunk_particle_curve_disabled: CodeChunk;
10
- import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
11
- //# sourceMappingURL=chunk_particle_curve_disabled.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"chunk_particle_curve_disabled.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/shaders/chunk_particle_curve_disabled.js"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,4CAFU,SAAS,CAIhB;0BAZuB,oCAAoC"}
@@ -1,13 +0,0 @@
1
- import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
2
-
3
- /**
4
- * Default curve provider: no curves bound, `CURVE` opcodes evaluate to 0. The production feature
5
- * swaps this for an animation-database-backed provider
6
- * ({@link ./chunk_particle_curve_animation.js}). Kept separate so an effect that uses no curves
7
- * compiles without any animation bindings.
8
- *
9
- * @type {CodeChunk}
10
- */
11
- export const chunk_particle_curve_disabled = CodeChunk.from(/* wgsl */ `
12
- fn particle_vm_sample_curve(handle : u32, t : f32) -> f32 { return 0.0; }
13
- `);
@@ -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"}