@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 +1 @@
1
- {"version":3,"file":"WGSLLanguageCore.d.ts","sourceRoot":"","sources":["../../../../../src/shade/wgsl/emulator/WGSLLanguageCore.js"],"names":[],"mappings":"AA2OA;;;;;;;;;;;;GAYG;AACH,+BAFU,MAAM,CAkyBd"}
1
+ {"version":3,"file":"WGSLLanguageCore.d.ts","sourceRoot":"","sources":["../../../../../src/shade/wgsl/emulator/WGSLLanguageCore.js"],"names":[],"mappings":"AA0PA;;;;;;;;;;;;GAYG;AACH,+BAFU,MAAM,CAm+Bd"}
@@ -1,4 +1,5 @@
1
1
  import { assert } from "../../../core/assert.js";
2
+ import { cpu_texture_gather, evaluate_gpu_compare_function } from "./cpu_texture_gather.js";
2
3
  import { cpu_texture_sample } from "./cpu_texture_sample.js";
3
4
 
4
5
  /**
@@ -15,6 +16,20 @@ const FALLBACK_LINEAR_CLAMP_SAMPLER = Object.freeze({
15
16
  mipmapFilter: "nearest",
16
17
  });
17
18
 
19
+ /**
20
+ * Normalised UV -> texel space, for the gather intrinsics. {@link cpu_texture_gather} takes
21
+ * texel-space coordinates, the same convention {@link cpu_texture_sample} documents, so the
22
+ * shader-facing side does the conversion — `textureGather` has no 3D or 1D overload in WGSL,
23
+ * so only the two axes are ever needed.
24
+ *
25
+ * @param {Float32Array | number[]} coords — normalised uv
26
+ * @param {import("./CPUBitmapData.js").CPUBitmapData} texture
27
+ * @returns {number[]}
28
+ */
29
+ function gather_texel_coord(coords, texture) {
30
+ return [coords[0] * texture.size[0], coords[1] * texture.size[1]];
31
+ }
32
+
18
33
  /**
19
34
  * Single-element scratch view used to round a number to IEEE 754 binary16 precision.
20
35
  * @type {Float16Array}
@@ -411,6 +426,34 @@ export const WGSLLanguageCore = {
411
426
  throw new Error(`determinant: unsupported matrix length ${m.length}`);
412
427
  },
413
428
 
429
+ /**
430
+ * Transpose of a square matrix stored as a flat column-major typed array.
431
+ *
432
+ * WGSL's `transpose` also accepts non-square `matCxR`, returning `matRxC`. Matrices here are
433
+ * flat arrays carrying no shape, so a 2x3 and a 3x2 are indistinguishable at runtime and only
434
+ * the square sizes can be answered — the same restriction {@link determinant} works under, for
435
+ * the same reason.
436
+ *
437
+ * @param {Float32Array|Float16Array} m
438
+ */
439
+ transpose(m) {
440
+ const n = Math.round(Math.sqrt(m.length));
441
+
442
+ if (n * n !== m.length || n < 2 || n > 4) {
443
+ throw new Error(`transpose: unsupported matrix length ${m.length}, expected a square 2x2, 3x3 or 4x4`);
444
+ }
445
+
446
+ const out = new m.constructor(m.length);
447
+
448
+ for (let col = 0; col < n; col++) {
449
+ for (let row = 0; row < n; row++) {
450
+ out[col * n + row] = m[row * n + col];
451
+ }
452
+ }
453
+
454
+ return out;
455
+ },
456
+
414
457
  // ---------------------------------------------------------------------
415
458
  // Arithmetic helpers (work on scalars and vectors element-wise)
416
459
  // ---------------------------------------------------------------------
