@woosh/meep-engine 3.36.0 → 3.38.0
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/package.json +1 -1
- package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
- package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +2 -0
- package/src/engine/ecs/transform/TRANSFORM64_EVENT_PLACED.d.ts +11 -0
- package/src/engine/ecs/transform/TRANSFORM64_EVENT_PLACED.d.ts.map +1 -0
- package/src/engine/ecs/transform/TRANSFORM64_EVENT_PLACED.js +10 -0
- package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.d.ts.map +1 -1
- package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.js +16 -0
- package/src/engine/graphics/ecs/water/Water.d.ts +30 -0
- package/src/engine/graphics/ecs/water/Water.d.ts.map +1 -1
- package/src/engine/graphics/ecs/water/Water.js +125 -104
- package/src/engine/graphics/ecs/water/WaterSerializationAdapter.d.ts.map +1 -1
- package/src/engine/graphics/ecs/water/WaterSerializationAdapter.js +13 -1
- package/src/engine/graphics/ecs/water/WaterSerializationUpgrader_1_2.d.ts +6 -0
- package/src/engine/graphics/ecs/water/WaterSerializationUpgrader_1_2.d.ts.map +1 -0
- package/src/engine/graphics/ecs/water/WaterSerializationUpgrader_1_2.js +18 -0
- package/src/engine/graphics3/WaterSystem.d.ts +22 -6
- package/src/engine/graphics3/WaterSystem.d.ts.map +1 -1
- package/src/engine/graphics3/WaterSystem.js +314 -293
- package/src/engine/input/devices/XRInputDevice.d.ts +51 -23
- package/src/engine/input/devices/XRInputDevice.d.ts.map +1 -1
- package/src/engine/input/devices/XRInputDevice.js +145 -52
- package/src/engine/input/devices/xr/XRGamepadMapping.d.ts +14 -0
- package/src/engine/input/devices/xr/XRGamepadMapping.d.ts.map +1 -0
- package/src/engine/input/devices/xr/XRGamepadMapping.js +9 -0
- package/src/engine/input/devices/xr/XRHandedness.d.ts +15 -0
- package/src/engine/input/devices/xr/XRHandedness.d.ts.map +1 -0
- package/src/engine/input/devices/xr/XRHandedness.js +10 -0
- package/src/engine/input/devices/xr/XRInputAction.d.ts +24 -11
- package/src/engine/input/devices/xr/XRInputAction.d.ts.map +1 -1
- package/src/engine/input/devices/xr/XRInputAction.js +55 -24
- package/src/engine/input/devices/xr/XRInputButton.d.ts +7 -9
- package/src/engine/input/devices/xr/XRInputButton.d.ts.map +1 -1
- package/src/engine/input/devices/xr/XRInputButton.js +18 -8
- package/src/engine/input/devices/xr/XRInputCoordinates.d.ts +11 -3
- package/src/engine/input/devices/xr/XRInputCoordinates.d.ts.map +1 -1
- package/src/engine/input/devices/xr/XRInputCoordinates.js +17 -3
- package/src/engine/input/devices/xr/XRInputHandle.d.ts +41 -11
- package/src/engine/input/devices/xr/XRInputHandle.d.ts.map +1 -1
- package/src/engine/input/devices/xr/XRInputHandle.js +129 -32
- package/src/engine/input/devices/xr/XRInputPose.d.ts +41 -5
- package/src/engine/input/devices/xr/XRInputPose.d.ts.map +1 -1
- package/src/engine/input/devices/xr/XRInputPose.js +57 -16
- package/src/engine/input/devices/xr/XRInputTypes.d.ts +18 -18
- package/src/engine/input/devices/xr/XRInputTypes.js +3 -3
- package/src/engine/input/devices/xr/XRTargetRayMode.d.ts +17 -0
- package/src/engine/input/devices/xr/XRTargetRayMode.d.ts.map +1 -0
- package/src/engine/input/devices/xr/XRTargetRayMode.js +12 -0
- package/src/engine/input/devices/xr/XRVisibilityState.d.ts +15 -0
- package/src/engine/input/devices/xr/XRVisibilityState.d.ts.map +1 -0
- package/src/engine/input/devices/xr/XRVisibilityState.js +10 -0
- package/src/engine/input/ecs/ism/coordinate/InputCoordinateDevice.d.ts +3 -1
- package/src/engine/input/ecs/ism/coordinate/InputCoordinateDevice.d.ts.map +1 -1
- package/src/engine/input/ecs/ism/coordinate/InputCoordinateDevice.js +5 -1
- package/src/engine/input/ecs/ism/device/XRInputDeviceAdapter.d.ts +19 -5
- package/src/engine/input/ecs/ism/device/XRInputDeviceAdapter.d.ts.map +1 -1
- package/src/engine/input/ecs/ism/device/XRInputDeviceAdapter.js +42 -9
- package/src/engine/input/ecs/ism/device/XR_INPUT_DEVICE_IDS.d.ts +8 -2
- package/src/engine/input/ecs/ism/device/XR_INPUT_DEVICE_IDS.d.ts.map +1 -1
- package/src/engine/input/ecs/ism/device/XR_INPUT_DEVICE_IDS.js +19 -9
- package/src/engine/input/ecs/ism/trigger/InputTriggerXRButton.d.ts +10 -2
- package/src/engine/input/ecs/ism/trigger/InputTriggerXRButton.d.ts.map +1 -1
- package/src/engine/input/ecs/ism/trigger/InputTriggerXRButton.js +12 -2
- package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts +13 -14
- package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts.map +1 -1
- package/src/engine/physics/cloth/collider/ClothColliderIndex.js +137 -36
- package/src/engine/physics/cloth/collider/cloth_collider_bounds.d.ts +30 -0
- package/src/engine/physics/cloth/collider/cloth_collider_bounds.d.ts.map +1 -1
- package/src/engine/physics/cloth/collider/cloth_collider_bounds.js +33 -0
- package/src/engine/physics/cloth/ecs/ClothColliderFlags.js +2 -1
- package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts +10 -1
- package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothColliderSystem.js +36 -14
- package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +15 -2
- package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothInstance.js +17 -2
- package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothWorld.js +19 -6
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts +18 -20
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.js +139 -89
- package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
- package/src/engine/physics/ecs/PhysicsSystem.js +32 -16
- package/src/shade/playground/water_refraction/README.md +149 -0
- package/src/shade/playground/water_refraction/index.html +42 -0
- package/src/shade/playground/water_refraction/main.d.ts +2 -0
- package/src/shade/playground/water_refraction/main.d.ts.map +1 -0
- package/src/shade/playground/water_refraction/main.js +201 -0
- package/src/shade/playground/water_refraction/world.d.ts +37 -0
- package/src/shade/playground/water_refraction/world.d.ts.map +1 -0
- package/src/shade/playground/water_refraction/world.js +137 -0
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +4 -0
- package/src/shade/renderer/animation/chunk_pose_accumulator.d.ts +2 -3
- package/src/shade/renderer/animation/chunk_pose_accumulator.d.ts.map +1 -1
- package/src/shade/renderer/animation/chunk_pose_accumulator.js +14 -24
- package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_reduce.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_reduce.js +16 -15
- package/src/shade/renderer/deferred/indirect/chunk_lpv_sample_light.js +1 -1
- package/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md +1123 -1122
- package/src/shade/renderer/gpu_primitive/bvh/PHASE1_HANDOVER.md +202 -201
- package/src/shade/renderer/light/environment/chunk_roughness_to_mip_ratio.d.ts +8 -0
- package/src/shade/renderer/light/environment/chunk_roughness_to_mip_ratio.d.ts.map +1 -0
- package/src/shade/renderer/light/environment/chunk_roughness_to_mip_ratio.js +24 -0
- package/src/shade/renderer/light/environment/chunk_sphere_probe_roughness_to_lod.d.ts +0 -6
- package/src/shade/renderer/light/environment/chunk_sphere_probe_roughness_to_lod.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/chunk_sphere_probe_roughness_to_lod.js +2 -25
- package/src/shade/renderer/light/environment/shader_project_environment_sh.d.ts +2 -2
- package/src/shade/renderer/light/environment/shader_project_environment_sh.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/shader_project_environment_sh.js +50 -19
- package/src/shade/renderer/particles/DESIGN.md +1 -1
- package/src/shade/renderer/particles/bounds/chunk_particle_bounds.d.ts +1 -1
- package/src/shade/renderer/particles/bounds/chunk_particle_bounds.d.ts.map +1 -1
- package/src/shade/renderer/particles/bounds/chunk_particle_bounds.js +10 -9
- package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts +17 -0
- package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.js +7 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_renormalization.d.ts +4 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_renormalization.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_renormalization.js +11 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_rgb_contribution.d.ts +4 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_rgb_contribution.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_rgb_contribution.js +19 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_splat_slice.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_splat_slice.js +5 -3
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_split_counts.d.ts +4 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_split_counts.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_split_counts.js +8 -0
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts +1 -1
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +21 -2
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_resolve.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_resolve.js +4 -8
- package/src/shade/renderer/scene/shader_bvh_extract_instance_leaves.d.ts.map +1 -1
- package/src/shade/renderer/scene/shader_bvh_extract_instance_leaves.js +10 -8
- package/src/shade/renderer/shader/chunk/atomic/chunk_atomic_add_f32_storage.d.ts +12 -0
- package/src/shade/renderer/shader/chunk/atomic/chunk_atomic_add_f32_storage.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/atomic/chunk_atomic_add_f32_storage.js +25 -0
- package/src/shade/renderer/shader/chunk/atomic/chunk_atomic_max_f32_storage.d.ts +12 -0
- package/src/shade/renderer/shader/chunk/atomic/chunk_atomic_max_f32_storage.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/atomic/chunk_atomic_max_f32_storage.js +28 -0
- package/src/shade/renderer/shader/chunk/atomic/chunk_atomic_min_f32_storage.d.ts +12 -0
- package/src/shade/renderer/shader/chunk/atomic/chunk_atomic_min_f32_storage.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/atomic/chunk_atomic_min_f32_storage.js +28 -0
- package/src/shade/renderer/shader/chunk/geometry/plane/{plane_ray_raycast.d.ts → chunk_plane_ray_raycast.d.ts} +2 -2
- package/src/shade/renderer/shader/chunk/geometry/plane/chunk_plane_ray_raycast.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/geometry/plane/{plane_ray_raycast.js → chunk_plane_ray_raycast.js} +1 -1
- package/src/shade/renderer/shader/chunk/screen_space/chunk_screen_space_newton_ray.d.ts +4 -0
- package/src/shade/renderer/shader/chunk/screen_space/chunk_screen_space_newton_ray.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/screen_space/chunk_screen_space_newton_ray.js +101 -0
- package/src/shade/renderer/shadow/map/csm/shader/shader_csm_caster_range.js +3 -3
- package/src/shade/renderer/water/GPUWaterRenderer.d.ts +62 -29
- package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
- package/src/shade/renderer/water/GPUWaterRenderer.js +235 -147
- package/src/shade/renderer/water/chunk_water_transport.d.ts +5 -0
- package/src/shade/renderer/water/chunk_water_transport.d.ts.map +1 -0
- package/src/shade/renderer/water/chunk_water_transport.js +94 -0
- package/src/shade/renderer/water/shader_water.d.ts +9 -26
- package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
- package/src/shade/renderer/water/shader_water.js +384 -246
- package/src/shade/renderer/water/shader_water_avboit.d.ts +12 -0
- package/src/shade/renderer/water/shader_water_avboit.d.ts.map +1 -0
- package/src/shade/renderer/water/shader_water_avboit.js +258 -0
- package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/WGSLLanguageCore.js +13 -0
- package/src/shade/renderer/animation/skinning/bounds_refresh/chunk_aabb_atomic_f32.d.ts +0 -29
- package/src/shade/renderer/animation/skinning/bounds_refresh/chunk_aabb_atomic_f32.d.ts.map +0 -1
- package/src/shade/renderer/animation/skinning/bounds_refresh/chunk_aabb_atomic_f32.js +0 -59
- package/src/shade/renderer/shader/chunk/geometry/plane/plane_ray_raycast.d.ts.map +0 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { WebGPUExtensionType } from "../../../descriptor/WebGPUExtensionType.js";
|
|
1
2
|
import { chunk_get_ibl_irradiance } from "../../deferred/indirect/chunk_get_ibl_irradiance.js";
|
|
2
3
|
import { PI_DECLARATION } from "../../shader/chunk/math/PI_DECLARATION.js";
|
|
3
4
|
import { chunk_sphere_fibonacci_point } from "../../shader/chunk/geometry/sphere/chunk_sphere_fibonacci_point.js";
|
|
@@ -21,12 +22,12 @@ export const ENVIRONMENT_SH_TYPE = WebGPUArray.from(vec4f, 4);
|
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* Directions the projection samples, spread evenly over the sphere (`sphere_fibonacci_point`).
|
|
24
|
-
* The field is
|
|
25
|
-
*
|
|
25
|
+
* The field is already prefiltered at the roughness diffuse reads it at; these samples project
|
|
26
|
+
* that smooth field into two bands. The pass runs only when the environment changes.
|
|
26
27
|
*
|
|
27
28
|
* @type {number}
|
|
28
29
|
*/
|
|
29
|
-
export const ENVIRONMENT_SH_SAMPLE_COUNT =
|
|
30
|
+
export const ENVIRONMENT_SH_SAMPLE_COUNT = 256;
|
|
30
31
|
|
|
31
32
|
const resources = new ShaderResourceSetDescriptor();
|
|
32
33
|
|
|
@@ -39,28 +40,56 @@ const body = CodeChunk.from(
|
|
|
39
40
|
//language=WGSL
|
|
40
41
|
`
|
|
41
42
|
const SAMPLE_COUNT : u32 = ${ENVIRONMENT_SH_SAMPLE_COUNT}u;
|
|
43
|
+
// The minimum subgroup size is four, so this holds every subgroup's partial sum.
|
|
44
|
+
const MAX_SUBGROUP_PARTIALS : u32 = SAMPLE_COUNT / 4u;
|
|
45
|
+
|
|
46
|
+
var<workgroup> wg_partial_count: atomic<u32>;
|
|
47
|
+
var<workgroup> wg_sh_0: array<vec3<f32>, MAX_SUBGROUP_PARTIALS>;
|
|
48
|
+
var<workgroup> wg_sh_1: array<vec3<f32>, MAX_SUBGROUP_PARTIALS>;
|
|
49
|
+
var<workgroup> wg_sh_2: array<vec3<f32>, MAX_SUBGROUP_PARTIALS>;
|
|
50
|
+
var<workgroup> wg_sh_3: array<vec3<f32>, MAX_SUBGROUP_PARTIALS>;
|
|
51
|
+
|
|
52
|
+
// One workgroup projects the sphere, with one invocation per sample.
|
|
53
|
+
@compute @workgroup_size(${ENVIRONMENT_SH_SAMPLE_COUNT})
|
|
54
|
+
fn main(@builtin(local_invocation_index) thread_index: u32) {
|
|
55
|
+
let direction = sphere_fibonacci_point(f32(thread_index), f32(SAMPLE_COUNT));
|
|
56
|
+
|
|
57
|
+
// exactly what the forward mesh path takes as a surface's diffuse irradiance under IBL
|
|
58
|
+
let irradiance = get_ibl_irradiance(direction);
|
|
59
|
+
let basis = sh2_basis_at(direction);
|
|
60
|
+
|
|
61
|
+
let sh_0_partial = subgroupAdd(irradiance * basis[0]);
|
|
62
|
+
let sh_1_partial = subgroupAdd(irradiance * basis[1]);
|
|
63
|
+
let sh_2_partial = subgroupAdd(irradiance * basis[2]);
|
|
64
|
+
let sh_3_partial = subgroupAdd(irradiance * basis[3]);
|
|
65
|
+
|
|
66
|
+
// Workgroup variables start zeroed. One elected lane claims a distinct slot per subgroup;
|
|
67
|
+
// local invocation indices need not map to subgroups in contiguous blocks.
|
|
68
|
+
if (subgroupElect()) {
|
|
69
|
+
let slot = atomicAdd(&wg_partial_count, 1u);
|
|
70
|
+
wg_sh_0[slot] = sh_0_partial;
|
|
71
|
+
wg_sh_1[slot] = sh_1_partial;
|
|
72
|
+
wg_sh_2[slot] = sh_2_partial;
|
|
73
|
+
wg_sh_3[slot] = sh_3_partial;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
workgroupBarrier();
|
|
77
|
+
|
|
78
|
+
if (thread_index != 0u) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
42
81
|
|
|
43
|
-
// One invocation: the projection is 1024 reads that happen when the environment changes and never
|
|
44
|
-
// otherwise, and a single lane needs no reduction and runs whole on the emulator.
|
|
45
|
-
@compute @workgroup_size(1)
|
|
46
|
-
fn main() {
|
|
47
82
|
var sh_0 = vec3<f32>(0.0);
|
|
48
83
|
var sh_1 = vec3<f32>(0.0);
|
|
49
84
|
var sh_2 = vec3<f32>(0.0);
|
|
50
85
|
var sh_3 = vec3<f32>(0.0);
|
|
86
|
+
let partial_count = atomicLoad(&wg_partial_count);
|
|
51
87
|
|
|
52
|
-
for (var i = 0u; i <
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
let basis = sh2_basis_at(direction);
|
|
59
|
-
|
|
60
|
-
sh_0 += irradiance * basis[0];
|
|
61
|
-
sh_1 += irradiance * basis[1];
|
|
62
|
-
sh_2 += irradiance * basis[2];
|
|
63
|
-
sh_3 += irradiance * basis[3];
|
|
88
|
+
for (var i = 0u; i < partial_count; i++) {
|
|
89
|
+
sh_0 += wg_sh_0[i];
|
|
90
|
+
sh_1 += wg_sh_1[i];
|
|
91
|
+
sh_2 += wg_sh_2[i];
|
|
92
|
+
sh_3 += wg_sh_3[i];
|
|
64
93
|
}
|
|
65
94
|
|
|
66
95
|
// each sample stands for an equal share of the sphere
|
|
@@ -83,6 +112,8 @@ fn main() {
|
|
|
83
112
|
PI_DECLARATION,
|
|
84
113
|
]);
|
|
85
114
|
|
|
115
|
+
body.addExtension(WebGPUExtensionType.Subgroups);
|
|
116
|
+
|
|
86
117
|
/**
|
|
87
118
|
* The environment as RGB SH2 of radiance ({@link ENVIRONMENT_SH_TYPE}): the form the renderer's other
|
|
88
119
|
* indirect lighting — Brick4, the light probe volume — already hands over, so the froxel GI stage
|
|
@@ -353,7 +353,7 @@ finished appending to the alive list:
|
|
|
353
353
|
`particle_billboard_radius`, the largest offset `particle_billboard_offset` can produce for that
|
|
354
354
|
size, velocity and projection, over every corner, every roll and any camera. The box has to hold
|
|
355
355
|
the *quads*, not the centres, and it has to be camera-independent, because it is read on a later
|
|
356
|
-
frame. The merge is `
|
|
356
|
+
frame. The merge is `atomic_min_f32_storage` / `atomic_max_f32_storage`, the same CAS-spin the
|
|
357
357
|
skinned-mesh bounds refresh uses; both load first and return without a CAS once the box holds the
|
|
358
358
|
contribution, so what survives is load traffic, not exchanges. Dispatched indirectly from
|
|
359
359
|
`sim_dispatch_args`, the args the coherence reset wrote from the GPU's own alive count.
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*
|
|
14
14
|
* ## Why f32 in the buffer, and not an order-preserving encoding
|
|
15
15
|
*
|
|
16
|
-
* `
|
|
16
|
+
* `atomic_min_f32_storage` / `atomic_max_f32_storage` are the engine's, shared with the skinned-mesh
|
|
17
17
|
* bounds refresh, and they CAS-spin over the plain float so the words are readable as floats at
|
|
18
18
|
* every moment of the frame. The sign-flip encoding that would let `atomicMin` do it in one
|
|
19
19
|
* instruction leaves the buffer in a form only a decoder understands, and the publish pass reads
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk_particle_bounds.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/bounds/chunk_particle_bounds.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"chunk_particle_bounds.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/bounds/chunk_particle_bounds.js"],"names":[],"mappings":"AAcA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,0CAFU,SAAS,CAwE8E;AAEjG;;;;;;;;;;;;;;;;GAgBG;AACH,8CAFU,SAAS,CA4CsC;0BArL/B,oCAAoC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
2
|
-
import {
|
|
2
|
+
import { chunk_atomic_min_f32_storage } from "../../shader/chunk/atomic/chunk_atomic_min_f32_storage.js";
|
|
3
|
+
import { chunk_atomic_max_f32_storage } from "../../shader/chunk/atomic/chunk_atomic_max_f32_storage.js";
|
|
3
4
|
import { AABB3_STRUCT } from "../../shader/chunk/geometry/aabb3/AABB3_STRUCT.js";
|
|
4
5
|
import {
|
|
5
6
|
PARTICLE_BOUNDS_BASE,
|
|
@@ -26,7 +27,7 @@ import { chunk_particle_render_math } from "../shaders/chunk_particle_render_mat
|
|
|
26
27
|
*
|
|
27
28
|
* ## Why f32 in the buffer, and not an order-preserving encoding
|
|
28
29
|
*
|
|
29
|
-
* `
|
|
30
|
+
* `atomic_min_f32_storage` / `atomic_max_f32_storage` are the engine's, shared with the skinned-mesh
|
|
30
31
|
* bounds refresh, and they CAS-spin over the plain float so the words are readable as floats at
|
|
31
32
|
* every moment of the frame. The sign-flip encoding that would let `atomicMin` do it in one
|
|
32
33
|
* instruction leaves the buffer in a form only a decoder understands, and the publish pass reads
|
|
@@ -71,12 +72,12 @@ fn particle_bounds_contribute(row : u32, center : vec3<f32>, radius : f32) {
|
|
|
71
72
|
let lo = center - vec3<f32>(radius);
|
|
72
73
|
let hi = center + vec3<f32>(radius);
|
|
73
74
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
75
|
+
atomic_min_f32_storage(&counters[base + 0u], lo.x);
|
|
76
|
+
atomic_min_f32_storage(&counters[base + 1u], lo.y);
|
|
77
|
+
atomic_min_f32_storage(&counters[base + 2u], lo.z);
|
|
78
|
+
atomic_max_f32_storage(&counters[base + 3u], hi.x);
|
|
79
|
+
atomic_max_f32_storage(&counters[base + 4u], hi.y);
|
|
80
|
+
atomic_max_f32_storage(&counters[base + 5u], hi.z);
|
|
80
81
|
}
|
|
81
82
|
|
|
82
83
|
// What the frame accumulated for one row. Empty (see \`particle_bounds_is_empty\`) when nothing
|
|
@@ -117,7 +118,7 @@ fn particle_bounds_reset(row : u32) {
|
|
|
117
118
|
fn particle_bounds_is_empty(box : ${AABB3_STRUCT.wgsl_ref}) -> bool {
|
|
118
119
|
return any(box.min > box.max);
|
|
119
120
|
}
|
|
120
|
-
`, [
|
|
121
|
+
`, [chunk_atomic_min_f32_storage, chunk_atomic_max_f32_storage, AABB3_STRUCT.declaration_chunk]);
|
|
121
122
|
|
|
122
123
|
/**
|
|
123
124
|
* One live particle's contribution to its emitter's box: where its quad is, and how far the quad
|
|
@@ -34,6 +34,23 @@
|
|
|
34
34
|
* channel without the method is always asked.
|
|
35
35
|
*/
|
|
36
36
|
export type AVBOITSideChannel = {
|
|
37
|
+
/**
|
|
38
|
+
* Optional optics preparation before occupancy; at most one producer per view. Inputs are
|
|
39
|
+
* immutable opaque resources. The returned background is read by the one shared resolve.
|
|
40
|
+
* Keep prepared state per graph/camera, not on an entity or in a global current-view slot.
|
|
41
|
+
*/
|
|
42
|
+
avboit_prepare?: (args: {
|
|
43
|
+
graph: import("../../../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph;
|
|
44
|
+
view_ctx: import("../../../view/GPUViewContext.js").GPUViewContext;
|
|
45
|
+
camera: number;
|
|
46
|
+
color_texture: number;
|
|
47
|
+
depth_texture: number;
|
|
48
|
+
normal_texture: number;
|
|
49
|
+
hzb_texture: number;
|
|
50
|
+
environment_texture: number;
|
|
51
|
+
}) => {
|
|
52
|
+
background_color?: number;
|
|
53
|
+
};
|
|
37
54
|
/**
|
|
38
55
|
* add the channel's slices to the occupancy bits; returns the bits'
|
|
39
56
|
* handle after the write. `cluster_parameters` is the frame's depth curve (`avboit_build_depth_curve`).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AVBOITSideChannel.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AVBOITSideChannel.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAoCc,CAAC,IAAI,EAAE;QAAC,KAAK,EAAE,OAAO,iEAAiE,EAAE,UAAU,CAAC;QACjH,QAAc,EAAE,OAAO,iCAAiC,EAAE,cAAc,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QACzF,aAAmB,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAC;QAC3E,WAAiB,EAAE,MAAM,CAAC;QAAC,mBAAmB,EAAE,MAAM,CAAA;KAAC,KAAK;QAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;KAAC;;;;;sBAI1E,CAAC,IAAI,EAAE;QACpB,KAAW,EAAE,OAAO,iEAAiE,EAAE,UAAU,CAAC;QAClG,MAAY,EAAE,MAAM,CAAC;QACrB,kBAAwB,EAAE,UAAU,MAAM,CAAC,CAAC;QAC5C,SAAe,EAAE,MAAM,CAAC;KACrB,KAAK,MAAM;;;;;;;;kBAED,CAAC,IAAI,EAAE;QACpB,KAAW,EAAE,OAAO,iEAAiE,EAAE,UAAU,CAAC;QAClG,MAAY,EAAE,MAAM,CAAC;QACrB,IAAU,EAAE,MAAM,CAAC;QACnB,aAAmB,EAAE,MAAM,CAAC;QAC5B,gBAAsB,EAAE,MAAM,EAAE,CAAC;QACjC,MAAY,EAAE;YAAC,UAAU,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAC,CAAC;KACjE,KAAK;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC;;;;;;;;;iBAKhD,CAAC,IAAI,EAAE;QACpB,KAAW,EAAE,OAAO,iEAAiE,EAAE,UAAU,CAAC;QAClG,QAAc,EAAE,OAAO,iCAAiC,EAAE,cAAc,CAAC;QACzE,MAAY,EAAE,MAAM,CAAC;QACrB,aAAmB,EAAE,MAAM,CAAC;QAC5B,IAAU,EAAE,MAAM,CAAC;QACnB,QAAc,EAAE,MAAM,CAAC;QACvB,eAAqB,EAAE,MAAM,CAAC;QAC9B,oBAA0B,EAAE,MAAM,CAAC;QACnC,sBAA4B,EAAE;YAAC,CAAC,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAC,CAAC;QACxD,YAAkB,EAAE;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAA;SAAC,CAAC;KACrF,KAAK;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAC;;;;;;sBAM9D,MAAM,OAAO"}
|
|
@@ -34,6 +34,13 @@
|
|
|
34
34
|
* channel without the method is always asked.
|
|
35
35
|
*
|
|
36
36
|
* @typedef {object} AVBOITSideChannel
|
|
37
|
+
* @property {(args: {graph: import("../../../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph,
|
|
38
|
+
* view_ctx: import("../../../view/GPUViewContext.js").GPUViewContext, camera: number,
|
|
39
|
+
* color_texture: number, depth_texture: number, normal_texture: number,
|
|
40
|
+
* hzb_texture: number, environment_texture: number}) => {background_color?: number}} [avboit_prepare]
|
|
41
|
+
* Optional optics preparation before occupancy; at most one producer per view. Inputs are
|
|
42
|
+
* immutable opaque resources. The returned background is read by the one shared resolve.
|
|
43
|
+
* Keep prepared state per graph/camera, not on an entity or in a global current-view slot.
|
|
37
44
|
* @property {(args: {
|
|
38
45
|
* graph: import("../../../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph,
|
|
39
46
|
* camera: number,
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Stable lost throughput at tiny extinction; a fixed norm cutoff drops bright faint surfaces. */
|
|
2
|
+
export const chunk_avboit_renormalization: CodeChunk;
|
|
3
|
+
import { CodeChunk } from "../../../shader/compiler/CodeChunk.js";
|
|
4
|
+
//# sourceMappingURL=chunk_avboit_renormalization.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk_avboit_renormalization.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/rasterize/native/avboit/chunk_avboit_renormalization.js"],"names":[],"mappings":"AAEA,kGAAkG;AAClG,qDAOG;0BAVuB,uCAAuC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { CodeChunk } from "../../../shader/compiler/CodeChunk.js";
|
|
2
|
+
|
|
3
|
+
/** Stable lost throughput at tiny extinction; a fixed norm cutoff drops bright faint surfaces. */
|
|
4
|
+
export const chunk_avboit_renormalization = CodeChunk.from(/* language=WGSL */ `
|
|
5
|
+
fn avboit_renormalization(extinction: vec3f, norm: vec3f) -> vec3f {
|
|
6
|
+
let x = max(extinction, vec3f(0.0));
|
|
7
|
+
let small_loss = x * (1.0 - 0.5 * x + x * x / 6.0);
|
|
8
|
+
let loss = select(vec3f(1.0) - exp(-x), small_loss, x < vec3f(0.001));
|
|
9
|
+
return select(vec3f(0.0), min(loss / max(norm, vec3f(1e-20)), vec3f(65504.0)), norm > vec3f(0.0));
|
|
10
|
+
}
|
|
11
|
+
`);
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** A covering RGB-throughput surface; the existing particle/scalar entry point stays unchanged. */
|
|
2
|
+
export const chunk_avboit_rgb_contribution: CodeChunk;
|
|
3
|
+
import { CodeChunk } from "../../../shader/compiler/CodeChunk.js";
|
|
4
|
+
//# sourceMappingURL=chunk_avboit_rgb_contribution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk_avboit_rgb_contribution.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/rasterize/native/avboit/chunk_avboit_rgb_contribution.js"],"names":[],"mappings":"AAGA,mGAAmG;AACnG,sDAc8C;0BAlBpB,uCAAuC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { CodeChunk } from "../../../shader/compiler/CodeChunk.js";
|
|
2
|
+
import { chunk_avboit_premultiplied_contribution } from "./chunk_avboit_premultiplied_contribution.js";
|
|
3
|
+
|
|
4
|
+
/** A covering RGB-throughput surface; the existing particle/scalar entry point stays unchanged. */
|
|
5
|
+
export const chunk_avboit_rgb_contribution = CodeChunk.from(/* language=WGSL */ `
|
|
6
|
+
fn avboit_rgb_contribution(
|
|
7
|
+
radiance: vec3<f32>, self_transmittance: vec3<f32>,
|
|
8
|
+
front_transmittance: vec3<f32>, fog: vec4<f32>,
|
|
9
|
+
) -> AVBOITContribution {
|
|
10
|
+
let t = clamp(self_transmittance, vec3<f32>(1e-6), vec3<f32>(1.0));
|
|
11
|
+
let loss = vec3<f32>(1.0) - t;
|
|
12
|
+
var out: AVBOITContribution;
|
|
13
|
+
out.color = vec4<f32>((radiance * fog.w + loss * fog.xyz) * front_transmittance, 0.0);
|
|
14
|
+
out.norm = vec4<f32>(loss * front_transmittance, 0.0);
|
|
15
|
+
out.extinction = vec4<f32>(-log(t), 0.0);
|
|
16
|
+
out.emission = vec4<f32>(0.0);
|
|
17
|
+
return out;
|
|
18
|
+
}
|
|
19
|
+
`, [chunk_avboit_premultiplied_contribution]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk_avboit_splat_slice.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/rasterize/native/avboit/chunk_avboit_splat_slice.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;GAcG;AACH,uCAFU,SAAS,
|
|
1
|
+
{"version":3,"file":"chunk_avboit_splat_slice.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/rasterize/native/avboit/chunk_avboit_splat_slice.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;GAcG;AACH,uCAFU,SAAS,CAyCjB;0BA3DwB,uCAAuC"}
|
|
@@ -21,12 +21,10 @@ import { chunk_avboit_pack_counts } from "./chunk_avboit_pack_counts.js";
|
|
|
21
21
|
export const chunk_avboit_splat_slice = CodeChunk.from(
|
|
22
22
|
//language=WGSL
|
|
23
23
|
`
|
|
24
|
-
fn
|
|
24
|
+
fn avboit_splat_counts(column: u32, slice: i32, counts: vec3<u32>, texel: vec2<u32>) {
|
|
25
25
|
let physical = i32(warp.physical_count);
|
|
26
26
|
let s = clamp(slice, 0, physical - 1);
|
|
27
27
|
|
|
28
|
-
let counts = avboit_extinction_to_counts(extinction);
|
|
29
|
-
|
|
30
28
|
if (all(counts == vec3<u32>(0u))) {
|
|
31
29
|
return;
|
|
32
30
|
}
|
|
@@ -50,6 +48,10 @@ fn avboit_splat_slice(column: u32, slice: i32, extinction: vec3<f32>, texel: vec
|
|
|
50
48
|
}
|
|
51
49
|
}
|
|
52
50
|
}
|
|
51
|
+
|
|
52
|
+
fn avboit_splat_slice(column: u32, slice: i32, extinction: vec3<f32>, texel: vec2<u32>) {
|
|
53
|
+
avboit_splat_counts(column, slice, avboit_extinction_to_counts(extinction), texel);
|
|
54
|
+
}
|
|
53
55
|
`, [
|
|
54
56
|
chunk_avboit_extinction_to_counts,
|
|
55
57
|
chunk_avboit_overflows,
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Partition already quantized counts. Rounding two fractional extinctions can erase both. */
|
|
2
|
+
export const chunk_avboit_split_counts: CodeChunk;
|
|
3
|
+
import { CodeChunk } from "../../../shader/compiler/CodeChunk.js";
|
|
4
|
+
//# sourceMappingURL=chunk_avboit_split_counts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk_avboit_split_counts.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/rasterize/native/avboit/chunk_avboit_split_counts.js"],"names":[],"mappings":"AAEA,8FAA8F;AAC9F,kDAIG;0BAPuB,uCAAuC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { CodeChunk } from "../../../shader/compiler/CodeChunk.js";
|
|
2
|
+
|
|
3
|
+
/** Partition already quantized counts. Rounding two fractional extinctions can erase both. */
|
|
4
|
+
export const chunk_avboit_split_counts = CodeChunk.from(/* language=WGSL */ `
|
|
5
|
+
fn avboit_split_counts(counts: vec3<u32>, fraction: f32) -> vec3<u32> {
|
|
6
|
+
return min(counts, vec3<u32>(vec3<f32>(counts) * clamp(fraction, 0.0, 1.0) + 0.5));
|
|
7
|
+
}
|
|
8
|
+
`);
|
package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts
CHANGED
|
@@ -164,7 +164,7 @@ export function avboit_create_accumulators(pass: FramePassBuilder, resolution: A
|
|
|
164
164
|
* sources of transparent fragments; the MBOIT orchestrator ignores them
|
|
165
165
|
* @returns {number} resource ID of the composited color texture
|
|
166
166
|
*/
|
|
167
|
-
export function graph_rasterize_meshes_transparent_avboit({ graph, buckets, view_ctx, viewport, depth_texture, color_texture, limits, light_cluster_parameters, light_cluster_lookup, light_cluster_data, shadowmap_atlas, volumetrics_lut, volumetrics_metadata, volumetrics_irradiance, indirect_lighting_mode, avboit, side_channels, }: {
|
|
167
|
+
export function graph_rasterize_meshes_transparent_avboit({ graph, buckets, view_ctx, viewport, depth_texture, color_texture, normal_texture, hzb_texture, environment_texture, limits, light_cluster_parameters, light_cluster_lookup, light_cluster_data, shadowmap_atlas, volumetrics_lut, volumetrics_metadata, volumetrics_irradiance, indirect_lighting_mode, avboit, side_channels, }: {
|
|
168
168
|
graph: FrameGraph;
|
|
169
169
|
buckets: number;
|
|
170
170
|
view_ctx: GPUViewContext;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph_rasterize_meshes_transparent_avboit.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js"],"names":[],"mappings":"AA4DA;;;;;GAKG;AACH,oDAHW,UAAU,MAAM,CAAC,GACf,MAAM,EAAE,CAOpB;AAED;;;;;;;;;;;;GAYG;AACH;IAT+B,KAAK;IACA,KAAK;IACd,MAAM,EAAtB,MAAM;IACqB,kBAAkB,EAA7C,UAAU,MAAM,CAAC;IACD,kBAAkB,EAAlC,MAAM;IACU,wBAAwB,EAAxC,MAAM;IACW,SAAS,GAA1B,MAAM;IACJ,MAAM,CA4DlB;AAED;;;;;;;;;;GAUG;AACH;IAP+B,KAAK;IACT,SAAS,EAAzB,MAAM;IACY,gBAAgB,EAAlC,MAAM,EAAE;IACmB,kBAAkB,EAA7C,UAAU,MAAM,CAAC;IACQ,MAAM,GAA/B,cAAc;IACZ,MAAM,CAsDlB;AAED;;;;;;;;;;;;;;;GAeG;AACH,6KAFa;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,CAiJjE;AAED;;;;;;;;;;GAUG;AACH;IAP+B,KAAK;IACT,IAAI,EAApB,MAAM;IACU,UAAU,EAA1B,MAAM;IACU,QAAQ,EAAxB,MAAM;IACY,gBAAgB,EAAlC,MAAM,EAAE;IACN,MAAM,CAoClB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qUAFa;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAC,CAwN7D;AAED;;;;;;;;GAQG;AACH,+EAHW,UAAU,MAAM,CAAC,GACf;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAC,CAe/E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH;IAtB+B,KAAK;IACT,OAAO,EAAvB,MAAM;IACkB,QAAQ;IACd,QAAQ,EAA1B,MAAM,EAAE;IACQ,aAAa,EAA7B,MAAM;IACU,aAAa,EAA7B,MAAM;IACuB,MAAM;IACnB,wBAAwB,EAAxC,MAAM;IACU,oBAAoB,EAApC,MAAM;IACU,kBAAkB,EAAlC,MAAM;IACU,eAAe,EAA/B,MAAM;IACU,eAAe,EAA/B,MAAM;IACU,oBAAoB,EAApC,MAAM;IAC6B,sBAAsB,EAAzD;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC;IAGU,sBAAsB,EAAzD,yBAAyB;IACA,MAAM,GAA/B,cAAc;IACiD,aAAa,GAA5E,OAAO,wBAAwB,EAAE,iBAAiB,EAAE;IAElD,MAAM,
|
|
1
|
+
{"version":3,"file":"graph_rasterize_meshes_transparent_avboit.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js"],"names":[],"mappings":"AA4DA;;;;;GAKG;AACH,oDAHW,UAAU,MAAM,CAAC,GACf,MAAM,EAAE,CAOpB;AAED;;;;;;;;;;;;GAYG;AACH;IAT+B,KAAK;IACA,KAAK;IACd,MAAM,EAAtB,MAAM;IACqB,kBAAkB,EAA7C,UAAU,MAAM,CAAC;IACD,kBAAkB,EAAlC,MAAM;IACU,wBAAwB,EAAxC,MAAM;IACW,SAAS,GAA1B,MAAM;IACJ,MAAM,CA4DlB;AAED;;;;;;;;;;GAUG;AACH;IAP+B,KAAK;IACT,SAAS,EAAzB,MAAM;IACY,gBAAgB,EAAlC,MAAM,EAAE;IACmB,kBAAkB,EAA7C,UAAU,MAAM,CAAC;IACQ,MAAM,GAA/B,cAAc;IACZ,MAAM,CAsDlB;AAED;;;;;;;;;;;;;;;GAeG;AACH,6KAFa;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,CAiJjE;AAED;;;;;;;;;;GAUG;AACH;IAP+B,KAAK;IACT,IAAI,EAApB,MAAM;IACU,UAAU,EAA1B,MAAM;IACU,QAAQ,EAAxB,MAAM;IACY,gBAAgB,EAAlC,MAAM,EAAE;IACN,MAAM,CAoClB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qUAFa;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAC,CAwN7D;AAED;;;;;;;;GAQG;AACH,+EAHW,UAAU,MAAM,CAAC,GACf;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAC,CAe/E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH;IAtB+B,KAAK;IACT,OAAO,EAAvB,MAAM;IACkB,QAAQ;IACd,QAAQ,EAA1B,MAAM,EAAE;IACQ,aAAa,EAA7B,MAAM;IACU,aAAa,EAA7B,MAAM;IACuB,MAAM;IACnB,wBAAwB,EAAxC,MAAM;IACU,oBAAoB,EAApC,MAAM;IACU,kBAAkB,EAAlC,MAAM;IACU,eAAe,EAA/B,MAAM;IACU,eAAe,EAA/B,MAAM;IACU,oBAAoB,EAApC,MAAM;IAC6B,sBAAsB,EAAzD;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC;IAGU,sBAAsB,EAAzD,yBAAyB;IACA,MAAM,GAA/B,cAAc;IACiD,aAAa,GAA5E,OAAO,wBAAwB,EAAE,iBAAiB,EAAE;IAElD,MAAM,CAiTlB;+BAx9B8B,qBAAqB;0CA9BV,uCAAuC"}
|
package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js
CHANGED
|
@@ -724,6 +724,9 @@ export function graph_rasterize_meshes_transparent_avboit({
|
|
|
724
724
|
viewport,
|
|
725
725
|
depth_texture,
|
|
726
726
|
color_texture,
|
|
727
|
+
normal_texture,
|
|
728
|
+
hzb_texture,
|
|
729
|
+
environment_texture,
|
|
727
730
|
limits,
|
|
728
731
|
light_cluster_parameters,
|
|
729
732
|
light_cluster_lookup,
|
|
@@ -809,7 +812,7 @@ export function graph_rasterize_meshes_transparent_avboit({
|
|
|
809
812
|
const primitive_front = construct_primitive_state(ShadeDrawMode.Triangles, ShadeDrawSide.Front);
|
|
810
813
|
const primitive_double = construct_primitive_state(ShadeDrawMode.Triangles, ShadeDrawSide.Double);
|
|
811
814
|
|
|
812
|
-
const gr_hzb = graph_import_texture(graph, view_ctx.hierarchical_z_buffer.texture);
|
|
815
|
+
const gr_hzb = hzb_texture ?? graph_import_texture(graph, view_ctx.hierarchical_z_buffer.texture);
|
|
813
816
|
const gr_camera = graph_import_buffer(graph, view_ctx.camera.buffer.buffer);
|
|
814
817
|
|
|
815
818
|
const voxel_resolution = avboit_voxel_resolution(view_ctx.resolution);
|
|
@@ -819,6 +822,22 @@ export function graph_rasterize_meshes_transparent_avboit({
|
|
|
819
822
|
const camera = view_ctx.camera.camera;
|
|
820
823
|
const cluster_parameters = avboit_build_depth_curve(camera.near, camera.far);
|
|
821
824
|
|
|
825
|
+
// A background producer transports only immutable opaque radiance. Reject ambiguity before
|
|
826
|
+
// recording any preparation rather than letting channel registration order choose a winner.
|
|
827
|
+
const preparers = side_channels.filter(channel => typeof channel.avboit_prepare === "function");
|
|
828
|
+
if (preparers.length > 1) {
|
|
829
|
+
throw new Error("AVBOIT supports one refractive background producer per view");
|
|
830
|
+
}
|
|
831
|
+
let background_color = color_texture;
|
|
832
|
+
for (const channel of preparers) {
|
|
833
|
+
const prepared = channel.avboit_prepare({ graph, view_ctx, camera: gr_camera, color_texture,
|
|
834
|
+
depth_texture, normal_texture, hzb_texture: gr_hzb, environment_texture });
|
|
835
|
+
if (prepared?.background_color !== undefined) {
|
|
836
|
+
assert.isNonNegativeInteger(prepared.background_color, 'prepared.background_color');
|
|
837
|
+
background_color = prepared.background_color;
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
|
|
822
841
|
// Draw artifacts (shared with MBOIT)
|
|
823
842
|
// ======
|
|
824
843
|
|
|
@@ -992,7 +1011,7 @@ export function graph_rasterize_meshes_transparent_avboit({
|
|
|
992
1011
|
shader: shader_avboit_resolve,
|
|
993
1012
|
output_resolution: view_ctx.resolution,
|
|
994
1013
|
inputs: {
|
|
995
|
-
tScene:
|
|
1014
|
+
tScene: background_color,
|
|
996
1015
|
tColor: accumulators.color,
|
|
997
1016
|
tNorm: accumulators.norm,
|
|
998
1017
|
tExtinction: accumulators.extinction,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader_avboit_resolve.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/rasterize/native/avboit/shader_avboit_resolve.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shader_avboit_resolve.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/rasterize/native/avboit/shader_avboit_resolve.js"],"names":[],"mappings":"AAwEA,gDAUE;4BAhF0B,gCAAgC"}
|
|
@@ -3,6 +3,7 @@ import { CodeChunk } from "../../../shader/compiler/CodeChunk.js";
|
|
|
3
3
|
import { ImageShader } from "../../../shader/ImageShader.js";
|
|
4
4
|
import { ShaderResourceSetDescriptor } from "../../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
5
5
|
import { ShaderDescriptor } from "../../../shader/ShaderDescriptor.js";
|
|
6
|
+
import { chunk_avboit_renormalization } from "./chunk_avboit_renormalization.js";
|
|
6
7
|
|
|
7
8
|
const resources = new ShaderResourceSetDescriptor();
|
|
8
9
|
resources.createGroup()
|
|
@@ -19,7 +20,7 @@ resources.createGroup()
|
|
|
19
20
|
*
|
|
20
21
|
* ```
|
|
21
22
|
* T_total = exp(-Σ extinction)
|
|
22
|
-
* norm = Σ norm >
|
|
23
|
+
* norm = Σ norm > 0 ? stable_lost_throughput(Σ extinction) / Σ norm : 0
|
|
23
24
|
* out = scene × T_total + Σ color × norm + Σ emission
|
|
24
25
|
* ```
|
|
25
26
|
*
|
|
@@ -58,19 +59,14 @@ fn main(
|
|
|
58
59
|
let total_transmittance = exp(-accum_extinction);
|
|
59
60
|
|
|
60
61
|
// sum of (1 - T_self) * T at each fragment; zero where nothing transparent was drawn
|
|
61
|
-
let
|
|
62
|
-
let renormalization = select(
|
|
63
|
-
vec3<f32>(0.0),
|
|
64
|
-
(vec3<f32>(1.0) - total_transmittance) / max(accum_norm, vec3<f32>(1e-4)),
|
|
65
|
-
safe
|
|
66
|
-
);
|
|
62
|
+
let renormalization = avboit_renormalization(accum_extinction, accum_norm);
|
|
67
63
|
|
|
68
64
|
let transparent = accum_color * renormalization;
|
|
69
65
|
|
|
70
66
|
return vec4<f32>(scene.rgb * total_transmittance + transparent + accum_emission, scene.a);
|
|
71
67
|
}
|
|
72
68
|
`, [
|
|
73
|
-
chunk_is_nan
|
|
69
|
+
chunk_is_nan, chunk_avboit_renormalization
|
|
74
70
|
]
|
|
75
71
|
)
|
|
76
72
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader_bvh_extract_instance_leaves.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/scene/shader_bvh_extract_instance_leaves.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shader_bvh_extract_instance_leaves.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/scene/shader_bvh_extract_instance_leaves.js"],"names":[],"mappings":"AAWA,4CAA6C;AAmH7C;;;;;;;;;;;;;;;;;GAiBG;AACH,iDAFU,aAAa,CAMpB;8BA9I2B,4BAA4B"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { WebGPUExtensionType } from "../../descriptor/WebGPUExtensionType.js";
|
|
2
2
|
import { atomic_u32, f32, u32 } from "../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
|
|
3
3
|
import { WebGPUArray } from "../shader/type/WebGPUArray.js";
|
|
4
|
-
import {
|
|
4
|
+
import { chunk_atomic_min_f32_storage } from "../shader/chunk/atomic/chunk_atomic_min_f32_storage.js";
|
|
5
|
+
import { chunk_atomic_max_f32_storage } from "../shader/chunk/atomic/chunk_atomic_max_f32_storage.js";
|
|
5
6
|
import { CodeChunk } from "../shader/compiler/CodeChunk.js";
|
|
6
7
|
import { ComputeShader } from "../shader/ComputeShader.js";
|
|
7
8
|
import { ShaderResourceSetDescriptor } from "../shader/resource/ShaderResourceSetDescriptor.js";
|
|
@@ -107,17 +108,18 @@ fn main(
|
|
|
107
108
|
group_high = max(group_high, wg_high[s]);
|
|
108
109
|
}
|
|
109
110
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
111
|
+
atomic_min_f32_storage(&scene_bounds[0], group_low.x);
|
|
112
|
+
atomic_min_f32_storage(&scene_bounds[1], group_low.y);
|
|
113
|
+
atomic_min_f32_storage(&scene_bounds[2], group_low.z);
|
|
114
|
+
atomic_max_f32_storage(&scene_bounds[3], group_high.x);
|
|
115
|
+
atomic_max_f32_storage(&scene_bounds[4], group_high.y);
|
|
116
|
+
atomic_max_f32_storage(&scene_bounds[5], group_high.z);
|
|
116
117
|
}
|
|
117
118
|
}
|
|
118
119
|
`, [
|
|
119
120
|
chunk_scene_database_access,
|
|
120
|
-
|
|
121
|
+
chunk_atomic_min_f32_storage,
|
|
122
|
+
chunk_atomic_max_f32_storage,
|
|
121
123
|
]);
|
|
122
124
|
|
|
123
125
|
body.addExtension(WebGPUExtensionType.Subgroups);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Atomic f32 addition over a read-write storage atomic<u32> cell containing f32 bits.
|
|
3
|
+
*
|
|
4
|
+
* Each compare-exchange attempt adds to the current float value and writes the sum
|
|
5
|
+
* as plain f32 bits. Failed or spurious exchanges retry from a fresh atomic load,
|
|
6
|
+
* so concurrent additions are not lost.
|
|
7
|
+
*
|
|
8
|
+
* @type {CodeChunk}
|
|
9
|
+
*/
|
|
10
|
+
export const chunk_atomic_add_f32_storage: CodeChunk;
|
|
11
|
+
import { CodeChunk } from "../../compiler/CodeChunk.js";
|
|
12
|
+
//# sourceMappingURL=chunk_atomic_add_f32_storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk_atomic_add_f32_storage.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/shader/chunk/atomic/chunk_atomic_add_f32_storage.js"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,2CAFU,SAAS,CAehB;0BAxBuB,6BAA6B"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { CodeChunk } from "../../compiler/CodeChunk.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Atomic f32 addition over a read-write storage atomic<u32> cell containing f32 bits.
|
|
5
|
+
*
|
|
6
|
+
* Each compare-exchange attempt adds to the current float value and writes the sum
|
|
7
|
+
* as plain f32 bits. Failed or spurious exchanges retry from a fresh atomic load,
|
|
8
|
+
* so concurrent additions are not lost.
|
|
9
|
+
*
|
|
10
|
+
* @type {CodeChunk}
|
|
11
|
+
*/
|
|
12
|
+
export const chunk_atomic_add_f32_storage = CodeChunk.from(
|
|
13
|
+
//language=WGSL
|
|
14
|
+
`
|
|
15
|
+
fn atomic_add_f32_storage(cell: ptr<storage, atomic<u32>, read_write>, value: f32) {
|
|
16
|
+
loop {
|
|
17
|
+
let old_u = atomicLoad(cell);
|
|
18
|
+
let old_f = bitcast<f32>(old_u);
|
|
19
|
+
let result = atomicCompareExchangeWeak(cell, old_u, bitcast<u32>(old_f + value));
|
|
20
|
+
if result.exchanged {
|
|
21
|
+
break;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
`);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Atomic f32 maximum over a read-write storage atomic<u32> cell containing f32 bits.
|
|
3
|
+
*
|
|
4
|
+
* Compare-exchange retries keep the cell in plain f32 representation. If the stored
|
|
5
|
+
* value already bounds the contribution, the function exits without an exchange.
|
|
6
|
+
* Infinities are supported; the stored value and contribution must not be NaN.
|
|
7
|
+
*
|
|
8
|
+
* @type {CodeChunk}
|
|
9
|
+
*/
|
|
10
|
+
export const chunk_atomic_max_f32_storage: CodeChunk;
|
|
11
|
+
import { CodeChunk } from "../../compiler/CodeChunk.js";
|
|
12
|
+
//# sourceMappingURL=chunk_atomic_max_f32_storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk_atomic_max_f32_storage.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/shader/chunk/atomic/chunk_atomic_max_f32_storage.js"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,2CAFU,SAAS,CAkBhB;0BA3BuB,6BAA6B"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { CodeChunk } from "../../compiler/CodeChunk.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Atomic f32 maximum over a read-write storage atomic<u32> cell containing f32 bits.
|
|
5
|
+
*
|
|
6
|
+
* Compare-exchange retries keep the cell in plain f32 representation. If the stored
|
|
7
|
+
* value already bounds the contribution, the function exits without an exchange.
|
|
8
|
+
* Infinities are supported; the stored value and contribution must not be NaN.
|
|
9
|
+
*
|
|
10
|
+
* @type {CodeChunk}
|
|
11
|
+
*/
|
|
12
|
+
export const chunk_atomic_max_f32_storage = CodeChunk.from(
|
|
13
|
+
//language=WGSL
|
|
14
|
+
`
|
|
15
|
+
fn atomic_max_f32_storage(cell: ptr<storage, atomic<u32>, read_write>, value: f32) {
|
|
16
|
+
loop {
|
|
17
|
+
let old_u = atomicLoad(cell);
|
|
18
|
+
let old_f = bitcast<f32>(old_u);
|
|
19
|
+
if value <= old_f {
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
22
|
+
let result = atomicCompareExchangeWeak(cell, old_u, bitcast<u32>(value));
|
|
23
|
+
if result.exchanged {
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
`);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Atomic f32 minimum over a read-write storage atomic<u32> cell containing f32 bits.
|
|
3
|
+
*
|
|
4
|
+
* Compare-exchange retries keep the cell in plain f32 representation. If the stored
|
|
5
|
+
* value already bounds the contribution, the function exits without an exchange.
|
|
6
|
+
* Infinities are supported; the stored value and contribution must not be NaN.
|
|
7
|
+
*
|
|
8
|
+
* @type {CodeChunk}
|
|
9
|
+
*/
|
|
10
|
+
export const chunk_atomic_min_f32_storage: CodeChunk;
|
|
11
|
+
import { CodeChunk } from "../../compiler/CodeChunk.js";
|
|
12
|
+
//# sourceMappingURL=chunk_atomic_min_f32_storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk_atomic_min_f32_storage.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/shader/chunk/atomic/chunk_atomic_min_f32_storage.js"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,2CAFU,SAAS,CAkBhB;0BA3BuB,6BAA6B"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { CodeChunk } from "../../compiler/CodeChunk.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Atomic f32 minimum over a read-write storage atomic<u32> cell containing f32 bits.
|
|
5
|
+
*
|
|
6
|
+
* Compare-exchange retries keep the cell in plain f32 representation. If the stored
|
|
7
|
+
* value already bounds the contribution, the function exits without an exchange.
|
|
8
|
+
* Infinities are supported; the stored value and contribution must not be NaN.
|
|
9
|
+
*
|
|
10
|
+
* @type {CodeChunk}
|
|
11
|
+
*/
|
|
12
|
+
export const chunk_atomic_min_f32_storage = CodeChunk.from(
|
|
13
|
+
//language=WGSL
|
|
14
|
+
`
|
|
15
|
+
fn atomic_min_f32_storage(cell: ptr<storage, atomic<u32>, read_write>, value: f32) {
|
|
16
|
+
loop {
|
|
17
|
+
let old_u = atomicLoad(cell);
|
|
18
|
+
let old_f = bitcast<f32>(old_u);
|
|
19
|
+
if value >= old_f {
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
22
|
+
let result = atomicCompareExchangeWeak(cell, old_u, bitcast<u32>(value));
|
|
23
|
+
if result.exchanged {
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
`);
|