@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,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Name of the texture holding cascade `index` of the sun's optical-depth volume.
|
|
3
|
+
*
|
|
4
|
+
* Generated rather than written out because the cascade count is a constant and everything that
|
|
5
|
+
* touches the structure — this chunk, the lighting pass's resource set, the frame graph — has to
|
|
6
|
+
* agree with it. A name spelled by hand in one of those places is the way a fourth cascade turns
|
|
7
|
+
* into a silent black frame.
|
|
8
|
+
*
|
|
9
|
+
* @param {number} index
|
|
10
|
+
* @returns {string}
|
|
11
|
+
*/
|
|
12
|
+
export function volumetrics_sun_shadow_texture_name(index: number): string;
|
|
13
|
+
/**
|
|
14
|
+
* Optical depth of the participating medium between a world position and the sun, in one fetch.
|
|
15
|
+
*
|
|
16
|
+
* Same quantity `integrate_optical_depth` returns for a directional light, and deliberately the
|
|
17
|
+
* same signature shape, so the two are interchangeable at the call site. What it does not expose is
|
|
18
|
+
* how the answer was produced: the caller passes a world position and gets an integral back, and
|
|
19
|
+
* whether that came from a light-aligned prefix scan, a Fourier basis or a march is not its
|
|
20
|
+
* business. Swapping the representation should not touch `shader_volumetrics_build_lighting`.
|
|
21
|
+
*
|
|
22
|
+
* Cascades are selected on **view depth**, not on containment in each box. The two agree — every
|
|
23
|
+
* box is sized from the bounding sphere of the sub-frustum out to that depth, so a froxel at or
|
|
24
|
+
* inside it is inside the box — and only the first gives a scalar to blend along. It also makes the
|
|
25
|
+
* branch uniform across a workgroup: the lighting pass dispatches one froxel slice per workgroup in
|
|
26
|
+
* z, and a slice is a surface of constant depth.
|
|
27
|
+
*
|
|
28
|
+
* The `saturate` in each lookup is a statement about the domain rather than a clamp that fires.
|
|
29
|
+
* Selection has already established the position is inside the cascade it reads; outside, the
|
|
30
|
+
* sensible reading of a clamped fetch is still the right one, since the outermost box's faces sit
|
|
31
|
+
* in empty space and the value there is the column's total.
|
|
32
|
+
*
|
|
33
|
+
* @see shader_volumetrics_build_sun_shadow_volume, build_volumetrics_sun_shadow_transform
|
|
34
|
+
* @type {CodeChunk}
|
|
35
|
+
*/
|
|
36
|
+
export const chunk_volumetrics_sun_optical_depth: CodeChunk;
|
|
37
|
+
import { CodeChunk } from "../shader/compiler/CodeChunk.js";
|
|
38
|
+
//# sourceMappingURL=chunk_volumetrics_sun_optical_depth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk_volumetrics_sun_optical_depth.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/volumetrics/chunk_volumetrics_sun_optical_depth.js"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AACH,2DAHW,MAAM,GACJ,MAAM,CAIlB;AA2ED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,kDAFU,SAAS,CAgBjB;0BAhIwB,iCAAiC"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { CAMERA_UNIFORM_STRUCT } from "../camera/CAMERA_UNIFORM_STRUCT.js";
|
|
2
|
+
import { CodeChunk } from "../shader/compiler/CodeChunk.js";
|
|
3
|
+
import { VOLUMETRICS_SUN_SHADOW_CASCADE_COUNT } from "./VOLUMETRICS_SUN_SHADOW_RESOLUTION.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Name of the texture holding cascade `index` of the sun's optical-depth volume.
|
|
7
|
+
*
|
|
8
|
+
* Generated rather than written out because the cascade count is a constant and everything that
|
|
9
|
+
* touches the structure — this chunk, the lighting pass's resource set, the frame graph — has to
|
|
10
|
+
* agree with it. A name spelled by hand in one of those places is the way a fourth cascade turns
|
|
11
|
+
* into a silent black frame.
|
|
12
|
+
*
|
|
13
|
+
* @param {number} index
|
|
14
|
+
* @returns {string}
|
|
15
|
+
*/
|
|
16
|
+
export function volumetrics_sun_shadow_texture_name(index) {
|
|
17
|
+
return `tSunShadowCascade${index}`;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Fraction of a cascade's range at which it starts handing over to the next one out.
|
|
22
|
+
*
|
|
23
|
+
* The two cascades do not agree where they meet — that is the entire point of having two, one is
|
|
24
|
+
* more accurate than the other — so a hard switch is a visible edge at a fixed view depth, which is
|
|
25
|
+
* to say a ring around the screen that the 0.95-blend froxel TAA would smear rather than remove.
|
|
26
|
+
* Cascaded shadow maps blend across a band for the same reason.
|
|
27
|
+
*
|
|
28
|
+
* @type {number}
|
|
29
|
+
*/
|
|
30
|
+
const CASCADE_BLEND_START = 0.9;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Outermost cascade. It is where the selection ladder falls out to, so it is the one cascade with
|
|
34
|
+
* no successor to hand over to, and therefore the bound on the ladder rather than a step in it.
|
|
35
|
+
*
|
|
36
|
+
* @type {number}
|
|
37
|
+
*/
|
|
38
|
+
const LAST_CASCADE = VOLUMETRICS_SUN_SHADOW_CASCADE_COUNT - 1;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* One `volumetrics_sun_optical_depth_cascade_<index>` per cascade.
|
|
42
|
+
*
|
|
43
|
+
* @type {string}
|
|
44
|
+
*/
|
|
45
|
+
let cascade_lookups = "";
|
|
46
|
+
|
|
47
|
+
for (let index = 0; index < VOLUMETRICS_SUN_SHADOW_CASCADE_COUNT; index++) {
|
|
48
|
+
|
|
49
|
+
//language=WGSL
|
|
50
|
+
cascade_lookups += `
|
|
51
|
+
fn volumetrics_sun_optical_depth_cascade_${index}(position_ws: vec3<f32>) -> vec3<f32> {
|
|
52
|
+
|
|
53
|
+
let uvw = (volumetrics_metadata.sun_shadow_ws_to_uvw[${index}] * vec4<f32>(position_ws, 1.0)).xyz;
|
|
54
|
+
|
|
55
|
+
return textureSampleLevel(${volumetrics_sun_shadow_texture_name(index)}, sLinear, saturate(uvw), 0.0).rgb;
|
|
56
|
+
}
|
|
57
|
+
`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The ladder that picks between those lookups, one block per hand-over, spliced into the body of
|
|
62
|
+
* `volumetrics_sun_optical_depth`. Indexed over the same cascades and one short, so a cascade
|
|
63
|
+
* declared above and never reached here is a function nothing samples, and a block here naming a
|
|
64
|
+
* cascade not declared above is a call to a function that does not exist.
|
|
65
|
+
*
|
|
66
|
+
* @type {string}
|
|
67
|
+
*/
|
|
68
|
+
let cascade_selection = "";
|
|
69
|
+
|
|
70
|
+
for (let index = 0; index < LAST_CASCADE; index++) {
|
|
71
|
+
|
|
72
|
+
//language=WGSL
|
|
73
|
+
cascade_selection += `
|
|
74
|
+
{
|
|
75
|
+
let far = volumetrics_metadata.sun_shadow_cascade_far[${index}];
|
|
76
|
+
let blend_start = far * ${CASCADE_BLEND_START};
|
|
77
|
+
|
|
78
|
+
if (view_depth < blend_start) {
|
|
79
|
+
return volumetrics_sun_optical_depth_cascade_${index}(position_ws);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (view_depth < far) {
|
|
83
|
+
return mix(
|
|
84
|
+
volumetrics_sun_optical_depth_cascade_${index}(position_ws),
|
|
85
|
+
volumetrics_sun_optical_depth_cascade_${index + 1}(position_ws),
|
|
86
|
+
(view_depth - blend_start) / (far - blend_start)
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
`;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Optical depth of the participating medium between a world position and the sun, in one fetch.
|
|
95
|
+
*
|
|
96
|
+
* Same quantity `integrate_optical_depth` returns for a directional light, and deliberately the
|
|
97
|
+
* same signature shape, so the two are interchangeable at the call site. What it does not expose is
|
|
98
|
+
* how the answer was produced: the caller passes a world position and gets an integral back, and
|
|
99
|
+
* whether that came from a light-aligned prefix scan, a Fourier basis or a march is not its
|
|
100
|
+
* business. Swapping the representation should not touch `shader_volumetrics_build_lighting`.
|
|
101
|
+
*
|
|
102
|
+
* Cascades are selected on **view depth**, not on containment in each box. The two agree — every
|
|
103
|
+
* box is sized from the bounding sphere of the sub-frustum out to that depth, so a froxel at or
|
|
104
|
+
* inside it is inside the box — and only the first gives a scalar to blend along. It also makes the
|
|
105
|
+
* branch uniform across a workgroup: the lighting pass dispatches one froxel slice per workgroup in
|
|
106
|
+
* z, and a slice is a surface of constant depth.
|
|
107
|
+
*
|
|
108
|
+
* The `saturate` in each lookup is a statement about the domain rather than a clamp that fires.
|
|
109
|
+
* Selection has already established the position is inside the cascade it reads; outside, the
|
|
110
|
+
* sensible reading of a clamped fetch is still the right one, since the outermost box's faces sit
|
|
111
|
+
* in empty space and the value there is the column's total.
|
|
112
|
+
*
|
|
113
|
+
* @see shader_volumetrics_build_sun_shadow_volume, build_volumetrics_sun_shadow_transform
|
|
114
|
+
* @type {CodeChunk}
|
|
115
|
+
*/
|
|
116
|
+
export const chunk_volumetrics_sun_optical_depth = CodeChunk.from(
|
|
117
|
+
//language=WGSL
|
|
118
|
+
`
|
|
119
|
+
${cascade_lookups}
|
|
120
|
+
fn volumetrics_sun_optical_depth(position_ws: vec3<f32>) -> vec3<f32> {
|
|
121
|
+
|
|
122
|
+
// view space looks down -Z
|
|
123
|
+
let view_depth = -(camera.view_matrix * vec4<f32>(position_ws, 1.0)).z;
|
|
124
|
+
${cascade_selection}
|
|
125
|
+
return volumetrics_sun_optical_depth_cascade_${LAST_CASCADE}(position_ws);
|
|
126
|
+
}
|
|
127
|
+
`, [
|
|
128
|
+
CAMERA_UNIFORM_STRUCT.declaration_chunk,
|
|
129
|
+
]
|
|
130
|
+
);
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transmittance LUT, then the multiple-scattering LUT that reads it. Exported for
|
|
3
|
+
* `graph_integrate_sky.spec.js`, which pins the dispatch shape and the transient's usage
|
|
4
|
+
* flags -- neither of which the WGSL validity gate can see.
|
|
5
|
+
*
|
|
6
|
+
* @param {FrameGraph} graph
|
|
7
|
+
* @returns {{transmittance_lut: number, multiscatted_lut: number}} resource handles
|
|
8
|
+
*/
|
|
9
|
+
export function graph_integrate_sky({ graph }: FrameGraph): {
|
|
10
|
+
transmittance_lut: number;
|
|
11
|
+
multiscatted_lut: number;
|
|
12
|
+
};
|
|
1
13
|
/**
|
|
2
14
|
*
|
|
3
15
|
* @param {FrameGraph} graph
|
|
@@ -9,14 +21,17 @@
|
|
|
9
21
|
* @param {number} light_cluster_parameters
|
|
10
22
|
* @param {number} shadowmap_atlas
|
|
11
23
|
* @param {number[]} volumetric_resolution
|
|
24
|
+
* @param {number[]} sun_shadow_resolution voxel counts of one Q-04 sun optical-depth cascade;
|
|
25
|
+
* `[1, 1, 1]` when the froxels are marching instead, which keeps the passes in the graph without
|
|
26
|
+
* doing any work
|
|
12
27
|
* @param {number} volumetrics_metadata
|
|
13
28
|
* @param {number} [taa_history] imported previous-frame accumulated scattering volume
|
|
14
29
|
* @param {number} [taa_output] imported destination for this frame's accumulated scattering volume
|
|
15
30
|
* @param {GPUCameraContext} [camera_previous] previous-frame camera, for temporal reprojection
|
|
16
31
|
*/
|
|
17
|
-
export function graph_build_volumetrics({ graph, camera, lights, view, light_cluster_data, light_cluster_lookup, light_cluster_parameters, shadowmap_atlas, volumetric_resolution, volumetrics_metadata, taa_history, taa_output, camera_previous, }: FrameGraph): {
|
|
18
|
-
lut_transmittance:
|
|
19
|
-
lut_multiple_scattering:
|
|
32
|
+
export function graph_build_volumetrics({ graph, camera, lights, view, light_cluster_data, light_cluster_lookup, light_cluster_parameters, shadowmap_atlas, volumetric_resolution, sun_shadow_resolution, volumetrics_metadata, taa_history, taa_output, camera_previous, }: FrameGraph): {
|
|
33
|
+
lut_transmittance: number;
|
|
34
|
+
lut_multiple_scattering: number;
|
|
20
35
|
lut_aerial: any;
|
|
21
36
|
volumetrics_metadata: FrameGraph;
|
|
22
37
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph_build_volumetrics.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/volumetrics/graph_build_volumetrics.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"graph_build_volumetrics.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/volumetrics/graph_build_volumetrics.js"],"names":[],"mappings":"AA4BA;;;;;;;GAOG;AACH,4DAFa;IAAC,iBAAiB,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAC,CAgEjE;AAqTD;;;;;;;;;;;;;;;;;;GAkBG;AACH;;;;;EAwKC"}
|
|
@@ -1,25 +1,43 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
1
|
import { assert } from "../../../core/assert.js";
|
|
4
2
|
import { SamplerDescriptor } from "../../descriptor/texture/SamplerDescriptor.js";
|
|
5
3
|
import { TextureResourceDescriptor } from "../../device/graph/TextureResourceDescriptor.js";
|
|
4
|
+
import { shader_multiscatter_lut } from "../atmosphere/shader_multiscatter_lut.js";
|
|
5
|
+
import { shader_transmittance_lut } from "../atmosphere/shader_transmittance_lut.js";
|
|
6
|
+
import { graph_compute_pass } from "../shader/graph/compute/graph_compute_pass.js";
|
|
7
|
+
import { graph_import_buffer } from "../shader/graph/graph_import_buffer.js";
|
|
6
8
|
import { SHADOWMAP_COMPARE_SAMPLER_DESCRIPTOR } from "../shadow/map/SHADOWMAP_COMPARE_SAMPLER_DESCRIPTOR.js";
|
|
7
9
|
import { STATIC_GRAPHICS_ENGINE_ASSETS } from "../STATIC_GRAPHICS_ENGINE_ASSETS.js";
|
|
8
10
|
import { DEFAULT_RENDER_TARGET_VIEW_DESCRIPTOR } from "../texture/DEFAULT_RENDER_TARGET_VIEW_DESCRIPTOR.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
import { volumetrics_sun_shadow_texture_name } from "./chunk_volumetrics_sun_optical_depth.js";
|
|
12
|
+
import {
|
|
13
|
+
shader_volumetrics_build_lighting,
|
|
14
|
+
VOLUMETRICS_LIGHTING_WORKGROUP_RESOLUTION
|
|
15
|
+
} from "./shader_volumetrics_build_lighting.js";
|
|
14
16
|
import { shader_volumetrics_build_participating_media } from "./shader_volumetrics_build_participating_media.js";
|
|
15
17
|
import { shader_volumetrics_build_scattering_lut } from "./shader_volumetrics_build_scattering_lut.js";
|
|
18
|
+
import {
|
|
19
|
+
shader_volumetrics_build_sun_shadow_volume_outermost,
|
|
20
|
+
shader_volumetrics_build_sun_shadow_volume_seeded
|
|
21
|
+
} from "./shader_volumetrics_build_sun_shadow_volume.js";
|
|
16
22
|
import { shader_volumetrics_taa } from "./taa/shader_volumetrics_taa.js";
|
|
23
|
+
import {
|
|
24
|
+
VOLUMETRICS_SUN_SHADOW_CASCADE_COUNT,
|
|
25
|
+
VOLUMETRICS_SUN_SHADOW_WORKGROUP_RESOLUTION,
|
|
26
|
+
volumetrics_sun_shadow_sub_steps
|
|
27
|
+
} from "./VOLUMETRICS_SUN_SHADOW_RESOLUTION.js";
|
|
17
28
|
|
|
18
29
|
/**
|
|
30
|
+
* Transmittance LUT, then the multiple-scattering LUT that reads it. Exported for
|
|
31
|
+
* `graph_integrate_sky.spec.js`, which pins the dispatch shape and the transient's usage
|
|
32
|
+
* flags -- neither of which the WGSL validity gate can see.
|
|
19
33
|
*
|
|
20
34
|
* @param {FrameGraph} graph
|
|
35
|
+
* @returns {{transmittance_lut: number, multiscatted_lut: number}} resource handles
|
|
21
36
|
*/
|
|
22
|
-
function graph_integrate_sky({ graph }) {
|
|
37
|
+
export function graph_integrate_sky({ graph }) {
|
|
38
|
+
|
|
39
|
+
graph.push_scope("integrate sky");
|
|
40
|
+
|
|
23
41
|
const t_data = {};
|
|
24
42
|
|
|
25
43
|
const t_pass = graph.add("transmittance", t_data, (data, resources, context) => {
|
|
@@ -31,7 +49,10 @@ function graph_integrate_sky({ graph }) {
|
|
|
31
49
|
const settings_type = shader_transmittance_lut.descriptor.resources.getResourceByName("settings").buffer_type;
|
|
32
50
|
|
|
33
51
|
const settings = encoder.allocateTransientValueBuffer(settings_type, {
|
|
34
|
-
steps: 40
|
|
52
|
+
steps: 40,
|
|
53
|
+
// taken off the target being drawn into, so the generator cannot be told a size
|
|
54
|
+
// the texture does not have
|
|
55
|
+
resolution: [output.width, output.height],
|
|
35
56
|
});
|
|
36
57
|
|
|
37
58
|
shader_transmittance_lut.draw({
|
|
@@ -53,46 +74,28 @@ function graph_integrate_sky({ graph }) {
|
|
|
53
74
|
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.RENDER_ATTACHMENT
|
|
54
75
|
}));
|
|
55
76
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const
|
|
59
|
-
const output = resources.get(data.output);
|
|
60
|
-
|
|
61
|
-
const settings_type = shader_multiscatter_lut.descriptor.resources.getResourceByName("settings").buffer_type;
|
|
62
|
-
|
|
63
|
-
const encoder = context.encoder;
|
|
64
|
-
|
|
65
|
-
const settings = encoder.allocateTransientValueBuffer(settings_type, {
|
|
66
|
-
steps: 20,
|
|
67
|
-
sqrt_samples: 8,
|
|
68
|
-
});
|
|
77
|
+
// The transient does not exist yet at graph-build time, so the dispatch cannot be
|
|
78
|
+
// counted off it the way GPUSky does; one local value feeds both instead.
|
|
79
|
+
const multiscatter_resolution = [32, 32];
|
|
69
80
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
shader_multiscatter_lut
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
})
|
|
81
|
+
const multiscatter_outputs = graph_compute_pass({
|
|
82
|
+
graph,
|
|
83
|
+
shader: shader_multiscatter_lut,
|
|
84
|
+
// one workgroup per LUT texel, each thread integrating one direction
|
|
85
|
+
group_count: [multiscatter_resolution[0], multiscatter_resolution[1], 1],
|
|
86
|
+
bindings: {
|
|
87
|
+
tSkyLutTransmittance: t_data.output,
|
|
88
|
+
tSkyLutMultiscatterOut: TextureResourceDescriptor.from({
|
|
89
|
+
resolution: multiscatter_resolution,
|
|
90
|
+
format: "rgba16float",
|
|
91
|
+
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.STORAGE_BINDING
|
|
92
|
+
})
|
|
93
|
+
}
|
|
84
94
|
});
|
|
85
95
|
|
|
86
|
-
|
|
87
|
-
resolution: [32, 32],
|
|
88
|
-
format: "rgba16float",
|
|
89
|
-
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.RENDER_ATTACHMENT
|
|
90
|
-
}))
|
|
91
|
-
|
|
92
|
-
m_data.tSkyLutTransmittance = m_pass.read(t_data.output);
|
|
96
|
+
graph.pop_scope();
|
|
93
97
|
|
|
94
|
-
|
|
95
|
-
return { transmittance_lut: t_data.output, multiscatted_lut: m_data.output };
|
|
98
|
+
return { transmittance_lut: t_data.output, multiscatted_lut: multiscatter_outputs.tSkyLutMultiscatterOut };
|
|
96
99
|
}
|
|
97
100
|
|
|
98
101
|
|
|
@@ -182,6 +185,97 @@ function graph_integrate_participating_media({
|
|
|
182
185
|
};
|
|
183
186
|
}
|
|
184
187
|
|
|
188
|
+
/**
|
|
189
|
+
* Q-04. The sun's optical depth, integrated once per frame into cascaded light-aligned volumes so
|
|
190
|
+
* the lighting pass can read it in a single fetch instead of marching toward the sun from every
|
|
191
|
+
* froxel.
|
|
192
|
+
*
|
|
193
|
+
* Sits between the participating-media build and the lighting pass because it reads the former and
|
|
194
|
+
* is read by the latter; the frame graph derives that ordering from the handles alone. The cascades
|
|
195
|
+
* are ordered among themselves for the same reason: each one is seeded from the value the cascade
|
|
196
|
+
* outside it already computed at its entry face, so the outermost is built first and the handle it
|
|
197
|
+
* returns is what makes the next pass wait for it.
|
|
198
|
+
*
|
|
199
|
+
* A texture per cascade rather than one texture with the cascades stacked along w. Stacking would
|
|
200
|
+
* put a pass's own output and its input in the same texture, which WebGPU rejects — a subresource
|
|
201
|
+
* cannot be bound as writable storage and as a sampled texture at once — and there is no
|
|
202
|
+
* subresource finer than the whole 3D texture to split it on.
|
|
203
|
+
*
|
|
204
|
+
* Always present, even with the mode off — the volumes are then dispatched at 1x1x1 (see
|
|
205
|
+
* `GPUViewVolumetrics`), which keeps the graph's topology identical on both sides of the A/B. A
|
|
206
|
+
* pass appearing and disappearing would change resource aliasing and pass scheduling along with the
|
|
207
|
+
* thing being measured, and this subsystem has already produced one confident wrong answer from a
|
|
208
|
+
* measurement where the two sides did not pay the same fixed costs.
|
|
209
|
+
*
|
|
210
|
+
* @param {FrameGraph} graph
|
|
211
|
+
* @param {GPUCameraContext} camera
|
|
212
|
+
* @param {number} participating_media1
|
|
213
|
+
* @param {number} volumetrics_metadata
|
|
214
|
+
* @param {number[]} resolution voxel counts of one cascade
|
|
215
|
+
* @returns {number[]} handles of the cascades, innermost first
|
|
216
|
+
*/
|
|
217
|
+
function graph_build_sun_shadow_volume({
|
|
218
|
+
graph,
|
|
219
|
+
camera,
|
|
220
|
+
participating_media1,
|
|
221
|
+
volumetrics_metadata,
|
|
222
|
+
resolution,
|
|
223
|
+
}) {
|
|
224
|
+
|
|
225
|
+
const camera_buffer = graph_import_buffer(graph, camera.buffer.buffer, "volumetrics sun shadow camera");
|
|
226
|
+
|
|
227
|
+
const group_count = [
|
|
228
|
+
// one invocation per COLUMN along the sun axis, so only x and y are dispatched
|
|
229
|
+
Math.ceil(resolution[0] / VOLUMETRICS_SUN_SHADOW_WORKGROUP_RESOLUTION[0]),
|
|
230
|
+
Math.ceil(resolution[1] / VOLUMETRICS_SUN_SHADOW_WORKGROUP_RESOLUTION[1]),
|
|
231
|
+
1,
|
|
232
|
+
];
|
|
233
|
+
|
|
234
|
+
const cascades = [];
|
|
235
|
+
|
|
236
|
+
for (let cascade = VOLUMETRICS_SUN_SHADOW_CASCADE_COUNT - 1; cascade >= 0; cascade--) {
|
|
237
|
+
|
|
238
|
+
// Every cascade but the outermost starts its scan from the one outside it — which the
|
|
239
|
+
// descending loop has already added, and which is the one difference the two build shaders
|
|
240
|
+
// exist for.
|
|
241
|
+
const seeded = cascade < VOLUMETRICS_SUN_SHADOW_CASCADE_COUNT - 1;
|
|
242
|
+
|
|
243
|
+
const bindings = {
|
|
244
|
+
// which cascade this dispatch is building; the shader is shared across all of them
|
|
245
|
+
settings: {
|
|
246
|
+
cascade,
|
|
247
|
+
sub_steps: volumetrics_sun_shadow_sub_steps(cascade),
|
|
248
|
+
},
|
|
249
|
+
camera: camera_buffer,
|
|
250
|
+
volumetrics_metadata,
|
|
251
|
+
tParticipatingMedia1: participating_media1,
|
|
252
|
+
tSunShadowVolume: TextureResourceDescriptor.from({
|
|
253
|
+
resolution,
|
|
254
|
+
dimension: "3d",
|
|
255
|
+
format: "rgba16float",
|
|
256
|
+
usage: GPUTextureUsage.STORAGE_BINDING | GPUTextureUsage.TEXTURE_BINDING
|
|
257
|
+
}),
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
if (seeded) {
|
|
261
|
+
bindings.tSunShadowOuter = cascades[cascade + 1];
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const outputs = graph_compute_pass({
|
|
265
|
+
graph,
|
|
266
|
+
shader: seeded
|
|
267
|
+
? shader_volumetrics_build_sun_shadow_volume_seeded
|
|
268
|
+
: shader_volumetrics_build_sun_shadow_volume_outermost,
|
|
269
|
+
group_count,
|
|
270
|
+
bindings,
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
cascades[cascade] = outputs.tSunShadowVolume;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
return cascades;
|
|
277
|
+
}
|
|
278
|
+
|
|
185
279
|
/**
|
|
186
280
|
*
|
|
187
281
|
* @param {FrameGraph} graph
|
|
@@ -194,6 +288,7 @@ function graph_integrate_participating_media({
|
|
|
194
288
|
* @param shadowmap_atlas
|
|
195
289
|
* @param sun_transmittance_lut
|
|
196
290
|
* @param sun_multiple_scattering_lut
|
|
291
|
+
* @param {number[]} sun_shadow_cascades handles of the Q-04 optical-depth cascades, innermost first
|
|
197
292
|
* @param lights
|
|
198
293
|
* @param view
|
|
199
294
|
* @param camera
|
|
@@ -210,6 +305,7 @@ function graph_integrate_light_scattering({
|
|
|
210
305
|
shadowmap_atlas,
|
|
211
306
|
sun_transmittance_lut,
|
|
212
307
|
sun_multiple_scattering_lut,
|
|
308
|
+
sun_shadow_cascades,
|
|
213
309
|
lights,
|
|
214
310
|
view,
|
|
215
311
|
camera,
|
|
@@ -233,6 +329,7 @@ function graph_integrate_light_scattering({
|
|
|
233
329
|
|
|
234
330
|
const sun_transmittance_lut = resources.get(data.sun_transmittance_lut);
|
|
235
331
|
const sun_multiple_scattering_lut = resources.get(data.sun_multiple_scattering_lut);
|
|
332
|
+
const sun_shadow_cascades = data.sun_shadow_cascades.map(handle => resources.get(handle));
|
|
236
333
|
|
|
237
334
|
const sampler_shadowmap = context.graphics.samplers.obtain(SHADOWMAP_COMPARE_SAMPLER_DESCRIPTOR);
|
|
238
335
|
const sLinear = context.graphics.samplers.obtain(SamplerDescriptor.from({
|
|
@@ -246,32 +343,40 @@ function graph_integrate_light_scattering({
|
|
|
246
343
|
|
|
247
344
|
const encoder = context.encoder;
|
|
248
345
|
|
|
346
|
+
const bindings = {
|
|
347
|
+
camera: camera.buffer.buffer,
|
|
348
|
+
view: view.uniform_buffer.buffer,
|
|
349
|
+
volumetrics_metadata,
|
|
350
|
+
sLinear,
|
|
351
|
+
tSunTransmittance: sun_transmittance_lut.obtainView(),
|
|
352
|
+
tMultiScattering: sun_multiple_scattering_lut.obtainView(),
|
|
353
|
+
tSTBN_vec3: tSTBN_vec3.obtainView(),
|
|
354
|
+
tParticipatingMedia0: participating_media0.obtainView(),
|
|
355
|
+
tParticipatingMedia1: participating_media1.obtainView(),
|
|
356
|
+
tLighting: output.obtainView(DEFAULT_RENDER_TARGET_VIEW_DESCRIPTOR),
|
|
357
|
+
//
|
|
358
|
+
light_data: lights.buffer_data,
|
|
359
|
+
|
|
360
|
+
cluster_data: light_cluster_data,
|
|
361
|
+
cluster_lookup: light_cluster_lookup,
|
|
362
|
+
cluster_parameters: light_cluster_parameters,
|
|
363
|
+
|
|
364
|
+
shadowmapAtlas: shadowmap_atlas.obtainView(),
|
|
365
|
+
sCompareLinear: sampler_shadowmap,
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
// One texture per cascade, under the names the read side declares. Bound here rather than
|
|
369
|
+
// above because the count is a constant of the structure, not of this pass.
|
|
370
|
+
for (let cascade = 0; cascade < sun_shadow_cascades.length; cascade++) {
|
|
371
|
+
bindings[volumetrics_sun_shadow_texture_name(cascade)] = sun_shadow_cascades[cascade].obtainView();
|
|
372
|
+
}
|
|
373
|
+
|
|
249
374
|
shader_volumetrics_build_lighting.dispatch({
|
|
250
375
|
encoder,
|
|
251
|
-
group_count_x: Math.ceil(output.width /
|
|
252
|
-
group_count_y: Math.ceil(output.height /
|
|
253
|
-
group_count_z: output.depth,
|
|
254
|
-
bindings
|
|
255
|
-
camera: camera.buffer.buffer,
|
|
256
|
-
view: view.uniform_buffer.buffer,
|
|
257
|
-
volumetrics_metadata,
|
|
258
|
-
sLinear,
|
|
259
|
-
tSunTransmittance: sun_transmittance_lut.obtainView(),
|
|
260
|
-
tMultiScattering: sun_multiple_scattering_lut.obtainView(),
|
|
261
|
-
tSTBN_vec3: tSTBN_vec3.obtainView(),
|
|
262
|
-
tParticipatingMedia0: participating_media0.obtainView(),
|
|
263
|
-
tParticipatingMedia1: participating_media1.obtainView(),
|
|
264
|
-
tLighting: output.obtainView(DEFAULT_RENDER_TARGET_VIEW_DESCRIPTOR),
|
|
265
|
-
//
|
|
266
|
-
light_data: lights.buffer_data,
|
|
267
|
-
|
|
268
|
-
cluster_data: light_cluster_data,
|
|
269
|
-
cluster_lookup: light_cluster_lookup,
|
|
270
|
-
cluster_parameters: light_cluster_parameters,
|
|
271
|
-
|
|
272
|
-
shadowmapAtlas: shadowmap_atlas.obtainView(),
|
|
273
|
-
sCompareLinear: sampler_shadowmap,
|
|
274
|
-
}
|
|
376
|
+
group_count_x: Math.ceil(output.width / VOLUMETRICS_LIGHTING_WORKGROUP_RESOLUTION[0]),
|
|
377
|
+
group_count_y: Math.ceil(output.height / VOLUMETRICS_LIGHTING_WORKGROUP_RESOLUTION[1]),
|
|
378
|
+
group_count_z: Math.ceil(output.depth / VOLUMETRICS_LIGHTING_WORKGROUP_RESOLUTION[2]),
|
|
379
|
+
bindings
|
|
275
380
|
})
|
|
276
381
|
});
|
|
277
382
|
|
|
@@ -286,6 +391,7 @@ function graph_integrate_light_scattering({
|
|
|
286
391
|
|
|
287
392
|
data.sun_transmittance_lut = pass.read(sun_transmittance_lut);
|
|
288
393
|
data.sun_multiple_scattering_lut = pass.read(sun_multiple_scattering_lut);
|
|
394
|
+
data.sun_shadow_cascades = sun_shadow_cascades.map(handle => pass.read(handle));
|
|
289
395
|
|
|
290
396
|
data.output = pass.create("Light Scattering LUT", TextureResourceDescriptor.from({
|
|
291
397
|
resolution,
|
|
@@ -310,6 +416,9 @@ function graph_integrate_light_scattering({
|
|
|
310
416
|
* @param {number} light_cluster_parameters
|
|
311
417
|
* @param {number} shadowmap_atlas
|
|
312
418
|
* @param {number[]} volumetric_resolution
|
|
419
|
+
* @param {number[]} sun_shadow_resolution voxel counts of one Q-04 sun optical-depth cascade;
|
|
420
|
+
* `[1, 1, 1]` when the froxels are marching instead, which keeps the passes in the graph without
|
|
421
|
+
* doing any work
|
|
313
422
|
* @param {number} volumetrics_metadata
|
|
314
423
|
* @param {number} [taa_history] imported previous-frame accumulated scattering volume
|
|
315
424
|
* @param {number} [taa_output] imported destination for this frame's accumulated scattering volume
|
|
@@ -325,6 +434,7 @@ export function graph_build_volumetrics({
|
|
|
325
434
|
light_cluster_parameters,
|
|
326
435
|
shadowmap_atlas,
|
|
327
436
|
volumetric_resolution,
|
|
437
|
+
sun_shadow_resolution,
|
|
328
438
|
volumetrics_metadata,
|
|
329
439
|
taa_history,
|
|
330
440
|
taa_output,
|
|
@@ -333,6 +443,9 @@ export function graph_build_volumetrics({
|
|
|
333
443
|
|
|
334
444
|
assert.defined(view, 'view');
|
|
335
445
|
assert.defined(volumetric_resolution, 'volumetric_resolution');
|
|
446
|
+
assert.defined(sun_shadow_resolution, 'sun_shadow_resolution');
|
|
447
|
+
|
|
448
|
+
graph.push_scope("build volumetrics");
|
|
336
449
|
|
|
337
450
|
const { transmittance_lut, multiscatted_lut } = graph_integrate_sky({ graph: graph });
|
|
338
451
|
|
|
@@ -348,6 +461,14 @@ export function graph_build_volumetrics({
|
|
|
348
461
|
camera,
|
|
349
462
|
});
|
|
350
463
|
|
|
464
|
+
const sun_shadow_cascades = graph_build_sun_shadow_volume({
|
|
465
|
+
graph,
|
|
466
|
+
camera,
|
|
467
|
+
participating_media1,
|
|
468
|
+
volumetrics_metadata,
|
|
469
|
+
resolution: sun_shadow_resolution,
|
|
470
|
+
});
|
|
471
|
+
|
|
351
472
|
const light_scattering_lut = graph_integrate_light_scattering({
|
|
352
473
|
graph,
|
|
353
474
|
resolution: volumetric_resolution,
|
|
@@ -355,6 +476,7 @@ export function graph_build_volumetrics({
|
|
|
355
476
|
view,
|
|
356
477
|
sun_transmittance_lut: transmittance_lut,
|
|
357
478
|
sun_multiple_scattering_lut: multiscatted_lut,
|
|
479
|
+
sun_shadow_cascades,
|
|
358
480
|
participating_media0,
|
|
359
481
|
participating_media1,
|
|
360
482
|
volumetrics_metadata,
|
|
@@ -409,7 +531,6 @@ export function graph_build_volumetrics({
|
|
|
409
531
|
|
|
410
532
|
|
|
411
533
|
const graphics = context.graphics;
|
|
412
|
-
const device = graphics.device;
|
|
413
534
|
|
|
414
535
|
const sLinear = graphics.samplers.obtain(SamplerDescriptor.from({
|
|
415
536
|
magFilter: "linear",
|
|
@@ -463,6 +584,8 @@ export function graph_build_volumetrics({
|
|
|
463
584
|
|
|
464
585
|
// TODO add temporal reprojection
|
|
465
586
|
|
|
587
|
+
graph.pop_scope();
|
|
588
|
+
|
|
466
589
|
return {
|
|
467
590
|
lut_transmittance: transmittance_lut,
|
|
468
591
|
lut_multiple_scattering: multiscatted_lut,
|
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workgroup shape of this pass, `[x, y, z]` in froxels, read by both the `@workgroup_size` below
|
|
3
|
+
* and the dispatch in `graph_build_volumetrics` so the two cannot drift.
|
|
4
|
+
*
|
|
5
|
+
* Flat in z. Lights are binned into 3D clusters and the largest distance between neighbouring
|
|
6
|
+
* clusters is along depth, so a group spanning z is the one spanning the most unrelated light
|
|
7
|
+
* lists.
|
|
8
|
+
*
|
|
9
|
+
* 64 invocations — one wave64, two warps — is a deliberate trade: 16x16x1 measures faster on the
|
|
10
|
+
* RTX 4090 this was benchmarked on, and is kept off because that part's register file is unusually
|
|
11
|
+
* large and the result is not expected to generalize (AMD favours smaller groups). NOTES.md carries
|
|
12
|
+
* the numbers and the reasoning.
|
|
13
|
+
*
|
|
14
|
+
* @type {number[]}
|
|
15
|
+
*/
|
|
16
|
+
export const VOLUMETRICS_LIGHTING_WORKGROUP_RESOLUTION: number[];
|
|
1
17
|
export const shader_volumetrics_build_lighting: ComputeShader;
|
|
2
18
|
import { ComputeShader } from "../shader/ComputeShader.js";
|
|
3
19
|
//# sourceMappingURL=shader_volumetrics_build_lighting.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader_volumetrics_build_lighting.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shader_volumetrics_build_lighting.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.js"],"names":[],"mappings":"AA6CA;;;;;;;;;;;;;;GAcG;AACH,wDAFU,MAAM,EAAE,CAEiD;AAkXnE,8DAIE;8BA9Z4B,4BAA4B"}
|