@woosh/meep-engine 3.14.6 → 3.15.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/network/orchestrator/ServerAuthoritativeClient.d.ts +48 -0
- package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts.map +1 -1
- package/src/engine/network/orchestrator/ServerAuthoritativeClient.js +246 -3
- package/src/shade/RENDERER_CONTRACT.md +584 -580
- package/src/shade/playground/avboit/README.md +117 -0
- package/src/shade/playground/avboit/index.html +215 -0
- package/src/shade/playground/avboit/main.d.ts +2 -0
- package/src/shade/playground/avboit/main.d.ts.map +1 -0
- package/src/shade/playground/avboit/main.js +875 -0
- package/src/shade/renderer/Renderer.d.ts +16 -0
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +29 -28
- package/src/shade/renderer/ShadeTransparencyMode.d.ts +13 -0
- package/src/shade/renderer/ShadeTransparencyMode.d.ts.map +1 -0
- package/src/shade/renderer/ShadeTransparencyMode.js +30 -0
- package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.d.ts +9 -0
- package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.d.ts.map +1 -1
- package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.js +26 -0
- package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts +7 -2
- package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +12 -1
- package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.js +1 -1
- package/src/shade/renderer/rasterize/forward/FORWARD_VERTEX_SHADER_STRUCT.d.ts +3 -0
- package/src/shade/renderer/rasterize/forward/FORWARD_VERTEX_SHADER_STRUCT.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/{native/oit → forward}/FORWARD_VERTEX_SHADER_STRUCT.js +4 -4
- package/src/shade/renderer/rasterize/forward/SHADING_SCENE_RESOURCE_GROUP.d.ts +3 -0
- package/src/shade/renderer/rasterize/forward/SHADING_SCENE_RESOURCE_GROUP.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/forward/SHADING_SCENE_RESOURCE_GROUP.js +17 -0
- package/src/shade/renderer/rasterize/{native/oit → forward}/chunk_forward_shade_standard_fragment_brick4.d.ts +1 -1
- package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/{native/oit → forward}/chunk_forward_shade_standard_fragment_brick4.js +16 -16
- package/src/shade/renderer/rasterize/{native/oit → forward}/chunk_forward_shade_standard_fragment_ibl.d.ts +1 -1
- package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/{native/oit → forward}/chunk_forward_shade_standard_fragment_ibl.js +17 -17
- package/src/shade/renderer/rasterize/{native/oit → forward}/chunk_material_side_should_draw.d.ts +1 -1
- package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/{native/oit → forward}/chunk_material_side_should_draw.js +2 -2
- package/src/shade/renderer/rasterize/forward/vertex_shader_chunk.d.ts +3 -0
- package/src/shade/renderer/rasterize/forward/vertex_shader_chunk.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/{native/oit → forward}/vertex_shader_chunk.js +4 -4
- package/src/shade/renderer/rasterize/native/avboit/AVBOITSettings.d.ts +27 -0
- package/src/shade/renderer/rasterize/native/avboit/AVBOITSettings.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/AVBOITSettings.js +27 -0
- package/src/shade/renderer/rasterize/native/avboit/AVBOIT_CONSTANTS.d.ts +107 -0
- package/src/shade/renderer/rasterize/native/avboit/AVBOIT_CONSTANTS.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/AVBOIT_CONSTANTS.js +120 -0
- package/src/shade/renderer/rasterize/native/avboit/AVBOIT_LEDGER.md +463 -0
- package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +509 -0
- package/src/shade/renderer/rasterize/native/avboit/AVBOIT_WARP_STRUCT.d.ts +15 -0
- package/src/shade/renderer/rasterize/native/avboit/AVBOIT_WARP_STRUCT.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/AVBOIT_WARP_STRUCT.js +33 -0
- package/src/shade/renderer/rasterize/native/avboit/avboit_build_depth_curve.d.ts +20 -0
- package/src/shade/renderer/rasterize/native/avboit/avboit_build_depth_curve.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/avboit_build_depth_curve.js +38 -0
- package/src/shade/renderer/rasterize/native/avboit/avboit_draw_fragment_body.d.ts +38 -0
- package/src/shade/renderer/rasterize/native/avboit/avboit_draw_fragment_body.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/avboit_draw_fragment_body.js +130 -0
- package/src/shade/renderer/rasterize/native/avboit/avboit_spec_support.d.ts +37 -0
- package/src/shade/renderer/rasterize/native/avboit/avboit_spec_support.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/avboit_spec_support.js +73 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_counts_to_extinction.d.ts +9 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_counts_to_extinction.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_counts_to_extinction.js +17 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_dilate_word.d.ts +11 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_dilate_word.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_dilate_word.js +18 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_extinction_to_counts.d.ts +9 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_extinction_to_counts.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_extinction_to_counts.js +17 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_extinction_to_transmittance.d.ts +9 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_extinction_to_transmittance.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_extinction_to_transmittance.js +17 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_fold_pairs.d.ts +15 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_fold_pairs.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_fold_pairs.js +25 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_integral_depth_coordinate.d.ts +17 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_integral_depth_coordinate.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_integral_depth_coordinate.js +35 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_occupancy_range.d.ts +11 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_occupancy_range.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_occupancy_range.js +21 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_occupancy_word_mask.d.ts +9 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_occupancy_word_mask.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_occupancy_word_mask.js +26 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_overflows.d.ts +11 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_overflows.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_overflows.js +22 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_pack_counts.d.ts +10 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_pack_counts.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_pack_counts.js +21 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_sample_transmittance.d.ts +10 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_sample_transmittance.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_sample_transmittance.js +32 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_transmission_tint.d.ts +20 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_transmission_tint.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_transmission_tint.js +27 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_transmittance_to_extinction.d.ts +10 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_transmittance_to_extinction.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_transmittance_to_extinction.js +18 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_unpack_counts.d.ts +9 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_unpack_counts.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_unpack_counts.js +21 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_view_depth_to_physical.d.ts +9 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_view_depth_to_physical.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_view_depth_to_physical.js +23 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_view_depth_to_virtual.d.ts +13 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_view_depth_to_virtual.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_view_depth_to_virtual.js +27 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_warp.d.ts +22 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_warp.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_warp.js +38 -0
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts +117 -0
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +935 -0
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_build_warp.d.ts +8 -0
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_build_warp.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_build_warp.js +135 -0
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_brick4.d.ts +3 -0
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_brick4.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_brick4.js +101 -0
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_ibl.d.ts +3 -0
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_ibl.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_ibl.js +96 -0
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_integrate.d.ts +3 -0
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_integrate.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_integrate.js +83 -0
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_occupancy.d.ts +9 -0
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_occupancy.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_occupancy.js +119 -0
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_resolve.d.ts +3 -0
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_resolve.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_resolve.js +81 -0
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.d.ts +15 -0
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.js +237 -0
- package/src/shade/renderer/rasterize/native/material_draw_indirect.d.ts +22 -0
- package/src/shade/renderer/rasterize/native/material_draw_indirect.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/material_draw_indirect.js +69 -0
- package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +665 -722
- package/src/shade/renderer/rasterize/native/oit/shader_oit_generate_moments.js +3 -3
- package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments.js +4 -4
- package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments_ibl.js +4 -4
- package/src/shade/renderer/rasterize/native/oit/FORWARD_VERTEX_SHADER_STRUCT.d.ts +0 -3
- package/src/shade/renderer/rasterize/native/oit/FORWARD_VERTEX_SHADER_STRUCT.d.ts.map +0 -1
- package/src/shade/renderer/rasterize/native/oit/SHADING_SCENE_RESOURCE_GROUP.d.ts +0 -3
- package/src/shade/renderer/rasterize/native/oit/SHADING_SCENE_RESOURCE_GROUP.d.ts.map +0 -1
- package/src/shade/renderer/rasterize/native/oit/SHADING_SCENE_RESOURCE_GROUP.js +0 -17
- package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_brick4.d.ts.map +0 -1
- package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_ibl.d.ts.map +0 -1
- package/src/shade/renderer/rasterize/native/oit/chunk_material_side_should_draw.d.ts.map +0 -1
- package/src/shade/renderer/rasterize/native/oit/vertex_shader_chunk.d.ts +0 -3
- package/src/shade/renderer/rasterize/native/oit/vertex_shader_chunk.d.ts.map +0 -1
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-frame inputs of the warp build, all of which land in the warp header.
|
|
3
|
+
*/
|
|
4
|
+
export const AVBOIT_BUILD_WARP_SETTINGS_STRUCT: WebGPUStruct;
|
|
5
|
+
export const shader_avboit_build_warp: ComputeShader;
|
|
6
|
+
import { WebGPUStruct } from "../../../shader/type/WebGPUStruct.js";
|
|
7
|
+
import { ComputeShader } from "../../../shader/ComputeShader.js";
|
|
8
|
+
//# sourceMappingURL=shader_avboit_build_warp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shader_avboit_build_warp.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/rasterize/native/avboit/shader_avboit_build_warp.js"],"names":[],"mappings":"AAWA;;GAEG;AACH,6DAUqC;AA0GrC,qDAIG;6BApI0B,sCAAsC;8BAErC,kCAAkC"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { u32, vec3f } from "../../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
|
|
2
|
+
import { WebGPUArray } from "../../../shader/type/WebGPUArray.js";
|
|
3
|
+
import { WebGPUStruct } from "../../../shader/type/WebGPUStruct.js";
|
|
4
|
+
import { CodeChunk } from "../../../shader/compiler/CodeChunk.js";
|
|
5
|
+
import { ComputeShader } from "../../../shader/ComputeShader.js";
|
|
6
|
+
import { ShaderResourceSetDescriptor } from "../../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
7
|
+
import { AVBOIT_OCCUPANCY_WORDS, AVBOIT_VIRTUAL_SLICES_MAX } from "./AVBOIT_CONSTANTS.js";
|
|
8
|
+
import { AVBOIT_WARP_STRUCT } from "./AVBOIT_WARP_STRUCT.js";
|
|
9
|
+
import { chunk_avboit_dilate_word } from "./chunk_avboit_dilate_word.js";
|
|
10
|
+
import { chunk_avboit_fold_pairs } from "./chunk_avboit_fold_pairs.js";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Per-frame inputs of the warp build, all of which land in the warp header.
|
|
14
|
+
*/
|
|
15
|
+
export const AVBOIT_BUILD_WARP_SETTINGS_STRUCT = WebGPUStruct.from({
|
|
16
|
+
/** AVBOIT_PHYSICAL_SLICES */
|
|
17
|
+
physical_count: u32,
|
|
18
|
+
/** extinction volume XY resolution, copied into the warp header for the fragment shaders */
|
|
19
|
+
voxel_width: u32,
|
|
20
|
+
voxel_height: u32,
|
|
21
|
+
/** AVBOITSettings.transmission_tint_from_base_color as 0 / 1, copied into the header */
|
|
22
|
+
tint_from_base_color: u32,
|
|
23
|
+
/** the depth curve, see avboit_build_depth_curve */
|
|
24
|
+
cluster_parameters: vec3f,
|
|
25
|
+
}, "AVBOITBuildWarpSettings").pack();
|
|
26
|
+
|
|
27
|
+
const resources = new ShaderResourceSetDescriptor();
|
|
28
|
+
|
|
29
|
+
resources.createGroup()
|
|
30
|
+
.addUniform("settings", AVBOIT_BUILD_WARP_SETTINGS_STRUCT)
|
|
31
|
+
.addStorageBuffer("occupancy", WebGPUArray.from(u32, AVBOIT_OCCUPANCY_WORDS))
|
|
32
|
+
.addStorageBuffer("warp", AVBOIT_WARP_STRUCT, true)
|
|
33
|
+
;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* AVBOIT warp build: turns the finest-level occupancy bits into the depth-warp LUT (plan §3.4).
|
|
37
|
+
*
|
|
38
|
+
* One invocation does the whole thing. Per level: dilate by one slice each side at that level,
|
|
39
|
+
* count; if the count fits the physical budget, or the level is already down at the physical count,
|
|
40
|
+
* stop — otherwise halve the *undilated* bits by OR-ing adjacent pairs and go again. Dilation is
|
|
41
|
+
* applied fresh at each level rather than once at the finest, because a one-slice margin at 1024
|
|
42
|
+
* slices is a quarter of a slice at 256 and rounds away; the margin is what keeps a fragment on the
|
|
43
|
+
* edge of a meshlet's bounds from linear-splatting into a neighbouring run.
|
|
44
|
+
*
|
|
45
|
+
* The LUT is then an exclusive prefix count of the dilated bits, with the bit itself in the low
|
|
46
|
+
* position — see `AVBOIT_WARP_STRUCT`.
|
|
47
|
+
*
|
|
48
|
+
* Single-lane by design, not as a fallback: 32 words and at most three halvings is a few thousand
|
|
49
|
+
* bit operations, and staying single-lane is what lets the WGSL emulator run this shader as-is.
|
|
50
|
+
*/
|
|
51
|
+
const body = CodeChunk.from(
|
|
52
|
+
//language=WGSL
|
|
53
|
+
`
|
|
54
|
+
const AVBOIT_OCCUPANCY_WORDS: u32 = ${AVBOIT_OCCUPANCY_WORDS}u;
|
|
55
|
+
|
|
56
|
+
@compute @workgroup_size(1)
|
|
57
|
+
fn main(@builtin(global_invocation_id) global_id : vec3<u32>) {
|
|
58
|
+
|
|
59
|
+
if (global_id.x != 0u) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let physical = settings.physical_count;
|
|
64
|
+
|
|
65
|
+
var words: array<u32, AVBOIT_OCCUPANCY_WORDS>;
|
|
66
|
+
var dilated: array<u32, AVBOIT_OCCUPANCY_WORDS>;
|
|
67
|
+
|
|
68
|
+
for (var w = 0u; w < AVBOIT_OCCUPANCY_WORDS; w++) {
|
|
69
|
+
words[w] = occupancy[w];
|
|
70
|
+
dilated[w] = 0u;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
var level_count = ${AVBOIT_VIRTUAL_SLICES_MAX}u;
|
|
74
|
+
var word_count = AVBOIT_OCCUPANCY_WORDS;
|
|
75
|
+
|
|
76
|
+
loop {
|
|
77
|
+
var occupied = 0u;
|
|
78
|
+
|
|
79
|
+
for (var w = 0u; w < word_count; w++) {
|
|
80
|
+
var below = 0u;
|
|
81
|
+
if (w > 0u) {
|
|
82
|
+
below = words[w - 1u] >> 31u;
|
|
83
|
+
}
|
|
84
|
+
var above = 0u;
|
|
85
|
+
if (w + 1u < word_count) {
|
|
86
|
+
above = (words[w + 1u] & 1u) << 31u;
|
|
87
|
+
}
|
|
88
|
+
let d = avboit_dilate_word(words[w], below, above);
|
|
89
|
+
dilated[w] = d;
|
|
90
|
+
occupied += countOneBits(d);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (occupied <= physical || level_count <= physical) {
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// halve: two old words become one new word
|
|
98
|
+
let half_words = word_count / 2u;
|
|
99
|
+
for (var nw = 0u; nw < half_words; nw++) {
|
|
100
|
+
words[nw] = avboit_fold_pairs(words[2u * nw]) | (avboit_fold_pairs(words[2u * nw + 1u]) << 16u);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
word_count = half_words;
|
|
104
|
+
level_count = level_count / 2u;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
warp.virtual_count = level_count;
|
|
108
|
+
warp.physical_count = physical;
|
|
109
|
+
warp.voxel_width = settings.voxel_width;
|
|
110
|
+
warp.voxel_height = settings.voxel_height;
|
|
111
|
+
warp.tint_from_base_color = settings.tint_from_base_color;
|
|
112
|
+
warp.cluster_parameters = settings.cluster_parameters;
|
|
113
|
+
|
|
114
|
+
var prefix = 0u;
|
|
115
|
+
|
|
116
|
+
for (var v = 0u; v < level_count; v++) {
|
|
117
|
+
let bit = (dilated[v >> 5u] >> (v & 31u)) & 1u;
|
|
118
|
+
warp.lut[v] = (prefix << 1u) | bit;
|
|
119
|
+
prefix += bit;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
warp.lut[level_count] = prefix << 1u;
|
|
123
|
+
warp.occupied_count = prefix;
|
|
124
|
+
}
|
|
125
|
+
`, [
|
|
126
|
+
chunk_avboit_dilate_word,
|
|
127
|
+
chunk_avboit_fold_pairs,
|
|
128
|
+
]
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
export const shader_avboit_build_warp = ComputeShader.from({
|
|
132
|
+
label: 'AVBOIT / build warp',
|
|
133
|
+
resources,
|
|
134
|
+
body,
|
|
135
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shader_avboit_draw_brick4.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_brick4.js"],"names":[],"mappings":"AA2FA,6DAAoE;qCAnF/B,8CAA8C"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { RenderPipelineDescriptor } from "../../../../descriptor/pipeline/render/RenderPipelineDescriptor.js";
|
|
2
|
+
import { CAMERA_UNIFORM_STRUCT } from "../../../camera/CAMERA_UNIFORM_STRUCT.js";
|
|
3
|
+
import { SHADING_LIGHT_RESOURCE_GROUP } from "../../../deferred/SHADING_LIGHT_RESOURCE_GROUP.js";
|
|
4
|
+
import { DEPTH_BACKGROUND_VALUE } from "../../../depth/DEPTH_BACKGROUND_VALUE.js";
|
|
5
|
+
import { BRICK4_DATA_STRUCT } from "../../../global_illumination/brick4/gpu/BRICK4_DATA_STRUCT.js";
|
|
6
|
+
import { SHADING_MATERIAL_RESOURCE_GROUP } from "../../../material/standard/SHADING_MATERIAL_RESOURCE_GROUP.js";
|
|
7
|
+
import { CodeChunk } from "../../../shader/compiler/CodeChunk.js";
|
|
8
|
+
import { RenderPassColorAttachmentDescriptor } from "../../../shader/pass/RenderPassColorAttachmentDescriptor.js";
|
|
9
|
+
import { RenderPassDescriptor } from "../../../shader/pass/RenderPassDescriptor.js";
|
|
10
|
+
import { ShaderResourceSetDescriptor } from "../../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
11
|
+
import { ShaderDescriptor } from "../../../shader/ShaderDescriptor.js";
|
|
12
|
+
import { SAMPLER_LINEAR_UPSCALE } from "../../../texture/SAMPLER_LINEAR_UPSCALE.js";
|
|
13
|
+
import { VIEW_UNIFORM_STRUCT } from "../../../view/VIEW_UNIFORM_STRUCT.js";
|
|
14
|
+
import { VOLUMETRICS_METADATA_STRUCT } from "../../../volumetrics/VOLUMETRICS_METADATA_STRUCT.js";
|
|
15
|
+
import {
|
|
16
|
+
chunk_forward_shade_standard_fragment_brick4
|
|
17
|
+
} from "../../forward/chunk_forward_shade_standard_fragment_brick4.js";
|
|
18
|
+
import { SHADING_SCENE_RESOURCE_GROUP } from "../../forward/SHADING_SCENE_RESOURCE_GROUP.js";
|
|
19
|
+
import { vertex_shader_chunk } from "../../forward/vertex_shader_chunk.js";
|
|
20
|
+
import { rasterization_primitive_state } from "../rasterization_primitive_state.js";
|
|
21
|
+
import { AVBOIT_WARP_STRUCT } from "./AVBOIT_WARP_STRUCT.js";
|
|
22
|
+
import {
|
|
23
|
+
AVBOIT_DRAW_FRAGMENT_BODY,
|
|
24
|
+
AVBOIT_DRAW_FRAGMENT_DEPENDENCIES,
|
|
25
|
+
AVBOIT_DRAW_TARGETS
|
|
26
|
+
} from "./avboit_draw_fragment_body.js";
|
|
27
|
+
|
|
28
|
+
const resources = new ShaderResourceSetDescriptor();
|
|
29
|
+
|
|
30
|
+
resources.addGroup(SHADING_MATERIAL_RESOURCE_GROUP);
|
|
31
|
+
resources.addGroup(SHADING_SCENE_RESOURCE_GROUP);
|
|
32
|
+
|
|
33
|
+
// Order is load-bearing: the orchestrator's view bind group lists its entries in this sequence.
|
|
34
|
+
// Identical to the IBL variant except for the brick4 buffer after the integral sampler.
|
|
35
|
+
resources.createGroup()
|
|
36
|
+
.addUniform("camera", CAMERA_UNIFORM_STRUCT)
|
|
37
|
+
.addUniform("view", VIEW_UNIFORM_STRUCT)
|
|
38
|
+
.addStorageBuffer("warp", AVBOIT_WARP_STRUCT)
|
|
39
|
+
// sampled through sLinear below: linear, clamped on every axis, which is what the integral needs
|
|
40
|
+
.addTexture("tIntegral", "float", "3d")
|
|
41
|
+
.addStorageBuffer("brick4", BRICK4_DATA_STRUCT, false)
|
|
42
|
+
.addTexture("tSplitSum", "float")
|
|
43
|
+
.addSampler("sLinear", "filtering", SAMPLER_LINEAR_UPSCALE)
|
|
44
|
+
// volumetrics (composited inline)
|
|
45
|
+
.addUniform("volumetrics_metadata", VOLUMETRICS_METADATA_STRUCT)
|
|
46
|
+
.addTexture("tVolumetrics", "float", "3d")
|
|
47
|
+
.addTexture("tSTBN_vec3", "float", "3d")
|
|
48
|
+
|
|
49
|
+
resources.addGroup(SHADING_LIGHT_RESOURCE_GROUP);
|
|
50
|
+
|
|
51
|
+
const shader_vertex = ShaderDescriptor.from({
|
|
52
|
+
label: 'AVBOIT Brick4 / vertex shader',
|
|
53
|
+
body: vertex_shader_chunk,
|
|
54
|
+
resources,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* AVBOIT draw, Brick4 (sparse volumetric lightmap) indirect lighting. See `avboit_draw_fragment_body.js`.
|
|
59
|
+
*/
|
|
60
|
+
const shader_fragment = ShaderDescriptor.from({
|
|
61
|
+
label: "AVBOIT Brick4 / draw",
|
|
62
|
+
resources,
|
|
63
|
+
body: CodeChunk.from(AVBOIT_DRAW_FRAGMENT_BODY, [
|
|
64
|
+
...AVBOIT_DRAW_FRAGMENT_DEPENDENCIES,
|
|
65
|
+
chunk_forward_shade_standard_fragment_brick4,
|
|
66
|
+
])
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const pipeline = RenderPipelineDescriptor.from({
|
|
70
|
+
label: "AVBOIT Brick4 / draw",
|
|
71
|
+
layout: resources.generatePipelineLayout(GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT),
|
|
72
|
+
vertex: {
|
|
73
|
+
module: {
|
|
74
|
+
code: shader_vertex.source
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
fragment: {
|
|
78
|
+
module: {
|
|
79
|
+
code: shader_fragment.source
|
|
80
|
+
},
|
|
81
|
+
targets: AVBOIT_DRAW_TARGETS,
|
|
82
|
+
},
|
|
83
|
+
depthStencil: {
|
|
84
|
+
// reversed Z
|
|
85
|
+
depthCompare: "greater",
|
|
86
|
+
format: "depth32float",
|
|
87
|
+
depthWriteEnabled: false
|
|
88
|
+
},
|
|
89
|
+
primitive: rasterization_primitive_state,
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
export const shader_avboit_draw_brick4 = new RenderPassDescriptor();
|
|
93
|
+
shader_avboit_draw_brick4.pipeline = pipeline;
|
|
94
|
+
shader_avboit_draw_brick4.resources = resources;
|
|
95
|
+
shader_avboit_draw_brick4.colorAttachments = AVBOIT_DRAW_TARGETS.map(() => RenderPassColorAttachmentDescriptor.from({
|
|
96
|
+
clearValue: [0, 0, 0, 0],
|
|
97
|
+
}));
|
|
98
|
+
/**
|
|
99
|
+
* Clear depth to 0 for reverse Z technique
|
|
100
|
+
*/
|
|
101
|
+
shader_avboit_draw_brick4.depthStencilAttachment.depthClearValue = DEPTH_BACKGROUND_VALUE;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shader_avboit_draw_ibl.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_ibl.js"],"names":[],"mappings":"AAsFA,0DAAiE;qCA/E5B,8CAA8C"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { RenderPipelineDescriptor } from "../../../../descriptor/pipeline/render/RenderPipelineDescriptor.js";
|
|
2
|
+
import { CAMERA_UNIFORM_STRUCT } from "../../../camera/CAMERA_UNIFORM_STRUCT.js";
|
|
3
|
+
import { SHADING_LIGHT_RESOURCE_GROUP } from "../../../deferred/SHADING_LIGHT_RESOURCE_GROUP.js";
|
|
4
|
+
import { DEPTH_BACKGROUND_VALUE } from "../../../depth/DEPTH_BACKGROUND_VALUE.js";
|
|
5
|
+
import { SHADING_MATERIAL_RESOURCE_GROUP } from "../../../material/standard/SHADING_MATERIAL_RESOURCE_GROUP.js";
|
|
6
|
+
import { CodeChunk } from "../../../shader/compiler/CodeChunk.js";
|
|
7
|
+
import { RenderPassColorAttachmentDescriptor } from "../../../shader/pass/RenderPassColorAttachmentDescriptor.js";
|
|
8
|
+
import { RenderPassDescriptor } from "../../../shader/pass/RenderPassDescriptor.js";
|
|
9
|
+
import { ShaderResourceSetDescriptor } from "../../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
10
|
+
import { ShaderDescriptor } from "../../../shader/ShaderDescriptor.js";
|
|
11
|
+
import { SAMPLER_LINEAR_UPSCALE } from "../../../texture/SAMPLER_LINEAR_UPSCALE.js";
|
|
12
|
+
import { VIEW_UNIFORM_STRUCT } from "../../../view/VIEW_UNIFORM_STRUCT.js";
|
|
13
|
+
import { VOLUMETRICS_METADATA_STRUCT } from "../../../volumetrics/VOLUMETRICS_METADATA_STRUCT.js";
|
|
14
|
+
import { chunk_forward_shade_standard_fragment_ibl } from "../../forward/chunk_forward_shade_standard_fragment_ibl.js";
|
|
15
|
+
import { SHADING_SCENE_RESOURCE_GROUP } from "../../forward/SHADING_SCENE_RESOURCE_GROUP.js";
|
|
16
|
+
import { vertex_shader_chunk } from "../../forward/vertex_shader_chunk.js";
|
|
17
|
+
import { rasterization_primitive_state } from "../rasterization_primitive_state.js";
|
|
18
|
+
import { AVBOIT_WARP_STRUCT } from "./AVBOIT_WARP_STRUCT.js";
|
|
19
|
+
import {
|
|
20
|
+
AVBOIT_DRAW_FRAGMENT_BODY,
|
|
21
|
+
AVBOIT_DRAW_FRAGMENT_DEPENDENCIES,
|
|
22
|
+
AVBOIT_DRAW_TARGETS
|
|
23
|
+
} from "./avboit_draw_fragment_body.js";
|
|
24
|
+
|
|
25
|
+
const resources = new ShaderResourceSetDescriptor();
|
|
26
|
+
|
|
27
|
+
resources.addGroup(SHADING_MATERIAL_RESOURCE_GROUP);
|
|
28
|
+
resources.addGroup(SHADING_SCENE_RESOURCE_GROUP);
|
|
29
|
+
|
|
30
|
+
// Order is load-bearing: the orchestrator's view bind group lists its entries in this sequence.
|
|
31
|
+
resources.createGroup()
|
|
32
|
+
.addUniform("camera", CAMERA_UNIFORM_STRUCT)
|
|
33
|
+
.addUniform("view", VIEW_UNIFORM_STRUCT)
|
|
34
|
+
.addStorageBuffer("warp", AVBOIT_WARP_STRUCT)
|
|
35
|
+
// sampled through sLinear below: linear, clamped on every axis, which is what the integral needs
|
|
36
|
+
.addTexture("tIntegral", "float", "3d")
|
|
37
|
+
.addTexture("tSplitSum", "float")
|
|
38
|
+
.addSampler("sLinear", "filtering", SAMPLER_LINEAR_UPSCALE)
|
|
39
|
+
// volumetrics (composited inline)
|
|
40
|
+
.addUniform("volumetrics_metadata", VOLUMETRICS_METADATA_STRUCT)
|
|
41
|
+
.addTexture("tVolumetrics", "float", "3d")
|
|
42
|
+
.addTexture("tSTBN_vec3", "float", "3d")
|
|
43
|
+
|
|
44
|
+
resources.addGroup(SHADING_LIGHT_RESOURCE_GROUP);
|
|
45
|
+
|
|
46
|
+
const shader_vertex = ShaderDescriptor.from({
|
|
47
|
+
label: 'AVBOIT IBL / vertex shader',
|
|
48
|
+
body: vertex_shader_chunk,
|
|
49
|
+
resources,
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* AVBOIT draw, image-based indirect lighting. See `avboit_draw_fragment_body.js`.
|
|
54
|
+
*/
|
|
55
|
+
const shader_fragment = ShaderDescriptor.from({
|
|
56
|
+
label: "AVBOIT IBL / draw",
|
|
57
|
+
resources,
|
|
58
|
+
body: CodeChunk.from(AVBOIT_DRAW_FRAGMENT_BODY, [
|
|
59
|
+
...AVBOIT_DRAW_FRAGMENT_DEPENDENCIES,
|
|
60
|
+
chunk_forward_shade_standard_fragment_ibl,
|
|
61
|
+
])
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const pipeline = RenderPipelineDescriptor.from({
|
|
65
|
+
label: "AVBOIT IBL / draw",
|
|
66
|
+
layout: resources.generatePipelineLayout(GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT),
|
|
67
|
+
vertex: {
|
|
68
|
+
module: {
|
|
69
|
+
code: shader_vertex.source
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
fragment: {
|
|
73
|
+
module: {
|
|
74
|
+
code: shader_fragment.source
|
|
75
|
+
},
|
|
76
|
+
targets: AVBOIT_DRAW_TARGETS,
|
|
77
|
+
},
|
|
78
|
+
depthStencil: {
|
|
79
|
+
// reversed Z
|
|
80
|
+
depthCompare: "greater",
|
|
81
|
+
format: "depth32float",
|
|
82
|
+
depthWriteEnabled: false
|
|
83
|
+
},
|
|
84
|
+
primitive: rasterization_primitive_state,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
export const shader_avboit_draw_ibl = new RenderPassDescriptor();
|
|
88
|
+
shader_avboit_draw_ibl.pipeline = pipeline;
|
|
89
|
+
shader_avboit_draw_ibl.resources = resources;
|
|
90
|
+
shader_avboit_draw_ibl.colorAttachments = AVBOIT_DRAW_TARGETS.map(() => RenderPassColorAttachmentDescriptor.from({
|
|
91
|
+
clearValue: [0, 0, 0, 0],
|
|
92
|
+
}));
|
|
93
|
+
/**
|
|
94
|
+
* Clear depth to 0 for reverse Z technique
|
|
95
|
+
*/
|
|
96
|
+
shader_avboit_draw_ibl.depthStencilAttachment.depthClearValue = DEPTH_BACKGROUND_VALUE;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shader_avboit_integrate.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/rasterize/native/avboit/shader_avboit_integrate.js"],"names":[],"mappings":"AA8EA,oDAIG;8BA/E2B,kCAAkC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { u32 } from "../../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
|
|
2
|
+
import { WebGPUArray } from "../../../shader/type/WebGPUArray.js";
|
|
3
|
+
import { CodeChunk } from "../../../shader/compiler/CodeChunk.js";
|
|
4
|
+
import { ComputeShader } from "../../../shader/ComputeShader.js";
|
|
5
|
+
import { ShaderResourceSetDescriptor } from "../../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
6
|
+
import { AVBOIT_INTEGRAL_FORMAT, AVBOIT_INTEGRATE_WORKGROUP_SIZE } from "./AVBOIT_CONSTANTS.js";
|
|
7
|
+
import { AVBOIT_WARP_STRUCT } from "./AVBOIT_WARP_STRUCT.js";
|
|
8
|
+
import { chunk_avboit_counts_to_extinction } from "./chunk_avboit_counts_to_extinction.js";
|
|
9
|
+
import { chunk_avboit_unpack_counts } from "./chunk_avboit_unpack_counts.js";
|
|
10
|
+
|
|
11
|
+
const resources = new ShaderResourceSetDescriptor();
|
|
12
|
+
|
|
13
|
+
resources.createGroup()
|
|
14
|
+
.addStorageBuffer("warp", AVBOIT_WARP_STRUCT)
|
|
15
|
+
.addStorageBuffer("extinction_volume", WebGPUArray.from(u32))
|
|
16
|
+
.addStorageBuffer("overflow_slice", WebGPUArray.from(u32))
|
|
17
|
+
.addStorageTexture("integral", AVBOIT_INTEGRAL_FORMAT, "3d", "write-only")
|
|
18
|
+
;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* AVBOIT integration: one thread per voxel column, summing extinction front to back into the 3D
|
|
22
|
+
* integral texture (plan §3.6).
|
|
23
|
+
*
|
|
24
|
+
* Exclusive prefix: texel `s` holds the integral at the *near boundary* of slice `s`, and the texture
|
|
25
|
+
* has `P + 1` depth texels so that texel `P` holds the total. That convention is what lets a sample
|
|
26
|
+
* that the warp has snapped to a run boundary read exactly the runs in front of it.
|
|
27
|
+
*
|
|
28
|
+
* Per channel, the running value saturates at 1.0 (a transmittance of `1/256`), and from the slice
|
|
29
|
+
* the splat recorded as that channel's first overflow it is pinned there: the packed field may have
|
|
30
|
+
* wrapped past that point and its contents no longer mean anything, but a ray that has overflowed
|
|
31
|
+
* a field is extinct anyway.
|
|
32
|
+
*/
|
|
33
|
+
const body = CodeChunk.from(
|
|
34
|
+
//language=WGSL
|
|
35
|
+
`
|
|
36
|
+
@compute @workgroup_size(${AVBOIT_INTEGRATE_WORKGROUP_SIZE}, ${AVBOIT_INTEGRATE_WORKGROUP_SIZE}, 1)
|
|
37
|
+
fn main(@builtin(global_invocation_id) global_id : vec3<u32>) {
|
|
38
|
+
|
|
39
|
+
let width = warp.voxel_width;
|
|
40
|
+
let height = warp.voxel_height;
|
|
41
|
+
|
|
42
|
+
if (global_id.x >= width || global_id.y >= height) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
let physical = warp.physical_count;
|
|
47
|
+
let texel = global_id.y * width + global_id.x;
|
|
48
|
+
let column = texel * physical;
|
|
49
|
+
let overflow_base = texel * 3u;
|
|
50
|
+
|
|
51
|
+
// first overflow slice per channel; a zero mark means none, which no slice reaches
|
|
52
|
+
let marks = vec3<u32>(
|
|
53
|
+
overflow_slice[overflow_base],
|
|
54
|
+
overflow_slice[overflow_base + 1u],
|
|
55
|
+
overflow_slice[overflow_base + 2u],
|
|
56
|
+
);
|
|
57
|
+
let stop = select(vec3<u32>(physical) - marks, vec3<u32>(physical), marks == vec3<u32>(0u));
|
|
58
|
+
|
|
59
|
+
var accumulated = vec3<f32>(0.0);
|
|
60
|
+
|
|
61
|
+
for (var s = 0u; s < physical; s++) {
|
|
62
|
+
textureStore(integral, vec3<i32>(i32(global_id.x), i32(global_id.y), i32(s)), vec4<f32>(accumulated, 1.0));
|
|
63
|
+
|
|
64
|
+
let counts = avboit_unpack_counts(extinction_volume[column + s]);
|
|
65
|
+
let extinction = avboit_counts_to_extinction(counts);
|
|
66
|
+
|
|
67
|
+
let pinned = vec3<u32>(s) >= stop;
|
|
68
|
+
accumulated = select(min(accumulated + extinction, vec3<f32>(1.0)), vec3<f32>(1.0), pinned);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
textureStore(integral, vec3<i32>(i32(global_id.x), i32(global_id.y), i32(physical)), vec4<f32>(accumulated, 1.0));
|
|
72
|
+
}
|
|
73
|
+
`, [
|
|
74
|
+
chunk_avboit_counts_to_extinction,
|
|
75
|
+
chunk_avboit_unpack_counts,
|
|
76
|
+
]
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
export const shader_avboit_integrate = ComputeShader.from({
|
|
80
|
+
label: 'AVBOIT / integrate',
|
|
81
|
+
resources,
|
|
82
|
+
body,
|
|
83
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The depth curve, built by `avboit_build_depth_curve`; the same values the warp header carries,
|
|
3
|
+
* needed here before the header exists.
|
|
4
|
+
*/
|
|
5
|
+
export const AVBOIT_OCCUPANCY_SETTINGS_STRUCT: WebGPUStruct;
|
|
6
|
+
export const shader_avboit_occupancy: ComputeShader;
|
|
7
|
+
import { WebGPUStruct } from "../../../shader/type/WebGPUStruct.js";
|
|
8
|
+
import { ComputeShader } from "../../../shader/ComputeShader.js";
|
|
9
|
+
//# sourceMappingURL=shader_avboit_occupancy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shader_avboit_occupancy.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/rasterize/native/avboit/shader_avboit_occupancy.js"],"names":[],"mappings":"AAmBA;;;GAGG;AACH,4DAEqC;AAyFrC,oDAIG;6BApH0B,sCAAsC;8BAUrC,kCAAkC"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { atomic_u32, u32, vec3f } from "../../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
|
|
2
|
+
import { WebGPUArray } from "../../../shader/type/WebGPUArray.js";
|
|
3
|
+
import { WebGPUStruct } from "../../../shader/type/WebGPUStruct.js";
|
|
4
|
+
import { CAMERA_UNIFORM_STRUCT } from "../../../camera/CAMERA_UNIFORM_STRUCT.js";
|
|
5
|
+
import { chunk_cluster_depth_to_z_slice } from "../../../light/cluster/chunk_cluster_depth_to_z_slice.js";
|
|
6
|
+
import { MESHLET_METADATA_STRUCT } from "../../../geometry/meshlet/encoding/MESHLET_METADATA_STRUCT.js";
|
|
7
|
+
import { chunk_scene_database_access } from "../../../scene/chunk_scene_database_access.js";
|
|
8
|
+
import { AABB3_STRUCT } from "../../../shader/chunk/geometry/aabb3/AABB3_STRUCT.js";
|
|
9
|
+
import { chunk_aabb3_project } from "../../../shader/chunk/geometry/aabb3/chunk_aabb3_project.js";
|
|
10
|
+
import { chunk_array_to_aabb3 } from "../../../shader/chunk/geometry/aabb3/chunk_array_to_aabb3.js";
|
|
11
|
+
import { CodeChunk } from "../../../shader/compiler/CodeChunk.js";
|
|
12
|
+
import { COMPUTE_SHADER_DEFAULT_GROUP_SIZE } from "../../../shader/COMPUTE_SHADER_DEFAULT_GROUP_SIZE.js";
|
|
13
|
+
import { ComputeShader } from "../../../shader/ComputeShader.js";
|
|
14
|
+
import { ShaderResourceSetDescriptor } from "../../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
15
|
+
import { MESHLET_COLLECTION_STRUCT } from "../../MESHLET_COLLECTION_STRUCT.js";
|
|
16
|
+
import { AVBOIT_OCCUPANCY_WORDS, AVBOIT_VIRTUAL_SLICES_MAX } from "./AVBOIT_CONSTANTS.js";
|
|
17
|
+
import { chunk_avboit_occupancy_range } from "./chunk_avboit_occupancy_range.js";
|
|
18
|
+
import { chunk_avboit_occupancy_word_mask } from "./chunk_avboit_occupancy_word_mask.js";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The depth curve, built by `avboit_build_depth_curve`; the same values the warp header carries,
|
|
22
|
+
* needed here before the header exists.
|
|
23
|
+
*/
|
|
24
|
+
export const AVBOIT_OCCUPANCY_SETTINGS_STRUCT = WebGPUStruct.from({
|
|
25
|
+
cluster_parameters: vec3f,
|
|
26
|
+
}, "AVBOITOccupancySettings").pack();
|
|
27
|
+
|
|
28
|
+
const resources = new ShaderResourceSetDescriptor();
|
|
29
|
+
|
|
30
|
+
resources.createGroup()
|
|
31
|
+
.addUniform("camera", CAMERA_UNIFORM_STRUCT)
|
|
32
|
+
.addUniform("settings", AVBOIT_OCCUPANCY_SETTINGS_STRUCT)
|
|
33
|
+
.addStorageBuffer("scene_database", WebGPUArray.from(u32))
|
|
34
|
+
.addStorageBuffer("meshlet_metadata", WebGPUArray.from(MESHLET_METADATA_STRUCT))
|
|
35
|
+
;
|
|
36
|
+
|
|
37
|
+
resources.createGroup()
|
|
38
|
+
.addStorageBuffer("input", MESHLET_COLLECTION_STRUCT)
|
|
39
|
+
;
|
|
40
|
+
|
|
41
|
+
resources.createGroup()
|
|
42
|
+
.addStorageBuffer("occupancy", WebGPUArray.from(atomic_u32, AVBOIT_OCCUPANCY_WORDS), true)
|
|
43
|
+
;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* AVBOIT occupancy prepass: one thread per HZB-surviving meshlet, marking the virtual depth slices its
|
|
47
|
+
* bounds span. The deck voxelizes quads and boxes conservatively in a compute job (slide 75); the
|
|
48
|
+
* engine already has per-meshlet AABBs on the GPU, which are tighter than a mesh box and free.
|
|
49
|
+
*
|
|
50
|
+
* Bounds go local → world → view through `aabb3_project` twice, the same projection the HZB meshlet
|
|
51
|
+
* filter uses. The camera looks down −Z, so the view-space depth interval is `[-max.z, -min.z]`.
|
|
52
|
+
* A meshlet entirely in front of the near plane marks nothing; anything else goes through the depth
|
|
53
|
+
* curve (`cluster_depth_to_z_slice`, clamped to the volume by its own limit) and is dilated one slice
|
|
54
|
+
* each side (`avboit_occupancy_range`).
|
|
55
|
+
*
|
|
56
|
+
* Runs once per transparent bucket (front-sided, double-sided) into the same word array.
|
|
57
|
+
*/
|
|
58
|
+
const body = CodeChunk.from(
|
|
59
|
+
//language=WGSL
|
|
60
|
+
`
|
|
61
|
+
@compute @workgroup_size(${COMPUTE_SHADER_DEFAULT_GROUP_SIZE})
|
|
62
|
+
fn main(@builtin(global_invocation_id) global_id : vec3<u32>) {
|
|
63
|
+
|
|
64
|
+
let input_index = global_id.x;
|
|
65
|
+
|
|
66
|
+
if (input_index >= input.count) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
let meshlet = input.elements[input_index];
|
|
71
|
+
|
|
72
|
+
let mesh = scene_read_mesh(&scene_database, meshlet.mesh);
|
|
73
|
+
let node = scene_read_node(&scene_database, mesh.node);
|
|
74
|
+
|
|
75
|
+
let local_bounds = array_to_aabb3(meshlet_metadata[meshlet.index].bounds_box);
|
|
76
|
+
let world_bounds = aabb3_project(local_bounds, node.global);
|
|
77
|
+
let view_bounds: ${AABB3_STRUCT.wgsl_ref} = aabb3_project(world_bounds, camera.view_matrix);
|
|
78
|
+
|
|
79
|
+
// camera looks down -Z: the nearest point of the box has the largest z
|
|
80
|
+
let depth_min = -view_bounds.max.z;
|
|
81
|
+
let depth_max = -view_bounds.min.z;
|
|
82
|
+
|
|
83
|
+
if (depth_max < camera.clip_near_far.x) {
|
|
84
|
+
// entirely in front of the near plane
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
let limit = ${AVBOIT_VIRTUAL_SLICES_MAX}.0;
|
|
89
|
+
let slice_near = cluster_depth_to_z_slice(depth_min, settings.cluster_parameters, limit);
|
|
90
|
+
let slice_far = cluster_depth_to_z_slice(depth_max, settings.cluster_parameters, limit);
|
|
91
|
+
|
|
92
|
+
let range = avboit_occupancy_range(slice_near, slice_far);
|
|
93
|
+
|
|
94
|
+
let word_first = u32(range.x) >> 5u;
|
|
95
|
+
let word_last = u32(range.y) >> 5u;
|
|
96
|
+
|
|
97
|
+
for (var word = word_first; word <= word_last; word++) {
|
|
98
|
+
let mask = avboit_occupancy_word_mask(word, range.x, range.y);
|
|
99
|
+
if (mask != 0u) {
|
|
100
|
+
atomicOr(&occupancy[word], mask);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
`, [
|
|
105
|
+
AABB3_STRUCT.declaration_chunk,
|
|
106
|
+
chunk_array_to_aabb3,
|
|
107
|
+
chunk_aabb3_project,
|
|
108
|
+
chunk_scene_database_access,
|
|
109
|
+
chunk_cluster_depth_to_z_slice,
|
|
110
|
+
chunk_avboit_occupancy_range,
|
|
111
|
+
chunk_avboit_occupancy_word_mask,
|
|
112
|
+
]
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
export const shader_avboit_occupancy = ComputeShader.from({
|
|
116
|
+
label: 'AVBOIT / occupancy',
|
|
117
|
+
resources,
|
|
118
|
+
body,
|
|
119
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shader_avboit_resolve.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/rasterize/native/avboit/shader_avboit_resolve.js"],"names":[],"mappings":"AAsEA,gDAUE;4BA9E0B,gCAAgC"}
|