@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
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A box of fog, smoke, dust or cloud that an entity carries around.
|
|
3
|
+
*
|
|
4
|
+
* **What is in here is the medium; the {@link Transform} beside it is the box.** Shade's
|
|
5
|
+
* {@link ParticipatingMediaVolume} is a unit cube centred on the origin, posed by a transform — so
|
|
6
|
+
* position, size and orientation are already an ECS concept and there is nothing to restate. Which
|
|
7
|
+
* is also why this component does nothing on its own: {@link ParticipatingMediaSystem3} links it
|
|
8
|
+
* against a `Transform` and only that pair becomes a volume.
|
|
9
|
+
*
|
|
10
|
+
* **Three numbers, in two different currencies.** {@link particle_spec} is what a single particle
|
|
11
|
+
* does to light — a Mie solution, physical and reusable — and {@link density} is how many of them
|
|
12
|
+
* there are per cubic metre. The pair is what makes smoke and fog different things rather than the
|
|
13
|
+
* same fog at two strengths. Authoring in raw density means knowing the cross-sections, so
|
|
14
|
+
* {@link target_extinction} exists to author the other way round: say how much light the medium
|
|
15
|
+
* should swallow and let the particle decide the count.
|
|
16
|
+
*
|
|
17
|
+
* @see ParticipatingMediaSystem3 what turns this into something the renderer draws
|
|
18
|
+
* @see ParticipatingMediaVolume the renderer's own object
|
|
19
|
+
*/
|
|
20
|
+
export class ParticipatingMedia {
|
|
21
|
+
/**
|
|
22
|
+
* @param {*} json
|
|
23
|
+
* @returns {ParticipatingMedia}
|
|
24
|
+
*/
|
|
25
|
+
static fromJSON(json: any): ParticipatingMedia;
|
|
26
|
+
/**
|
|
27
|
+
* Particles per cubic metre.
|
|
28
|
+
*
|
|
29
|
+
* Physically a count, so the numbers are large — the default is dense fog — and the useful range
|
|
30
|
+
* depends entirely on {@link particle_spec}: a cloud droplet blocks far more light than a haze
|
|
31
|
+
* particle, so the same count of them is a very different medium.
|
|
32
|
+
*
|
|
33
|
+
* @type {number}
|
|
34
|
+
*/
|
|
35
|
+
density: number;
|
|
36
|
+
/**
|
|
37
|
+
* What one particle of this medium does to light.
|
|
38
|
+
*
|
|
39
|
+
* Defaults to fog. The generated `MIE_PARTICLES_STANDARD_PRECOMPUTED` library is where the
|
|
40
|
+
* physically meaningful values live — `VolumetricsParticleSpec.fromMeep` converts an entry of it
|
|
41
|
+
* into one of these.
|
|
42
|
+
*
|
|
43
|
+
* @type {VolumetricsParticleSpec}
|
|
44
|
+
*/
|
|
45
|
+
particle_spec: VolumetricsParticleSpec;
|
|
46
|
+
/**
|
|
47
|
+
* How far in from the box's faces the medium fades out, in metres.
|
|
48
|
+
*
|
|
49
|
+
* **World-space, and deliberately not scaled by the transform**, so a 0.5 here is half a metre
|
|
50
|
+
* of softness whether the volume is a metre across or a hundred. Zero gives the box hard edges,
|
|
51
|
+
* which is visible as a straight line across the screen wherever the box crosses the view.
|
|
52
|
+
*
|
|
53
|
+
* @type {number}
|
|
54
|
+
*/
|
|
55
|
+
fade_distance: number;
|
|
56
|
+
/**
|
|
57
|
+
* @param {number} value
|
|
58
|
+
*/
|
|
59
|
+
set target_extinction(arg: number);
|
|
60
|
+
/**
|
|
61
|
+
* The medium's extinction per metre, which is {@link density} expressed in what it does rather
|
|
62
|
+
* than in how many particles it took.
|
|
63
|
+
*
|
|
64
|
+
* The point of it is that it is comparable across particles: a smoke volume and a fog volume set
|
|
65
|
+
* to the same target extinction swallow the same amount of light, while the same *density* in
|
|
66
|
+
* both would differ by orders of magnitude.
|
|
67
|
+
*
|
|
68
|
+
* **Derived, not stored** — writing it sets {@link density}, and changing `particle_spec`
|
|
69
|
+
* afterwards therefore changes what reading it back gives. The density is what survives a save.
|
|
70
|
+
*
|
|
71
|
+
* @returns {number}
|
|
72
|
+
*/
|
|
73
|
+
get target_extinction(): number;
|
|
74
|
+
toJSON(): {
|
|
75
|
+
density: number;
|
|
76
|
+
fade_distance: number;
|
|
77
|
+
particle_spec: {
|
|
78
|
+
scattering: number[];
|
|
79
|
+
extinction: number[];
|
|
80
|
+
radius: number;
|
|
81
|
+
g: number;
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* @param {number} [density]
|
|
86
|
+
* @param {number} [fade_distance]
|
|
87
|
+
* @param {object} [particle_spec] omitted resets the medium to fog rather than leaving whatever
|
|
88
|
+
* the component already held — a load has to determine the whole component, or an instance being
|
|
89
|
+
* reused would carry the previous level's particle into the next one
|
|
90
|
+
*/
|
|
91
|
+
fromJSON({ density, fade_distance, particle_spec }?: number): void;
|
|
92
|
+
/**
|
|
93
|
+
* **The cross-sections and the radius are left out of this on purpose.** They run to 1e-16 and
|
|
94
|
+
* 1e-6, and {@link computeHashFloat} collapses anything that small to zero, so mixing them in
|
|
95
|
+
* would cost a multiply and buy no dispersion at all. A hash is allowed to collide;
|
|
96
|
+
* {@link equals} is the exact one.
|
|
97
|
+
*
|
|
98
|
+
* @returns {number}
|
|
99
|
+
*/
|
|
100
|
+
hash(): number;
|
|
101
|
+
/**
|
|
102
|
+
* @param {ParticipatingMedia} other
|
|
103
|
+
* @returns {boolean}
|
|
104
|
+
*/
|
|
105
|
+
equals(other: ParticipatingMedia): boolean;
|
|
106
|
+
}
|
|
107
|
+
export namespace ParticipatingMedia {
|
|
108
|
+
let typeName: string;
|
|
109
|
+
}
|
|
110
|
+
import { VolumetricsParticleSpec } from "../../shade/renderer/volumetrics/ParticipatingMediaVolume.js";
|
|
111
|
+
//# sourceMappingURL=ParticipatingMedia.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ParticipatingMedia.d.ts","sourceRoot":"","sources":["../../../../src/engine/graphics3/ParticipatingMedia.js"],"names":[],"mappings":"AAoBA;;;;;;;;;;;;;;;;;;GAkBG;AACH;IAyEI;;;OAGG;IACH,4BAFa,kBAAkB,CAQ9B;IAjFD;;;;;;;;OAQG;IACH,SAFU,MAAM,CAEU;IAE1B;;;;;;;;OAQG;IACH,eAFU,uBAAuB,CAE8C;IAE/E;;;;;;;;OAQG;IACH,eAFU,MAAM,CAEsB;IAmBtC;;OAEG;IACH,mCAgBC;IApCD;;;;;;;;;;;;OAYG;IACH,gCAEC;IAmCD;;;;;;;;;MAaC;IAED;;;;;;OAMG;IACH,qDANW,MAAM,QA2BhB;IAED;;;;;;;OAOG;IACH,QAFa,MAAM,CAUlB;IAED;;;OAGG;IACH,cAHW,kBAAkB,GAChB,OAAO,CAMnB;CACJ;;kBAIS,MAAM;;wCAjMT,8DAA8D"}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { assert } from "../../core/assert.js";
|
|
2
|
+
import { combine_hash } from "../../core/collection/array/combine_hash.js";
|
|
3
|
+
import { rgb_to_luminance } from "../../core/color/rgb_to_luminance.js";
|
|
4
|
+
import { computeHashFloat } from "../../core/primitives/numbers/computeHashFloat.js";
|
|
5
|
+
import {
|
|
6
|
+
VOLUMETRIC_PARTICLE_SPEC_FOG,
|
|
7
|
+
VolumetricsParticleSpec
|
|
8
|
+
} from "../../shade/renderer/volumetrics/ParticipatingMediaVolume.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Particles per cubic metre of dense fog, which is what a medium is until it is told otherwise.
|
|
12
|
+
* @type {number}
|
|
13
|
+
*/
|
|
14
|
+
const DEFAULT_DENSITY = 3e7;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @type {number}
|
|
18
|
+
*/
|
|
19
|
+
const DEFAULT_FADE_DISTANCE = 0.1;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* A box of fog, smoke, dust or cloud that an entity carries around.
|
|
23
|
+
*
|
|
24
|
+
* **What is in here is the medium; the {@link Transform} beside it is the box.** Shade's
|
|
25
|
+
* {@link ParticipatingMediaVolume} is a unit cube centred on the origin, posed by a transform — so
|
|
26
|
+
* position, size and orientation are already an ECS concept and there is nothing to restate. Which
|
|
27
|
+
* is also why this component does nothing on its own: {@link ParticipatingMediaSystem3} links it
|
|
28
|
+
* against a `Transform` and only that pair becomes a volume.
|
|
29
|
+
*
|
|
30
|
+
* **Three numbers, in two different currencies.** {@link particle_spec} is what a single particle
|
|
31
|
+
* does to light — a Mie solution, physical and reusable — and {@link density} is how many of them
|
|
32
|
+
* there are per cubic metre. The pair is what makes smoke and fog different things rather than the
|
|
33
|
+
* same fog at two strengths. Authoring in raw density means knowing the cross-sections, so
|
|
34
|
+
* {@link target_extinction} exists to author the other way round: say how much light the medium
|
|
35
|
+
* should swallow and let the particle decide the count.
|
|
36
|
+
*
|
|
37
|
+
* @see ParticipatingMediaSystem3 what turns this into something the renderer draws
|
|
38
|
+
* @see ParticipatingMediaVolume the renderer's own object
|
|
39
|
+
*/
|
|
40
|
+
export class ParticipatingMedia {
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Particles per cubic metre.
|
|
44
|
+
*
|
|
45
|
+
* Physically a count, so the numbers are large — the default is dense fog — and the useful range
|
|
46
|
+
* depends entirely on {@link particle_spec}: a cloud droplet blocks far more light than a haze
|
|
47
|
+
* particle, so the same count of them is a very different medium.
|
|
48
|
+
*
|
|
49
|
+
* @type {number}
|
|
50
|
+
*/
|
|
51
|
+
density = DEFAULT_DENSITY;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* What one particle of this medium does to light.
|
|
55
|
+
*
|
|
56
|
+
* Defaults to fog. The generated `MIE_PARTICLES_STANDARD_PRECOMPUTED` library is where the
|
|
57
|
+
* physically meaningful values live — `VolumetricsParticleSpec.fromMeep` converts an entry of it
|
|
58
|
+
* into one of these.
|
|
59
|
+
*
|
|
60
|
+
* @type {VolumetricsParticleSpec}
|
|
61
|
+
*/
|
|
62
|
+
particle_spec = VolumetricsParticleSpec.fromJSON(VOLUMETRIC_PARTICLE_SPEC_FOG);
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* How far in from the box's faces the medium fades out, in metres.
|
|
66
|
+
*
|
|
67
|
+
* **World-space, and deliberately not scaled by the transform**, so a 0.5 here is half a metre
|
|
68
|
+
* of softness whether the volume is a metre across or a hundred. Zero gives the box hard edges,
|
|
69
|
+
* which is visible as a straight line across the screen wherever the box crosses the view.
|
|
70
|
+
*
|
|
71
|
+
* @type {number}
|
|
72
|
+
*/
|
|
73
|
+
fade_distance = DEFAULT_FADE_DISTANCE;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* The medium's extinction per metre, which is {@link density} expressed in what it does rather
|
|
77
|
+
* than in how many particles it took.
|
|
78
|
+
*
|
|
79
|
+
* The point of it is that it is comparable across particles: a smoke volume and a fog volume set
|
|
80
|
+
* to the same target extinction swallow the same amount of light, while the same *density* in
|
|
81
|
+
* both would differ by orders of magnitude.
|
|
82
|
+
*
|
|
83
|
+
* **Derived, not stored** — writing it sets {@link density}, and changing `particle_spec`
|
|
84
|
+
* afterwards therefore changes what reading it back gives. The density is what survives a save.
|
|
85
|
+
*
|
|
86
|
+
* @returns {number}
|
|
87
|
+
*/
|
|
88
|
+
get target_extinction() {
|
|
89
|
+
return this.density * rgb_to_luminance(...this.particle_spec.extinction);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @param {number} value
|
|
94
|
+
*/
|
|
95
|
+
set target_extinction(value) {
|
|
96
|
+
assert.isNumber(value, 'target_extinction');
|
|
97
|
+
assert.isFinite(value, 'target_extinction');
|
|
98
|
+
|
|
99
|
+
const density = value / rgb_to_luminance(...this.particle_spec.extinction);
|
|
100
|
+
|
|
101
|
+
/*
|
|
102
|
+
Catches the one way this goes wrong: a particle spec that extinguishes nothing. A default-
|
|
103
|
+
constructed `VolumetricsParticleSpec` has zero cross-sections, and asking such a medium to
|
|
104
|
+
reach any extinction at all needs infinitely many of its particles. Rejecting it here names
|
|
105
|
+
the mistake; letting it through puts an `Infinity` in the GPU table, where it becomes a
|
|
106
|
+
screenful of NaN several passes later.
|
|
107
|
+
*/
|
|
108
|
+
assert.isFinite(density, 'the density this target_extinction implies (the particle spec extinguishes nothing)');
|
|
109
|
+
|
|
110
|
+
this.density = density;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* @param {*} json
|
|
115
|
+
* @returns {ParticipatingMedia}
|
|
116
|
+
*/
|
|
117
|
+
static fromJSON(json) {
|
|
118
|
+
const r = new ParticipatingMedia();
|
|
119
|
+
|
|
120
|
+
r.fromJSON(json);
|
|
121
|
+
|
|
122
|
+
return r;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
toJSON() {
|
|
126
|
+
const spec = this.particle_spec;
|
|
127
|
+
|
|
128
|
+
return {
|
|
129
|
+
density: this.density,
|
|
130
|
+
fade_distance: this.fade_distance,
|
|
131
|
+
particle_spec: {
|
|
132
|
+
scattering: spec.scattering.slice(),
|
|
133
|
+
extinction: spec.extinction.slice(),
|
|
134
|
+
radius: spec.radius,
|
|
135
|
+
g: spec.g
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* @param {number} [density]
|
|
142
|
+
* @param {number} [fade_distance]
|
|
143
|
+
* @param {object} [particle_spec] omitted resets the medium to fog rather than leaving whatever
|
|
144
|
+
* the component already held — a load has to determine the whole component, or an instance being
|
|
145
|
+
* reused would carry the previous level's particle into the next one
|
|
146
|
+
*/
|
|
147
|
+
fromJSON({
|
|
148
|
+
density = DEFAULT_DENSITY,
|
|
149
|
+
fade_distance = DEFAULT_FADE_DISTANCE,
|
|
150
|
+
particle_spec
|
|
151
|
+
}) {
|
|
152
|
+
assert.isNumber(density, 'density');
|
|
153
|
+
assert.isFinite(density, 'density');
|
|
154
|
+
assert.greaterThanOrEqual(density, 0, 'density must not be negative');
|
|
155
|
+
|
|
156
|
+
assert.isNumber(fade_distance, 'fade_distance');
|
|
157
|
+
assert.isFinite(fade_distance, 'fade_distance');
|
|
158
|
+
assert.greaterThanOrEqual(fade_distance, 0, 'fade_distance must not be negative');
|
|
159
|
+
|
|
160
|
+
this.density = density;
|
|
161
|
+
this.fade_distance = fade_distance;
|
|
162
|
+
|
|
163
|
+
if (particle_spec === undefined) {
|
|
164
|
+
this.particle_spec.copy(VOLUMETRIC_PARTICLE_SPEC_FOG);
|
|
165
|
+
} else {
|
|
166
|
+
this.particle_spec.fromJSON(particle_spec);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* **The cross-sections and the radius are left out of this on purpose.** They run to 1e-16 and
|
|
172
|
+
* 1e-6, and {@link computeHashFloat} collapses anything that small to zero, so mixing them in
|
|
173
|
+
* would cost a multiply and buy no dispersion at all. A hash is allowed to collide;
|
|
174
|
+
* {@link equals} is the exact one.
|
|
175
|
+
*
|
|
176
|
+
* @returns {number}
|
|
177
|
+
*/
|
|
178
|
+
hash() {
|
|
179
|
+
const spec = this.particle_spec;
|
|
180
|
+
|
|
181
|
+
return combine_hash(
|
|
182
|
+
computeHashFloat(this.density),
|
|
183
|
+
computeHashFloat(this.fade_distance),
|
|
184
|
+
computeHashFloat(spec.g)
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* @param {ParticipatingMedia} other
|
|
190
|
+
* @returns {boolean}
|
|
191
|
+
*/
|
|
192
|
+
equals(other) {
|
|
193
|
+
return this.density === other.density
|
|
194
|
+
&& this.fade_distance === other.fade_distance
|
|
195
|
+
&& this.particle_spec.equals(other.particle_spec);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* @readonly
|
|
201
|
+
* @type {string}
|
|
202
|
+
*/
|
|
203
|
+
ParticipatingMedia.typeName = "ParticipatingMedia";
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ten numbers, all of them `float64`.
|
|
3
|
+
*
|
|
4
|
+
* **The width is the whole design decision here, and it is not the usual one.** Component adapters
|
|
5
|
+
* around this one write `float32`, which is what the GPU reads anyway — but a participating medium
|
|
6
|
+
* is authored at the two far ends of the exponent range at once: cross-sections run to 1e-16 and the
|
|
7
|
+
* particle counts that pay for them run to 1e16. `float32` holds both magnitudes comfortably and
|
|
8
|
+
* keeps about seven digits of each, so a round trip through it moves every one of these values a
|
|
9
|
+
* little. Nothing about the rendered picture would change. What would change is that
|
|
10
|
+
* `ParticipatingMedia.equals` stops answering `true` across a save, and a level that reloads into
|
|
11
|
+
* components which merely *look* like the ones that were saved is a level whose blueprints stop
|
|
12
|
+
* matching. Ten doubles is eighty bytes; that is the price of the round trip being exact.
|
|
13
|
+
*
|
|
14
|
+
* **`target_extinction` is not in the format** because it is not in the component — it is
|
|
15
|
+
* {@link ParticipatingMedia.density} read through the particle spec, and both of its inputs are
|
|
16
|
+
* here.
|
|
17
|
+
*/
|
|
18
|
+
export class ParticipatingMediaSerializationAdapter extends BinaryClassSerializationAdapter<any> {
|
|
19
|
+
constructor();
|
|
20
|
+
klass: typeof ParticipatingMedia;
|
|
21
|
+
/**
|
|
22
|
+
* @param {BinaryBuffer} buffer
|
|
23
|
+
* @param {ParticipatingMedia} value
|
|
24
|
+
*/
|
|
25
|
+
serialize(buffer: BinaryBuffer, value: ParticipatingMedia): void;
|
|
26
|
+
/**
|
|
27
|
+
* @param {BinaryBuffer} buffer
|
|
28
|
+
* @param {ParticipatingMedia} value
|
|
29
|
+
*/
|
|
30
|
+
deserialize(buffer: BinaryBuffer, value: ParticipatingMedia): void;
|
|
31
|
+
}
|
|
32
|
+
import { BinaryClassSerializationAdapter } from "../ecs/storage/binary/BinaryClassSerializationAdapter.js";
|
|
33
|
+
import { ParticipatingMedia } from "./ParticipatingMedia.js";
|
|
34
|
+
//# sourceMappingURL=ParticipatingMediaSerializationAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ParticipatingMediaSerializationAdapter.d.ts","sourceRoot":"","sources":["../../../../src/engine/graphics3/ParticipatingMediaSerializationAdapter.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;GAgBG;AACH;;IAEI,iCAA2B;IAG3B;;;OAGG;IACH,uCAFW,kBAAkB,QAkB5B;IAED;;;OAGG;IACH,yCAFW,kBAAkB,QAsB5B;CACJ;gDAxE+C,0DAA0D;mCACvE,yBAAyB"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { BinaryClassSerializationAdapter } from "../ecs/storage/binary/BinaryClassSerializationAdapter.js";
|
|
2
|
+
import { ParticipatingMedia } from "./ParticipatingMedia.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Ten numbers, all of them `float64`.
|
|
6
|
+
*
|
|
7
|
+
* **The width is the whole design decision here, and it is not the usual one.** Component adapters
|
|
8
|
+
* around this one write `float32`, which is what the GPU reads anyway — but a participating medium
|
|
9
|
+
* is authored at the two far ends of the exponent range at once: cross-sections run to 1e-16 and the
|
|
10
|
+
* particle counts that pay for them run to 1e16. `float32` holds both magnitudes comfortably and
|
|
11
|
+
* keeps about seven digits of each, so a round trip through it moves every one of these values a
|
|
12
|
+
* little. Nothing about the rendered picture would change. What would change is that
|
|
13
|
+
* `ParticipatingMedia.equals` stops answering `true` across a save, and a level that reloads into
|
|
14
|
+
* components which merely *look* like the ones that were saved is a level whose blueprints stop
|
|
15
|
+
* matching. Ten doubles is eighty bytes; that is the price of the round trip being exact.
|
|
16
|
+
*
|
|
17
|
+
* **`target_extinction` is not in the format** because it is not in the component — it is
|
|
18
|
+
* {@link ParticipatingMedia.density} read through the particle spec, and both of its inputs are
|
|
19
|
+
* here.
|
|
20
|
+
*/
|
|
21
|
+
export class ParticipatingMediaSerializationAdapter extends BinaryClassSerializationAdapter {
|
|
22
|
+
|
|
23
|
+
klass = ParticipatingMedia;
|
|
24
|
+
version = 0;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param {BinaryBuffer} buffer
|
|
28
|
+
* @param {ParticipatingMedia} value
|
|
29
|
+
*/
|
|
30
|
+
serialize(buffer, value) {
|
|
31
|
+
buffer.writeFloat64(value.density);
|
|
32
|
+
buffer.writeFloat64(value.fade_distance);
|
|
33
|
+
|
|
34
|
+
const spec = value.particle_spec;
|
|
35
|
+
|
|
36
|
+
for (let i = 0; i < 3; i++) {
|
|
37
|
+
buffer.writeFloat64(spec.scattering[i]);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
for (let i = 0; i < 3; i++) {
|
|
41
|
+
buffer.writeFloat64(spec.extinction[i]);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
buffer.writeFloat64(spec.radius);
|
|
45
|
+
buffer.writeFloat64(spec.g);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @param {BinaryBuffer} buffer
|
|
50
|
+
* @param {ParticipatingMedia} value
|
|
51
|
+
*/
|
|
52
|
+
deserialize(buffer, value) {
|
|
53
|
+
value.density = buffer.readFloat64();
|
|
54
|
+
value.fade_distance = buffer.readFloat64();
|
|
55
|
+
|
|
56
|
+
const spec = value.particle_spec;
|
|
57
|
+
|
|
58
|
+
/*
|
|
59
|
+
In place, which is safe because a spec owns its arrays: every route into one —
|
|
60
|
+
`fromJSON`, `copy`, `clone` — slices what it was given rather than keeping the reference.
|
|
61
|
+
*/
|
|
62
|
+
for (let i = 0; i < 3; i++) {
|
|
63
|
+
spec.scattering[i] = buffer.readFloat64();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
for (let i = 0; i < 3; i++) {
|
|
67
|
+
spec.extinction[i] = buffer.readFloat64();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
spec.radius = buffer.readFloat64();
|
|
71
|
+
spec.g = buffer.readFloat64();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copy what the component and its transform say onto the volume Shade will render.
|
|
3
|
+
*
|
|
4
|
+
* The particle spec is **copied, not referenced**: two entities are routinely built from the same
|
|
5
|
+
* blueprint and would otherwise share one spec, so tuning one volume's particle would silently
|
|
6
|
+
* retune the other's.
|
|
7
|
+
*
|
|
8
|
+
* @param {ParticipatingMediaVolume} volume Shade's
|
|
9
|
+
* @param {ParticipatingMedia} component meep's
|
|
10
|
+
* @param {Transform} transform where the box is
|
|
11
|
+
*/
|
|
12
|
+
export function participating_media_volume_write(volume: ParticipatingMediaVolume, component: ParticipatingMedia, transform: Transform): void;
|
|
13
|
+
/**
|
|
14
|
+
* Whether the volume already says what the component and transform say.
|
|
15
|
+
*
|
|
16
|
+
* True on all but a handful of frames, which is the point of asking: a `false` here costs the whole
|
|
17
|
+
* scene's volumetrics table a trip to the GPU.
|
|
18
|
+
*
|
|
19
|
+
* **The transform is compared by its matrix rather than by `Transform.equals`**, because the matrix
|
|
20
|
+
* is the entire transform the GPU is given — the volume's position, rotation and scale are never
|
|
21
|
+
* read on their own. That makes this exactly the question worth asking, "would the upload differ",
|
|
22
|
+
* and it catches a transform posed by writing its matrix, which comparing position, rotation and
|
|
23
|
+
* scale would not.
|
|
24
|
+
*
|
|
25
|
+
* @param {ParticipatingMediaVolume} volume
|
|
26
|
+
* @param {ParticipatingMedia} component
|
|
27
|
+
* @param {Transform} transform
|
|
28
|
+
* @returns {boolean}
|
|
29
|
+
*/
|
|
30
|
+
export function participating_media_volume_is_current(volume: ParticipatingMediaVolume, component: ParticipatingMedia, transform: Transform): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Mirrors fog, smoke and cloud entities into Shade's volumetrics.
|
|
33
|
+
*
|
|
34
|
+
* The same shape as {@link LightSystem3}: the ECS says what exists and where, and this keeps the
|
|
35
|
+
* renderer's own objects in step. A {@link ParticipatingMediaVolume} is a unit cube posed by a
|
|
36
|
+
* transform, so an entity's `Transform` is the volume — position, size and orientation with no
|
|
37
|
+
* translation step in between.
|
|
38
|
+
*
|
|
39
|
+
* **The transform is taken as world-space, with no hierarchy applied**, which is what the volume
|
|
40
|
+
* model can express: a volume is an oriented box in the scene and Shade has no parent chain to walk
|
|
41
|
+
* for it. Parenting a fog volume to a moving entity therefore leaves the fog where the child's own
|
|
42
|
+
* transform puts it. The lights are placed the same way, for the same reason.
|
|
43
|
+
*
|
|
44
|
+
* **Changes are polled once a frame rather than subscribed to.** A `Transform` announces itself and
|
|
45
|
+
* nothing else here does — a density tuned by an editor slider, a particle spec swapped wholesale
|
|
46
|
+
* for a different Mie solution — so subscribing would cover one field in three and the other two
|
|
47
|
+
* would still have to be polled. Two paths that have to agree, where one does the whole job. It
|
|
48
|
+
* costs about two dozen float comparisons per volume per frame and a scene holds volumes in the
|
|
49
|
+
* tens, so the comparison is cheaper than the signal plumbing it replaces. The price is latency: a
|
|
50
|
+
* change is visible within a frame rather than instantly.
|
|
51
|
+
*
|
|
52
|
+
* **Nothing is uploaded unless something actually changed.** The GPU table is repacked whole
|
|
53
|
+
* whenever {@link SceneVolumetrics.version} moves, so an unconditional copy every frame would
|
|
54
|
+
* re-upload every volume in the scene forever. The comparison is what decides, and on almost every
|
|
55
|
+
* frame it decides nothing has to happen.
|
|
56
|
+
*
|
|
57
|
+
* @see ParticipatingMedia the component
|
|
58
|
+
* @see SceneVolumetrics what the volumes are handed to
|
|
59
|
+
*/
|
|
60
|
+
export class ParticipatingMediaSystem3 extends System<any> {
|
|
61
|
+
/**
|
|
62
|
+
* @param {GraphicsEngine3} graphics
|
|
63
|
+
* @param {Scene} scene
|
|
64
|
+
*/
|
|
65
|
+
constructor(graphics: GraphicsEngine3, scene: Scene);
|
|
66
|
+
dependencies: (typeof Transform | typeof ParticipatingMedia)[];
|
|
67
|
+
startup(entityManager: any): Promise<void>;
|
|
68
|
+
shutdown(entityManager: any): Promise<void>;
|
|
69
|
+
/**
|
|
70
|
+
* @param {ParticipatingMedia} component
|
|
71
|
+
* @param {Transform} transform
|
|
72
|
+
* @param {number} entity
|
|
73
|
+
*/
|
|
74
|
+
link(component: ParticipatingMedia, transform: Transform, entity: number): void;
|
|
75
|
+
/**
|
|
76
|
+
* @param {ParticipatingMedia} component
|
|
77
|
+
* @param {Transform} transform
|
|
78
|
+
* @param {number} entity
|
|
79
|
+
*/
|
|
80
|
+
unlink(component: ParticipatingMedia, transform: Transform, entity: number): void;
|
|
81
|
+
#private;
|
|
82
|
+
}
|
|
83
|
+
import { ParticipatingMediaVolume } from "../../shade/renderer/volumetrics/ParticipatingMediaVolume.js";
|
|
84
|
+
import { ParticipatingMedia } from "./ParticipatingMedia.js";
|
|
85
|
+
import { Transform } from "../ecs/transform/Transform.js";
|
|
86
|
+
import { System } from "../ecs/System.js";
|
|
87
|
+
//# sourceMappingURL=ParticipatingMediaSystem3.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ParticipatingMediaSystem3.d.ts","sourceRoot":"","sources":["../../../../src/engine/graphics3/ParticipatingMediaSystem3.js"],"names":[],"mappings":"AA6IA;;;;;;;;;;GAUG;AACH,yDAJW,wBAAwB,aACxB,kBAAkB,aAClB,SAAS,QASnB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,8DALW,wBAAwB,aACxB,kBAAkB,aAClB,SAAS,GACP,OAAO,CAOnB;AAhLD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH;IAmBI;;;OAGG;IACH,qDASC;IA9BD,+DAA+C;IAgC/C,2CAIC;IAED,4CAIC;IAED;;;;OAIG;IACH,gBAJW,kBAAkB,aAClB,SAAS,UACT,MAAM,QAUhB;IAED;;;;OAIG;IACH,kBAJW,kBAAkB,aAClB,SAAS,UACT,MAAM,QAIhB;;CAmCJ;yCAzIwC,8DAA8D;mCAGpE,yBAAyB;0BADlC,+BAA+B;uBADlC,kBAAkB"}
|