@woosh/meep-engine 3.34.0 → 3.36.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/Engine.d.ts +2 -0
- package/src/engine/Engine.d.ts.map +1 -1
- package/src/engine/Engine.js +5 -1
- package/src/engine/input/devices/XRInputDevice.d.ts +63 -0
- package/src/engine/input/devices/XRInputDevice.d.ts.map +1 -0
- package/src/engine/input/devices/XRInputDevice.js +386 -0
- package/src/engine/input/devices/xr/XRInputAction.d.ts +37 -0
- package/src/engine/input/devices/xr/XRInputAction.d.ts.map +1 -0
- package/src/engine/input/devices/xr/XRInputAction.js +85 -0
- package/src/engine/input/devices/xr/XRInputButton.d.ts +28 -0
- package/src/engine/input/devices/xr/XRInputButton.d.ts.map +1 -0
- package/src/engine/input/devices/xr/XRInputButton.js +43 -0
- package/src/engine/input/devices/xr/XRInputCoordinates.d.ts +15 -0
- package/src/engine/input/devices/xr/XRInputCoordinates.d.ts.map +1 -0
- package/src/engine/input/devices/xr/XRInputCoordinates.js +21 -0
- package/src/engine/input/devices/xr/XRInputHandle.d.ts +63 -0
- package/src/engine/input/devices/xr/XRInputHandle.d.ts.map +1 -0
- package/src/engine/input/devices/xr/XRInputHandle.js +171 -0
- package/src/engine/input/devices/xr/XRInputPose.d.ts +23 -0
- package/src/engine/input/devices/xr/XRInputPose.d.ts.map +1 -0
- package/src/engine/input/devices/xr/XRInputPose.js +36 -0
- package/src/engine/input/devices/xr/XRInputTypes.d.ts +76 -0
- package/src/engine/input/devices/xr/XRInputTypes.d.ts.map +1 -0
- package/src/engine/input/devices/xr/XRInputTypes.js +31 -0
- package/src/engine/input/devices/xr/XRInputValueSource.d.ts +11 -0
- package/src/engine/input/devices/xr/XRInputValueSource.d.ts.map +1 -0
- package/src/engine/input/devices/xr/XRInputValueSource.js +11 -0
- package/src/engine/input/ecs/ism/coordinate/InputCoordinateChannel.d.ts +15 -1
- package/src/engine/input/ecs/ism/coordinate/InputCoordinateChannel.d.ts.map +1 -1
- package/src/engine/input/ecs/ism/coordinate/InputCoordinateChannel.js +9 -0
- package/src/engine/input/ecs/ism/coordinate/InputCoordinateDevice.d.ts +15 -4
- package/src/engine/input/ecs/ism/coordinate/InputCoordinateDevice.d.ts.map +1 -1
- package/src/engine/input/ecs/ism/coordinate/InputCoordinateDevice.js +22 -0
- package/src/engine/input/ecs/ism/coordinate/InputCoordinateSwitches.d.ts +17 -2
- package/src/engine/input/ecs/ism/coordinate/InputCoordinateSwitches.d.ts.map +1 -1
- package/src/engine/input/ecs/ism/device/GamepadInputDeviceAdapter.d.ts +5 -0
- package/src/engine/input/ecs/ism/device/GamepadInputDeviceAdapter.d.ts.map +1 -1
- package/src/engine/input/ecs/ism/device/InputDeviceAdapter.d.ts +2 -0
- package/src/engine/input/ecs/ism/device/InputDeviceAdapter.d.ts.map +1 -1
- package/src/engine/input/ecs/ism/device/InputDeviceAdapter.js +2 -0
- package/src/engine/input/ecs/ism/device/KeyboardInputDeviceAdapter.d.ts +7 -0
- package/src/engine/input/ecs/ism/device/KeyboardInputDeviceAdapter.d.ts.map +1 -1
- package/src/engine/input/ecs/ism/device/ManualInputDeviceAdapter.d.ts +5 -0
- package/src/engine/input/ecs/ism/device/ManualInputDeviceAdapter.d.ts.map +1 -1
- package/src/engine/input/ecs/ism/device/PointerInputDeviceAdapter.d.ts +5 -0
- package/src/engine/input/ecs/ism/device/PointerInputDeviceAdapter.d.ts.map +1 -1
- package/src/engine/input/ecs/ism/device/XRInputDeviceAdapter.d.ts +16 -0
- package/src/engine/input/ecs/ism/device/XRInputDeviceAdapter.d.ts.map +1 -0
- package/src/engine/input/ecs/ism/device/XRInputDeviceAdapter.js +54 -0
- package/src/engine/input/ecs/ism/device/XR_INPUT_DEVICE_IDS.d.ts +9 -0
- package/src/engine/input/ecs/ism/device/XR_INPUT_DEVICE_IDS.d.ts.map +1 -0
- package/src/engine/input/ecs/ism/device/XR_INPUT_DEVICE_IDS.js +12 -0
- package/src/engine/input/ecs/ism/trigger/InputTrigger.d.ts +11 -1
- package/src/engine/input/ecs/ism/trigger/InputTrigger.d.ts.map +1 -1
- package/src/engine/input/ecs/ism/trigger/InputTrigger.js +7 -0
- package/src/engine/input/ecs/ism/trigger/InputTriggerChord.d.ts +16 -2
- package/src/engine/input/ecs/ism/trigger/InputTriggerChord.d.ts.map +1 -1
- package/src/engine/input/ecs/ism/trigger/InputTriggerHold.d.ts +22 -2
- package/src/engine/input/ecs/ism/trigger/InputTriggerHold.d.ts.map +1 -1
- package/src/engine/input/ecs/ism/trigger/InputTriggerRelease.d.ts +16 -2
- package/src/engine/input/ecs/ism/trigger/InputTriggerRelease.d.ts.map +1 -1
- package/src/engine/input/ecs/ism/trigger/InputTriggerSequence.d.ts +24 -4
- package/src/engine/input/ecs/ism/trigger/InputTriggerSequence.d.ts.map +1 -1
- package/src/engine/input/ecs/ism/trigger/InputTriggerSwitch.d.ts +6 -8
- package/src/engine/input/ecs/ism/trigger/InputTriggerSwitch.d.ts.map +1 -1
- package/src/engine/input/ecs/ism/trigger/InputTriggerSwitch.js +5 -0
- package/src/engine/input/ecs/ism/trigger/InputTriggerXRButton.d.ts +7 -0
- package/src/engine/input/ecs/ism/trigger/InputTriggerXRButton.d.ts.map +1 -0
- package/src/engine/input/ecs/ism/trigger/InputTriggerXRButton.js +15 -0
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/shade/device/timing/profile/GPUProfileSession.d.ts +25 -11
- package/src/shade/device/timing/profile/GPUProfileSession.d.ts.map +1 -1
- package/src/shade/device/timing/profile/GPUProfileSession.js +553 -474
- package/src/shade/playground/avboit/main.d.ts.map +1 -1
- package/src/shade/playground/avboit/main.js +888 -916
- package/src/shade/playground/particle_ecs/README.md +13 -7
- package/src/shade/playground/particle_ecs/bonfire_effects.d.ts +5 -5
- package/src/shade/playground/particle_ecs/bonfire_effects.js +5 -5
- package/src/shade/playground/particle_ecs/effects/smoke.json +1859 -1859
- package/src/shade/playground/particle_ecs/effects/soot.json +1605 -1605
- package/src/shade/playground/particle_system/README.md +1 -2
- package/src/shade/playground/profile_hotkey.d.ts.map +1 -1
- package/src/shade/playground/profile_hotkey.js +4 -40
- package/src/shade/playground/skinned_blas_refit/main.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/main.js +4 -39
- package/src/shade/playground/volumetrics_froxel/main.d.ts.map +1 -1
- package/src/shade/playground/volumetrics_froxel/main.js +4 -39
- package/src/shade/playground/volumetrics_froxel/measure.d.ts.map +1 -1
- package/src/shade/playground/volumetrics_froxel/measure.js +2 -4
- package/src/shade/renderer/Renderer.d.ts +1 -1
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +3 -1
- package/src/shade/renderer/light/GPULightCollection.d.ts +9 -1
- package/src/shade/renderer/light/GPULightCollection.d.ts.map +1 -1
- package/src/shade/renderer/light/GPULightCollection.js +41 -0
- package/src/shade/renderer/light/environment/shader_project_environment_sh.d.ts +37 -0
- package/src/shade/renderer/light/environment/shader_project_environment_sh.d.ts.map +1 -0
- package/src/shade/renderer/light/environment/shader_project_environment_sh.js +105 -0
- package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
- package/src/shade/renderer/particles/DESIGN.md +65 -8
- package/src/shade/renderer/particles/GPUParticleSystem.d.ts +7 -1
- package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
- package/src/shade/renderer/particles/GPUParticleSystem.js +1247 -1244
- package/src/shade/renderer/particles/graph_particles_avboit.d.ts +7 -1
- package/src/shade/renderer/particles/graph_particles_avboit.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph_particles_avboit.js +9 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_billboard_vertex.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/chunk_particle_billboard_vertex.js +4 -2
- package/src/shade/renderer/particles/shaders/chunk_particle_lighting.d.ts +15 -9
- package/src/shade/renderer/particles/shaders/chunk_particle_lighting.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/chunk_particle_lighting.js +29 -11
- package/src/shade/renderer/particles/shaders/chunk_particle_lighting_model.d.ts +24 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_lighting_model.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_lighting_model.js +45 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_render_math.d.ts +3 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_render_math.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/chunk_particle_render_math.js +38 -0
- package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.js +190 -185
- package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts +8 -0
- package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.js +5 -0
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts +8 -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 +9 -0
- package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts +13 -3
- package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +9 -1
- package/src/shade/renderer/volumetrics/chunk_volumetrics_irradiance_sh.d.ts +39 -0
- package/src/shade/renderer/volumetrics/chunk_volumetrics_irradiance_sh.d.ts.map +1 -0
- package/src/shade/renderer/volumetrics/chunk_volumetrics_irradiance_sh.js +107 -0
- package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_froxel_centre_ws.d.ts +15 -0
- package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_froxel_centre_ws.d.ts.map +1 -0
- package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_froxel_centre_ws.js +44 -0
- package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.d.ts +19 -0
- package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.d.ts.map +1 -0
- package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.js +48 -0
- package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.d.ts +29 -0
- package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.d.ts.map +1 -0
- package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.js +90 -0
- package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_brick4.d.ts +10 -0
- package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_brick4.d.ts.map +1 -0
- package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_brick4.js +55 -0
- package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_ibl.d.ts +10 -0
- package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_ibl.d.ts.map +1 -0
- package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_ibl.js +47 -0
- package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_lpv.d.ts +10 -0
- package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_lpv.d.ts.map +1 -0
- package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_lpv.js +63 -0
- package/src/shade/renderer/volumetrics/gi/volumetrics_gi_resources.d.ts +17 -0
- package/src/shade/renderer/volumetrics/gi/volumetrics_gi_resources.d.ts.map +1 -0
- package/src/shade/renderer/volumetrics/gi/volumetrics_gi_resources.js +26 -0
- package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts +8 -1
- package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +50 -2
- package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.js +488 -436
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts +1 -1
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +254 -63
|
@@ -134,6 +134,5 @@ and `camera_state()` / `apply_camera(...)` copy a view between sessions.
|
|
|
134
134
|
|
|
135
135
|
## What this page does not cover
|
|
136
136
|
|
|
137
|
-
|
|
138
|
-
lit-emitter variant would swap in. No emitter opts into simulation culling, so the frustum test in
|
|
137
|
+
No emitter here opts into `EMITTER_FLAG.LIGHTING`; the bonfire in `../particle_ecs/` does. No emitter opts into simulation culling, so the frustum test in
|
|
139
138
|
the tick pass is never taken here; the measured boxes are read by the occupancy pass all the same.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"profile_hotkey.d.ts","sourceRoot":"","sources":["../../../../src/shade/playground/profile_hotkey.js"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AAEH;;;;;GAKG;AAEH;;;;;;;;;;;;;;;GAeG;AACH;IAZ8D,QAAQ,EAA3D,OAAO,yBAAyB,EAAE,QAAQ;IAE3B,IAAI,EAAnB,MAAM;IACoB,MAAM,GAAhC,WAAW,GAAC,IAAI;IAEc,QAAQ,SAA1B,MAAM,EAAE;IAEJ,KAAK,GAArB,MAAM;IACU,GAAG,GAAnB,MAAM;IACe,MAAM,GAA3B,WAAW;IACT,mBAAmB,
|
|
1
|
+
{"version":3,"file":"profile_hotkey.d.ts","sourceRoot":"","sources":["../../../../src/shade/playground/profile_hotkey.js"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AAEH;;;;;GAKG;AAEH;;;;;;;;;;;;;;;GAeG;AACH;IAZ8D,QAAQ,EAA3D,OAAO,yBAAyB,EAAE,QAAQ;IAE3B,IAAI,EAAnB,MAAM;IACoB,MAAM,GAAhC,WAAW,GAAC,IAAI;IAEc,QAAQ,SAA1B,MAAM,EAAE;IAEJ,KAAK,GAArB,MAAM;IACU,GAAG,GAAnB,MAAM;IACe,MAAM,GAA3B,WAAW;IACT,mBAAmB,CAoM/B;;wBAvNyB,OAAO;;;;kBACP,QAAQ,IAAI,CAAC;;;;mBACb,IAAI"}
|
|
@@ -139,56 +139,20 @@ export function install_profile_hotkey({
|
|
|
139
139
|
);
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
-
/**
|
|
143
|
-
* Wait for frames already submitted to finish landing in the session.
|
|
144
|
-
*
|
|
145
|
-
* A frame is committed when its timestamp readback resolves — a `mapAsync` a frame or two behind
|
|
146
|
-
* submit, see `ShadeGPUCommandContext.profiling_absorbed` — and `record_frame` silently ignores
|
|
147
|
-
* anything arriving after `stop()`. Stopping the instant the key goes down therefore discards
|
|
148
|
-
* the last few frames, which are the ones you were most likely looking at.
|
|
149
|
-
*
|
|
150
|
-
* Drains the queue, then waits for the frame count to stop moving. Capped, because a recording
|
|
151
|
-
* taken while the page is paused never moves at all.
|
|
152
|
-
*
|
|
153
|
-
* @param {GPUProfileSession} recording
|
|
154
|
-
* @returns {Promise<void>}
|
|
155
|
-
*/
|
|
156
|
-
async function drain(recording) {
|
|
157
|
-
const DEADLINE_MS = 1000;
|
|
158
|
-
const QUIET_MS = 60;
|
|
159
|
-
|
|
160
|
-
await renderer.device.queue.onSubmittedWorkDone();
|
|
161
|
-
|
|
162
|
-
const deadline = performance.now() + DEADLINE_MS;
|
|
163
|
-
|
|
164
|
-
let previous = recording.frames_recorded;
|
|
165
|
-
|
|
166
|
-
while (performance.now() < deadline) {
|
|
167
|
-
await new Promise(resolve => setTimeout(resolve, QUIET_MS));
|
|
168
|
-
|
|
169
|
-
if (recording.frames_recorded === previous) {
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
previous = recording.frames_recorded;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
142
|
async function stop() {
|
|
178
143
|
const recording = session;
|
|
179
144
|
|
|
180
145
|
session = null;
|
|
181
146
|
|
|
182
|
-
// Detached first, so nothing encoded
|
|
183
|
-
//
|
|
147
|
+
// Detached first, so nothing encoded while the frames in flight land joins the recording.
|
|
148
|
+
// Those frames are unaffected: Renderer captures the session into a local before it
|
|
184
149
|
// subscribes to the readback.
|
|
185
150
|
renderer.profile_session = null;
|
|
186
151
|
|
|
187
152
|
set_status("stopping — draining in-flight frames…");
|
|
188
153
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
const bytes = recording.stop();
|
|
154
|
+
// resolves once the frames already submitted have landed, the last ones you were looking at
|
|
155
|
+
const bytes = await recording.stop();
|
|
192
156
|
const filename = `${name}-${file_timestamp()}.sgpt`;
|
|
193
157
|
|
|
194
158
|
download_bytes(bytes, filename);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../../../src/shade/playground/skinned_blas_refit/main.js"],"names":[],"mappings":"AAwQA;;;;;GAKG;AACH,yBAFa,QAAQ,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../../../src/shade/playground/skinned_blas_refit/main.js"],"names":[],"mappings":"AAwQA;;;;;GAKG;AACH,yBAFa,QAAQ,IAAI,CAAC,CAoiBzB"}
|
|
@@ -702,55 +702,20 @@ export async function start() {
|
|
|
702
702
|
);
|
|
703
703
|
}
|
|
704
704
|
|
|
705
|
-
/**
|
|
706
|
-
* Wait for frames already submitted to finish landing in the session.
|
|
707
|
-
*
|
|
708
|
-
* A frame is committed when its timestamp readback resolves — a `mapAsync` a frame or two behind
|
|
709
|
-
* submit, see `ShadeGPUCommandContext.profiling_absorbed` — and `record_frame` silently ignores
|
|
710
|
-
* anything arriving after `stop()`. Stopping the instant the key goes down therefore discards
|
|
711
|
-
* the last few frames, which are the ones you were most likely looking at.
|
|
712
|
-
*
|
|
713
|
-
* Drains the queue, then waits for the frame count to stop moving. Capped, because a recording
|
|
714
|
-
* taken while the page is paused never moves at all.
|
|
715
|
-
*
|
|
716
|
-
* @param {GPUProfileSession} session
|
|
717
|
-
*/
|
|
718
|
-
async function drain_profile(session) {
|
|
719
|
-
const DEADLINE_MS = 1000;
|
|
720
|
-
const QUIET_MS = 60;
|
|
721
|
-
|
|
722
|
-
await renderer.device.queue.onSubmittedWorkDone();
|
|
723
|
-
|
|
724
|
-
const deadline = performance.now() + DEADLINE_MS;
|
|
725
|
-
|
|
726
|
-
let previous = session.frames_recorded;
|
|
727
|
-
|
|
728
|
-
while (performance.now() < deadline) {
|
|
729
|
-
await new Promise(resolve => setTimeout(resolve, QUIET_MS));
|
|
730
|
-
|
|
731
|
-
if (session.frames_recorded === previous) {
|
|
732
|
-
return;
|
|
733
|
-
}
|
|
734
|
-
|
|
735
|
-
previous = session.frames_recorded;
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
|
|
739
705
|
async function stop_profile() {
|
|
740
706
|
const session = profile_session;
|
|
741
707
|
|
|
742
708
|
profile_session = null;
|
|
743
709
|
|
|
744
|
-
//
|
|
745
|
-
//
|
|
710
|
+
// Detached first, so nothing encoded while the frames in flight land joins the recording.
|
|
711
|
+
// Those frames are unaffected: Renderer captures the session into a local before it
|
|
746
712
|
// subscribes to the readback.
|
|
747
713
|
renderer.profile_session = null;
|
|
748
714
|
|
|
749
715
|
set_profile_status('stopping — draining in-flight frames…');
|
|
750
716
|
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
const bytes = session.stop();
|
|
717
|
+
// resolves once the frames already submitted have landed, the last ones you were looking at
|
|
718
|
+
const bytes = await session.stop();
|
|
754
719
|
|
|
755
720
|
const filename = `skinned_blas_refit-${file_timestamp()}.sgpt`;
|
|
756
721
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../../../src/shade/playground/volumetrics_froxel/main.js"],"names":[],"mappings":"AA2aA,
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../../../src/shade/playground/volumetrics_froxel/main.js"],"names":[],"mappings":"AA2aA,uCA8dC"}
|
|
@@ -766,55 +766,20 @@ export async function start() {
|
|
|
766
766
|
);
|
|
767
767
|
}
|
|
768
768
|
|
|
769
|
-
/**
|
|
770
|
-
* Wait for frames already submitted to finish landing in the session.
|
|
771
|
-
*
|
|
772
|
-
* A frame is committed when its timestamp readback resolves — a `mapAsync` a frame or two behind
|
|
773
|
-
* submit, see `ShadeGPUCommandContext.profiling_absorbed` — and `record_frame` silently ignores
|
|
774
|
-
* anything arriving after `stop()`. Stopping the instant the key goes down therefore discards
|
|
775
|
-
* the last few frames, which are the ones you were most likely looking at.
|
|
776
|
-
*
|
|
777
|
-
* Drains the queue, then waits for the frame count to stop moving. Capped, because a recording
|
|
778
|
-
* taken while the page is paused never moves at all.
|
|
779
|
-
*
|
|
780
|
-
* @param {GPUProfileSession} session
|
|
781
|
-
*/
|
|
782
|
-
async function drain_profile(session) {
|
|
783
|
-
const DEADLINE_MS = 1000;
|
|
784
|
-
const QUIET_MS = 60;
|
|
785
|
-
|
|
786
|
-
await renderer.device.queue.onSubmittedWorkDone();
|
|
787
|
-
|
|
788
|
-
const deadline = performance.now() + DEADLINE_MS;
|
|
789
|
-
|
|
790
|
-
let previous = session.frames_recorded;
|
|
791
|
-
|
|
792
|
-
while (performance.now() < deadline) {
|
|
793
|
-
await new Promise(resolve => setTimeout(resolve, QUIET_MS));
|
|
794
|
-
|
|
795
|
-
if (session.frames_recorded === previous) {
|
|
796
|
-
return;
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
previous = session.frames_recorded;
|
|
800
|
-
}
|
|
801
|
-
}
|
|
802
|
-
|
|
803
769
|
async function stop_profile() {
|
|
804
770
|
const session = profile_session;
|
|
805
771
|
|
|
806
772
|
profile_session = null;
|
|
807
773
|
|
|
808
|
-
//
|
|
809
|
-
//
|
|
774
|
+
// Detached first, so nothing encoded while the frames in flight land joins the recording.
|
|
775
|
+
// Those frames are unaffected: Renderer captures the session into a local before it
|
|
810
776
|
// subscribes to the readback.
|
|
811
777
|
renderer.profile_session = null;
|
|
812
778
|
|
|
813
779
|
set_profile_status('stopping — draining in-flight frames…');
|
|
814
780
|
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
const bytes = session.stop();
|
|
781
|
+
// resolves once the frames already submitted have landed, the last ones you were looking at
|
|
782
|
+
const bytes = await session.stop();
|
|
818
783
|
|
|
819
784
|
const filename = `volumetrics_froxel-${file_timestamp()}.sgpt`;
|
|
820
785
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"measure.d.ts","sourceRoot":"","sources":["../../../../../src/shade/playground/volumetrics_froxel/measure.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH;;;;;;GAMG;AACH;IAL8B,QAAQ;IACX,KAAK;IACO,MAAM;IACA,UAAU;;;;;;;;;;UAuLtC,QAAQ,YAAY,CAAC;;;;;gCA5DvB,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA4MV,QAAQ,MAAM,EAAE,CAAC;;;;;;;;;;;;;QAsGF,MAAM,GAAvB,MAAM;QACW,MAAM,GAAvB,MAAM;UACJ;YAAe,MAAM,GAAE,MAAM;MAAE;;
|
|
1
|
+
{"version":3,"file":"measure.d.ts","sourceRoot":"","sources":["../../../../../src/shade/playground/volumetrics_froxel/measure.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH;;;;;;GAMG;AACH;IAL8B,QAAQ;IACX,KAAK;IACO,MAAM;IACA,UAAU;;;;;;;;;;UAuLtC,QAAQ,YAAY,CAAC;;;;;gCA5DvB,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA4MV,QAAQ,MAAM,EAAE,CAAC;;;;;;;;;;;;;QAsGF,MAAM,GAAvB,MAAM;QACW,MAAM,GAAvB,MAAM;UACJ;YAAe,MAAM,GAAE,MAAM;MAAE;;GAoF/C"}
|
|
@@ -495,10 +495,8 @@ export async function attach({
|
|
|
495
495
|
|
|
496
496
|
renderer.profile_session = null;
|
|
497
497
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
const bytes = session.stop();
|
|
498
|
+
// resolves once the frames already submitted have landed
|
|
499
|
+
const bytes = await session.stop();
|
|
502
500
|
|
|
503
501
|
const buffer = bytes instanceof ArrayBuffer
|
|
504
502
|
? bytes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Renderer.d.ts","sourceRoot":"","sources":["../../../../src/shade/renderer/Renderer.js"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"Renderer.d.ts","sourceRoot":"","sources":["../../../../src/shade/renderer/Renderer.js"],"names":[],"mappings":"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"}
|
|
@@ -668,7 +668,7 @@ export class Renderer {
|
|
|
668
668
|
* renderer.profile_session = session;
|
|
669
669
|
* session.start();
|
|
670
670
|
* // ... frames ...
|
|
671
|
-
* const bytes = session.stop();
|
|
671
|
+
* const bytes = await session.stop();
|
|
672
672
|
* renderer.profile_session = null;
|
|
673
673
|
* ```
|
|
674
674
|
*
|
|
@@ -2433,6 +2433,7 @@ export class Renderer {
|
|
|
2433
2433
|
light_cluster_lookup: light_clusters.lookup,
|
|
2434
2434
|
light_cluster_parameters: light_clusters.parameters,
|
|
2435
2435
|
shadowmap_atlas: gr_shadowmap_atlas,
|
|
2436
|
+
indirect_lighting_mode: this.indirect_lighting_mode,
|
|
2436
2437
|
});
|
|
2437
2438
|
|
|
2438
2439
|
/**
|
|
@@ -2687,6 +2688,7 @@ export class Renderer {
|
|
|
2687
2688
|
|
|
2688
2689
|
volumetrics_lut: volumetrics.resolved,
|
|
2689
2690
|
volumetrics_metadata: volumetrics.metadata,
|
|
2691
|
+
volumetrics_irradiance: volumetrics.irradiance,
|
|
2690
2692
|
|
|
2691
2693
|
indirect_lighting_mode: this.indirect_lighting_mode,
|
|
2692
2694
|
avboit: this.avboit,
|
|
@@ -42,7 +42,15 @@ export class GPULightCollection {
|
|
|
42
42
|
* @returns {GPUTextureContext}
|
|
43
43
|
*/
|
|
44
44
|
get environment(): GPUTextureContext;
|
|
45
|
-
|
|
45
|
+
/**
|
|
46
|
+
* The environment's radiance as RGB SH2 (`ENVIRONMENT_SH_TYPE`), the form the renderer's probe-based
|
|
47
|
+
* indirect lighting hands over too: what the froxel GI stage starts the froxel irradiance volume
|
|
48
|
+
* with under IBL. Zero while there is no environment, as {@link environment} is black then.
|
|
49
|
+
*
|
|
50
|
+
* @returns {GPUBuffer}
|
|
51
|
+
*/
|
|
52
|
+
get environment_sh(): GPUBuffer;
|
|
53
|
+
get gpu_memory_usage(): any;
|
|
46
54
|
/**
|
|
47
55
|
*
|
|
48
56
|
* @param {GraphicsContext} ctx
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GPULightCollection.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/light/GPULightCollection.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"GPULightCollection.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/light/GPULightCollection.js"],"names":[],"mappings":"AA2CA;IAmJI;;;;;;OAMG;IACH,sBALW,eAAe,aACf,eAAe,EAqCzB;IApLD;;;OAGG;IACH,6DAEC;IAeD;;OAEG;IACH,4BAEC;IAED;;;;;;OAMG;IACH,6BAEC;IAED;;;;;;;OAOG;IACH,qFAEC;IAWD;;OAEG;IACH,+CAEC;IAgDD;;;OAGG;IACH,qCAEC;IAED;;;;;;OAMG;IACH,gCAEC;IAGD,4BAKC;IAgID;;;OAGG;IACH,YAFW,eAAe,QA8BzB;IAED;;;;;;;;;OASG;IACH,gBAFW,OAAO,+BAA+B,EAAE,YAAY,QAkC9D;IAED;;;;;;OAMG;IACH,uBAHW,sBAAsB,mCAyBhC;IAwED,gBASC;;CACJ;8BAneY,OAAO,uBAAuB,EAAE,eAAe;8BAC/C,OAAO,6BAA6B,EAAE,eAAe;8BACrD,OAAO,sBAAsB,EAAE,eAAe;4BArB/B,gCAAgC;yCACnB,2CAA2C;kCAClD,iCAAiC;uCAH5B,wCAAwC"}
|
|
@@ -7,6 +7,7 @@ import { GPUTextureContext } from "../texture/GPUTextureContext.js";
|
|
|
7
7
|
import { texture_mip_level_count } from "../../util/texture_mip_extent.js";
|
|
8
8
|
import { texture_write_to_gpu } from "../texture/texture_write_to_gpu.js";
|
|
9
9
|
import { execute_filter_environment_map } from "./environment/execute_filter_environment_map.js";
|
|
10
|
+
import { ENVIRONMENT_SH_TYPE, shader_project_environment_sh } from "./environment/shader_project_environment_sh.js";
|
|
10
11
|
import { LIGHT_DATABASE_SPEC } from "./LIGHT_DATABASE_SPEC.js";
|
|
11
12
|
import { light_record_directional } from "./model/io/light_record_directional.js";
|
|
12
13
|
import { light_record_point } from "./model/io/light_record_point.js";
|
|
@@ -152,6 +153,13 @@ export class GPULightCollection {
|
|
|
152
153
|
*/
|
|
153
154
|
#environment_source;
|
|
154
155
|
|
|
156
|
+
/**
|
|
157
|
+
* The environment's radiance as RGB SH2, projected from {@link #environment} whenever it changes;
|
|
158
|
+
* see {@link shader_project_environment_sh}.
|
|
159
|
+
* @type {GPUBuffer}
|
|
160
|
+
*/
|
|
161
|
+
#environment_sh;
|
|
162
|
+
|
|
155
163
|
|
|
156
164
|
/**
|
|
157
165
|
*
|
|
@@ -161,9 +169,21 @@ export class GPULightCollection {
|
|
|
161
169
|
return this.#environment;
|
|
162
170
|
}
|
|
163
171
|
|
|
172
|
+
/**
|
|
173
|
+
* The environment's radiance as RGB SH2 (`ENVIRONMENT_SH_TYPE`), the form the renderer's probe-based
|
|
174
|
+
* indirect lighting hands over too: what the froxel GI stage starts the froxel irradiance volume
|
|
175
|
+
* with under IBL. Zero while there is no environment, as {@link environment} is black then.
|
|
176
|
+
*
|
|
177
|
+
* @returns {GPUBuffer}
|
|
178
|
+
*/
|
|
179
|
+
get environment_sh() {
|
|
180
|
+
return this.#environment_sh;
|
|
181
|
+
}
|
|
182
|
+
|
|
164
183
|
|
|
165
184
|
get gpu_memory_usage() {
|
|
166
185
|
return this.#environment.gpu_memory_usage
|
|
186
|
+
+ this.#environment_sh.size
|
|
167
187
|
+ this.#database.gpu_memory_usage
|
|
168
188
|
;
|
|
169
189
|
}
|
|
@@ -194,6 +214,13 @@ export class GPULightCollection {
|
|
|
194
214
|
| GPUTextureUsage.STORAGE_BINDING // so we can convolve it in compute shader
|
|
195
215
|
;
|
|
196
216
|
|
|
217
|
+
// zeroed on creation, which is what an absent environment projects to
|
|
218
|
+
this.#environment_sh = device.createBuffer({
|
|
219
|
+
label: "environment SH",
|
|
220
|
+
size: ENVIRONMENT_SH_TYPE.size,
|
|
221
|
+
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
|
|
222
|
+
});
|
|
223
|
+
|
|
197
224
|
this.#database = new GPUDatabase({
|
|
198
225
|
device,
|
|
199
226
|
label: 'Light Collection / Database',
|
|
@@ -236,6 +263,9 @@ export class GPULightCollection {
|
|
|
236
263
|
|
|
237
264
|
gpu_ctx.allocate();
|
|
238
265
|
|
|
266
|
+
// what a black environment projects to; nothing to run the projection over
|
|
267
|
+
this.#device.queue.writeBuffer(this.#environment_sh, 0, new Float32Array(this.#environment_sh.size / 4));
|
|
268
|
+
|
|
239
269
|
return;
|
|
240
270
|
}
|
|
241
271
|
|
|
@@ -271,6 +301,16 @@ export class GPULightCollection {
|
|
|
271
301
|
|
|
272
302
|
execute_filter_environment_map(gpu_ctx, cmd);
|
|
273
303
|
|
|
304
|
+
// after the prefilter, whose roughest levels are what it reads
|
|
305
|
+
shader_project_environment_sh.dispatch({
|
|
306
|
+
encoder: cmd,
|
|
307
|
+
group_count_x: 1,
|
|
308
|
+
bindings: {
|
|
309
|
+
tEnvironment: gpu_ctx.obtainView(),
|
|
310
|
+
output: this.#environment_sh,
|
|
311
|
+
},
|
|
312
|
+
});
|
|
313
|
+
|
|
274
314
|
cmd.finish();
|
|
275
315
|
}
|
|
276
316
|
|
|
@@ -461,5 +501,6 @@ export class GPULightCollection {
|
|
|
461
501
|
this.#shadow_context.destroy();
|
|
462
502
|
this.#database.destroy();
|
|
463
503
|
this.#environment.destroy();
|
|
504
|
+
this.#environment_sh.destroy();
|
|
464
505
|
}
|
|
465
506
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The layout {@link shader_project_environment_sh} writes: the environment's radiance as RGB SH2,
|
|
3
|
+
* coefficient `k` in `.xyz` of element `k`, ordered `[DC, y, z, x]` in the project's all-positive
|
|
4
|
+
* basis (`sh2_basis_at`); `.w` is unused. Radiance, not cosine-convolved — the convention the probes
|
|
5
|
+
* of Brick4 and of the light probe volume are stored in — so `sh2_color_get_irradiance_at` turns it
|
|
6
|
+
* into the irradiance of a surface facing the direction evaluated at.
|
|
7
|
+
*
|
|
8
|
+
* @type {WebGPUArray}
|
|
9
|
+
*/
|
|
10
|
+
export const ENVIRONMENT_SH_TYPE: WebGPUArray;
|
|
11
|
+
/**
|
|
12
|
+
* Directions the projection samples, spread evenly over the sphere (`sphere_fibonacci_point`).
|
|
13
|
+
* The field is the environment at the roughness diffuse reads it at, so this is far more than its
|
|
14
|
+
* two bands can hold, and it costs nothing that recurs: the pass runs when the environment changes.
|
|
15
|
+
*
|
|
16
|
+
* @type {number}
|
|
17
|
+
*/
|
|
18
|
+
export const ENVIRONMENT_SH_SAMPLE_COUNT: number;
|
|
19
|
+
/**
|
|
20
|
+
* The environment as RGB SH2 of radiance ({@link ENVIRONMENT_SH_TYPE}): the form the renderer's other
|
|
21
|
+
* indirect lighting — Brick4, the light probe volume — already hands over, so the froxel GI stage
|
|
22
|
+
* (`volumetrics/gi/`) takes the environment as one more source of it. What the froxel irradiance
|
|
23
|
+
* volume is started with under IBL, and what a lit particle's ambient is there; reading the
|
|
24
|
+
* environment itself per pixel, as the forward mesh path does, cost 880 us of lighting's 1,090 us on
|
|
25
|
+
* the bonfire's overdraw at 1898x926 (RTX 4090).
|
|
26
|
+
*
|
|
27
|
+
* The field projected is the one the forward path reads (`get_ibl_irradiance`: the prefiltered map at
|
|
28
|
+
* roughness 1, times pi), and the radiance stored is what that field is the cosine convolution of, so
|
|
29
|
+
* convolving it back gives the forward path's diffuse up to what two bands drop. Run by
|
|
30
|
+
* `GPULightCollection` when the environment changes, after the prefilter it reads.
|
|
31
|
+
*
|
|
32
|
+
* @type {ComputeShader}
|
|
33
|
+
*/
|
|
34
|
+
export const shader_project_environment_sh: ComputeShader;
|
|
35
|
+
import { WebGPUArray } from "../../shader/type/WebGPUArray.js";
|
|
36
|
+
import { ComputeShader } from "../../shader/ComputeShader.js";
|
|
37
|
+
//# sourceMappingURL=shader_project_environment_sh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shader_project_environment_sh.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/light/environment/shader_project_environment_sh.js"],"names":[],"mappings":"AAUA;;;;;;;;GAQG;AACH,kCAFU,WAAW,CAEyC;AAE9D;;;;;;GAMG;AACH,0CAFU,MAAM,CAEgC;AAyDhD;;;;;;;;;;;;;;GAcG;AACH,4CAFU,aAAa,CAMpB;4BAjGyB,kCAAkC;8BAFhC,+BAA+B"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { chunk_get_ibl_irradiance } from "../../deferred/indirect/chunk_get_ibl_irradiance.js";
|
|
2
|
+
import { PI_DECLARATION } from "../../shader/chunk/math/PI_DECLARATION.js";
|
|
3
|
+
import { chunk_sphere_fibonacci_point } from "../../shader/chunk/geometry/sphere/chunk_sphere_fibonacci_point.js";
|
|
4
|
+
import { chunk_sh2_basis_at } from "../../shader/chunk/spherical_harmonics/chunk_sh2_basis_at.js";
|
|
5
|
+
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
6
|
+
import { ComputeShader } from "../../shader/ComputeShader.js";
|
|
7
|
+
import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
8
|
+
import { WebGPUArray } from "../../shader/type/WebGPUArray.js";
|
|
9
|
+
import { vec4f } from "../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The layout {@link shader_project_environment_sh} writes: the environment's radiance as RGB SH2,
|
|
13
|
+
* coefficient `k` in `.xyz` of element `k`, ordered `[DC, y, z, x]` in the project's all-positive
|
|
14
|
+
* basis (`sh2_basis_at`); `.w` is unused. Radiance, not cosine-convolved — the convention the probes
|
|
15
|
+
* of Brick4 and of the light probe volume are stored in — so `sh2_color_get_irradiance_at` turns it
|
|
16
|
+
* into the irradiance of a surface facing the direction evaluated at.
|
|
17
|
+
*
|
|
18
|
+
* @type {WebGPUArray}
|
|
19
|
+
*/
|
|
20
|
+
export const ENVIRONMENT_SH_TYPE = WebGPUArray.from(vec4f, 4);
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Directions the projection samples, spread evenly over the sphere (`sphere_fibonacci_point`).
|
|
24
|
+
* The field is the environment at the roughness diffuse reads it at, so this is far more than its
|
|
25
|
+
* two bands can hold, and it costs nothing that recurs: the pass runs when the environment changes.
|
|
26
|
+
*
|
|
27
|
+
* @type {number}
|
|
28
|
+
*/
|
|
29
|
+
export const ENVIRONMENT_SH_SAMPLE_COUNT = 1024;
|
|
30
|
+
|
|
31
|
+
const resources = new ShaderResourceSetDescriptor();
|
|
32
|
+
|
|
33
|
+
resources.createGroup()
|
|
34
|
+
// read texel by texel (texture_octahedral_sample_bilinear), as the forward path reads it
|
|
35
|
+
.addTexture("tEnvironment")
|
|
36
|
+
.addStorageBuffer("output", ENVIRONMENT_SH_TYPE, true);
|
|
37
|
+
|
|
38
|
+
const body = CodeChunk.from(
|
|
39
|
+
//language=WGSL
|
|
40
|
+
`
|
|
41
|
+
const SAMPLE_COUNT : u32 = ${ENVIRONMENT_SH_SAMPLE_COUNT}u;
|
|
42
|
+
|
|
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
|
+
var sh_0 = vec3<f32>(0.0);
|
|
48
|
+
var sh_1 = vec3<f32>(0.0);
|
|
49
|
+
var sh_2 = vec3<f32>(0.0);
|
|
50
|
+
var sh_3 = vec3<f32>(0.0);
|
|
51
|
+
|
|
52
|
+
for (var i = 0u; i < SAMPLE_COUNT; i++) {
|
|
53
|
+
let direction = sphere_fibonacci_point(f32(i), f32(SAMPLE_COUNT));
|
|
54
|
+
|
|
55
|
+
// exactly what the forward mesh path takes as a surface's diffuse irradiance under IBL
|
|
56
|
+
let irradiance = get_ibl_irradiance(direction);
|
|
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];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// each sample stands for an equal share of the sphere
|
|
67
|
+
let weight = 4.0 * PI / f32(SAMPLE_COUNT);
|
|
68
|
+
|
|
69
|
+
// What was projected is irradiance; what is stored is the radiance it is the cosine convolution
|
|
70
|
+
// of, band by band: the clamped cosine's zonal weights are pi for band 0 and 2 pi / 3 for band 1.
|
|
71
|
+
let band_0 = weight / PI;
|
|
72
|
+
let band_1 = weight * 3.0 / (2.0 * PI);
|
|
73
|
+
|
|
74
|
+
output[0] = vec4<f32>(sh_0 * band_0, 0.0);
|
|
75
|
+
output[1] = vec4<f32>(sh_1 * band_1, 0.0);
|
|
76
|
+
output[2] = vec4<f32>(sh_2 * band_1, 0.0);
|
|
77
|
+
output[3] = vec4<f32>(sh_3 * band_1, 0.0);
|
|
78
|
+
}
|
|
79
|
+
`, [
|
|
80
|
+
chunk_sphere_fibonacci_point,
|
|
81
|
+
chunk_get_ibl_irradiance,
|
|
82
|
+
chunk_sh2_basis_at,
|
|
83
|
+
PI_DECLARATION,
|
|
84
|
+
]);
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* The environment as RGB SH2 of radiance ({@link ENVIRONMENT_SH_TYPE}): the form the renderer's other
|
|
88
|
+
* indirect lighting — Brick4, the light probe volume — already hands over, so the froxel GI stage
|
|
89
|
+
* (`volumetrics/gi/`) takes the environment as one more source of it. What the froxel irradiance
|
|
90
|
+
* volume is started with under IBL, and what a lit particle's ambient is there; reading the
|
|
91
|
+
* environment itself per pixel, as the forward mesh path does, cost 880 us of lighting's 1,090 us on
|
|
92
|
+
* the bonfire's overdraw at 1898x926 (RTX 4090).
|
|
93
|
+
*
|
|
94
|
+
* The field projected is the one the forward path reads (`get_ibl_irradiance`: the prefiltered map at
|
|
95
|
+
* roughness 1, times pi), and the radiance stored is what that field is the cosine convolution of, so
|
|
96
|
+
* convolving it back gives the forward path's diffuse up to what two bands drop. Run by
|
|
97
|
+
* `GPULightCollection` when the environment changes, after the prefilter it reads.
|
|
98
|
+
*
|
|
99
|
+
* @type {ComputeShader}
|
|
100
|
+
*/
|
|
101
|
+
export const shader_project_environment_sh = ComputeShader.from({
|
|
102
|
+
label: "Environment / project SH",
|
|
103
|
+
resources,
|
|
104
|
+
body,
|
|
105
|
+
});
|
|
@@ -13,7 +13,7 @@ export class TinyGltf {
|
|
|
13
13
|
* @readonly
|
|
14
14
|
* @type {TextureFormat}
|
|
15
15
|
*/
|
|
16
|
-
static readonly "__#
|
|
16
|
+
static readonly "__#254@#UNCOMPRESSED_TARGET": TextureFormat;
|
|
17
17
|
/**
|
|
18
18
|
* @param {AssetManager} assetManager
|
|
19
19
|
* @param {AssetRequestScope} [scope]
|
|
@@ -21,7 +21,8 @@ rows, and the decision to spawn is the GPU's.
|
|
|
21
21
|
- Scene / bone attachment: an emitter stands at an entity with a row; its world matrix is that row
|
|
22
22
|
of the scene's `transforms` table, composed by the GPU hierarchy pass.
|
|
23
23
|
- Distinct per-particle lifecycle: **no** built-in age/position — the schema + program define state.
|
|
24
|
-
-
|
|
24
|
+
- Lighting per emitter (`EMITTER_FLAG.LIGHTING`): the scene's lights from the froxel irradiance
|
|
25
|
+
volume the fog pass writes, plus the environment map. See "Lighting" below.
|
|
25
26
|
- Blend modes (alpha + additive) via a **single** premultiplied blend setup.
|
|
26
27
|
- Authored curves and RGB/RGBA gradients compiled into arithmetic for simulation.
|
|
27
28
|
- Spawning decided on the GPU, per emitter, with the CPU able to ask for bursts through the same path.
|
|
@@ -516,10 +517,9 @@ draw's.
|
|
|
516
517
|
### Rendering
|
|
517
518
|
|
|
518
519
|
A 6-vertex quad is expanded per instance (billboard/velocity-stretch/axis-lock/world modes) by
|
|
519
|
-
`chunk_particle_billboard_vertex`. Fragment: sample atlas (region + flipbook frame), optional
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
alpha scaled before premultiplication.
|
|
520
|
+
`chunk_particle_billboard_vertex`. Fragment: sample atlas (region + flipbook frame), optional
|
|
521
|
+
soft-depth fade, optional lighting (below). Soft-depth fading scales both RGB and alpha for
|
|
522
|
+
premultiplied inputs; straight-alpha and additive inputs have alpha scaled before premultiplication.
|
|
523
523
|
|
|
524
524
|
Additive vs. alpha is never a pipeline switch: the shader emits premultiplied RGB with alpha 0
|
|
525
525
|
(additive) or alpha a (normal), so one setup covers both and the choice stays per particle and
|
|
@@ -778,6 +778,63 @@ was seeded.
|
|
|
778
778
|
|
|
779
779
|
Done: `Renderer.feature_particles_enabled` (off by default), `Renderer.particles(scene_ctx)` creating
|
|
780
780
|
one system per scene context on first use, `simulate` recorded before the transparency pass and the
|
|
781
|
-
system passed to the AVBOIT orchestrator as its side channel.
|
|
782
|
-
|
|
783
|
-
|
|
781
|
+
system passed to the AVBOIT orchestrator as its side channel.
|
|
782
|
+
|
|
783
|
+
### Lighting
|
|
784
|
+
|
|
785
|
+
An emitter flagged `EMITTER_FLAG.LIGHTING` treats its colour as a diffuse albedo; an emitter without
|
|
786
|
+
it is its own colour, which is what additive (emissive) emitters want and stay. The flag is read per
|
|
787
|
+
fragment from the emitter record, so lit and unlit particles share one pipeline and one draw. All of
|
|
788
|
+
it is evaluated per pixel (`chunk_particle_lighting`, the model in `chunk_particle_lighting_model`):
|
|
789
|
+
a vertex need not be on screen, and one quad can span the frustum.
|
|
790
|
+
|
|
791
|
+
- **Direct light comes from the froxel irradiance volume** (`volumetrics/chunk_volumetrics_irradiance_sh`),
|
|
792
|
+
which `shader_volumetrics_build_lighting` writes in the loop that lights the fog: every
|
|
793
|
+
directional, point and spot light at the froxel, shadowed, attenuated by the fog toward it, stored
|
|
794
|
+
as luma SH2 + constant chroma (Metro's L1 YCoCg, 6 coefficients in two `rgba16float` volumes, since
|
|
795
|
+
`rg16float` is not a storage format without `texture-formats-tier1`). The volume rides the
|
|
796
|
+
orchestrator to side channels as `volumetrics_irradiance`. Resolution is the fog's — 16 px tiles
|
|
797
|
+
and 64 slices — so light and shadow edges inside a particle are soft. idTech 8 builds the same
|
|
798
|
+
volume in the same pass (Sousa, SIGGRAPH 2025, p.29); Ghost of Tsushima lights particles from its
|
|
799
|
+
haze grid the same way. Chosen over per-pixel forward shading (UE's most expensive mode, and a
|
|
800
|
+
flat card lit that way goes black from behind), per-vertex/per-particle lighting (the light
|
|
801
|
+
clusters are screen-space: a point off screen has no light list, the artefact that moved idTech 8
|
|
802
|
+
off it) and a per-particle lighting atlas (DOOM 2016, CoD IW: best-looking, but it needs a
|
|
803
|
+
world-space light lookup this engine does not have).
|
|
804
|
+
- **The SH is evaluated at the normal and the irradiance clamped at zero.** One light gives
|
|
805
|
+
`E max(0, 1/4 + cos/2)`. SH2 cannot keep two lights apart: a light's lobe is `-E/4` facing away
|
|
806
|
+
from it, so a light behind a particle subtracts from the ones in front before the clamp sees a
|
|
807
|
+
total. Measured on the bonfire before transmission, the moon behind the smoke brought the fire-lit
|
|
808
|
+
side down to about half (display red 10 against 21).
|
|
809
|
+
- **Chroma has no direction**: two lights of different colours from opposite sides tint both sides
|
|
810
|
+
their mix. Measured on the bonfire, the blue moon moves the fire-lit underside of the smoke from
|
|
811
|
+
(22.9, 5.3, 1.5) to (15.9, 4.7, 2.6) in display values; a same-coloured moon only brightens it.
|
|
812
|
+
- **Indirect light is in the same volume**, whatever the renderer's `indirect_lighting_mode`. The
|
|
813
|
+
froxel GI stage (`volumetrics/gi/`) starts the volume with one concrete module per mode — IBL,
|
|
814
|
+
Brick4, LPV — each asking its source what radiance arrives at the froxel's centre, as RGB SH2,
|
|
815
|
+
and `shader_volumetrics_build_lighting` adds the lights to that. The particle knows no mode: a new
|
|
816
|
+
GI system is one more module. IBL's source is `GPULightCollection.environment_sh`, the
|
|
817
|
+
environment projected to radiance SH2 when it changes (`shader_project_environment_sh`); Brick4
|
|
818
|
+
interpolates its probes (SH3, truncated) with a zero normal, which weighs every probe of the
|
|
819
|
+
brick alike; LPV interpolates the tetrahedron the froxel falls in, and gives nothing outside the
|
|
820
|
+
mesh, as the deferred LPV pass does. Measured at 1898x926 (RTX 4090): the IBL module 5-6 us, the
|
|
821
|
+
Brick4 module 31 us over an empty map. Reading the environment per pixel instead, as the forward
|
|
822
|
+
mesh path does, had been 880 us of lighting's 1,090 us — the particle draw is all overdraw.
|
|
823
|
+
- **Back-face transmission** (Persson, "Practical Particle Lighting", GDC 2012, pp.34-37): the same
|
|
824
|
+
light evaluated at `-normal`, passed on in proportion to `1 - alpha`. The dense core of a puff
|
|
825
|
+
holds light from behind back and its thin edges let it through — smoke backlit by the moon has an
|
|
826
|
+
edge instead of being black. It costs nothing measurable: the draw is bound by its texture reads.
|
|
827
|
+
- **The normal** is the quad's own plane per projection mode, turned to the side the eye is on and
|
|
828
|
+
bent out toward the corners (`particle_billboard_normal`), so a sprite shades as a puff.
|
|
829
|
+
- **The directional light skips the atmosphere's transmittance** the fog applies: meshes are lit by
|
|
830
|
+
`sun.color` as it stands, and a lit particle has to agree with the surface beside it.
|
|
831
|
+
|
|
832
|
+
Cost, bonfire (~1,300 live, smoke and soot lit), RTX 4090, lit minus unlit p10 in one page: the
|
|
833
|
+
draw +90..275 us at 1898x926 (of ~450) across runs, +0.8..1.2 ms at 3818x2006 (of ~2.1 ms). The fog pass does
|
|
834
|
+
not get slower for the two extra stores — paired against the tree before it, it measured 77 vs 89 us
|
|
835
|
+
and 280 vs 320 us, reason not established. The volume has no temporal filter of its own: with the
|
|
836
|
+
simulation frozen, lit and unlit smoke change equally from frame to frame even with the screen TAA
|
|
837
|
+
off (0.09 vs 0.09 mean display units). That scene has no shadow edge through the smoke, which is
|
|
838
|
+
where a one-sample-per-froxel volume would show it first.
|
|
839
|
+
|
|
840
|
+
Open: a particle does not shade the fog or other particles (the volume holds no particle density).
|