viewport_lib/plugin_api/mod.rs
1//! Plugin substrate: target descriptors, shared bind layouts, WGSL helpers,
2//! and pipeline builders.
3//!
4//! This module publishes the pieces a plugin needs to build pipelines that
5//! drop into the lib's existing render passes. A plugin reuses:
6//!
7//! - Target descriptors ([`OpaqueTargetDesc`], [`OitTargetDesc`],
8//! [`MaskTargetDesc`], [`PickTargetDesc`], [`ShadowTargetDesc`]) describe
9//! the render-target formats, blend states, and depth-stencil state each
10//! lib pass expects. Pipelines built against these are compatible with the
11//! corresponding pass.
12//! - [`SharedBindings`] is the group-0 bind layout (camera, lights, shadows,
13//! clip, IBL) shared by every scene pipeline. Plugin pipeline layouts list
14//! it as group 0.
15//! - [`shared_wgsl`] holds string constants with the standard bind
16//! declarations and shading helpers (`viewport_pbr_shade`,
17//! `viewport_oit_pack`, `viewport_sample_csm`, etc.) so plugin shaders stay
18//! in lockstep with the lib's lighting and transparency contracts.
19//! - Pipeline builders on [`crate::resources::DeviceResources`]
20//! (`build_opaque_pipeline`, `build_oit_pipeline`, ...) construct the
21//! common variants in one call. Plugins ship one shader and call a
22//! builder per variant.
23//!
24//! All accessors live on [`crate::resources::DeviceResources`].
25//!
26//! # Compatibility policy
27//!
28//! Pre-1.0, this surface evolves more freely than a stable crate would, but
29//! the policy below describes what plugins can rely on within a given minor
30//! version and how breakage is signalled.
31//!
32//! Plugins are expected to track `viewport-lib` minor versions. The
33//! convention is that a minor bump may rename or remove items the audit
34//! flags as non-additive; a patch bump never does.
35//!
36//! - **Group-0 binding indices ([`SharedBindings`]) are additive-only.**
37//! The constants in `SharedBindings` (`CAMERA_BINDING`, ...) keep their
38//! numeric values forever. New bindings are appended at the next free
39//! index. This is the strongest guarantee in the API: a plugin pipeline
40//! built once stays valid as new bindings are added.
41//!
42//! - **WGSL helper strings in [`shared_wgsl`] are stable within a minor
43//! version.** Helper *function signatures* (`viewport_pbr_shade`,
44//! `viewport_oit_pack`, `viewport_sample_csm`, ...) and the struct
45//! layouts they declare may change with a minor bump. When a helper's
46//! signature changes in an incompatible way, the helper is renamed (the
47//! old name is removed) so a plugin shader that referenced the old name
48//! fails to compile loudly rather than silently producing wrong output.
49//! Additive changes (new helpers, new optional fields appended to
50//! structs) ride patch bumps.
51//!
52//! - **Target descriptors and pipeline builder signatures are stable within
53//! a minor version.** Format constants (`HDR_COLOR_FORMAT`, blend
54//! states, depth-stencil state) follow the same rule: any change rides a
55//! minor bump and is noted in the CHANGELOG.
56//!
57//! - **The deformer registry hook contract is additive-only.** The
58//! `DeformVertex` and `DeformContext` struct shapes (see
59//! [`crate::resources::mesh_sidecar::registry::DeformerDesc`]) keep
60//! existing fields stable across releases; new fields may be appended.
61//! The composition-order policy (ObjectSpace before WorldSpace, priority
62//! ascending within stage) is part of the contract and will not change.
63//!
64//! - **Builder methods on [`crate::resources::DeviceResources`] that
65//! construct pipelines for plugins** (`build_opaque_pipeline`,
66//! `build_oit_pipeline`, ...) keep their behaviour stable within a minor
67//! version. Signature changes ride minor bumps and are listed in the
68//! CHANGELOG.
69//!
70//! Anything not listed above is internal: a plugin that reaches past the
71//! published surface (private modules, undocumented constants) may break at
72//! any release.
73
74pub mod cull;
75pub mod item_type;
76pub mod shared_wgsl;
77pub mod target_desc;
78
79pub use cull::{BatchMeta, CullSubmission, InstanceAabb, SingleMeshDraw};
80pub use item_type::{
81 ItemFrameContext, ItemTypePlugin, OutlineMaskContext, PaintContext, PickRay,
82 PluginItemCollection, ShadowCastContext,
83};
84pub use target_desc::{
85 MaskTargetDesc, OIT_ACCUM_BLEND, OIT_REVEAL_BLEND, OitTargetDesc, OpaqueTargetDesc,
86 PickTargetDesc, ShadowTargetDesc,
87};
88
89/// Group-0 bind layout shared by every scene pipeline.
90///
91/// Plugin pipeline layouts must list this layout as group 0 so the lib's bound
92/// camera / lights / shadow / clip / IBL resources are visible to the plugin's
93/// shader. Bindings 0-13 match [`shared_wgsl::SHARED_BINDINGS_WGSL`]; do not
94/// re-declare them in plugin WGSL.
95///
96/// Obtain a reference via
97/// [`DeviceResources::shared_bindings`](crate::resources::DeviceResources::shared_bindings).
98pub struct SharedBindings<'a> {
99 /// The group-0 `BindGroupLayout`. Pass by reference when calling
100 /// `device.create_pipeline_layout`.
101 pub group0_layout: &'a wgpu::BindGroupLayout,
102}
103
104impl<'a> SharedBindings<'a> {
105 /// Binding indices inside group 0. Stable across releases: additive
106 /// changes only. See [`shared_wgsl::SHARED_BINDINGS_WGSL`] for the WGSL
107 /// declarations.
108 pub const CAMERA_BINDING: u32 = 0;
109 /// Shadow atlas depth texture.
110 pub const SHADOW_ATLAS_BINDING: u32 = 1;
111 /// Comparison sampler used for PCF shadow filtering.
112 pub const SHADOW_SAMPLER_BINDING: u32 = 2;
113 /// Lights header uniform (count, hemisphere, IBL toggles).
114 pub const LIGHTS_HEADER_BINDING: u32 = 3;
115 /// Clip planes uniform (section-view planes).
116 pub const CLIP_PLANES_BINDING: u32 = 4;
117 /// Shadow info uniform (CSM matrices, splits, PCSS params).
118 pub const SHADOW_INFO_BINDING: u32 = 5;
119 /// Clip volume uniform (box/sphere/cylinder regions).
120 pub const CLIP_VOLUME_BINDING: u32 = 6;
121 /// IBL irradiance equirect texture.
122 pub const IBL_IRRADIANCE_BINDING: u32 = 7;
123 /// IBL prefiltered specular equirect texture.
124 pub const IBL_SPECULAR_BINDING: u32 = 8;
125 /// BRDF integration LUT.
126 pub const IBL_BRDF_LUT_BINDING: u32 = 9;
127 /// IBL filtering sampler (linear, clamp-to-edge).
128 pub const IBL_SAMPLER_BINDING: u32 = 10;
129 /// Skybox / environment equirect texture (full-resolution).
130 pub const SKYBOX_BINDING: u32 = 11;
131 /// Per-fragment debug storage buffer.
132 pub const DEBUG_FRAG_BINDING: u32 = 12;
133 /// Lights array storage buffer.
134 pub const LIGHTS_ARRAY_BINDING: u32 = 13;
135}