@woosh/meep-engine 3.11.1 → 3.11.3

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 (225) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/package.json +1 -1
  3. package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
  4. package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +294 -290
  5. package/src/engine/graphics3/ParticipatingMedia.d.ts +111 -0
  6. package/src/engine/graphics3/ParticipatingMedia.d.ts.map +1 -0
  7. package/src/engine/graphics3/ParticipatingMedia.js +203 -0
  8. package/src/engine/graphics3/ParticipatingMediaSerializationAdapter.d.ts +34 -0
  9. package/src/engine/graphics3/ParticipatingMediaSerializationAdapter.d.ts.map +1 -0
  10. package/src/engine/graphics3/ParticipatingMediaSerializationAdapter.js +73 -0
  11. package/src/engine/graphics3/ParticipatingMediaSystem3.d.ts +87 -0
  12. package/src/engine/graphics3/ParticipatingMediaSystem3.d.ts.map +1 -0
  13. package/src/engine/graphics3/ParticipatingMediaSystem3.js +184 -0
  14. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  15. package/src/shade/descriptor/pipeline/PipelineLayoutDescriptor.d.ts +16 -2
  16. package/src/shade/descriptor/pipeline/PipelineLayoutDescriptor.d.ts.map +1 -1
  17. package/src/shade/descriptor/pipeline/PipelineLayoutDescriptor.js +28 -4
  18. package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.d.ts +1 -1
  19. package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.d.ts.map +1 -1
  20. package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.js +5 -2
  21. package/src/shade/device/IMMEDIATE_DATA_PLAN_2026_08_28.md +564 -451
  22. package/src/shade/device/ShadeGPUCommandContext.d.ts +18 -2
  23. package/src/shade/device/ShadeGPUCommandContext.d.ts.map +1 -1
  24. package/src/shade/device/ShadeGPUCommandContext.js +994 -940
  25. package/src/shade/device/immediate_data_supported.d.ts +33 -0
  26. package/src/shade/device/immediate_data_supported.d.ts.map +1 -0
  27. package/src/shade/device/immediate_data_supported.js +53 -0
  28. package/src/shade/device/mock/SoftwareGPUCommandEncoder.d.ts +18 -0
  29. package/src/shade/device/mock/SoftwareGPUCommandEncoder.d.ts.map +1 -1
  30. package/src/shade/device/mock/SoftwareGPUCommandEncoder.js +24 -0
  31. package/src/shade/device/mock/SoftwareGPUComputePassEncoder.d.ts +7 -0
  32. package/src/shade/device/mock/SoftwareGPUComputePassEncoder.d.ts.map +1 -1
  33. package/src/shade/device/mock/SoftwareGPUComputePassEncoder.js +49 -1
  34. package/src/shade/device/mock/SoftwareGPUDevice.d.ts.map +1 -1
  35. package/src/shade/device/mock/SoftwareGPUDevice.js +20 -2
  36. package/src/shade/device/mock/SoftwareGPUImmediateData.d.ts +65 -0
  37. package/src/shade/device/mock/SoftwareGPUImmediateData.d.ts.map +1 -0
  38. package/src/shade/device/mock/SoftwareGPUImmediateData.js +160 -0
  39. package/src/shade/device/mock/SoftwareGPURenderPassEncoder.d.ts +7 -0
  40. package/src/shade/device/mock/SoftwareGPURenderPassEncoder.d.ts.map +1 -1
  41. package/src/shade/device/mock/SoftwareGPURenderPassEncoder.js +50 -0
  42. package/src/shade/device/mock/pipeline_immediate_size.d.ts +11 -0
  43. package/src/shade/device/mock/pipeline_immediate_size.d.ts.map +1 -0
  44. package/src/shade/device/mock/pipeline_immediate_size.js +18 -0
  45. package/src/shade/device/pipeline/PipelineLayoutManager.d.ts.map +1 -1
  46. package/src/shade/device/pipeline/PipelineLayoutManager.js +1 -0
  47. package/src/shade/playground/volumetrics_froxel/README.md +104 -1
  48. package/src/shade/playground/volumetrics_froxel/index.html +20 -1
  49. package/src/shade/playground/volumetrics_froxel/main.d.ts.map +1 -1
  50. package/src/shade/playground/volumetrics_froxel/main.js +298 -0
  51. package/src/shade/playground/volumetrics_froxel/measure.d.ts +119 -0
  52. package/src/shade/playground/volumetrics_froxel/measure.d.ts.map +1 -0
  53. package/src/shade/playground/volumetrics_froxel/measure.js +559 -0
  54. package/src/shade/renderer/GraphicsContext.d.ts +9 -2
  55. package/src/shade/renderer/GraphicsContext.d.ts.map +1 -1
  56. package/src/shade/renderer/GraphicsContext.js +13 -1
  57. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  58. package/src/shade/renderer/Renderer.js +22 -18
  59. package/src/shade/renderer/atmosphere/GPUSky.d.ts.map +1 -1
  60. package/src/shade/renderer/atmosphere/GPUSky.js +145 -142
  61. package/src/shade/renderer/atmosphere/MULTISCATTER_LUT_CONFIG.d.ts +34 -0
  62. package/src/shade/renderer/atmosphere/MULTISCATTER_LUT_CONFIG.d.ts.map +1 -0
  63. package/src/shade/renderer/atmosphere/MULTISCATTER_LUT_CONFIG.js +36 -0
  64. package/src/shade/renderer/atmosphere/SAMPLER_SKY_LUT.d.ts +20 -0
  65. package/src/shade/renderer/atmosphere/SAMPLER_SKY_LUT.d.ts.map +1 -0
  66. package/src/shade/renderer/atmosphere/SAMPLER_SKY_LUT.js +25 -0
  67. package/src/shade/renderer/atmosphere/chunk_get_multiscatter_values.d.ts +14 -1
  68. package/src/shade/renderer/atmosphere/chunk_get_multiscatter_values.d.ts.map +1 -1
  69. package/src/shade/renderer/atmosphere/chunk_get_multiscatter_values.js +163 -177
  70. package/src/shade/renderer/atmosphere/chunk_multiscatter_sample_direction.d.ts +20 -0
  71. package/src/shade/renderer/atmosphere/chunk_multiscatter_sample_direction.d.ts.map +1 -0
  72. package/src/shade/renderer/atmosphere/chunk_multiscatter_sample_direction.js +46 -0
  73. package/src/shade/renderer/atmosphere/chunk_sample_multiscatter_lut.d.ts +11 -1
  74. package/src/shade/renderer/atmosphere/chunk_sample_multiscatter_lut.d.ts.map +1 -1
  75. package/src/shade/renderer/atmosphere/chunk_sample_multiscatter_lut.js +57 -27
  76. package/src/shade/renderer/atmosphere/chunk_sample_transmittance_lut.d.ts +19 -1
  77. package/src/shade/renderer/atmosphere/chunk_sample_transmittance_lut.d.ts.map +1 -1
  78. package/src/shade/renderer/atmosphere/chunk_sample_transmittance_lut.js +69 -33
  79. package/src/shade/renderer/atmosphere/chunk_sky_lut_compute_uv.d.ts +13 -0
  80. package/src/shade/renderer/atmosphere/chunk_sky_lut_compute_uv.d.ts.map +1 -1
  81. package/src/shade/renderer/atmosphere/chunk_sky_lut_compute_uv.js +35 -35
  82. package/src/shade/renderer/atmosphere/chunk_sky_lut_params.d.ts +13 -0
  83. package/src/shade/renderer/atmosphere/chunk_sky_lut_params.d.ts.map +1 -0
  84. package/src/shade/renderer/atmosphere/chunk_sky_lut_params.js +38 -0
  85. package/src/shade/renderer/atmosphere/chunk_sky_lut_texel_to_unit.d.ts +17 -0
  86. package/src/shade/renderer/atmosphere/chunk_sky_lut_texel_to_unit.d.ts.map +1 -0
  87. package/src/shade/renderer/atmosphere/chunk_sky_lut_texel_to_unit.js +29 -0
  88. package/src/shade/renderer/atmosphere/chunk_sky_lut_uv.d.ts +21 -0
  89. package/src/shade/renderer/atmosphere/chunk_sky_lut_uv.d.ts.map +1 -0
  90. package/src/shade/renderer/atmosphere/chunk_sky_lut_uv.js +42 -0
  91. package/src/shade/renderer/atmosphere/shader_multiscatter_lut.d.ts +2 -2
  92. package/src/shade/renderer/atmosphere/shader_multiscatter_lut.d.ts.map +1 -1
  93. package/src/shade/renderer/atmosphere/shader_multiscatter_lut.js +165 -84
  94. package/src/shade/renderer/atmosphere/shader_sky_irradiance_lut.d.ts.map +1 -1
  95. package/src/shade/renderer/atmosphere/shader_sky_irradiance_lut.js +215 -204
  96. package/src/shade/renderer/atmosphere/shader_transmittance_lut.d.ts.map +1 -1
  97. package/src/shade/renderer/atmosphere/shader_transmittance_lut.js +79 -67
  98. package/src/shade/renderer/light/cluster/graph_assign_clsuters.d.ts.map +1 -1
  99. package/src/shade/renderer/light/cluster/graph_assign_clsuters.js +6 -2
  100. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts.map +1 -1
  101. package/src/shade/renderer/postprocess/gtao/GTAO.js +4 -0
  102. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  103. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  104. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +341 -345
  105. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts +0 -2
  106. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts.map +1 -1
  107. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.js +58 -57
  108. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.d.ts.map +1 -1
  109. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.js +7 -3
  110. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.d.ts.map +1 -1
  111. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.js +77 -81
  112. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.d.ts.map +1 -1
  113. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.js +5 -1
  114. package/src/shade/renderer/shader/ComputeShader.d.ts.map +1 -1
  115. package/src/shade/renderer/shader/ComputeShader.js +6 -2
  116. package/src/shade/renderer/shader/ImageShader.d.ts.map +1 -1
  117. package/src/shade/renderer/shader/ImageShader.js +4 -1
  118. package/src/shade/renderer/shader/ShaderDescriptor.d.ts.map +1 -1
  119. package/src/shade/renderer/shader/ShaderDescriptor.js +26 -0
  120. package/src/shade/renderer/shader/chunk/atmosphere/ATMOSPHERE_RADII_DECLARATION.d.ts +18 -0
  121. package/src/shade/renderer/shader/chunk/atmosphere/ATMOSPHERE_RADII_DECLARATION.d.ts.map +1 -0
  122. package/src/shade/renderer/shader/chunk/atmosphere/ATMOSPHERE_RADII_DECLARATION.js +32 -0
  123. package/src/shade/renderer/shader/chunk/atmosphere/PLANET_CENTER_DECLARATION.d.ts +7 -0
  124. package/src/shade/renderer/shader/chunk/atmosphere/PLANET_CENTER_DECLARATION.d.ts.map +1 -1
  125. package/src/shade/renderer/shader/chunk/atmosphere/PLANET_CENTER_DECLARATION.js +17 -6
  126. package/src/shade/renderer/shader/chunk/atmosphere/chunk_atmosphere_ray_bounds.d.ts +21 -0
  127. package/src/shade/renderer/shader/chunk/atmosphere/chunk_atmosphere_ray_bounds.d.ts.map +1 -0
  128. package/src/shade/renderer/shader/chunk/atmosphere/chunk_atmosphere_ray_bounds.js +69 -0
  129. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_contains_aabb3.d.ts +9 -0
  130. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_contains_aabb3.d.ts.map +1 -0
  131. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_contains_aabb3.js +22 -0
  132. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_from_transformed_corners.d.ts +16 -0
  133. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_from_transformed_corners.d.ts.map +1 -0
  134. package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_from_transformed_corners.js +41 -0
  135. package/src/shade/renderer/shader/chunk/geometry/frustum/chunk_frustum_transform_m4.d.ts +11 -0
  136. package/src/shade/renderer/shader/chunk/geometry/frustum/chunk_frustum_transform_m4.d.ts.map +1 -1
  137. package/src/shade/renderer/shader/chunk/geometry/frustum/chunk_frustum_transform_m4.js +15 -19
  138. package/src/shade/renderer/shader/chunk/geometry/frustum/chunk_frustum_transform_plane_matrix.d.ts +23 -0
  139. package/src/shade/renderer/shader/chunk/geometry/frustum/chunk_frustum_transform_plane_matrix.d.ts.map +1 -0
  140. package/src/shade/renderer/shader/chunk/geometry/frustum/chunk_frustum_transform_plane_matrix.js +44 -0
  141. package/src/shade/renderer/shader/chunk/geometry/octahedron/chunk_uv_octahedral_unit_decode.d.ts.map +1 -1
  142. package/src/shade/renderer/shader/chunk/geometry/octahedron/chunk_uv_octahedral_unit_decode.js +1 -4
  143. package/src/shade/renderer/shader/compiler/CodeChunk.d.ts +7 -1
  144. package/src/shade/renderer/shader/compiler/CodeChunk.d.ts.map +1 -1
  145. package/src/shade/renderer/shader/compiler/CodeChunk.js +37 -2
  146. package/src/shade/renderer/shader/graph/compute/compute_binding_read_names.d.ts.map +1 -1
  147. package/src/shade/renderer/shader/graph/compute/compute_binding_read_names.js +6 -0
  148. package/src/shade/renderer/shader/graph/compute/graph_compute_indirect_pass.js +1 -1
  149. package/src/shade/renderer/shader/graph/compute/graph_compute_pass.js +1 -1
  150. package/src/shade/renderer/shader/graph/graph_image_pass.js +1 -1
  151. package/src/shade/renderer/shader/graph/graph_prepare_bindings.d.ts.map +1 -1
  152. package/src/shade/renderer/shader/graph/graph_prepare_bindings.js +7 -0
  153. package/src/shade/renderer/shader/graph/graph_prepare_pass_input_data.d.ts +3 -1
  154. package/src/shade/renderer/shader/graph/graph_prepare_pass_input_data.d.ts.map +1 -1
  155. package/src/shade/renderer/shader/graph/graph_prepare_pass_input_data.js +12 -1
  156. package/src/shade/renderer/shader/pass/RenderPassDescriptor.d.ts.map +1 -1
  157. package/src/shade/renderer/shader/pass/RenderPassDescriptor.js +1 -0
  158. package/src/shade/renderer/shader/resource/IMMEDIATE_DATA.d.ts +21 -0
  159. package/src/shade/renderer/shader/resource/IMMEDIATE_DATA.d.ts.map +1 -0
  160. package/src/shade/renderer/shader/resource/IMMEDIATE_DATA.js +21 -0
  161. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.d.ts +59 -1
  162. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.d.ts.map +1 -1
  163. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.js +195 -2
  164. package/src/shade/renderer/shader/type/type_has_arrays.d.ts +14 -0
  165. package/src/shade/renderer/shader/type/type_has_arrays.d.ts.map +1 -0
  166. package/src/shade/renderer/shader/type/type_has_arrays.js +33 -0
  167. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_point2.d.ts +14 -13
  168. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_point2.d.ts.map +1 -1
  169. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_point2.js +133 -129
  170. package/src/shade/renderer/view/GPUViewSkyContext.d.ts.map +1 -1
  171. package/src/shade/renderer/view/GPUViewSkyContext.js +169 -173
  172. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts.map +1 -1
  173. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +480 -315
  174. package/src/shade/renderer/volumetrics/NOTES.md +887 -8
  175. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.d.ts +5 -0
  176. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.d.ts.map +1 -1
  177. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.js +21 -2
  178. package/src/shade/renderer/volumetrics/SceneVolumetrics.d.ts +26 -0
  179. package/src/shade/renderer/volumetrics/SceneVolumetrics.d.ts.map +1 -1
  180. package/src/shade/renderer/volumetrics/SceneVolumetrics.js +64 -21
  181. package/src/shade/renderer/volumetrics/VOLUMETRICS_METADATA_STRUCT.d.ts.map +1 -1
  182. package/src/shade/renderer/volumetrics/VOLUMETRICS_METADATA_STRUCT.js +84 -28
  183. package/src/shade/renderer/volumetrics/VOLUMETRICS_SUN_SHADOW_RESOLUTION.d.ts +98 -0
  184. package/src/shade/renderer/volumetrics/VOLUMETRICS_SUN_SHADOW_RESOLUTION.d.ts.map +1 -0
  185. package/src/shade/renderer/volumetrics/VOLUMETRICS_SUN_SHADOW_RESOLUTION.js +111 -0
  186. package/src/shade/renderer/volumetrics/build_volumetrics_sun_shadow_transform.d.ts +84 -0
  187. package/src/shade/renderer/volumetrics/build_volumetrics_sun_shadow_transform.d.ts.map +1 -0
  188. package/src/shade/renderer/volumetrics/build_volumetrics_sun_shadow_transform.js +252 -0
  189. package/src/shade/renderer/volumetrics/chunk_integrate_optical_depth.js +75 -75
  190. package/src/shade/renderer/volumetrics/chunk_volumetrics_local_light_shadow.d.ts +43 -0
  191. package/src/shade/renderer/volumetrics/chunk_volumetrics_local_light_shadow.d.ts.map +1 -0
  192. package/src/shade/renderer/volumetrics/chunk_volumetrics_local_light_shadow.js +145 -0
  193. package/src/shade/renderer/volumetrics/chunk_volumetrics_sample_froxel_extinction.d.ts +20 -0
  194. package/src/shade/renderer/volumetrics/chunk_volumetrics_sample_froxel_extinction.d.ts.map +1 -0
  195. package/src/shade/renderer/volumetrics/chunk_volumetrics_sample_froxel_extinction.js +48 -0
  196. package/src/shade/renderer/volumetrics/chunk_volumetrics_sun_optical_depth.d.ts +38 -0
  197. package/src/shade/renderer/volumetrics/chunk_volumetrics_sun_optical_depth.d.ts.map +1 -0
  198. package/src/shade/renderer/volumetrics/chunk_volumetrics_sun_optical_depth.js +130 -0
  199. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts +18 -3
  200. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts.map +1 -1
  201. package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +193 -70
  202. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts +16 -0
  203. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts.map +1 -1
  204. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.js +83 -15
  205. package/src/shade/renderer/volumetrics/shader_volumetrics_build_participating_media.d.ts.map +1 -1
  206. package/src/shade/renderer/volumetrics/shader_volumetrics_build_participating_media.js +29 -18
  207. package/src/shade/renderer/volumetrics/shader_volumetrics_build_scattering_lut.js +260 -260
  208. package/src/shade/renderer/volumetrics/shader_volumetrics_build_sun_shadow_volume.d.ts +58 -0
  209. package/src/shade/renderer/volumetrics/shader_volumetrics_build_sun_shadow_volume.d.ts.map +1 -0
  210. package/src/shade/renderer/volumetrics/shader_volumetrics_build_sun_shadow_volume.js +290 -0
  211. package/src/shade/wgsl/emulator/CPUBitmapData.d.ts +25 -0
  212. package/src/shade/wgsl/emulator/CPUBitmapData.d.ts.map +1 -1
  213. package/src/shade/wgsl/emulator/CPUBitmapData.js +33 -0
  214. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +2228 -2215
  215. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  216. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +210 -2
  217. package/src/shade/wgsl/emulator/cpu_texture_gather.d.ts +69 -0
  218. package/src/shade/wgsl/emulator/cpu_texture_gather.d.ts.map +1 -0
  219. package/src/shade/wgsl/emulator/cpu_texture_gather.js +148 -0
  220. package/src/shade/wgsl/emulator/cpu_texture_sample.d.ts +16 -0
  221. package/src/shade/wgsl/emulator/cpu_texture_sample.d.ts.map +1 -1
  222. package/src/shade/wgsl/emulator/cpu_texture_sample.js +176 -172
  223. package/src/shade/renderer/volumetrics/VOLUMETRICS_WORKGROUP_RESOLUTION.d.ts +0 -2
  224. package/src/shade/renderer/volumetrics/VOLUMETRICS_WORKGROUP_RESOLUTION.d.ts.map +0 -1
  225. package/src/shade/renderer/volumetrics/VOLUMETRICS_WORKGROUP_RESOLUTION.js +0 -1