@@ -761,10 +804,15 @@ export const WGSLLanguageCore = {
761
804
  * across all channels (with alpha defaulting to 1.0 for textures with
762
805
  * fewer than 4 channels - matches WGSL semantics).
763
806
  *
807
+ * A texture flagged `is_depth` returns a bare `f32` instead, matching WGSL: `textureLoad` on a
808
+ * `texture_depth_*` is declared to yield a scalar, and shader code written against one uses it
809
+ * as such. Handing that code a vec4 would turn every use into a component-wise broadcast that
810
+ * neither throws nor matches the device.
811
+ *
764
812
  * @param {import("./CPUBitmapData.js").CPUBitmapData} t
765
813
  * @param {Int32Array | Uint32Array | number[] | number} coords
766
814
  * @param {number} [_level] - ignored, mipmaps are not modelled
767
- * @returns {Float32Array}
815
+ * @returns {Float32Array | number}
768
816
  */
769
817
  textureLoad(t, coords, _level_or_index = 0, _array_level = undefined) {
770
818
  assert.defined(t, 'texture');
@@ -780,8 +828,14 @@ export const WGSLLanguageCore = {
780
828
  */
781
829
  const z = (_array_level !== undefined ? _level_or_index : (dim >= 3 ? coords[2] : 0)) | 0;
782
830
  const item_size = t.item_size;
831
+ const out_of_bounds = x < 0 || x >= t.size[0] || y < 0 || y >= t.size[1] || z < 0 || z >= t.size[2];
832
+
833
+ if (t.is_depth === true) {
834
+ return out_of_bounds ? 0.0 : t.data[t.pixel_offset(x, y, z)];
835
+ }
836
+
783
837
  if (item_size < 4) out[3] = 1.0;
784
- if (x < 0 || x >= t.size[0] || y < 0 || y >= t.size[1] || z < 0 || z >= t.size[2]) {
838
+ if (out_of_bounds) {
785
839
  return out;
786
840
  }
787
841
  const base = t.pixel_offset(x, y, z);
@@ -878,6 +932,160 @@ export const WGSLLanguageCore = {
878
932
  return WGSLLanguageCore.textureSampleLevel(t, sampler, coords, 0);
879
933
  },
880
934
 
935
+ /**
936
+ * `textureGather(component, t, s, coords[, array_index][, offset]) -> vec4<f32>` and the
937
+ * depth-texture overloads `textureGather(t, s, coords[, array_index][, offset])`, which carry
938
+ * no `component` argument because a `texture_depth_*` has a single channel.
939
+ *
940
+ * Returns the four texels of the bilinear footprint unblended, in WGSL's order —
941
+ * counter-clockwise from the lower-left, so `.wzxy` is row-major. See
942
+ * {@link cpu_texture_gather} for the footprint derivation, the component order in full, and
943
+ * why `magFilter` is ignored here (a gather never filters).
944
+ *
945
+ * Overloads are told apart by argument SHAPE, the way `textureLoad` and `textureSampleLevel`
946
+ * already tell their array forms apart: a leading number is the `component` of a colour
947
+ * gather, a leading texture means the depth overload; among the trailing arguments a number
948
+ * is an `array_index` and a vector is the const `offset`.
949
+ *
950
+ * **Cube textures are not supported** and throw rather than returning something. The emulator
951
+ * models no cube layout at all — {@link CPUBitmapData} is a flat 1D/2D/3D grid — so there is
952
+ * no face selection to gather across. A cube gather is recognisable by its `vec3` direction
953
+ * coordinate (`texture_3d` has no gather overload in WGSL at all).
954
+ *
955
+ * @param {number | import("./CPUBitmapData.js").CPUBitmapData} p0 — `component`, or the
956
+ * texture in the depth overloads
957
+ * @param {*} p1
958
+ * @param {*} p2
959
+ * @param {*} p3
960
+ * @param {*} [p4]
961
+ * @param {*} [p5]
962
+ * @returns {Float32Array}
963
+ */
964
+ textureGather(p0, p1, p2, p3, p4 = undefined, p5 = undefined) {
965
+ const has_component = typeof p0 === 'number';
966
+
967
+ const t = has_component ? p1 : p0;
968
+ const sampler = has_component ? p2 : p1;
969
+ const coords = has_component ? p3 : p2;
970
+
971
+ assert.defined(t, 'texture');
972
+
973
+ if (coords !== null && coords !== undefined && coords.length >= 3) {
974
+ throw new Error("textureGather: cube textures are not supported — the emulator has no cube layout to gather a face out of (CPUBitmapData is a flat 1D/2D/3D grid). Remap to an octahedral or array atlas, as the engine's shadow path does, and gather from that.");
975
+ }
976
+
977
+ const component = has_component ? (p0 | 0) : 0;
978
+
979
+ let array_index = 0;
980
+ let offset_x = 0;
981
+ let offset_y = 0;
982
+
983
+ const extra_a = has_component ? p4 : p3;
984
+ const extra_b = has_component ? p5 : p4;
985
+
986
+ if (typeof extra_a === 'number') array_index = extra_a;
987
+ else if (extra_a !== undefined) { offset_x = extra_a[0]; offset_y = extra_a[1]; }
988
+
989
+ if (extra_b !== undefined) { offset_x = extra_b[0]; offset_y = extra_b[1]; }
990
+
991
+ const result = new Float32Array(4);
992
+
993
+ cpu_texture_gather(
994
+ result,
995
+ sampler ?? FALLBACK_LINEAR_CLAMP_SAMPLER,
996
+ t,
997
+ gather_texel_coord(coords, t),
998
+ component,
999
+ offset_x,
1000
+ offset_y,
1001
+ array_index
1002
+ );
1003
+
1004
+ return result;
1005
+ },
1006
+
1007
+ /**
1008
+ * `textureGatherCompare(t, s, coords[, array_index], depth_ref[, offset]) -> vec4<f32>`
1009
+ *
1010
+ * The comparison form: each of the four gathered texels is tested against `depth_ref` and
1011
+ * yields 1.0 or 0.0 — unfiltered, per texel. The blend is the shader's job, which is exactly
1012
+ * what `shadowmap_sample_filtered` does with the result (`.wzxy` into
1013
+ * `interpolate_bilinear_f32`).
1014
+ *
1015
+ * The comparison itself comes from the bound sampler's `compare`, evaluated as
1016
+ * `compare(depth_ref, texel)` — see {@link evaluate_gpu_compare_function} for why that order
1017
+ * is load-bearing. A sampler with no `compare` set is an error rather than a defaulted one:
1018
+ * WGSL requires a `sampler_comparison` here, and picking a direction on the caller's behalf
1019
+ * would invert shadows silently.
1020
+ *
1021
+ * Overload disambiguation is by shape, as in {@link textureGather}: a trailing vector is the
1022
+ * const `offset`, and a fourth argument that is followed by another number is the
1023
+ * `array_index` rather than the reference depth.
1024
+ *
1025
+ * @param {import("./CPUBitmapData.js").CPUBitmapData} t
1026
+ * @param {import("../../descriptor/texture/SamplerDescriptor.js").SamplerDescriptor} sampler
1027
+ * @param {Float32Array | number[]} coords
1028
+ * @param {*} p3 — `depth_ref`, or the `array_index` in the array forms
1029
+ * @param {*} [p4]
1030
+ * @param {*} [p5]
1031
+ * @returns {Float32Array}
1032
+ */
1033
+ textureGatherCompare(t, sampler, coords, p3, p4 = undefined, p5 = undefined) {
1034
+ assert.defined(t, 'texture');
1035
+
1036
+ if (coords !== null && coords !== undefined && coords.length >= 3) {
1037
+ throw new Error("textureGatherCompare: cube textures are not supported — the emulator has no cube layout to gather a face out of (CPUBitmapData is a flat 1D/2D/3D grid). Remap to an octahedral or array atlas, as the engine's shadow path does, and gather from that.");
1038
+ }
1039
+
1040
+ let array_index = 0;
1041
+ let depth_ref;
1042
+ let offset = undefined;
1043
+
1044
+ if (p5 !== undefined) {
1045
+ // (t, s, coords, array_index, depth_ref, offset)
1046
+ array_index = p3;
1047
+ depth_ref = p4;
1048
+ offset = p5;
1049
+ } else if (p4 === undefined) {
1050
+ // (t, s, coords, depth_ref)
1051
+ depth_ref = p3;
1052
+ } else if (typeof p4 === 'number') {
1053
+ // (t, s, coords, array_index, depth_ref) — a scalar in the 5th slot is the reference
1054
+ array_index = p3;
1055
+ depth_ref = p4;
1056
+ } else {
1057
+ // (t, s, coords, depth_ref, offset) — a vector in the 5th slot is the offset
1058
+ depth_ref = p3;
1059
+ offset = p4;
1060
+ }
1061
+
1062
+ const effective_sampler = sampler ?? FALLBACK_LINEAR_CLAMP_SAMPLER;
1063
+ const compare = effective_sampler.compare;
1064
+
1065
+ if (compare === undefined || compare === null) {
1066
+ throw new Error("textureGatherCompare: the bound sampler has no 'compare' function — WGSL requires a sampler_comparison here. Bind a SamplerDescriptor with `compare` set (the engine's shadow path uses SHADOWMAP_COMPARE_SAMPLER_DESCRIPTOR, `compare: \"greater\"` for reverse-Z).");
1067
+ }
1068
+
1069
+ const result = new Float32Array(4);
1070
+
1071
+ cpu_texture_gather(
1072
+ result,
1073
+ effective_sampler,
1074
+ t,
1075
+ gather_texel_coord(coords, t),
1076
+ 0,
1077
+ offset !== undefined ? offset[0] : 0,
1078
+ offset !== undefined ? offset[1] : 0,
1079
+ array_index
1080
+ );
1081
+
1082
+ for (let i = 0; i < 4; i++) {
1083
+ result[i] = evaluate_gpu_compare_function(compare, depth_ref, result[i]);
1084
+ }
1085
+
1086
+ return result;
1087
+ },
1088
+
881
1089
  /**
882
1090
  * `textureStore(t, coords, value) -> ()`
883
1091
  *
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Read the four texels of a bilinear footprint out of a {@link CPUBitmapData} without
3
+ * blending them — the CPU side of WGSL's `textureGather` / `textureGatherCompare`.
4
+ *
5
+ * **The footprint is the linear filter's footprint.** `cpu_texture_sample` derives it as
6
+ * `px = texel_coord - 0.5`, then `floor(px)` and `floor(px) + 1` on each axis, each index
7
+ * passed through {@link wrap_int} for the address mode. A gather covers exactly those four
8
+ * texels, so this function reuses that arithmetic rather than restating it.
9
+ *
10
+ * **`magFilter` is deliberately ignored.** A gather always returns four texels — the
11
+ * sampler's filter mode selects nothing, because no filtering happens. This is the one
12
+ * place `cpu_texture_sample` cannot simply be called: under `magFilter: "nearest"` it
13
+ * collapses to a single texel, which is right for a sample and wrong for a gather. The
14
+ * address modes still apply, and they are the only part of the sampler this reads.
15
+ *
16
+ * **Mipmaps are not modelled — LOD 0 only.** Same stance, and for the same reason, as
17
+ * {@link cpu_texture_sample}; see its header. `textureGather` has no LOD parameter in WGSL
18
+ * anyway, so here the restriction costs nothing.
19
+ *
20
+ * Convention for `texel_coord`, as in {@link cpu_texture_sample}: **texel-space**
21
+ * coordinates (UV * size), not normalised UV. The shader-facing intrinsics in
22
+ * {@link WGSLLanguageCore} do the conversion before calling.
23
+ *
24
+ * Component order is WGSL's, counter-clockwise from the lower-left texel — the same order
25
+ * D3D and Vulkan use:
26
+ *
27
+ * ```
28
+ * output[0] = (u_min, v_max) lower-left
29
+ * output[1] = (u_max, v_max) lower-right
30
+ * output[2] = (u_max, v_min) upper-right
31
+ * output[3] = (u_min, v_min) upper-left
32
+ * ```
33
+ *
34
+ * so `gathered.wzxy` is the row-major (x0y0, x1y0, x0y1, x1y1) order a bilinear blend
35
+ * wants — which is exactly the swizzle `shadowmap_sample_filtered` applies before handing
36
+ * the result to `interpolate_bilinear_f32`.
37
+ *
38
+ * @param {Float32Array | number[]} output — receives the 4 gathered texel values
39
+ * @param {import("../../descriptor/texture/SamplerDescriptor.js").SamplerDescriptor} sampler
40
+ * @param {import("./CPUBitmapData.js").CPUBitmapData} texture
41
+ * @param {Float32Array | number[]} texel_coord — `[x, y]` in texel space
42
+ * @param {number} [component] — channel to read, 0..3. Forced to 0 for a depth texture,
43
+ * which has a single channel and whose WGSL overloads take no component argument.
44
+ * @param {number} [offset_x] — const `vec2<i32>` offset, applied to the integer texel
45
+ * indices *before* the address mode, per WGSL
46
+ * @param {number} [offset_y]
47
+ * @param {number} [layer] — array slice for the `_2d_array` forms; clamped to the
48
+ * texture's depth
49
+ */
50
+ export function cpu_texture_gather(output: Float32Array | number[], sampler: import("../../descriptor/texture/SamplerDescriptor.js").SamplerDescriptor, texture: import("./CPUBitmapData.js").CPUBitmapData, texel_coord: Float32Array | number[], component?: number, offset_x?: number, offset_y?: number, layer?: number): void;
51
+ /**
52
+ * Evaluate a `GPUCompareFunction` the way a comparison sampler does.
53
+ *
54
+ * **Argument order matters and is easy to invert.** WebGPU evaluates
55
+ * `compare(reference, sampled)` — the shader's `depth_ref` is the LEFT operand, the value
56
+ * read out of the depth texture is the right one. So under `"greater"` (what the engine's
57
+ * {@link SHADOWMAP_COMPARE_SAMPLER_DESCRIPTOR} uses, because shadow maps are reverse-Z) a
58
+ * receiver passes — result 1.0, "lit" — when its own depth is *greater* than the stored
59
+ * occluder depth, i.e. when it is nearer to the light. Swapping the operands inverts every
60
+ * shadow in the engine while still producing plausible-looking output, which is why
61
+ * `cpu_texture_gather.spec.js` pins the direction explicitly.
62
+ *
63
+ * @param {GPUCompareFunction} compare
64
+ * @param {number} reference — the shader's `depth_ref`
65
+ * @param {number} sampled — the texel read from the depth texture
66
+ * @returns {number} 1.0 when the comparison passes, 0.0 when it fails
67
+ */
68
+ export function evaluate_gpu_compare_function(compare: GPUCompareFunction, reference: number, sampled: number): number;
69
+ //# sourceMappingURL=cpu_texture_gather.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cpu_texture_gather.d.ts","sourceRoot":"","sources":["../../../../../src/shade/wgsl/emulator/cpu_texture_gather.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,2CAZW,YAAY,GAAG,MAAM,EAAE,WACvB,OAAO,+CAA+C,EAAE,iBAAiB,WACzE,OAAO,oBAAoB,EAAE,aAAa,eAC1C,YAAY,GAAG,MAAM,EAAE,cACvB,MAAM,aAEN,MAAM,aAEN,MAAM,UACN,MAAM,QAqChB;AAwBD;;;;;;;;;;;;;;;;GAgBG;AACH,sFAJW,MAAM,WACN,MAAM,GACJ,MAAM,CAuBlB"}
@@ -0,0 +1,148 @@
1
+ import { wrap_int } from "./cpu_texture_sample.js";
2
+
3
+ /**
4
+ * Read the four texels of a bilinear footprint out of a {@link CPUBitmapData} without
5
+ * blending them — the CPU side of WGSL's `textureGather` / `textureGatherCompare`.
6
+ *
7
+ * **The footprint is the linear filter's footprint.** `cpu_texture_sample` derives it as
8
+ * `px = texel_coord - 0.5`, then `floor(px)` and `floor(px) + 1` on each axis, each index
9
+ * passed through {@link wrap_int} for the address mode. A gather covers exactly those four
10
+ * texels, so this function reuses that arithmetic rather than restating it.
11
+ *
12
+ * **`magFilter` is deliberately ignored.** A gather always returns four texels — the
13
+ * sampler's filter mode selects nothing, because no filtering happens. This is the one
14
+ * place `cpu_texture_sample` cannot simply be called: under `magFilter: "nearest"` it
15
+ * collapses to a single texel, which is right for a sample and wrong for a gather. The
16
+ * address modes still apply, and they are the only part of the sampler this reads.
17
+ *
18
+ * **Mipmaps are not modelled — LOD 0 only.** Same stance, and for the same reason, as
19
+ * {@link cpu_texture_sample}; see its header. `textureGather` has no LOD parameter in WGSL
20
+ * anyway, so here the restriction costs nothing.
21
+ *
22
+ * Convention for `texel_coord`, as in {@link cpu_texture_sample}: **texel-space**
23
+ * coordinates (UV * size), not normalised UV. The shader-facing intrinsics in
24
+ * {@link WGSLLanguageCore} do the conversion before calling.
25
+ *
26
+ * Component order is WGSL's, counter-clockwise from the lower-left texel — the same order
27
+ * D3D and Vulkan use:
28
+ *
29
+ * ```
30
+ * output[0] = (u_min, v_max) lower-left
31
+ * output[1] = (u_max, v_max) lower-right
32
+ * output[2] = (u_max, v_min) upper-right
33
+ * output[3] = (u_min, v_min) upper-left
34
+ * ```
35
+ *
36
+ * so `gathered.wzxy` is the row-major (x0y0, x1y0, x0y1, x1y1) order a bilinear blend
37
+ * wants — which is exactly the swizzle `shadowmap_sample_filtered` applies before handing
38
+ * the result to `interpolate_bilinear_f32`.
39
+ *
40
+ * @param {Float32Array | number[]} output — receives the 4 gathered texel values
41
+ * @param {import("../../descriptor/texture/SamplerDescriptor.js").SamplerDescriptor} sampler
42
+ * @param {import("./CPUBitmapData.js").CPUBitmapData} texture
43
+ * @param {Float32Array | number[]} texel_coord — `[x, y]` in texel space
44
+ * @param {number} [component] — channel to read, 0..3. Forced to 0 for a depth texture,
45
+ * which has a single channel and whose WGSL overloads take no component argument.
46
+ * @param {number} [offset_x] — const `vec2<i32>` offset, applied to the integer texel
47
+ * indices *before* the address mode, per WGSL
48
+ * @param {number} [offset_y]
49
+ * @param {number} [layer] — array slice for the `_2d_array` forms; clamped to the
50
+ * texture's depth
51
+ */
52
+ export function cpu_texture_gather(
53
+ output,
54
+ sampler,
55
+ texture,
56
+ texel_coord,
57
+ component = 0,
58
+ offset_x = 0,
59
+ offset_y = 0,
60
+ layer = 0
61
+ ) {
62
+ const w = texture.size[0];
63
+ const h = texture.size[1];
64
+ const d = texture.size[2];
65
+
66
+ // A depth texture is single-channel; its gather overloads carry no component argument.
67
+ const channel = texture.is_depth === true ? 0 : (component | 0);
68
+
69
+ // Same derivation as the linear branch of `cpu_texture_sample`: shift by half a texel so
70
+ // the footprint is anchored on texel CENTRES, then floor.
71
+ const x_floor = Math.floor(texel_coord[0] - 0.5) + (offset_x | 0);
72
+ const y_floor = Math.floor(texel_coord[1] - 0.5) + (offset_y | 0);
73
+
74
+ const x0 = wrap_int(x_floor, w, sampler.addressModeU);
75
+ const x1 = wrap_int(x_floor + 1, w, sampler.addressModeU);
76
+ const y0 = wrap_int(y_floor, h, sampler.addressModeV);
77
+ const y1 = wrap_int(y_floor + 1, h, sampler.addressModeV);
78
+
79
+ // The array index is not an address-mode axis — WGSL clamps it to the layer count.
80
+ const z = d <= 0 ? 0 : Math.min(Math.max(layer | 0, 0), d - 1);
81
+
82
+ output[0] = read_channel(texture, x0, y1, z, channel);
83
+ output[1] = read_channel(texture, x1, y1, z, channel);
84
+ output[2] = read_channel(texture, x1, y0, z, channel);
85
+ output[3] = read_channel(texture, x0, y0, z, channel);
86
+ }
87
+
88
+ /**
89
+ * One channel of one texel. Channels past the texture's `item_size` follow the same
90
+ * convention `cpu_texture_sample` uses for its output vector: zero, with alpha defaulting
91
+ * to 1 — matching WGSL's rule for formats with fewer than four channels.
92
+ *
93
+ * Coordinates arrive already wrapped by {@link wrap_int}, so no bounds check is needed.
94
+ *
95
+ * @param {import("./CPUBitmapData.js").CPUBitmapData} texture
96
+ * @param {number} x
97
+ * @param {number} y
98
+ * @param {number} z
99
+ * @param {number} component
100
+ * @returns {number}
101
+ */
102
+ function read_channel(texture, x, y, z, component) {
103
+ if (component >= texture.item_size) {
104
+ return component === 3 ? 1 : 0;
105
+ }
106
+
107
+ return texture.data[texture.pixel_offset(x, y, z) + component];
108
+ }
109
+
110
+ /**
111
+ * Evaluate a `GPUCompareFunction` the way a comparison sampler does.
112
+ *
113
+ * **Argument order matters and is easy to invert.** WebGPU evaluates
114
+ * `compare(reference, sampled)` — the shader's `depth_ref` is the LEFT operand, the value
115
+ * read out of the depth texture is the right one. So under `"greater"` (what the engine's
116
+ * {@link SHADOWMAP_COMPARE_SAMPLER_DESCRIPTOR} uses, because shadow maps are reverse-Z) a
117
+ * receiver passes — result 1.0, "lit" — when its own depth is *greater* than the stored
118
+ * occluder depth, i.e. when it is nearer to the light. Swapping the operands inverts every
119
+ * shadow in the engine while still producing plausible-looking output, which is why
120
+ * `cpu_texture_gather.spec.js` pins the direction explicitly.
121
+ *
122
+ * @param {GPUCompareFunction} compare
123
+ * @param {number} reference — the shader's `depth_ref`
124
+ * @param {number} sampled — the texel read from the depth texture
125
+ * @returns {number} 1.0 when the comparison passes, 0.0 when it fails
126
+ */
127
+ export function evaluate_gpu_compare_function(compare, reference, sampled) {
128
+ switch (compare) {
129
+ case "never":
130
+ return 0;
131
+ case "less":
132
+ return reference < sampled ? 1 : 0;
133
+ case "equal":
134
+ return reference === sampled ? 1 : 0;
135
+ case "less-equal":
136
+ return reference <= sampled ? 1 : 0;
137
+ case "greater":
138
+ return reference > sampled ? 1 : 0;
139
+ case "not-equal":
140
+ return reference !== sampled ? 1 : 0;
141
+ case "greater-equal":
142
+ return reference >= sampled ? 1 : 0;
143
+ case "always":
144
+ return 1;
145
+ default:
146
+ throw new Error(`evaluate_gpu_compare_function: unsupported compare function '${compare}' (expected one of "never", "less", "equal", "less-equal", "greater", "not-equal", "greater-equal", "always")`);
147
+ }
148
+ }
@@ -36,4 +36,20 @@
36
36
  * `texture.dimensionality` (1, 2 or 3 entries)
37
37
  */
38
38
  export function cpu_texture_sample(output: Float32Array | number[], sampler: import("../../descriptor/texture/SamplerDescriptor.js").SamplerDescriptor, texture: import("./CPUBitmapData.js").CPUBitmapData, texel_coord: Float32Array | number[]): void;
39
+ /**
40
+ * Wrap an integer texel index back into `[0, size)` using the address
41
+ * mode. Shared by both nearest and linear filtering — the linear filter
42
+ * passes both the floor and floor+1 indices through this so wrapping at
43
+ * the edge is consistent.
44
+ *
45
+ * Exported because {@link cpu_texture_gather} needs the *same* address
46
+ * arithmetic: a gather's 2x2 footprint is the linear filter's footprint,
47
+ * and a second copy of this switch would be free to drift from it.
48
+ *
49
+ * @param {number} i
50
+ * @param {number} size
51
+ * @param {GPUAddressMode} mode
52
+ * @returns {number}
53
+ */
54
+ export function wrap_int(i: number, size: number, mode: GPUAddressMode): number;
39
55
  //# sourceMappingURL=cpu_texture_sample.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cpu_texture_sample.d.ts","sourceRoot":"","sources":["../../../../../src/shade/wgsl/emulator/cpu_texture_sample.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,2CARW,YAAY,GAAG,MAAM,EAAE,WAGvB,OAAO,+CAA+C,EAAE,iBAAiB,WACzE,OAAO,oBAAoB,EAAE,aAAa,eAC1C,YAAY,GAAG,MAAM,EAAE,QAsGjC"}
1
+ {"version":3,"file":"cpu_texture_sample.d.ts","sourceRoot":"","sources":["../../../../../src/shade/wgsl/emulator/cpu_texture_sample.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,2CARW,YAAY,GAAG,MAAM,EAAE,WAGvB,OAAO,+CAA+C,EAAE,iBAAiB,WACzE,OAAO,oBAAoB,EAAE,aAAa,eAC1C,YAAY,GAAG,MAAM,EAAE,QAsGjC;AAED;;;;;;;;;;;;;;GAcG;AACH,4BALW,MAAM,QACN,MAAM,yBAEJ,MAAM,CAsBlB"}