@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.
Files changed (154) hide show
  1. package/package.json +1 -1
  2. package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts +48 -0
  3. package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts.map +1 -1
  4. package/src/engine/network/orchestrator/ServerAuthoritativeClient.js +246 -3
  5. package/src/shade/RENDERER_CONTRACT.md +584 -580
  6. package/src/shade/playground/avboit/README.md +117 -0
  7. package/src/shade/playground/avboit/index.html +215 -0
  8. package/src/shade/playground/avboit/main.d.ts +2 -0
  9. package/src/shade/playground/avboit/main.d.ts.map +1 -0
  10. package/src/shade/playground/avboit/main.js +875 -0
  11. package/src/shade/renderer/Renderer.d.ts +16 -0
  12. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  13. package/src/shade/renderer/Renderer.js +29 -28
  14. package/src/shade/renderer/ShadeTransparencyMode.d.ts +13 -0
  15. package/src/shade/renderer/ShadeTransparencyMode.d.ts.map +1 -0
  16. package/src/shade/renderer/ShadeTransparencyMode.js +30 -0
  17. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.d.ts +9 -0
  18. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.d.ts.map +1 -1
  19. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.js +26 -0
  20. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts +7 -2
  21. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  22. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +12 -1
  23. package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.js +1 -1
  24. package/src/shade/renderer/rasterize/forward/FORWARD_VERTEX_SHADER_STRUCT.d.ts +3 -0
  25. package/src/shade/renderer/rasterize/forward/FORWARD_VERTEX_SHADER_STRUCT.d.ts.map +1 -0
  26. package/src/shade/renderer/rasterize/{native/oit → forward}/FORWARD_VERTEX_SHADER_STRUCT.js +4 -4
  27. package/src/shade/renderer/rasterize/forward/SHADING_SCENE_RESOURCE_GROUP.d.ts +3 -0
  28. package/src/shade/renderer/rasterize/forward/SHADING_SCENE_RESOURCE_GROUP.d.ts.map +1 -0
  29. package/src/shade/renderer/rasterize/forward/SHADING_SCENE_RESOURCE_GROUP.js +17 -0
  30. package/src/shade/renderer/rasterize/{native/oit → forward}/chunk_forward_shade_standard_fragment_brick4.d.ts +1 -1
  31. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.d.ts.map +1 -0
  32. package/src/shade/renderer/rasterize/{native/oit → forward}/chunk_forward_shade_standard_fragment_brick4.js +16 -16
  33. package/src/shade/renderer/rasterize/{native/oit → forward}/chunk_forward_shade_standard_fragment_ibl.d.ts +1 -1
  34. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.d.ts.map +1 -0
  35. package/src/shade/renderer/rasterize/{native/oit → forward}/chunk_forward_shade_standard_fragment_ibl.js +17 -17
  36. package/src/shade/renderer/rasterize/{native/oit → forward}/chunk_material_side_should_draw.d.ts +1 -1
  37. package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.d.ts.map +1 -0
  38. package/src/shade/renderer/rasterize/{native/oit → forward}/chunk_material_side_should_draw.js +2 -2
  39. package/src/shade/renderer/rasterize/forward/vertex_shader_chunk.d.ts +3 -0
  40. package/src/shade/renderer/rasterize/forward/vertex_shader_chunk.d.ts.map +1 -0
  41. package/src/shade/renderer/rasterize/{native/oit → forward}/vertex_shader_chunk.js +4 -4
  42. package/src/shade/renderer/rasterize/native/avboit/AVBOITSettings.d.ts +27 -0
  43. package/src/shade/renderer/rasterize/native/avboit/AVBOITSettings.d.ts.map +1 -0
  44. package/src/shade/renderer/rasterize/native/avboit/AVBOITSettings.js +27 -0
  45. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_CONSTANTS.d.ts +107 -0
  46. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_CONSTANTS.d.ts.map +1 -0
  47. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_CONSTANTS.js +120 -0
  48. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_LEDGER.md +463 -0
  49. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +509 -0
  50. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_WARP_STRUCT.d.ts +15 -0
  51. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_WARP_STRUCT.d.ts.map +1 -0
  52. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_WARP_STRUCT.js +33 -0
  53. package/src/shade/renderer/rasterize/native/avboit/avboit_build_depth_curve.d.ts +20 -0
  54. package/src/shade/renderer/rasterize/native/avboit/avboit_build_depth_curve.d.ts.map +1 -0
  55. package/src/shade/renderer/rasterize/native/avboit/avboit_build_depth_curve.js +38 -0
  56. package/src/shade/renderer/rasterize/native/avboit/avboit_draw_fragment_body.d.ts +38 -0
  57. package/src/shade/renderer/rasterize/native/avboit/avboit_draw_fragment_body.d.ts.map +1 -0
  58. package/src/shade/renderer/rasterize/native/avboit/avboit_draw_fragment_body.js +130 -0
  59. package/src/shade/renderer/rasterize/native/avboit/avboit_spec_support.d.ts +37 -0
  60. package/src/shade/renderer/rasterize/native/avboit/avboit_spec_support.d.ts.map +1 -0
  61. package/src/shade/renderer/rasterize/native/avboit/avboit_spec_support.js +73 -0
  62. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_counts_to_extinction.d.ts +9 -0
  63. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_counts_to_extinction.d.ts.map +1 -0
  64. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_counts_to_extinction.js +17 -0
  65. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_dilate_word.d.ts +11 -0
  66. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_dilate_word.d.ts.map +1 -0
  67. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_dilate_word.js +18 -0
  68. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_extinction_to_counts.d.ts +9 -0
  69. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_extinction_to_counts.d.ts.map +1 -0
  70. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_extinction_to_counts.js +17 -0
  71. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_extinction_to_transmittance.d.ts +9 -0
  72. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_extinction_to_transmittance.d.ts.map +1 -0
  73. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_extinction_to_transmittance.js +17 -0
  74. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_fold_pairs.d.ts +15 -0
  75. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_fold_pairs.d.ts.map +1 -0
  76. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_fold_pairs.js +25 -0
  77. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_integral_depth_coordinate.d.ts +17 -0
  78. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_integral_depth_coordinate.d.ts.map +1 -0
  79. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_integral_depth_coordinate.js +35 -0
  80. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_occupancy_range.d.ts +11 -0
  81. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_occupancy_range.d.ts.map +1 -0
  82. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_occupancy_range.js +21 -0
  83. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_occupancy_word_mask.d.ts +9 -0
  84. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_occupancy_word_mask.d.ts.map +1 -0
  85. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_occupancy_word_mask.js +26 -0
  86. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_overflows.d.ts +11 -0
  87. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_overflows.d.ts.map +1 -0
  88. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_overflows.js +22 -0
  89. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_pack_counts.d.ts +10 -0
  90. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_pack_counts.d.ts.map +1 -0
  91. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_pack_counts.js +21 -0
  92. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_sample_transmittance.d.ts +10 -0
  93. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_sample_transmittance.d.ts.map +1 -0
  94. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_sample_transmittance.js +32 -0
  95. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_transmission_tint.d.ts +20 -0
  96. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_transmission_tint.d.ts.map +1 -0
  97. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_transmission_tint.js +27 -0
  98. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_transmittance_to_extinction.d.ts +10 -0
  99. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_transmittance_to_extinction.d.ts.map +1 -0
  100. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_transmittance_to_extinction.js +18 -0
  101. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_unpack_counts.d.ts +9 -0
  102. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_unpack_counts.d.ts.map +1 -0
  103. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_unpack_counts.js +21 -0
  104. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_view_depth_to_physical.d.ts +9 -0
  105. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_view_depth_to_physical.d.ts.map +1 -0
  106. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_view_depth_to_physical.js +23 -0
  107. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_view_depth_to_virtual.d.ts +13 -0
  108. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_view_depth_to_virtual.d.ts.map +1 -0
  109. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_view_depth_to_virtual.js +27 -0
  110. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_warp.d.ts +22 -0
  111. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_warp.d.ts.map +1 -0
  112. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_warp.js +38 -0
  113. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts +117 -0
  114. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -0
  115. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +935 -0
  116. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_build_warp.d.ts +8 -0
  117. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_build_warp.d.ts.map +1 -0
  118. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_build_warp.js +135 -0
  119. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_brick4.d.ts +3 -0
  120. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_brick4.d.ts.map +1 -0
  121. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_brick4.js +101 -0
  122. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_ibl.d.ts +3 -0
  123. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_ibl.d.ts.map +1 -0
  124. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_ibl.js +96 -0
  125. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_integrate.d.ts +3 -0
  126. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_integrate.d.ts.map +1 -0
  127. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_integrate.js +83 -0
  128. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_occupancy.d.ts +9 -0
  129. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_occupancy.d.ts.map +1 -0
  130. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_occupancy.js +119 -0
  131. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_resolve.d.ts +3 -0
  132. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_resolve.d.ts.map +1 -0
  133. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_resolve.js +81 -0
  134. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.d.ts +15 -0
  135. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.d.ts.map +1 -0
  136. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.js +237 -0
  137. package/src/shade/renderer/rasterize/native/material_draw_indirect.d.ts +22 -0
  138. package/src/shade/renderer/rasterize/native/material_draw_indirect.d.ts.map +1 -0
  139. package/src/shade/renderer/rasterize/native/material_draw_indirect.js +69 -0
  140. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts.map +1 -1
  141. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +665 -722
  142. package/src/shade/renderer/rasterize/native/oit/shader_oit_generate_moments.js +3 -3
  143. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments.js +4 -4
  144. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments_ibl.js +4 -4
  145. package/src/shade/renderer/rasterize/native/oit/FORWARD_VERTEX_SHADER_STRUCT.d.ts +0 -3
  146. package/src/shade/renderer/rasterize/native/oit/FORWARD_VERTEX_SHADER_STRUCT.d.ts.map +0 -1
  147. package/src/shade/renderer/rasterize/native/oit/SHADING_SCENE_RESOURCE_GROUP.d.ts +0 -3
  148. package/src/shade/renderer/rasterize/native/oit/SHADING_SCENE_RESOURCE_GROUP.d.ts.map +0 -1
  149. package/src/shade/renderer/rasterize/native/oit/SHADING_SCENE_RESOURCE_GROUP.js +0 -17
  150. package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_brick4.d.ts.map +0 -1
  151. package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_ibl.d.ts.map +0 -1
  152. package/src/shade/renderer/rasterize/native/oit/chunk_material_side_should_draw.d.ts.map +0 -1
  153. package/src/shade/renderer/rasterize/native/oit/vertex_shader_chunk.d.ts +0 -3
  154. package/src/shade/renderer/rasterize/native/oit/vertex_shader_chunk.d.ts.map +0 -1