@@ -1,172 +1,176 @@
1
- import { assert } from "../../../core/assert.js";
2
-
3
- /**
4
- * Sample a {@link CPUBitmapData} as if it were a GPU texture bound with
5
- * the given sampler. Routes through nearest or linear filtering on each of
6
- * the texture's actual axes (1D / 2D / 3D inferred from
7
- * `texture.dimensionality`).
8
- *
9
- * **Mipmaps are intentionally not modelled.** The emulator runs at LOD 0
10
- * only — there is no mip pyramid in {@link CPUBitmapData}, and
11
- * `mipmapFilter` / `lodMinClamp` / `lodMaxClamp` on the sampler are
12
- * ignored. We pick `magFilter` for the actual filter mode, which matches
13
- * the intuition that emulator tests are typically up-sampling. Add a mip
14
- * pyramid + minification path later if a test ever needs minified
15
- * sampling.
16
- *
17
- * Convention for `texel_coord`: this is **TEXEL-SPACE coordinates** (i.e.
18
- * UV * size, NOT normalised UV in [0, 1]). The shader-facing intrinsics
19
- * `textureSample` / `textureSampleLevel` take normalised UV; the emulator
20
- * converts to texel-space before calling here so the address-mode
21
- * arithmetic doesn't have to special-case sub-1.0 jitter. WebGPU's
22
- * convention places texel `i`'s centre at texel-space `i + 0.5`, so the
23
- * left edge of the texture is at 0 and the right edge at `size`.
24
- *
25
- * Address-mode handling lives in {@link wrap_int}: every integer texel
26
- * index produced by either filter passes through it before reading the
27
- * backing buffer. Out-of-range fractional inputs fall out naturally from
28
- * floor + integer wrap, so we don't pre-clamp the fractional coord (a
29
- * previous version did and lost full-edge texel sampling for
30
- * `clamp-to-edge`).
31
- *
32
- * @param {Float32Array | number[]} output — receives 4 channel values
33
- * (channels beyond `texture.item_size` are zero, with alpha forced to 1
34
- * for textures with fewer than 4 channels — matches WGSL semantics)
35
- * @param {import("../../descriptor/texture/SamplerDescriptor.js").SamplerDescriptor} sampler
36
- * @param {import("./CPUBitmapData.js").CPUBitmapData} texture
37
- * @param {Float32Array | number[]} texel_coord — length matches
38
- * `texture.dimensionality` (1, 2 or 3 entries)
39
- */
40
- export function cpu_texture_sample(output, sampler, texture, texel_coord) {
41
- assert.defined(output, 'output');
42
- assert.defined(sampler, 'sampler');
43
- assert.defined(texture, 'texture');
44
- assert.defined(texel_coord, 'texel_coord');
45
-
46
- // Default channels 0..3 to 0; alpha to 1 if the texture has < 4 channels.
47
- const item_size = texture.item_size;
48
- for (let i = 0; i < 4; i++) output[i] = 0;
49
- if (item_size < 4) output[3] = 1;
50
-
51
- const dim = texture.dimensionality;
52
- const w = texture.size[0];
53
- const h = texture.size[1];
54
- const d = texture.size[2];
55
-
56
- const tx = texel_coord[0];
57
- const ty = dim >= 2 ? texel_coord[1] : 0;
58
- const tz = dim >= 3 ? texel_coord[2] : 0;
59
-
60
- // Mipmaps not modelled — see header. Use magFilter as the single
61
- // filter setting (sampler is bound at LOD 0 conceptually).
62
- const filter = sampler.magFilter;
63
-
64
- if (filter === "nearest") {
65
- // WGSL nearest: texel index = floor(texel_coord), then wrap.
66
- const ix = wrap_int(Math.floor(tx), w, sampler.addressModeU);
67
- const iy = dim >= 2 ? wrap_int(Math.floor(ty), h, sampler.addressModeV) : 0;
68
- const iz = dim >= 3 ? wrap_int(Math.floor(tz), d, sampler.addressModeW) : 0;
69
- const base = texture.pixel_offset(ix, iy, iz);
70
- const n = Math.min(item_size, 4);
71
- for (let i = 0; i < n; i++) output[i] = texture.data[base + i];
72
- return;
73
- }
74
-
75
- if (filter !== "linear") {
76
- throw new Error(`cpu_texture_sample: unsupported magFilter '${filter}' (expected "nearest" or "linear")`);
77
- }
78
-
79
- // Linear filter. Sample 2 (1D) / 4 (2D) / 8 (3D) neighbouring texels
80
- // around `texel_coord - 0.5` (the offset puts the bilinear origin at
81
- // texel CENTRES) with weights `(1 - frac, frac)` per axis. Each
82
- // integer index passes through `wrap_int` so the right/bottom/back
83
- // neighbour falling off the edge is resolved by the address mode.
84
- const px = tx - 0.5;
85
- const fx_floor = Math.floor(px);
86
- const ix0 = wrap_int(fx_floor, w, sampler.addressModeU);
87
- const ix1 = wrap_int(fx_floor + 1, w, sampler.addressModeU);
88
- const fx = px - fx_floor;
89
-
90
- let iy0 = 0, iy1 = 0, fy = 0;
91
- if (dim >= 2) {
92
- const py = ty - 0.5;
93
- const fy_floor = Math.floor(py);
94
- iy0 = wrap_int(fy_floor, h, sampler.addressModeV);
95
- iy1 = wrap_int(fy_floor + 1, h, sampler.addressModeV);
96
- fy = py - fy_floor;
97
- }
98
-
99
- let iz0 = 0, iz1 = 0, fz = 0;
100
- if (dim >= 3) {
101
- const pz = tz - 0.5;
102
- const fz_floor = Math.floor(pz);
103
- iz0 = wrap_int(fz_floor, d, sampler.addressModeW);
104
- iz1 = wrap_int(fz_floor + 1, d, sampler.addressModeW);
105
- fz = pz - fz_floor;
106
- }
107
-
108
- const n = Math.min(item_size, 4);
109
-
110
- // Unrolled 2-corner loop per active axis (max 8 corners total). Skip
111
- // zero-weight corners early — common when the fractional offset is
112
- // exactly an integer (texel-centre sample).
113
- const xs = [ix0, ix1];
114
- const wxs = [1 - fx, fx];
115
- const ys = [iy0, iy1];
116
- const wys = [1 - fy, fy];
117
- const zs = [iz0, iz1];
118
- const wzs = [1 - fz, fz];
119
-
120
- const y_count = dim >= 2 ? 2 : 1;
121
- const z_count = dim >= 3 ? 2 : 1;
122
-
123
- for (let kz = 0; kz < z_count; kz++) {
124
- const wz = z_count === 1 ? 1 : wzs[kz];
125
- const z = zs[kz];
126
- for (let ky = 0; ky < y_count; ky++) {
127
- const wy = y_count === 1 ? 1 : wys[ky];
128
- const y = ys[ky];
129
- for (let kx = 0; kx < 2; kx++) {
130
- const wx = wxs[kx];
131
- const x = xs[kx];
132
- const weight = wx * wy * wz;
133
- if (weight === 0) continue;
134
- const base = texture.pixel_offset(x, y, z);
135
- for (let i = 0; i < n; i++) output[i] += texture.data[base + i] * weight;
136
- }
137
- }
138
- }
139
- }
140
-
141
- /**
142
- * Wrap an integer texel index back into `[0, size)` using the address
143
- * mode. Shared by both nearest and linear filtering — the linear filter
144
- * passes both the floor and floor+1 indices through this so wrapping at
145
- * the edge is consistent.
146
- *
147
- * @param {number} i
148
- * @param {number} size
149
- * @param {GPUAddressMode} mode
150
- * @returns {number}
151
- */
152
- function wrap_int(i, size, mode) {
153
- if (size <= 0) return 0;
154
- switch (mode) {
155
- case "clamp-to-edge":
156
- if (i < 0) return 0;
157
- if (i >= size) return size - 1;
158
- return i;
159
- case "repeat":
160
- return ((i % size) + size) % size;
161
- case "mirror-repeat": {
162
- // fold the second half of the period back onto the first:
163
- // w in [size, 2*size) maps to period - 1 - w in [0, size)
164
- const period = size * 2;
165
- let w = ((i % period) + period) % period;
166
- if (w >= size) w = period - 1 - w;
167
- return w;
168
- }
169
- default:
170
- throw new Error(`cpu_texture_sample: unsupported address mode '${mode}' (expected "clamp-to-edge", "repeat", or "mirror-repeat")`);
171
- }
172
- }
1
+ import { assert } from "../../../core/assert.js";
2
+
3
+ /**
4
+ * Sample a {@link CPUBitmapData} as if it were a GPU texture bound with
5
+ * the given sampler. Routes through nearest or linear filtering on each of
6
+ * the texture's actual axes (1D / 2D / 3D inferred from
7
+ * `texture.dimensionality`).
8
+ *
9
+ * **Mipmaps are intentionally not modelled.** The emulator runs at LOD 0
10
+ * only — there is no mip pyramid in {@link CPUBitmapData}, and
11
+ * `mipmapFilter` / `lodMinClamp` / `lodMaxClamp` on the sampler are
12
+ * ignored. We pick `magFilter` for the actual filter mode, which matches
13
+ * the intuition that emulator tests are typically up-sampling. Add a mip
14
+ * pyramid + minification path later if a test ever needs minified
15
+ * sampling.
16
+ *
17
+ * Convention for `texel_coord`: this is **TEXEL-SPACE coordinates** (i.e.
18
+ * UV * size, NOT normalised UV in [0, 1]). The shader-facing intrinsics
19
+ * `textureSample` / `textureSampleLevel` take normalised UV; the emulator
20
+ * converts to texel-space before calling here so the address-mode
21
+ * arithmetic doesn't have to special-case sub-1.0 jitter. WebGPU's
22
+ * convention places texel `i`'s centre at texel-space `i + 0.5`, so the
23
+ * left edge of the texture is at 0 and the right edge at `size`.
24
+ *
25
+ * Address-mode handling lives in {@link wrap_int}: every integer texel
26
+ * index produced by either filter passes through it before reading the
27
+ * backing buffer. Out-of-range fractional inputs fall out naturally from
28
+ * floor + integer wrap, so we don't pre-clamp the fractional coord (a
29
+ * previous version did and lost full-edge texel sampling for
30
+ * `clamp-to-edge`).
31
+ *
32
+ * @param {Float32Array | number[]} output — receives 4 channel values
33
+ * (channels beyond `texture.item_size` are zero, with alpha forced to 1
34
+ * for textures with fewer than 4 channels — matches WGSL semantics)
35
+ * @param {import("../../descriptor/texture/SamplerDescriptor.js").SamplerDescriptor} sampler
36
+ * @param {import("./CPUBitmapData.js").CPUBitmapData} texture
37
+ * @param {Float32Array | number[]} texel_coord — length matches
38
+ * `texture.dimensionality` (1, 2 or 3 entries)
39
+ */
40
+ export function cpu_texture_sample(output, sampler, texture, texel_coord) {
41
+ assert.defined(output, 'output');
42
+ assert.defined(sampler, 'sampler');
43
+ assert.defined(texture, 'texture');
44
+ assert.defined(texel_coord, 'texel_coord');
45
+
46
+ // Default channels 0..3 to 0; alpha to 1 if the texture has < 4 channels.
47
+ const item_size = texture.item_size;
48
+ for (let i = 0; i < 4; i++) output[i] = 0;
49
+ if (item_size < 4) output[3] = 1;
50
+
51
+ const dim = texture.dimensionality;
52
+ const w = texture.size[0];
53
+ const h = texture.size[1];
54
+ const d = texture.size[2];
55
+
56
+ const tx = texel_coord[0];
57
+ const ty = dim >= 2 ? texel_coord[1] : 0;
58
+ const tz = dim >= 3 ? texel_coord[2] : 0;
59
+
60
+ // Mipmaps not modelled — see header. Use magFilter as the single
61
+ // filter setting (sampler is bound at LOD 0 conceptually).
62
+ const filter = sampler.magFilter;
63
+
64
+ if (filter === "nearest") {
65
+ // WGSL nearest: texel index = floor(texel_coord), then wrap.
66
+ const ix = wrap_int(Math.floor(tx), w, sampler.addressModeU);
67
+ const iy = dim >= 2 ? wrap_int(Math.floor(ty), h, sampler.addressModeV) : 0;
68
+ const iz = dim >= 3 ? wrap_int(Math.floor(tz), d, sampler.addressModeW) : 0;
69
+ const base = texture.pixel_offset(ix, iy, iz);
70
+ const n = Math.min(item_size, 4);
71
+ for (let i = 0; i < n; i++) output[i] = texture.data[base + i];
72
+ return;
73
+ }
74
+
75
+ if (filter !== "linear") {
76
+ throw new Error(`cpu_texture_sample: unsupported magFilter '${filter}' (expected "nearest" or "linear")`);
77
+ }
78
+
79
+ // Linear filter. Sample 2 (1D) / 4 (2D) / 8 (3D) neighbouring texels
80
+ // around `texel_coord - 0.5` (the offset puts the bilinear origin at
81
+ // texel CENTRES) with weights `(1 - frac, frac)` per axis. Each
82
+ // integer index passes through `wrap_int` so the right/bottom/back
83
+ // neighbour falling off the edge is resolved by the address mode.
84
+ const px = tx - 0.5;
85
+ const fx_floor = Math.floor(px);
86
+ const ix0 = wrap_int(fx_floor, w, sampler.addressModeU);
87
+ const ix1 = wrap_int(fx_floor + 1, w, sampler.addressModeU);
88
+ const fx = px - fx_floor;
89
+
90
+ let iy0 = 0, iy1 = 0, fy = 0;
91
+ if (dim >= 2) {
92
+ const py = ty - 0.5;
93
+ const fy_floor = Math.floor(py);
94
+ iy0 = wrap_int(fy_floor, h, sampler.addressModeV);
95
+ iy1 = wrap_int(fy_floor + 1, h, sampler.addressModeV);
96
+ fy = py - fy_floor;
97
+ }
98
+
99
+ let iz0 = 0, iz1 = 0, fz = 0;
100
+ if (dim >= 3) {
101
+ const pz = tz - 0.5;
102
+ const fz_floor = Math.floor(pz);
103
+ iz0 = wrap_int(fz_floor, d, sampler.addressModeW);
104
+ iz1 = wrap_int(fz_floor + 1, d, sampler.addressModeW);
105
+ fz = pz - fz_floor;
106
+ }
107
+
108
+ const n = Math.min(item_size, 4);
109
+
110
+ // Unrolled 2-corner loop per active axis (max 8 corners total). Skip
111
+ // zero-weight corners early — common when the fractional offset is
112
+ // exactly an integer (texel-centre sample).
113
+ const xs = [ix0, ix1];
114
+ const wxs = [1 - fx, fx];
115
+ const ys = [iy0, iy1];
116
+ const wys = [1 - fy, fy];
117
+ const zs = [iz0, iz1];
118
+ const wzs = [1 - fz, fz];
119
+
120
+ const y_count = dim >= 2 ? 2 : 1;
121
+ const z_count = dim >= 3 ? 2 : 1;
122
+
123
+ for (let kz = 0; kz < z_count; kz++) {
124
+ const wz = z_count === 1 ? 1 : wzs[kz];
125
+ const z = zs[kz];
126
+ for (let ky = 0; ky < y_count; ky++) {
127
+ const wy = y_count === 1 ? 1 : wys[ky];
128
+ const y = ys[ky];
129
+ for (let kx = 0; kx < 2; kx++) {
130
+ const wx = wxs[kx];
131
+ const x = xs[kx];
132
+ const weight = wx * wy * wz;
133
+ if (weight === 0) continue;
134
+ const base = texture.pixel_offset(x, y, z);
135
+ for (let i = 0; i < n; i++) output[i] += texture.data[base + i] * weight;
136
+ }
137
+ }
138
+ }
139
+ }
140
+
141
+ /**
142
+ * Wrap an integer texel index back into `[0, size)` using the address
143
+ * mode. Shared by both nearest and linear filtering — the linear filter
144
+ * passes both the floor and floor+1 indices through this so wrapping at
145
+ * the edge is consistent.
146
+ *
147
+ * Exported because {@link cpu_texture_gather} needs the *same* address
148
+ * arithmetic: a gather's 2x2 footprint is the linear filter's footprint,
149
+ * and a second copy of this switch would be free to drift from it.
150
+ *
151
+ * @param {number} i
152
+ * @param {number} size
153
+ * @param {GPUAddressMode} mode
154
+ * @returns {number}
155
+ */
156
+ export function wrap_int(i, size, mode) {
157
+ if (size <= 0) return 0;
158
+ switch (mode) {
159
+ case "clamp-to-edge":
160
+ if (i < 0) return 0;
161
+ if (i >= size) return size - 1;
162
+ return i;
163
+ case "repeat":
164
+ return ((i % size) + size) % size;
165
+ case "mirror-repeat": {
166
+ // fold the second half of the period back onto the first:
167
+ // w in [size, 2*size) maps to period - 1 - w in [0, size)
168
+ const period = size * 2;
169
+ let w = ((i % period) + period) % period;
170
+ if (w >= size) w = period - 1 - w;
171
+ return w;
172
+ }
173
+ default:
174
+ throw new Error(`cpu_texture_sample: unsupported address mode '${mode}' (expected "clamp-to-edge", "repeat", or "mirror-repeat")`);
175
+ }
176
+ }
@@ -1,2 +0,0 @@
1
- export const VOLUMETRICS_WORKGROUP_RESOLUTION: number[];
2
- //# sourceMappingURL=VOLUMETRICS_WORKGROUP_RESOLUTION.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"VOLUMETRICS_WORKGROUP_RESOLUTION.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/volumetrics/VOLUMETRICS_WORKGROUP_RESOLUTION.js"],"names":[],"mappings":"AAAA,wDAA0D"}
@@ -1 +0,0 @@
1
- export const VOLUMETRICS_WORKGROUP_RESOLUTION = [8, 8, 4];