@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.
- package/build/bundle-worker-terrain.js +1 -1
- package/package.json +1 -1
- package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
- package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +294 -290
- package/src/engine/graphics3/ParticipatingMedia.d.ts +111 -0
- package/src/engine/graphics3/ParticipatingMedia.d.ts.map +1 -0
- package/src/engine/graphics3/ParticipatingMedia.js +203 -0
- package/src/engine/graphics3/ParticipatingMediaSerializationAdapter.d.ts +34 -0
- package/src/engine/graphics3/ParticipatingMediaSerializationAdapter.d.ts.map +1 -0
- package/src/engine/graphics3/ParticipatingMediaSerializationAdapter.js +73 -0
- package/src/engine/graphics3/ParticipatingMediaSystem3.d.ts +87 -0
- package/src/engine/graphics3/ParticipatingMediaSystem3.d.ts.map +1 -0
- package/src/engine/graphics3/ParticipatingMediaSystem3.js +184 -0
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/shade/descriptor/pipeline/PipelineLayoutDescriptor.d.ts +16 -2
- package/src/shade/descriptor/pipeline/PipelineLayoutDescriptor.d.ts.map +1 -1
- package/src/shade/descriptor/pipeline/PipelineLayoutDescriptor.js +28 -4
- package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.d.ts +1 -1
- package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.d.ts.map +1 -1
- package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.js +5 -2
- package/src/shade/device/IMMEDIATE_DATA_PLAN_2026_08_28.md +564 -451
- package/src/shade/device/ShadeGPUCommandContext.d.ts +18 -2
- package/src/shade/device/ShadeGPUCommandContext.d.ts.map +1 -1
- package/src/shade/device/ShadeGPUCommandContext.js +994 -940
- package/src/shade/device/immediate_data_supported.d.ts +33 -0
- package/src/shade/device/immediate_data_supported.d.ts.map +1 -0
- package/src/shade/device/immediate_data_supported.js +53 -0
- package/src/shade/device/mock/SoftwareGPUCommandEncoder.d.ts +18 -0
- package/src/shade/device/mock/SoftwareGPUCommandEncoder.d.ts.map +1 -1
- package/src/shade/device/mock/SoftwareGPUCommandEncoder.js +24 -0
- package/src/shade/device/mock/SoftwareGPUComputePassEncoder.d.ts +7 -0
- package/src/shade/device/mock/SoftwareGPUComputePassEncoder.d.ts.map +1 -1
- package/src/shade/device/mock/SoftwareGPUComputePassEncoder.js +49 -1
- package/src/shade/device/mock/SoftwareGPUDevice.d.ts.map +1 -1
- package/src/shade/device/mock/SoftwareGPUDevice.js +20 -2
- package/src/shade/device/mock/SoftwareGPUImmediateData.d.ts +65 -0
- package/src/shade/device/mock/SoftwareGPUImmediateData.d.ts.map +1 -0
- package/src/shade/device/mock/SoftwareGPUImmediateData.js +160 -0
- package/src/shade/device/mock/SoftwareGPURenderPassEncoder.d.ts +7 -0
- package/src/shade/device/mock/SoftwareGPURenderPassEncoder.d.ts.map +1 -1
- package/src/shade/device/mock/SoftwareGPURenderPassEncoder.js +50 -0
- package/src/shade/device/mock/pipeline_immediate_size.d.ts +11 -0
- package/src/shade/device/mock/pipeline_immediate_size.d.ts.map +1 -0
- package/src/shade/device/mock/pipeline_immediate_size.js +18 -0
- package/src/shade/device/pipeline/PipelineLayoutManager.d.ts.map +1 -1
- package/src/shade/device/pipeline/PipelineLayoutManager.js +1 -0
- package/src/shade/playground/volumetrics_froxel/README.md +104 -1
- package/src/shade/playground/volumetrics_froxel/index.html +20 -1
- package/src/shade/playground/volumetrics_froxel/main.d.ts.map +1 -1
- package/src/shade/playground/volumetrics_froxel/main.js +298 -0
- package/src/shade/playground/volumetrics_froxel/measure.d.ts +119 -0
- package/src/shade/playground/volumetrics_froxel/measure.d.ts.map +1 -0
- package/src/shade/playground/volumetrics_froxel/measure.js +559 -0
- package/src/shade/renderer/GraphicsContext.d.ts +9 -2
- package/src/shade/renderer/GraphicsContext.d.ts.map +1 -1
- package/src/shade/renderer/GraphicsContext.js +13 -1
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +22 -18
- package/src/shade/renderer/atmosphere/GPUSky.d.ts.map +1 -1
- package/src/shade/renderer/atmosphere/GPUSky.js +145 -142
- package/src/shade/renderer/atmosphere/MULTISCATTER_LUT_CONFIG.d.ts +34 -0
- package/src/shade/renderer/atmosphere/MULTISCATTER_LUT_CONFIG.d.ts.map +1 -0
- package/src/shade/renderer/atmosphere/MULTISCATTER_LUT_CONFIG.js +36 -0
- package/src/shade/renderer/atmosphere/SAMPLER_SKY_LUT.d.ts +20 -0
- package/src/shade/renderer/atmosphere/SAMPLER_SKY_LUT.d.ts.map +1 -0
- package/src/shade/renderer/atmosphere/SAMPLER_SKY_LUT.js +25 -0
- package/src/shade/renderer/atmosphere/chunk_get_multiscatter_values.d.ts +14 -1
- package/src/shade/renderer/atmosphere/chunk_get_multiscatter_values.d.ts.map +1 -1
- package/src/shade/renderer/atmosphere/chunk_get_multiscatter_values.js +163 -177
- package/src/shade/renderer/atmosphere/chunk_multiscatter_sample_direction.d.ts +20 -0
- package/src/shade/renderer/atmosphere/chunk_multiscatter_sample_direction.d.ts.map +1 -0
- package/src/shade/renderer/atmosphere/chunk_multiscatter_sample_direction.js +46 -0
- package/src/shade/renderer/atmosphere/chunk_sample_multiscatter_lut.d.ts +11 -1
- package/src/shade/renderer/atmosphere/chunk_sample_multiscatter_lut.d.ts.map +1 -1
- package/src/shade/renderer/atmosphere/chunk_sample_multiscatter_lut.js +57 -27
- package/src/shade/renderer/atmosphere/chunk_sample_transmittance_lut.d.ts +19 -1
- package/src/shade/renderer/atmosphere/chunk_sample_transmittance_lut.d.ts.map +1 -1
- package/src/shade/renderer/atmosphere/chunk_sample_transmittance_lut.js +69 -33
- package/src/shade/renderer/atmosphere/chunk_sky_lut_compute_uv.d.ts +13 -0
- package/src/shade/renderer/atmosphere/chunk_sky_lut_compute_uv.d.ts.map +1 -1
- package/src/shade/renderer/atmosphere/chunk_sky_lut_compute_uv.js +35 -35
- package/src/shade/renderer/atmosphere/chunk_sky_lut_params.d.ts +13 -0
- package/src/shade/renderer/atmosphere/chunk_sky_lut_params.d.ts.map +1 -0
- package/src/shade/renderer/atmosphere/chunk_sky_lut_params.js +38 -0
- package/src/shade/renderer/atmosphere/chunk_sky_lut_texel_to_unit.d.ts +17 -0
- package/src/shade/renderer/atmosphere/chunk_sky_lut_texel_to_unit.d.ts.map +1 -0
- package/src/shade/renderer/atmosphere/chunk_sky_lut_texel_to_unit.js +29 -0
- package/src/shade/renderer/atmosphere/chunk_sky_lut_uv.d.ts +21 -0
- package/src/shade/renderer/atmosphere/chunk_sky_lut_uv.d.ts.map +1 -0
- package/src/shade/renderer/atmosphere/chunk_sky_lut_uv.js +42 -0
- package/src/shade/renderer/atmosphere/shader_multiscatter_lut.d.ts +2 -2
- package/src/shade/renderer/atmosphere/shader_multiscatter_lut.d.ts.map +1 -1
- package/src/shade/renderer/atmosphere/shader_multiscatter_lut.js +165 -84
- package/src/shade/renderer/atmosphere/shader_sky_irradiance_lut.d.ts.map +1 -1
- package/src/shade/renderer/atmosphere/shader_sky_irradiance_lut.js +215 -204
- package/src/shade/renderer/atmosphere/shader_transmittance_lut.d.ts.map +1 -1
- package/src/shade/renderer/atmosphere/shader_transmittance_lut.js +79 -67
- package/src/shade/renderer/light/cluster/graph_assign_clsuters.d.ts.map +1 -1
- package/src/shade/renderer/light/cluster/graph_assign_clsuters.js +6 -2
- package/src/shade/renderer/postprocess/gtao/GTAO.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/gtao/GTAO.js +4 -0
- package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
- package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +341 -345
- package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts +0 -2
- package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.js +58 -57
- package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.js +7 -3
- package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.js +77 -81
- package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.js +5 -1
- package/src/shade/renderer/shader/ComputeShader.d.ts.map +1 -1
- package/src/shade/renderer/shader/ComputeShader.js +6 -2
- package/src/shade/renderer/shader/ImageShader.d.ts.map +1 -1
- package/src/shade/renderer/shader/ImageShader.js +4 -1
- package/src/shade/renderer/shader/ShaderDescriptor.d.ts.map +1 -1
- package/src/shade/renderer/shader/ShaderDescriptor.js +26 -0
- package/src/shade/renderer/shader/chunk/atmosphere/ATMOSPHERE_RADII_DECLARATION.d.ts +18 -0
- package/src/shade/renderer/shader/chunk/atmosphere/ATMOSPHERE_RADII_DECLARATION.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/atmosphere/ATMOSPHERE_RADII_DECLARATION.js +32 -0
- package/src/shade/renderer/shader/chunk/atmosphere/PLANET_CENTER_DECLARATION.d.ts +7 -0
- package/src/shade/renderer/shader/chunk/atmosphere/PLANET_CENTER_DECLARATION.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/atmosphere/PLANET_CENTER_DECLARATION.js +17 -6
- package/src/shade/renderer/shader/chunk/atmosphere/chunk_atmosphere_ray_bounds.d.ts +21 -0
- package/src/shade/renderer/shader/chunk/atmosphere/chunk_atmosphere_ray_bounds.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/atmosphere/chunk_atmosphere_ray_bounds.js +69 -0
- package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_contains_aabb3.d.ts +9 -0
- package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_contains_aabb3.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_contains_aabb3.js +22 -0
- package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_from_transformed_corners.d.ts +16 -0
- package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_from_transformed_corners.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/geometry/aabb3/chunk_aabb3_from_transformed_corners.js +41 -0
- package/src/shade/renderer/shader/chunk/geometry/frustum/chunk_frustum_transform_m4.d.ts +11 -0
- package/src/shade/renderer/shader/chunk/geometry/frustum/chunk_frustum_transform_m4.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/geometry/frustum/chunk_frustum_transform_m4.js +15 -19
- package/src/shade/renderer/shader/chunk/geometry/frustum/chunk_frustum_transform_plane_matrix.d.ts +23 -0
- package/src/shade/renderer/shader/chunk/geometry/frustum/chunk_frustum_transform_plane_matrix.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/geometry/frustum/chunk_frustum_transform_plane_matrix.js +44 -0
- package/src/shade/renderer/shader/chunk/geometry/octahedron/chunk_uv_octahedral_unit_decode.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/geometry/octahedron/chunk_uv_octahedral_unit_decode.js +1 -4
- package/src/shade/renderer/shader/compiler/CodeChunk.d.ts +7 -1
- package/src/shade/renderer/shader/compiler/CodeChunk.d.ts.map +1 -1
- package/src/shade/renderer/shader/compiler/CodeChunk.js +37 -2
- package/src/shade/renderer/shader/graph/compute/compute_binding_read_names.d.ts.map +1 -1
- package/src/shade/renderer/shader/graph/compute/compute_binding_read_names.js +6 -0
- package/src/shade/renderer/shader/graph/compute/graph_compute_indirect_pass.js +1 -1
- package/src/shade/renderer/shader/graph/compute/graph_compute_pass.js +1 -1
- package/src/shade/renderer/shader/graph/graph_image_pass.js +1 -1
- package/src/shade/renderer/shader/graph/graph_prepare_bindings.d.ts.map +1 -1
- package/src/shade/renderer/shader/graph/graph_prepare_bindings.js +7 -0
- package/src/shade/renderer/shader/graph/graph_prepare_pass_input_data.d.ts +3 -1
- package/src/shade/renderer/shader/graph/graph_prepare_pass_input_data.d.ts.map +1 -1
- package/src/shade/renderer/shader/graph/graph_prepare_pass_input_data.js +12 -1
- package/src/shade/renderer/shader/pass/RenderPassDescriptor.d.ts.map +1 -1
- package/src/shade/renderer/shader/pass/RenderPassDescriptor.js +1 -0
- package/src/shade/renderer/shader/resource/IMMEDIATE_DATA.d.ts +21 -0
- package/src/shade/renderer/shader/resource/IMMEDIATE_DATA.d.ts.map +1 -0
- package/src/shade/renderer/shader/resource/IMMEDIATE_DATA.js +21 -0
- package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.d.ts +59 -1
- package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.d.ts.map +1 -1
- package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.js +195 -2
- package/src/shade/renderer/shader/type/type_has_arrays.d.ts +14 -0
- package/src/shade/renderer/shader/type/type_has_arrays.d.ts.map +1 -0
- package/src/shade/renderer/shader/type/type_has_arrays.js +33 -0
- package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_point2.d.ts +14 -13
- package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_point2.d.ts.map +1 -1
- package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_point2.js +133 -129
- package/src/shade/renderer/view/GPUViewSkyContext.d.ts.map +1 -1
- package/src/shade/renderer/view/GPUViewSkyContext.js +169 -173
- package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +480 -315
- package/src/shade/renderer/volumetrics/NOTES.md +887 -8
- package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.d.ts +5 -0
- package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.js +21 -2
- package/src/shade/renderer/volumetrics/SceneVolumetrics.d.ts +26 -0
- package/src/shade/renderer/volumetrics/SceneVolumetrics.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/SceneVolumetrics.js +64 -21
- package/src/shade/renderer/volumetrics/VOLUMETRICS_METADATA_STRUCT.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/VOLUMETRICS_METADATA_STRUCT.js +84 -28
- package/src/shade/renderer/volumetrics/VOLUMETRICS_SUN_SHADOW_RESOLUTION.d.ts +98 -0
- package/src/shade/renderer/volumetrics/VOLUMETRICS_SUN_SHADOW_RESOLUTION.d.ts.map +1 -0
- package/src/shade/renderer/volumetrics/VOLUMETRICS_SUN_SHADOW_RESOLUTION.js +111 -0
- package/src/shade/renderer/volumetrics/build_volumetrics_sun_shadow_transform.d.ts +84 -0
- package/src/shade/renderer/volumetrics/build_volumetrics_sun_shadow_transform.d.ts.map +1 -0
- package/src/shade/renderer/volumetrics/build_volumetrics_sun_shadow_transform.js +252 -0
- package/src/shade/renderer/volumetrics/chunk_integrate_optical_depth.js +75 -75
- package/src/shade/renderer/volumetrics/chunk_volumetrics_local_light_shadow.d.ts +43 -0
- package/src/shade/renderer/volumetrics/chunk_volumetrics_local_light_shadow.d.ts.map +1 -0
- package/src/shade/renderer/volumetrics/chunk_volumetrics_local_light_shadow.js +145 -0
- package/src/shade/renderer/volumetrics/chunk_volumetrics_sample_froxel_extinction.d.ts +20 -0
- package/src/shade/renderer/volumetrics/chunk_volumetrics_sample_froxel_extinction.d.ts.map +1 -0
- package/src/shade/renderer/volumetrics/chunk_volumetrics_sample_froxel_extinction.js +48 -0
- package/src/shade/renderer/volumetrics/chunk_volumetrics_sun_optical_depth.d.ts +38 -0
- package/src/shade/renderer/volumetrics/chunk_volumetrics_sun_optical_depth.d.ts.map +1 -0
- package/src/shade/renderer/volumetrics/chunk_volumetrics_sun_optical_depth.js +130 -0
- package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts +18 -3
- package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +193 -70
- package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts +16 -0
- package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.js +83 -15
- package/src/shade/renderer/volumetrics/shader_volumetrics_build_participating_media.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/shader_volumetrics_build_participating_media.js +29 -18
- package/src/shade/renderer/volumetrics/shader_volumetrics_build_scattering_lut.js +260 -260
- package/src/shade/renderer/volumetrics/shader_volumetrics_build_sun_shadow_volume.d.ts +58 -0
- package/src/shade/renderer/volumetrics/shader_volumetrics_build_sun_shadow_volume.d.ts.map +1 -0
- package/src/shade/renderer/volumetrics/shader_volumetrics_build_sun_shadow_volume.js +290 -0
- package/src/shade/wgsl/emulator/CPUBitmapData.d.ts +25 -0
- package/src/shade/wgsl/emulator/CPUBitmapData.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/CPUBitmapData.js +33 -0
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +2228 -2215
- package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/WGSLLanguageCore.js +210 -2
- package/src/shade/wgsl/emulator/cpu_texture_gather.d.ts +69 -0
- package/src/shade/wgsl/emulator/cpu_texture_gather.d.ts.map +1 -0
- package/src/shade/wgsl/emulator/cpu_texture_gather.js +148 -0
- package/src/shade/wgsl/emulator/cpu_texture_sample.d.ts +16 -0
- package/src/shade/wgsl/emulator/cpu_texture_sample.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/cpu_texture_sample.js +176 -172
- package/src/shade/renderer/volumetrics/VOLUMETRICS_WORKGROUP_RESOLUTION.d.ts +0 -2
- package/src/shade/renderer/volumetrics/VOLUMETRICS_WORKGROUP_RESOLUTION.d.ts.map +0 -1
- 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
|
-
* @
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
case "
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
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 +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];
|