Skip to main content

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}