sceneInputs property
Per-frame engine textures this material samples.
RenderInput.opaqueSceneColor binds scene_opaque_color, the scene
composed behind this draw, RenderInput.filteredSceneColor adds its
roughness-filtered atlas as scene_filtered_color (and implies the
snapshot), and RenderInput.depth binds scene_depth, the opaque
geometry's linear view-space depth. Together they are what a translucent
surface needs for refraction and depth-fade absorption.
Include <scene_inputs.glsl> to get the samplers and their accessors
rather than declaring them by hand. It gates each read on whether the
engine produced the input this frame, which a raw shader cannot otherwise
know, and it derives the screen UV from a SceneInputInfo block the
engine binds. Hand-rolling that means sampling an opaque-white placeholder
on the frames an input is missing.
Declaring an input the shader does not sample is a crash, not a
no-op. A declared-but-unsampled sampler is eliminated by the compiler
while the runtime reflection still lists it, and the bind then writes into
a slot that does not exist. Keep this set and the shader's
FLUTTER_SCENE_* defines in step.
This is a declaration, not a per-frame knob. Producing an input is not free: RenderInput.depth forces the depth prepass, and the scene-color inputs split the scene pass around every screen-reading layer. Any non-empty set also moves the frame off its cached whole-scene answer onto a per-view collection, and each change re-summarizes the whole scene.
Implementation
@override
Set<RenderInput> get sceneInputs => _sceneInputs;
Implementation
set sceneInputs(Set<RenderInput> value) {
final normalized = _normalizeSceneInputs(value);
if (setEquals(_sceneInputs, normalized)) return;
_sceneInputs = normalized;
// The frame's input set is summarized across materials and cached, so a
// change has to invalidate it or the engine keeps producing (or skipping)
// last frame's buffers.
markMaterialSceneInputsChanged();
}