@@ -1,723 +1,666 @@
1
- import { assert } from "../../../../../core/assert.js";
2
- import { SamplerDescriptor } from "../../../../descriptor/texture/SamplerDescriptor.js";
3
- import { TextureResourceDescriptor } from "../../../../device/graph/TextureResourceDescriptor.js";
4
- import { rp_rewrite_for_primitive_state } from "../../../../device/pipeline/rp_rewrite_for_primitive_state.js";
5
- import { STRUCT_UNINDEXED_DRAW_COMMAND } from "../../../gpu_primitive/indirect/STRUCT_UNINDEXED_DRAW_COMMAND.js";
6
- import { BindGroupDescriptor } from "../../../binding/BindGroupDescriptor.js";
7
- import { SHADING_LIGHT_RESOURCE_GROUP } from "../../../deferred/SHADING_LIGHT_RESOURCE_GROUP.js";
8
- import { ShadeDrawMode } from "../../../material/ShadeDrawMode.js";
9
- import { ShadeDrawSide } from "../../../material/ShadeDrawSide.js";
10
- import { SHADING_MATERIAL_RESOURCE_GROUP } from "../../../material/standard/SHADING_MATERIAL_RESOURCE_GROUP.js";
11
- import { TransparencyMode } from "../../../material/TransparencyMode.js";
12
- import { ShadeIndirectLightingMode } from "../../../ShadeIndirectLightingMode.js";
13
- import { graph_image_pass } from "../../../shader/graph/graph_image_pass.js";
14
- import { graph_import_buffer } from "../../../shader/graph/graph_import_buffer.js";
15
- import { graph_import_texture } from "../../../shader/graph/graph_import_texture.js";
16
- import {
17
- SHADOWMAP_COMPARE_SAMPLER_DESCRIPTOR
18
- } from "../../../shadow/map/SHADOWMAP_COMPARE_SAMPLER_DESCRIPTOR.js";
19
- import { STATIC_GRAPHICS_ENGINE_ASSETS } from "../../../STATIC_GRAPHICS_ENGINE_ASSETS.js";
20
- import { rasterization_material_bucket } from "../../expand/bucket/chunk_rasterization_material_bucket.js";
21
- import { construct_primitive_state } from "../../bucket/construct_primitive_state.js";
22
- import { filter_materials_by_bucket } from "../../bucket/filter_materials_by_bucket.js";
23
- import {
24
- graph_prepare_meshlet_draw_commands_by_material
25
- } from "../../bucket/prepare_meshlet_draw_commands_by_material.js";
26
- import {
27
- RASTERIZATION_SHADER_BIND_GROUP_SCENE,
28
- RASTERIZATION_SHADER_BIND_GROUP_VIEW
29
- } from "../alpha_tested_pass_resources.js";
30
- import { shader_oit_blend } from "./shader_oit_blend.js";
31
- import { shader_oit_generate_moments } from "./shader_oit_generate_moments.js";
32
- import { shader_oit_resolve_moments } from "./shader_oit_resolve_moments.js";
33
- import { shader_oit_resolve_moments_ibl } from "./shader_oit_resolve_moments_ibl.js";
34
- import { SHADING_SCENE_RESOURCE_GROUP } from "./SHADING_SCENE_RESOURCE_GROUP.js";
35
-
36
- const DRAW_COMMAND_BYTE_SIZE = STRUCT_UNINDEXED_DRAW_COMMAND.aligned_size;
37
-
38
- const BIND_GROUP_LAYOUT_SCENE = SHADING_SCENE_RESOURCE_GROUP.generateBindGroupLayoutDescriptor(GPUShaderStage.FRAGMENT | GPUShaderStage.VERTEX);
39
- const BIND_GROUP_LAYOUT_MATERIAL = SHADING_MATERIAL_RESOURCE_GROUP.generateBindGroupLayoutDescriptor(GPUShaderStage.FRAGMENT | GPUShaderStage.VERTEX);
40
- const BIND_GROUP_LAYOUT_LIGHT = SHADING_LIGHT_RESOURCE_GROUP.generateBindGroupLayoutDescriptor(GPUShaderStage.FRAGMENT | GPUShaderStage.VERTEX);
41
-
42
-
43
- /**
44
- *
45
- * @param {GPUMaterialManager} material_manager
46
- * @param {number} material_count
47
- * @param {ShadeMaterial[]} materials
48
- * @param {RenderPassDescriptor} render_pass_descriptor
49
- * @param {BindGroupManager} bind_manager
50
- * @param {ShadeGPURenderPassEncoder} pass_encoder
51
- * @param {GPUBuffer} command_buffer_draw
52
- */
53
- function material_draw(
54
- material_manager,
55
- material_count,
56
- materials,
57
- render_pass_descriptor,
58
- bind_manager,
59
- pass_encoder,
60
- command_buffer_draw
61
- ) {
62
-
63
- assert.defined(material_manager, 'material_manager');
64
- assert.isNonNegativeInteger(material_count, 'material_count');
65
- assert.isArray(materials, 'materials');
66
-
67
- for (let i = 0; i < material_count; i++) {
68
-
69
- const material = materials[i];
70
- const gpu_material = material_manager.obtain(material);
71
-
72
- if (!gpu_material.is_built) {
73
- // skip, not ready for rendering
74
- continue;
75
- }
76
-
77
- const material_resource_group = render_pass_descriptor.resources.groups[0];
78
- const binding_entries = material_resource_group.generateBindings(gpu_material.binding_data);
79
- const material_bindings = bind_manager.obtain(BindGroupDescriptor.from(
80
- BIND_GROUP_LAYOUT_MATERIAL,
81
- binding_entries
82
- ));
83
-
84
- // set material-specific bind group at 0
85
- pass_encoder.setBindGroup(0, material_bindings)
86
-
87
- pass_encoder.drawIndirect(
88
- command_buffer_draw,
89
- i * DRAW_COMMAND_BYTE_SIZE,
90
- );
91
-
92
- }
93
- }
94
-
95
- /**
96
- *
97
- * @param {FrameGraph} graph
98
- * @param {GPUViewContext} view_ctx
99
- * @param {number} material_count
100
- * @param {ShadeMaterial[]} materials
101
- * @param {boolean} [clear_targets]
102
- * @param {number} texture_moments
103
- * @param {number} texture_optical_depth
104
- * @param {number} draw_commands
105
- * @param {number} meshlets
106
- * @param {number} depth_texture
107
- * @param {number} light_cluster_parameters
108
- * @param {number} light_cluster_lookup
109
- * @param {number} light_cluster_data
110
- * @param {number} shadowmap_atlas
111
- * @param {number} output
112
- * @param {PrimitiveState} primitive
113
- * @param {ShadeIndirectLightingMode} indirect_lighting_mode
114
- * @return {number}
115
- */
116
- function graph_oit_resolve_moments({
117
- graph,
118
- view_ctx,
119
- material_count,
120
- materials,
121
- clear_targets = true,
122
- texture_moments,
123
- texture_optical_depth,
124
- draw_commands,
125
- meshlets,
126
- depth_texture ,
127
- primitive,
128
- light_cluster_parameters ,
129
- light_cluster_lookup ,
130
- light_cluster_data ,
131
-
132
- shadowmap_atlas ,
133
-
134
- volumetrics_lut,
135
- volumetrics_metadata,
136
-
137
- output = -1,
138
- indirect_lighting_mode = ShadeIndirectLightingMode.IBL,
139
- }) {
140
-
141
- assert.isNonNegativeInteger(material_count, 'material_count');
142
- assert.isNonNegativeInteger(draw_commands, 'draw_commands');
143
- assert.isNonNegativeInteger(meshlets, 'meshlets');
144
-
145
- const scene_ctx = view_ctx.scene;
146
-
147
- /**
148
- *
149
- * @param data
150
- * @param {FramePassResources} resources
151
- * @param {GraphicsExecutionContext} context
152
- */
153
- function execute(data, resources, context) {
154
-
155
- assert.ok(context.graphics.device.features.has("indirect-first-instance"), '"indirect-first-instance" feature needs to be enabled for non-zero firstInstance values to be used.')
156
-
157
- const command_buffer_draw = resources.get(data.draw_commands);
158
- const meshlet_buffer = resources.get(data.meshlets);
159
-
160
- const t_moments = resources.get(data.moments);
161
- const t_optical_depth = resources.get(data.optical_depth);
162
- const t_resolved = resources.get(data.resolved);
163
- const t_depth = resources.get(data.depth);
164
-
165
- const light_cluster_parameters = resources.get(data.light_cluster_parameters);
166
- const light_cluster_lookup = resources.get(data.light_cluster_lookup);
167
- const light_cluster_data = resources.get(data.light_cluster_data);
168
-
169
- const shadowmap_atlas = resources.get(data.shadowmap_atlas);
170
-
171
- const t_volumetrics_lut = resources.get(data.volumetrics_lut);
172
- const volumetrics_metadata = resources.get(data.volumetrics_metadata);
173
-
174
- const encoder = context.encoder;
175
-
176
- const graphics = context.graphics;
177
-
178
- const bind_manager = graphics.bind_groups;
179
-
180
- const scene_bindings = bind_manager.obtain(BindGroupDescriptor.from(
181
- BIND_GROUP_LAYOUT_SCENE,
182
- [
183
- { buffer: meshlet_buffer },
184
- { buffer: scene_ctx.geometries.meshlets.buffer_metadata },
185
- { buffer: scene_ctx.geometries.meshlets.buffer_data },
186
- { buffer: scene_ctx.scene_database_buffer },
187
- { buffer: scene_ctx.geometries.buffer_metadata },
188
- ]
189
- ));
190
-
191
- const sampler_shadowmap = context.graphics.samplers.obtain(SHADOWMAP_COMPARE_SAMPLER_DESCRIPTOR);
192
-
193
- const light_bindings = bind_manager.obtain(BindGroupDescriptor.from(
194
- BIND_GROUP_LAYOUT_LIGHT,
195
- [
196
- { buffer: view_ctx.scene.lights.buffer_data },
197
- view_ctx.scene.lights.environment.obtainView(),
198
- //
199
- { buffer: light_cluster_parameters },
200
- { buffer: light_cluster_lookup },
201
- { buffer: light_cluster_data },
202
- //
203
- shadowmap_atlas.obtainView(),
204
- sampler_shadowmap,
205
- ]
206
- ));
207
-
208
- // Select render pass descriptor based on indirect lighting mode
209
- const use_brick4 = data.indirect_lighting_mode === ShadeIndirectLightingMode.Brick4;
210
- const render_pass_descriptor = use_brick4
211
- ? shader_oit_resolve_moments
212
- : shader_oit_resolve_moments_ibl;
213
-
214
- const pass_encoder = encoder.beginRenderPass(render_pass_descriptor.toGPU({
215
- colorTargets: [t_resolved],
216
- depthTarget: t_depth,
217
- colorLoadOp: clear_targets ? "clear" : "load",
218
- depthLoadOp: "load",
219
- storeOp: "store",
220
- }));
221
-
222
- const pipeline_descriptor = rp_rewrite_for_primitive_state(render_pass_descriptor.pipeline, primitive);
223
-
224
- const pipeline = graphics.render_pipelines.obtain(pipeline_descriptor)
225
- pass_encoder.setPipeline(pipeline);
226
-
227
- pass_encoder.setBindGroup(RASTERIZATION_SHADER_BIND_GROUP_SCENE, scene_bindings);
228
- pass_encoder.setBindGroup(3, light_bindings);
229
-
230
- const sampler_linear = graphics.samplers.obtain(SamplerDescriptor.from({
231
- magFilter: "linear",
232
- }));
233
-
234
- const t_split_sum_lut = graphics.textures.obtain(STATIC_GRAPHICS_ENGINE_ASSETS.split_sum);
235
-
236
- const stbn_vec3 = graphics.textures.obtain(STATIC_GRAPHICS_ENGINE_ASSETS.stbn_vec3);
237
-
238
- // Brick4 variant requires brick4 buffer in the view bind group;
239
- // IBL variant does not. Volumetrics bindings are appended last (after sLinear), matching
240
- // the order declared in shader_oit_resolve_moments[_ibl].
241
- const view_bind_entries = use_brick4
242
- ? [
243
- { buffer: view_ctx.camera.buffer.buffer },
244
- { buffer: view_ctx.uniform_buffer.buffer },
245
- t_moments.obtainView(),
246
- t_optical_depth.obtainView(),
247
- { buffer: view_ctx.scene.volumetric_light_map.buffer },
248
- t_split_sum_lut.obtainView(),
249
- sampler_linear,
250
- // volumetrics
251
- { buffer: volumetrics_metadata },
252
- t_volumetrics_lut.obtainView(),
253
- stbn_vec3.obtainView(),
254
- ]
255
- : [
256
- { buffer: view_ctx.camera.buffer.buffer },
257
- { buffer: view_ctx.uniform_buffer.buffer },
258
- t_moments.obtainView(),
259
- t_optical_depth.obtainView(),
260
- t_split_sum_lut.obtainView(),
261
- sampler_linear,
262
- // volumetrics
263
- { buffer: volumetrics_metadata },
264
- t_volumetrics_lut.obtainView(),
265
- stbn_vec3.obtainView(),
266
- ];
267
-
268
- const view_bindings = bind_manager.obtain(BindGroupDescriptor.from(
269
- render_pass_descriptor.pipeline.layout.bindGroupLayouts[RASTERIZATION_SHADER_BIND_GROUP_VIEW],
270
- view_bind_entries
271
- ));
272
-
273
- pass_encoder.setBindGroup(RASTERIZATION_SHADER_BIND_GROUP_VIEW, view_bindings);
274
-
275
- material_draw(
276
- scene_ctx.materials,
277
- material_count,
278
- materials,
279
- render_pass_descriptor,
280
- bind_manager,
281
- pass_encoder,
282
- command_buffer_draw
283
- );
284
-
285
- pass_encoder.end();
286
-
287
- }
288
-
289
- const pass_data = {
290
- indirect_lighting_mode,
291
- };
292
- const pass = graph.add("MBOIT/resolve moments", pass_data, execute);
293
-
294
- pass_data.draw_commands = pass.read(draw_commands);
295
- pass_data.meshlets = pass.read(meshlets)
296
-
297
- pass_data.depth = pass.read(depth_texture);
298
-
299
- pass_data.optical_depth = pass.read(texture_optical_depth);
300
- pass_data.moments = pass.read(texture_moments);
301
-
302
- if (output !== -1) {
303
- pass.read(output);
304
- pass_data.resolved = pass.write(output);
305
- } else {
306
- pass_data.resolved = pass.create("OIT resolved", TextureResourceDescriptor.from({
307
- resolution: view_ctx.resolution,
308
- format: 'rgba16float',
309
- usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING
310
- }));
311
- }
312
-
313
- pass_data.light_cluster_parameters = pass.read(light_cluster_parameters);
314
- pass_data.light_cluster_lookup = pass.read(light_cluster_lookup);
315
- pass_data.light_cluster_data = pass.read(light_cluster_data);
316
-
317
- pass_data.shadowmap_atlas = pass.read(shadowmap_atlas);
318
-
319
- pass_data.volumetrics_lut = pass.read(volumetrics_lut);
320
- pass_data.volumetrics_metadata = pass.read(volumetrics_metadata);
321
-
322
- return pass_data.resolved;
323
- }
324
-
325
- /**
326
- *
327
- * @param {FrameGraph} graph
328
- * @param {GPUViewContext} view_ctx
329
- * @param {number} material_count
330
- * @param {ShadeMaterial[]} materials
331
- * @param {number} draw_commands resource ID
332
- * @param {number} meshlets resource ID
333
- * @param {number} depth_texture resource ID
334
- * @param {number} [output_optical_depth]
335
- * @param {number} [output_moments]
336
- * @param {PrimitiveState} primitive
337
- * @param {boolean} [clear_targets]
338
- * @return {{optical_depth:number, moments:number}}
339
- */
340
- function graph_oit_generate_moments({
341
- graph,
342
- view_ctx,
343
- material_count,
344
- materials,
345
- draw_commands,
346
- meshlets,
347
- depth_texture ,
348
- output_optical_depth = -1,
349
- output_moments = -1,
350
- primitive,
351
- clear_targets = true,
352
- }) {
353
-
354
- assert.isNonNegativeInteger(material_count, 'material_count');
355
- assert.isNonNegativeInteger(draw_commands, 'draw_commands');
356
- assert.isNonNegativeInteger(meshlets, 'meshlets');
357
- assert.equal(view_ctx.isGPUViewContext, true, 'view_ctx.isGPUViewContext !== true');
358
-
359
-
360
- const scene_ctx = view_ctx.scene;
361
-
362
- /**
363
- *
364
- * @param data
365
- * @param {FramePassResources} resources
366
- * @param {GraphicsExecutionContext} context
367
- */
368
- function execute(data, resources, context) {
369
-
370
- assert.ok(context.graphics.device.features.has("indirect-first-instance"), '"indirect-first-instance" feature needs to be enabled for non-zero firstInstance values to be used.')
371
-
372
-
373
- const command_buffer_draw = resources.get(data.draw_commands);
374
- const meshlet_buffer = resources.get(data.meshlets);
375
-
376
- const t_moments = resources.get(data.moments);
377
- const t_optical_depth = resources.get(data.optical_depth);
378
- const t_depth = resources.get(data.depth);
379
-
380
- const encoder = context.encoder;
381
-
382
- const graphics = context.graphics;
383
-
384
- const bind_manager = graphics.bind_groups;
385
-
386
- const scene_bindings = bind_manager.obtain(BindGroupDescriptor.from(
387
- BIND_GROUP_LAYOUT_SCENE,
388
- [
389
- { buffer: meshlet_buffer },
390
- { buffer: scene_ctx.geometries.meshlets.buffer_metadata },
391
- { buffer: scene_ctx.geometries.meshlets.buffer_data },
392
- { buffer: scene_ctx.scene_database_buffer },
393
- { buffer: scene_ctx.geometries.buffer_metadata },
394
- ]
395
- ));
396
-
397
- const render_pass_descriptor = shader_oit_generate_moments;
398
- const pass_encoder = encoder.beginRenderPass(render_pass_descriptor.toGPU({
399
- colorTargets: [
400
- t_optical_depth,
401
- t_moments,
402
- ],
403
- depthTarget: t_depth,
404
- colorLoadOp: clear_targets ? "clear" : "load",
405
- // we don't modify depth, only use it for depth test
406
- depthLoadOp: "load",
407
- storeOp: "store",
408
- }));
409
-
410
- const pipeline_descriptor = rp_rewrite_for_primitive_state(render_pass_descriptor.pipeline, primitive);
411
-
412
- const pipeline = graphics.render_pipelines.obtain(pipeline_descriptor)
413
- pass_encoder.setPipeline(pipeline);
414
-
415
- pass_encoder.setBindGroup(RASTERIZATION_SHADER_BIND_GROUP_SCENE, scene_bindings);
416
-
417
- const view_bindings = bind_manager.obtain(BindGroupDescriptor.from(
418
- render_pass_descriptor.pipeline.layout.bindGroupLayouts[RASTERIZATION_SHADER_BIND_GROUP_VIEW],
419
- [
420
- { buffer: view_ctx.camera.buffer.buffer },
421
- { buffer: view_ctx.uniform_buffer.buffer },
422
- ]
423
- ));
424
-
425
- pass_encoder.setBindGroup(RASTERIZATION_SHADER_BIND_GROUP_VIEW, view_bindings);
426
-
427
- material_draw(
428
- scene_ctx.materials,
429
- material_count,
430
- materials,
431
- render_pass_descriptor,
432
- bind_manager,
433
- pass_encoder,
434
- command_buffer_draw
435
- );
436
-
437
- pass_encoder.end();
438
-
439
- }
440
-
441
- const pass_data = {};
442
- const pass = graph.add("MBOIT/generate moments", pass_data, execute);
443
-
444
- pass_data.draw_commands = pass.read(draw_commands);
445
- pass_data.meshlets = pass.read(meshlets)
446
-
447
- pass_data.depth = pass.read(depth_texture);
448
-
449
- if (output_optical_depth !== -1) {
450
- pass.read(output_optical_depth);
451
- pass_data.optical_depth = pass.write(output_optical_depth);
452
- } else {
453
- pass_data.optical_depth = pass.create("OIT depth", TextureResourceDescriptor.from({
454
- resolution: view_ctx.resolution,
455
- format: 'r32float',
456
- usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING
457
- }));
458
- }
459
-
460
- if (output_moments !== -1) {
461
- pass.read(output_moments);
462
- pass_data.moments = pass.write(output_moments);
463
- } else {
464
-
465
- pass_data.moments = pass.create('OIT moments', TextureResourceDescriptor.from({
466
- resolution: view_ctx.resolution,
467
- format: 'rgba32float',
468
- usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING
469
- }));
470
- }
471
-
472
- return {
473
- optical_depth: pass_data.optical_depth,
474
- moments: pass_data.moments
475
- }
476
- }
477
-
478
- /**
479
- * Order-independent transparency. Does not write depth.
480
- *
481
- * @param {FrameGraph} graph
482
- * @param {number} buckets
483
- * @param {GPUViewContext} view_ctx
484
- * @param {number[]} viewport
485
- * @param {number} color_texture resource ID
486
- * @param {number} [depth_texture] resource ID
487
- * @param {GPUCollectionLimits} limits
488
- * @param {number} light_cluster_parameters
489
- * @param {number} light_cluster_lookup
490
- * @param {number} light_cluster_data
491
- * @param {number} shadowmap_atlas
492
- * @param {ShadeIndirectLightingMode} indirect_lighting_mode
493
- * @returns {number} resource ID of modified color texture
494
- */
495
- export function graph_rasterize_meshes_transparent_oit({
496
- graph,
497
- buckets,
498
- view_ctx,
499
- viewport,
500
- depth_texture ,
501
- color_texture,
502
- limits,
503
- light_cluster_parameters ,
504
- light_cluster_lookup ,
505
- light_cluster_data ,
506
-
507
- shadowmap_atlas ,
508
-
509
- volumetrics_lut,
510
- volumetrics_metadata,
511
-
512
- indirect_lighting_mode = ShadeIndirectLightingMode.IBL,
513
- }) {
514
-
515
-
516
- assert.isNonNegativeInteger(buckets, 'buckets');
517
-
518
- assert.isNonNegativeInteger(light_cluster_parameters, 'light_cluster_parameters');
519
- assert.isNonNegativeInteger(light_cluster_lookup, 'light_cluster_lookup');
520
- assert.isNonNegativeInteger(light_cluster_data, 'light_cluster_data');
521
-
522
- assert.isNonNegativeInteger(shadowmap_atlas, 'shadowmap_atlas');
523
-
524
-
525
- assert.equal(view_ctx.isGPUViewContext, true, 'view_ctx.isGPUViewContext !== true');
526
-
527
- const scene_ctx = view_ctx.scene;
528
-
529
- /**
530
- *
531
- * @type {ShadeMaterial[]}
532
- */
533
- const materials_front = [];
534
- /**
535
- *
536
- * @type {ShadeMaterial[]}
537
- */
538
- const materials_double = [];
539
-
540
- const scene_materials = scene_ctx.scene.instances.materials;
541
-
542
- // we need to draw with different pipeline states, so the code is a little convoluted
543
- // Essentially, we draw Double-side and Front-sided materials
544
-
545
- const material_count_front = filter_materials_by_bucket(
546
- materials_front, 0,
547
- TransparencyMode.Transparent,
548
- ShadeDrawMode.Triangles,
549
- ShadeDrawSide.Front,
550
- scene_materials,
551
- scene_materials.length
552
- );
553
-
554
- const material_count_double = filter_materials_by_bucket(
555
- materials_double, 0,
556
- TransparencyMode.Transparent,
557
- ShadeDrawMode.Triangles,
558
- ShadeDrawSide.Double,
559
- scene_materials,
560
- scene_materials.length
561
- );
562
-
563
- if ((material_count_front + material_count_double) === 0) {
564
- // nothing to do
565
- return color_texture;
566
- }
567
-
568
- // TODO prepare depth bounds (min-max) for better moments, using meshlet metadata that has survived the cull
569
- // tight bounds will help improve reconstruction accuracy according to the original paper
570
-
571
- const bucket_index_front = rasterization_material_bucket(
572
- TransparencyMode.Transparent, ShadeDrawMode.Triangles, ShadeDrawSide.Front
573
- );
574
-
575
- const bucket_index_double = rasterization_material_bucket(
576
- TransparencyMode.Transparent, ShadeDrawMode.Triangles, ShadeDrawSide.Double
577
- );
578
-
579
- const primitive_front = construct_primitive_state(
580
- ShadeDrawMode.Triangles, ShadeDrawSide.Front,
581
- );
582
- const primitive_double = construct_primitive_state(
583
- ShadeDrawMode.Triangles, ShadeDrawSide.Double,
584
- );
585
-
586
- const gr_hzb = graph_import_texture(graph, view_ctx.hierarchical_z_buffer.texture);
587
- const gr_camera = graph_import_buffer(graph, view_ctx.camera.buffer.buffer);
588
-
589
- // Prepare draw artifacts
590
- // ======
591
-
592
- const {
593
- meshlets: meshlets_front,
594
- draw_commands: draw_commands_front
595
- } = graph_prepare_meshlet_draw_commands_by_material({
596
- graph,
597
- materials: materials_front,
598
- bucket_id: bucket_index_front,
599
- limits,
600
- buckets,
601
- scene: scene_ctx,
602
- camera: gr_camera,
603
- hzb: gr_hzb,
604
- resolution: [viewport[2], viewport[3]],
605
- label: `${view_ctx.label}/OIT-front`,
606
- });
607
-
608
- const {
609
- meshlets: meshlets_double,
610
- draw_commands: draw_commands_double
611
- } = graph_prepare_meshlet_draw_commands_by_material({
612
- graph,
613
- materials: materials_double,
614
- bucket_id: bucket_index_double,
615
- limits,
616
- buckets,
617
- scene: scene_ctx,
618
- camera: gr_camera,
619
- hzb: gr_hzb,
620
- resolution: [viewport[2], viewport[3]],
621
- label: `${view_ctx.label}/OIT-double`,
622
- });
623
-
624
- // Generate moments
625
- // ==========
626
-
627
- const { moments: moments_front, optical_depth: optical_depth_front } = graph_oit_generate_moments({
628
- graph,
629
- view_ctx,
630
- material_count: material_count_front,
631
- meshlets: meshlets_front,
632
- clear_targets: true,
633
- materials: materials_front,
634
- draw_commands: draw_commands_front,
635
- depth_texture,
636
- primitive: primitive_front,
637
- });
638
-
639
- const { moments, optical_depth } = graph_oit_generate_moments({
640
- graph,
641
- view_ctx,
642
- material_count: material_count_double,
643
- meshlets: meshlets_double,
644
- clear_targets: false,
645
- materials: materials_double,
646
- draw_commands: draw_commands_double,
647
- output_optical_depth: optical_depth_front,
648
- output_moments: moments_front,
649
- depth_texture,
650
- primitive: primitive_double,
651
- });
652
-
653
- // Resolve moments
654
- // ===========
655
-
656
- let resolved = graph_oit_resolve_moments({
657
- graph,
658
- view_ctx,
659
- primitive: primitive_front,
660
- material_count: material_count_front,
661
- materials: materials_front,
662
- clear_targets: true,
663
- draw_commands: draw_commands_front,
664
- meshlets: meshlets_front,
665
- depth_texture,
666
- texture_moments: moments,
667
- texture_optical_depth: optical_depth,
668
-
669
- //
670
- light_cluster_parameters,
671
- light_cluster_lookup,
672
- light_cluster_data,
673
-
674
- shadowmap_atlas,
675
-
676
- volumetrics_lut,
677
- volumetrics_metadata,
678
-
679
- indirect_lighting_mode,
680
- });
681
-
682
- resolved = graph_oit_resolve_moments({
683
- graph,
684
- view_ctx,
685
- primitive: primitive_double,
686
- output: resolved,
687
- material_count: material_count_double,
688
- materials: materials_double,
689
- clear_targets: false,
690
- draw_commands: draw_commands_double,
691
- meshlets: meshlets_double,
692
- depth_texture,
693
- texture_moments: moments,
694
- texture_optical_depth: optical_depth,
695
-
696
- //
697
- light_cluster_parameters,
698
- light_cluster_lookup,
699
- light_cluster_data,
700
-
701
- shadowmap_atlas,
702
-
703
- volumetrics_lut,
704
- volumetrics_metadata,
705
-
706
- indirect_lighting_mode,
707
- });
708
-
709
- const [blended] = graph_image_pass({
710
- graph,
711
- shader: shader_oit_blend,
712
- output: [color_texture],
713
- load_op: "load",
714
- store_op: "store",
715
- inputs: {
716
- transparent: resolved,
717
- moment_zero: optical_depth,
718
- }
719
- });
720
-
721
-
722
- return blended;
1
+ import { assert } from "../../../../../core/assert.js";
2
+ import { SamplerDescriptor } from "../../../../descriptor/texture/SamplerDescriptor.js";
3
+ import { TextureResourceDescriptor } from "../../../../device/graph/TextureResourceDescriptor.js";
4
+ import { rp_rewrite_for_primitive_state } from "../../../../device/pipeline/rp_rewrite_for_primitive_state.js";
5
+ import { BindGroupDescriptor } from "../../../binding/BindGroupDescriptor.js";
6
+ import { SHADING_LIGHT_RESOURCE_GROUP } from "../../../deferred/SHADING_LIGHT_RESOURCE_GROUP.js";
7
+ import { ShadeDrawMode } from "../../../material/ShadeDrawMode.js";
8
+ import { ShadeDrawSide } from "../../../material/ShadeDrawSide.js";
9
+ import { TransparencyMode } from "../../../material/TransparencyMode.js";
10
+ import { ShadeIndirectLightingMode } from "../../../ShadeIndirectLightingMode.js";
11
+ import { graph_image_pass } from "../../../shader/graph/graph_image_pass.js";
12
+ import { graph_import_buffer } from "../../../shader/graph/graph_import_buffer.js";
13
+ import { graph_import_texture } from "../../../shader/graph/graph_import_texture.js";
14
+ import {
15
+ SHADOWMAP_COMPARE_SAMPLER_DESCRIPTOR
16
+ } from "../../../shadow/map/SHADOWMAP_COMPARE_SAMPLER_DESCRIPTOR.js";
17
+ import { STATIC_GRAPHICS_ENGINE_ASSETS } from "../../../STATIC_GRAPHICS_ENGINE_ASSETS.js";
18
+ import { rasterization_material_bucket } from "../../expand/bucket/chunk_rasterization_material_bucket.js";
19
+ import { construct_primitive_state } from "../../bucket/construct_primitive_state.js";
20
+ import { filter_materials_by_bucket } from "../../bucket/filter_materials_by_bucket.js";
21
+ import {
22
+ graph_prepare_meshlet_draw_commands_by_material
23
+ } from "../../bucket/prepare_meshlet_draw_commands_by_material.js";
24
+ import {
25
+ RASTERIZATION_SHADER_BIND_GROUP_SCENE,
26
+ RASTERIZATION_SHADER_BIND_GROUP_VIEW
27
+ } from "../alpha_tested_pass_resources.js";
28
+ import { material_draw_indirect } from "../material_draw_indirect.js";
29
+ import { shader_oit_blend } from "./shader_oit_blend.js";
30
+ import { shader_oit_generate_moments } from "./shader_oit_generate_moments.js";
31
+ import { shader_oit_resolve_moments } from "./shader_oit_resolve_moments.js";
32
+ import { shader_oit_resolve_moments_ibl } from "./shader_oit_resolve_moments_ibl.js";
33
+ import { SHADING_SCENE_RESOURCE_GROUP } from "../../forward/SHADING_SCENE_RESOURCE_GROUP.js";
34
+
35
+ const BIND_GROUP_LAYOUT_SCENE = SHADING_SCENE_RESOURCE_GROUP.generateBindGroupLayoutDescriptor(GPUShaderStage.FRAGMENT | GPUShaderStage.VERTEX);
36
+ const BIND_GROUP_LAYOUT_LIGHT = SHADING_LIGHT_RESOURCE_GROUP.generateBindGroupLayoutDescriptor(GPUShaderStage.FRAGMENT | GPUShaderStage.VERTEX);
37
+
38
+ /**
39
+ *
40
+ * @param {FrameGraph} graph
41
+ * @param {GPUViewContext} view_ctx
42
+ * @param {number} material_count
43
+ * @param {ShadeMaterial[]} materials
44
+ * @param {boolean} [clear_targets]
45
+ * @param {number} texture_moments
46
+ * @param {number} texture_optical_depth
47
+ * @param {number} draw_commands
48
+ * @param {number} meshlets
49
+ * @param {number} depth_texture
50
+ * @param {number} light_cluster_parameters
51
+ * @param {number} light_cluster_lookup
52
+ * @param {number} light_cluster_data
53
+ * @param {number} shadowmap_atlas
54
+ * @param {number} output
55
+ * @param {PrimitiveState} primitive
56
+ * @param {ShadeIndirectLightingMode} indirect_lighting_mode
57
+ * @return {number}
58
+ */
59
+ function graph_oit_resolve_moments({
60
+ graph,
61
+ view_ctx,
62
+ material_count,
63
+ materials,
64
+ clear_targets = true,
65
+ texture_moments,
66
+ texture_optical_depth,
67
+ draw_commands,
68
+ meshlets,
69
+ depth_texture ,
70
+ primitive,
71
+ light_cluster_parameters ,
72
+ light_cluster_lookup ,
73
+ light_cluster_data ,
74
+
75
+ shadowmap_atlas ,
76
+
77
+ volumetrics_lut,
78
+ volumetrics_metadata,
79
+
80
+ output = -1,
81
+ indirect_lighting_mode = ShadeIndirectLightingMode.IBL,
82
+ }) {
83
+
84
+ assert.isNonNegativeInteger(material_count, 'material_count');
85
+ assert.isNonNegativeInteger(draw_commands, 'draw_commands');
86
+ assert.isNonNegativeInteger(meshlets, 'meshlets');
87
+
88
+ const scene_ctx = view_ctx.scene;
89
+
90
+ /**
91
+ *
92
+ * @param data
93
+ * @param {FramePassResources} resources
94
+ * @param {GraphicsExecutionContext} context
95
+ */
96
+ function execute(data, resources, context) {
97
+
98
+ assert.ok(context.graphics.device.features.has("indirect-first-instance"), '"indirect-first-instance" feature needs to be enabled for non-zero firstInstance values to be used.')
99
+
100
+ const command_buffer_draw = resources.get(data.draw_commands);
101
+ const meshlet_buffer = resources.get(data.meshlets);
102
+
103
+ const t_moments = resources.get(data.moments);
104
+ const t_optical_depth = resources.get(data.optical_depth);
105
+ const t_resolved = resources.get(data.resolved);
106
+ const t_depth = resources.get(data.depth);
107
+
108
+ const light_cluster_parameters = resources.get(data.light_cluster_parameters);
109
+ const light_cluster_lookup = resources.get(data.light_cluster_lookup);
110
+ const light_cluster_data = resources.get(data.light_cluster_data);
111
+
112
+ const shadowmap_atlas = resources.get(data.shadowmap_atlas);
113
+
114
+ const t_volumetrics_lut = resources.get(data.volumetrics_lut);
115
+ const volumetrics_metadata = resources.get(data.volumetrics_metadata);
116
+
117
+ const encoder = context.encoder;
118
+
119
+ const graphics = context.graphics;
120
+
121
+ const bind_manager = graphics.bind_groups;
122
+
123
+ const scene_bindings = bind_manager.obtain(BindGroupDescriptor.from(
124
+ BIND_GROUP_LAYOUT_SCENE,
125
+ [
126
+ { buffer: meshlet_buffer },
127
+ { buffer: scene_ctx.geometries.meshlets.buffer_metadata },
128
+ { buffer: scene_ctx.geometries.meshlets.buffer_data },
129
+ { buffer: scene_ctx.scene_database_buffer },
130
+ { buffer: scene_ctx.geometries.buffer_metadata },
131
+ ]
132
+ ));
133
+
134
+ const sampler_shadowmap = context.graphics.samplers.obtain(SHADOWMAP_COMPARE_SAMPLER_DESCRIPTOR);
135
+
136
+ const light_bindings = bind_manager.obtain(BindGroupDescriptor.from(
137
+ BIND_GROUP_LAYOUT_LIGHT,
138
+ [
139
+ { buffer: view_ctx.scene.lights.buffer_data },
140
+ view_ctx.scene.lights.environment.obtainView(),
141
+ //
142
+ { buffer: light_cluster_parameters },
143
+ { buffer: light_cluster_lookup },
144
+ { buffer: light_cluster_data },
145
+ //
146
+ shadowmap_atlas.obtainView(),
147
+ sampler_shadowmap,
148
+ ]
149
+ ));
150
+
151
+ // Select render pass descriptor based on indirect lighting mode
152
+ const use_brick4 = data.indirect_lighting_mode === ShadeIndirectLightingMode.Brick4;
153
+ const render_pass_descriptor = use_brick4
154
+ ? shader_oit_resolve_moments
155
+ : shader_oit_resolve_moments_ibl;
156
+
157
+ const pass_encoder = encoder.beginRenderPass(render_pass_descriptor.toGPU({
158
+ colorTargets: [t_resolved],
159
+ depthTarget: t_depth,
160
+ colorLoadOp: clear_targets ? "clear" : "load",
161
+ depthLoadOp: "load",
162
+ storeOp: "store",
163
+ }));
164
+
165
+ const pipeline_descriptor = rp_rewrite_for_primitive_state(render_pass_descriptor.pipeline, primitive);
166
+
167
+ const pipeline = graphics.render_pipelines.obtain(pipeline_descriptor)
168
+ pass_encoder.setPipeline(pipeline);
169
+
170
+ pass_encoder.setBindGroup(RASTERIZATION_SHADER_BIND_GROUP_SCENE, scene_bindings);
171
+ pass_encoder.setBindGroup(3, light_bindings);
172
+
173
+ const sampler_linear = graphics.samplers.obtain(SamplerDescriptor.from({
174
+ magFilter: "linear",
175
+ }));
176
+
177
+ const t_split_sum_lut = graphics.textures.obtain(STATIC_GRAPHICS_ENGINE_ASSETS.split_sum);
178
+
179
+ const stbn_vec3 = graphics.textures.obtain(STATIC_GRAPHICS_ENGINE_ASSETS.stbn_vec3);
180
+
181
+ // Brick4 variant requires brick4 buffer in the view bind group;
182
+ // IBL variant does not. Volumetrics bindings are appended last (after sLinear), matching
183
+ // the order declared in shader_oit_resolve_moments[_ibl].
184
+ const view_bind_entries = use_brick4
185
+ ? [
186
+ { buffer: view_ctx.camera.buffer.buffer },
187
+ { buffer: view_ctx.uniform_buffer.buffer },
188
+ t_moments.obtainView(),
189
+ t_optical_depth.obtainView(),
190
+ { buffer: view_ctx.scene.volumetric_light_map.buffer },
191
+ t_split_sum_lut.obtainView(),
192
+ sampler_linear,
193
+ // volumetrics
194
+ { buffer: volumetrics_metadata },
195
+ t_volumetrics_lut.obtainView(),
196
+ stbn_vec3.obtainView(),
197
+ ]
198
+ : [
199
+ { buffer: view_ctx.camera.buffer.buffer },
200
+ { buffer: view_ctx.uniform_buffer.buffer },
201
+ t_moments.obtainView(),
202
+ t_optical_depth.obtainView(),
203
+ t_split_sum_lut.obtainView(),
204
+ sampler_linear,
205
+ // volumetrics
206
+ { buffer: volumetrics_metadata },
207
+ t_volumetrics_lut.obtainView(),
208
+ stbn_vec3.obtainView(),
209
+ ];
210
+
211
+ const view_bindings = bind_manager.obtain(BindGroupDescriptor.from(
212
+ render_pass_descriptor.pipeline.layout.bindGroupLayouts[RASTERIZATION_SHADER_BIND_GROUP_VIEW],
213
+ view_bind_entries
214
+ ));
215
+
216
+ pass_encoder.setBindGroup(RASTERIZATION_SHADER_BIND_GROUP_VIEW, view_bindings);
217
+
218
+ material_draw_indirect(
219
+ scene_ctx.materials,
220
+ material_count,
221
+ materials,
222
+ render_pass_descriptor,
223
+ bind_manager,
224
+ pass_encoder,
225
+ command_buffer_draw
226
+ );
227
+
228
+ pass_encoder.end();
229
+
230
+ }
231
+
232
+ const pass_data = {
233
+ indirect_lighting_mode,
234
+ };
235
+ const pass = graph.add("MBOIT/resolve moments", pass_data, execute);
236
+
237
+ pass_data.draw_commands = pass.read(draw_commands);
238
+ pass_data.meshlets = pass.read(meshlets)
239
+
240
+ pass_data.depth = pass.read(depth_texture);
241
+
242
+ pass_data.optical_depth = pass.read(texture_optical_depth);
243
+ pass_data.moments = pass.read(texture_moments);
244
+
245
+ if (output !== -1) {
246
+ pass.read(output);
247
+ pass_data.resolved = pass.write(output);
248
+ } else {
249
+ pass_data.resolved = pass.create("OIT resolved", TextureResourceDescriptor.from({
250
+ resolution: view_ctx.resolution,
251
+ format: 'rgba16float',
252
+ usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING
253
+ }));
254
+ }
255
+
256
+ pass_data.light_cluster_parameters = pass.read(light_cluster_parameters);
257
+ pass_data.light_cluster_lookup = pass.read(light_cluster_lookup);
258
+ pass_data.light_cluster_data = pass.read(light_cluster_data);
259
+
260
+ pass_data.shadowmap_atlas = pass.read(shadowmap_atlas);
261
+
262
+ pass_data.volumetrics_lut = pass.read(volumetrics_lut);
263
+ pass_data.volumetrics_metadata = pass.read(volumetrics_metadata);
264
+
265
+ return pass_data.resolved;
266
+ }
267
+
268
+ /**
269
+ *
270
+ * @param {FrameGraph} graph
271
+ * @param {GPUViewContext} view_ctx
272
+ * @param {number} material_count
273
+ * @param {ShadeMaterial[]} materials
274
+ * @param {number} draw_commands resource ID
275
+ * @param {number} meshlets resource ID
276
+ * @param {number} depth_texture resource ID
277
+ * @param {number} [output_optical_depth]
278
+ * @param {number} [output_moments]
279
+ * @param {PrimitiveState} primitive
280
+ * @param {boolean} [clear_targets]
281
+ * @return {{optical_depth:number, moments:number}}
282
+ */
283
+ function graph_oit_generate_moments({
284
+ graph,
285
+ view_ctx,
286
+ material_count,
287
+ materials,
288
+ draw_commands,
289
+ meshlets,
290
+ depth_texture ,
291
+ output_optical_depth = -1,
292
+ output_moments = -1,
293
+ primitive,
294
+ clear_targets = true,
295
+ }) {
296
+
297
+ assert.isNonNegativeInteger(material_count, 'material_count');
298
+ assert.isNonNegativeInteger(draw_commands, 'draw_commands');
299
+ assert.isNonNegativeInteger(meshlets, 'meshlets');
300
+ assert.equal(view_ctx.isGPUViewContext, true, 'view_ctx.isGPUViewContext !== true');
301
+
302
+
303
+ const scene_ctx = view_ctx.scene;
304
+
305
+ /**
306
+ *
307
+ * @param data
308
+ * @param {FramePassResources} resources
309
+ * @param {GraphicsExecutionContext} context
310
+ */
311
+ function execute(data, resources, context) {
312
+
313
+ assert.ok(context.graphics.device.features.has("indirect-first-instance"), '"indirect-first-instance" feature needs to be enabled for non-zero firstInstance values to be used.')
314
+
315
+
316
+ const command_buffer_draw = resources.get(data.draw_commands);
317
+ const meshlet_buffer = resources.get(data.meshlets);
318
+
319
+ const t_moments = resources.get(data.moments);
320
+ const t_optical_depth = resources.get(data.optical_depth);
321
+ const t_depth = resources.get(data.depth);
322
+
323
+ const encoder = context.encoder;
324
+
325
+ const graphics = context.graphics;
326
+
327
+ const bind_manager = graphics.bind_groups;
328
+
329
+ const scene_bindings = bind_manager.obtain(BindGroupDescriptor.from(
330
+ BIND_GROUP_LAYOUT_SCENE,
331
+ [
332
+ { buffer: meshlet_buffer },
333
+ { buffer: scene_ctx.geometries.meshlets.buffer_metadata },
334
+ { buffer: scene_ctx.geometries.meshlets.buffer_data },
335
+ { buffer: scene_ctx.scene_database_buffer },
336
+ { buffer: scene_ctx.geometries.buffer_metadata },
337
+ ]
338
+ ));
339
+
340
+ const render_pass_descriptor = shader_oit_generate_moments;
341
+ const pass_encoder = encoder.beginRenderPass(render_pass_descriptor.toGPU({
342
+ colorTargets: [
343
+ t_optical_depth,
344
+ t_moments,
345
+ ],
346
+ depthTarget: t_depth,
347
+ colorLoadOp: clear_targets ? "clear" : "load",
348
+ // we don't modify depth, only use it for depth test
349
+ depthLoadOp: "load",
350
+ storeOp: "store",
351
+ }));
352
+
353
+ const pipeline_descriptor = rp_rewrite_for_primitive_state(render_pass_descriptor.pipeline, primitive);
354
+
355
+ const pipeline = graphics.render_pipelines.obtain(pipeline_descriptor)
356
+ pass_encoder.setPipeline(pipeline);
357
+
358
+ pass_encoder.setBindGroup(RASTERIZATION_SHADER_BIND_GROUP_SCENE, scene_bindings);
359
+
360
+ const view_bindings = bind_manager.obtain(BindGroupDescriptor.from(
361
+ render_pass_descriptor.pipeline.layout.bindGroupLayouts[RASTERIZATION_SHADER_BIND_GROUP_VIEW],
362
+ [
363
+ { buffer: view_ctx.camera.buffer.buffer },
364
+ { buffer: view_ctx.uniform_buffer.buffer },
365
+ ]
366
+ ));
367
+
368
+ pass_encoder.setBindGroup(RASTERIZATION_SHADER_BIND_GROUP_VIEW, view_bindings);
369
+
370
+ material_draw_indirect(
371
+ scene_ctx.materials,
372
+ material_count,
373
+ materials,
374
+ render_pass_descriptor,
375
+ bind_manager,
376
+ pass_encoder,
377
+ command_buffer_draw
378
+ );
379
+
380
+ pass_encoder.end();
381
+
382
+ }
383
+
384
+ const pass_data = {};
385
+ const pass = graph.add("MBOIT/generate moments", pass_data, execute);
386
+
387
+ pass_data.draw_commands = pass.read(draw_commands);
388
+ pass_data.meshlets = pass.read(meshlets)
389
+
390
+ pass_data.depth = pass.read(depth_texture);
391
+
392
+ if (output_optical_depth !== -1) {
393
+ pass.read(output_optical_depth);
394
+ pass_data.optical_depth = pass.write(output_optical_depth);
395
+ } else {
396
+ pass_data.optical_depth = pass.create("OIT depth", TextureResourceDescriptor.from({
397
+ resolution: view_ctx.resolution,
398
+ format: 'r32float',
399
+ usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING
400
+ }));
401
+ }
402
+
403
+ if (output_moments !== -1) {
404
+ pass.read(output_moments);
405
+ pass_data.moments = pass.write(output_moments);
406
+ } else {
407
+
408
+ pass_data.moments = pass.create('OIT moments', TextureResourceDescriptor.from({
409
+ resolution: view_ctx.resolution,
410
+ format: 'rgba32float',
411
+ usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING
412
+ }));
413
+ }
414
+
415
+ return {
416
+ optical_depth: pass_data.optical_depth,
417
+ moments: pass_data.moments
418
+ }
419
+ }
420
+
421
+ /**
422
+ * Order-independent transparency. Does not write depth.
423
+ *
424
+ * @param {FrameGraph} graph
425
+ * @param {number} buckets
426
+ * @param {GPUViewContext} view_ctx
427
+ * @param {number[]} viewport
428
+ * @param {number} color_texture resource ID
429
+ * @param {number} [depth_texture] resource ID
430
+ * @param {GPUCollectionLimits} limits
431
+ * @param {number} light_cluster_parameters
432
+ * @param {number} light_cluster_lookup
433
+ * @param {number} light_cluster_data
434
+ * @param {number} shadowmap_atlas
435
+ * @param {ShadeIndirectLightingMode} indirect_lighting_mode
436
+ * @returns {number} resource ID of modified color texture
437
+ */
438
+ export function graph_rasterize_meshes_transparent_oit({
439
+ graph,
440
+ buckets,
441
+ view_ctx,
442
+ viewport,
443
+ depth_texture ,
444
+ color_texture,
445
+ limits,
446
+ light_cluster_parameters ,
447
+ light_cluster_lookup ,
448
+ light_cluster_data ,
449
+
450
+ shadowmap_atlas ,
451
+
452
+ volumetrics_lut,
453
+ volumetrics_metadata,
454
+
455
+ indirect_lighting_mode = ShadeIndirectLightingMode.IBL,
456
+ }) {
457
+
458
+
459
+ assert.isNonNegativeInteger(buckets, 'buckets');
460
+
461
+ assert.isNonNegativeInteger(light_cluster_parameters, 'light_cluster_parameters');
462
+ assert.isNonNegativeInteger(light_cluster_lookup, 'light_cluster_lookup');
463
+ assert.isNonNegativeInteger(light_cluster_data, 'light_cluster_data');
464
+
465
+ assert.isNonNegativeInteger(shadowmap_atlas, 'shadowmap_atlas');
466
+
467
+
468
+ assert.equal(view_ctx.isGPUViewContext, true, 'view_ctx.isGPUViewContext !== true');
469
+
470
+ const scene_ctx = view_ctx.scene;
471
+
472
+ /**
473
+ *
474
+ * @type {ShadeMaterial[]}
475
+ */
476
+ const materials_front = [];
477
+ /**
478
+ *
479
+ * @type {ShadeMaterial[]}
480
+ */
481
+ const materials_double = [];
482
+
483
+ const scene_materials = scene_ctx.scene.instances.materials;
484
+
485
+ // we need to draw with different pipeline states, so the code is a little convoluted
486
+ // Essentially, we draw Double-side and Front-sided materials
487
+
488
+ const material_count_front = filter_materials_by_bucket(
489
+ materials_front, 0,
490
+ TransparencyMode.Transparent,
491
+ ShadeDrawMode.Triangles,
492
+ ShadeDrawSide.Front,
493
+ scene_materials,
494
+ scene_materials.length
495
+ );
496
+
497
+ const material_count_double = filter_materials_by_bucket(
498
+ materials_double, 0,
499
+ TransparencyMode.Transparent,
500
+ ShadeDrawMode.Triangles,
501
+ ShadeDrawSide.Double,
502
+ scene_materials,
503
+ scene_materials.length
504
+ );
505
+
506
+ if ((material_count_front + material_count_double) === 0) {
507
+ // nothing to do
508
+ return color_texture;
509
+ }
510
+
511
+ // TODO prepare depth bounds (min-max) for better moments, using meshlet metadata that has survived the cull
512
+ // tight bounds will help improve reconstruction accuracy according to the original paper
513
+
514
+ const bucket_index_front = rasterization_material_bucket(
515
+ TransparencyMode.Transparent, ShadeDrawMode.Triangles, ShadeDrawSide.Front
516
+ );
517
+
518
+ const bucket_index_double = rasterization_material_bucket(
519
+ TransparencyMode.Transparent, ShadeDrawMode.Triangles, ShadeDrawSide.Double
520
+ );
521
+
522
+ const primitive_front = construct_primitive_state(
523
+ ShadeDrawMode.Triangles, ShadeDrawSide.Front,
524
+ );
525
+ const primitive_double = construct_primitive_state(
526
+ ShadeDrawMode.Triangles, ShadeDrawSide.Double,
527
+ );
528
+
529
+ const gr_hzb = graph_import_texture(graph, view_ctx.hierarchical_z_buffer.texture);
530
+ const gr_camera = graph_import_buffer(graph, view_ctx.camera.buffer.buffer);
531
+
532
+ // Prepare draw artifacts
533
+ // ======
534
+
535
+ const {
536
+ meshlets: meshlets_front,
537
+ draw_commands: draw_commands_front
538
+ } = graph_prepare_meshlet_draw_commands_by_material({
539
+ graph,
540
+ materials: materials_front,
541
+ bucket_id: bucket_index_front,
542
+ limits,
543
+ buckets,
544
+ scene: scene_ctx,
545
+ camera: gr_camera,
546
+ hzb: gr_hzb,
547
+ resolution: [viewport[2], viewport[3]],
548
+ label: `${view_ctx.label}/OIT-front`,
549
+ });
550
+
551
+ const {
552
+ meshlets: meshlets_double,
553
+ draw_commands: draw_commands_double
554
+ } = graph_prepare_meshlet_draw_commands_by_material({
555
+ graph,
556
+ materials: materials_double,
557
+ bucket_id: bucket_index_double,
558
+ limits,
559
+ buckets,
560
+ scene: scene_ctx,
561
+ camera: gr_camera,
562
+ hzb: gr_hzb,
563
+ resolution: [viewport[2], viewport[3]],
564
+ label: `${view_ctx.label}/OIT-double`,
565
+ });
566
+
567
+ // Generate moments
568
+ // ==========
569
+
570
+ const { moments: moments_front, optical_depth: optical_depth_front } = graph_oit_generate_moments({
571
+ graph,
572
+ view_ctx,
573
+ material_count: material_count_front,
574
+ meshlets: meshlets_front,
575
+ clear_targets: true,
576
+ materials: materials_front,
577
+ draw_commands: draw_commands_front,
578
+ depth_texture,
579
+ primitive: primitive_front,
580
+ });
581
+
582
+ const { moments, optical_depth } = graph_oit_generate_moments({
583
+ graph,
584
+ view_ctx,
585
+ material_count: material_count_double,
586
+ meshlets: meshlets_double,
587
+ clear_targets: false,
588
+ materials: materials_double,
589
+ draw_commands: draw_commands_double,
590
+ output_optical_depth: optical_depth_front,
591
+ output_moments: moments_front,
592
+ depth_texture,
593
+ primitive: primitive_double,
594
+ });
595
+
596
+ // Resolve moments
597
+ // ===========
598
+
599
+ let resolved = graph_oit_resolve_moments({
600
+ graph,
601
+ view_ctx,
602
+ primitive: primitive_front,
603
+ material_count: material_count_front,
604
+ materials: materials_front,
605
+ clear_targets: true,
606
+ draw_commands: draw_commands_front,
607
+ meshlets: meshlets_front,
608
+ depth_texture,
609
+ texture_moments: moments,
610
+ texture_optical_depth: optical_depth,
611
+
612
+ //
613
+ light_cluster_parameters,
614
+ light_cluster_lookup,
615
+ light_cluster_data,
616
+
617
+ shadowmap_atlas,
618
+
619
+ volumetrics_lut,
620
+ volumetrics_metadata,
621
+
622
+ indirect_lighting_mode,
623
+ });
624
+
625
+ resolved = graph_oit_resolve_moments({
626
+ graph,
627
+ view_ctx,
628
+ primitive: primitive_double,
629
+ output: resolved,
630
+ material_count: material_count_double,
631
+ materials: materials_double,
632
+ clear_targets: false,
633
+ draw_commands: draw_commands_double,
634
+ meshlets: meshlets_double,
635
+ depth_texture,
636
+ texture_moments: moments,
637
+ texture_optical_depth: optical_depth,
638
+
639
+ //
640
+ light_cluster_parameters,
641
+ light_cluster_lookup,
642
+ light_cluster_data,
643
+
644
+ shadowmap_atlas,
645
+
646
+ volumetrics_lut,
647
+ volumetrics_metadata,
648
+
649
+ indirect_lighting_mode,
650
+ });
651
+
652
+ const [blended] = graph_image_pass({
653
+ graph,
654
+ shader: shader_oit_blend,
655
+ output: [color_texture],
656
+ load_op: "load",
657
+ store_op: "store",
658
+ inputs: {
659
+ transparent: resolved,
660
+ moment_zero: optical_depth,
661
+ }
662
+ });
663
+
664
+
665
+ return blended;
723
666
  }