ShaderMaterial class Materials
A Material backed by a caller-supplied fragment shader.
ShaderMaterial is the foundation for writing custom materials in
flutter_scene. Use it when UnlitMaterial and
PhysicallyBasedMaterial don't cover what you need: stylized
shading, custom alpha modes, screen-space effects, vertex-painted
looks, and so on.
Authoring a custom material
- Write a fragment shader. It should consume the engine's
standard vertex outputs and declare its own uniform blocks /
samplers for any parameters. See
MATERIALS.mdfor the full contract. - Compile the shader through the
flutter_gpu_shadersbuild hook withShaderBundleAssetMode.dataAssetsRequired. The generated.shaderbundleis a managed DataAsset, not a source file. - Load the bundle at runtime with
await gpu.loadShaderLibraryAsync('packages/<package>/flutter_gpu_shaders/shaderbundles/<name>.shaderbundle')and pull out the fragment shader entry. - Construct a
ShaderMaterialpointing at the shader, populate its uniform blocks and textures by name, and attach it to a MeshPrimitive.
Engine-bound resources available to your fragment shader
These vertex outputs are written by the engine's standard vertex
shader and are always available as in declarations in your
fragment shader (the names are part of the engine contract):
in vec3 v_position; // world space
in vec3 v_normal; // world space (not necessarily unit)
in vec3 v_viewvector; // camera_position - vertex_position, world space
in vec2 v_texture_coords;
in vec2 v_texture_coords_1;
in vec4 v_color; // per-vertex color, white when absent
Setting useEnvironment to true makes the engine bind the active
environment's IBL textures by their standard names when your fragment
shader declares them: prefiltered_radiance (the PMREM-style
roughness-band atlas; sample it with SamplePrefilteredRadiance from
texture.glsl) and brdf_lut (both as sampler2D). The diffuse
irradiance SH coefficients are not bound generically; declare them in
your own uniform block if you need them. Useful when a custom shader
still wants the engine's image-based lighting.
Uniform block packing
Flutter GPU resolves uniform blocks by name (via gpu.Shader.getUniformSlot) but the block's contents are a flat byte buffer that your code packs and the GPU interprets according to the shader's std140 layout. Common rules:
float,int,booloccupy 4 bytes.vec2occupies 8 bytes aligned to 8.vec3,vec4occupy 16 bytes aligned to 16.mat4occupies 64 bytes;mat3occupies 48 bytes laid out as threevec4columns (12 bytes of padding).- Array elements stride to the next 16 bytes.
Put a Float32List together that matches the block's declared
member order (including padding) and pass it via
setUniformBlock.
TODO(fmat-codegen): generate this packing from the shader's
reflection at build time so callers don't write it by hand, the
way PreprocessedMaterial packs a .fmat.
Constructors
- ShaderMaterial({Shader? fragmentShader, Shader? radianceCubeFragmentShader, Shader? vertexShader, Shader? skinnedVertexShader, Shader? depthVertexShader, bool useEnvironment = false, CullMode cullingMode = gpu.CullMode.backFace, WindingOrder windingOrder = gpu.WindingOrder.counterClockwise, bool isOpaqueOverride = true})
-
Creates a ShaderMaterial wrapping
fragmentShader.
Properties
- cullingMode ↔ CullMode
-
Backface culling mode applied before drawing. Defaults to
gpu.CullMode.backFaceto match the standard materials.getter/setter pair - depthBias ↔ double
-
World-space offset toward the camera used for coplanar surface details.
Positive values keep an overlay in front of its supporting surface
without modifying its node transform. Zero and negative values leave the
draw position unchanged. A fixed world offset provides fewer depth-buffer
units as camera distance grows, so distant coplanar surfaces may need a
larger value.
getter/setter pairinherited
- doubleSided ↔ bool
-
Whether to render both faces of triangles drawn with this material
(glTF's
material.doubleSided). When true, bind disables back-face culling so the geometry is visible from both sides; otherwise back faces are culled. Defaults to false. The runtime importer sets it from the glTF material.getter/setter pairinherited - fragmentShader → Shader
-
The fragment shader used when rendering geometry with this material.
no setterinherited
- hashCode → int
-
The hash code for this object.
no setterinherited
- isOpaqueOverride ↔ bool
-
Whether this material participates in the opaque pass.
getter/setter pair
- name ↔ String
-
The name of this material, used for identification.
getter/setter pairinherited
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
-
sceneInputs
→ Set<
RenderInput> -
Per-frame engine inputs this material samples, produced only when a
visible material asks for them: RenderInput.depth binds the linear
scene depth of the opaque geometry (forcing the depth prepass), and
RenderInput.opaqueSceneColor binds the accumulated scene color behind
the current draw, and RenderInput.filteredSceneColor adds its
roughness-filtered atlas.
Together they enable refraction, depth-fade absorption, shoreline
foam, and soft-particle style effects on translucent surfaces. The
base material requests nothing; a
.fmatmaterial declares these withengine_inputs:.no setterinherited -
textureNames
→ Iterable<
String> -
All currently-bound fragment sampler names, in insertion order.
no setter
-
uniformBlockNames
→ Iterable<
String> -
All currently-bound fragment uniform block names, in insertion order.
no setter
- useEnvironment ↔ bool
-
Whether the engine should bind the active environment's IBL textures
(
prefiltered_radiance,brdf_lut) when the fragment shader declares them. Defaults tofalse.getter/setter pair -
vertexTextureNames
→ Iterable<
String> -
All currently-bound vertex sampler names, in insertion order.
no setter
-
vertexUniformBlockNames
→ Iterable<
String> -
All currently-bound vertex uniform block names, in insertion order.
no setter
- windingOrder ↔ WindingOrder
-
Triangle winding order. Defaults to
gpu.WindingOrder.counterClockwiseto match the glTF convention and the standard materials.getter/setter pair
Methods
-
bind(
RenderPass pass, TransientWriter transientsBuffer, Lighting lighting) → void -
Binds this material's render-pass state, uniforms, and textures.
override
-
bindVertexStage(
RenderPass pass, Shader vertexShader, TransientWriter transientsBuffer) → void -
Binds this material's vertex-stage uniforms to
vertexShader, called by the encoder only when it used a material-supplied vertex shader (see materialVertexShader). The base implementation is a no-op; a material with vertex-stage parameters binds them here. -
getTexture(
String name, {ShaderStage stage = ShaderStage.fragment}) → Texture? -
Read back a previously-set texture binding, or
nullwhen none has been set. -
getUniformBlock(
String name, {ShaderStage stage = ShaderStage.fragment}) → ByteData? -
Read back a previously-set uniform block, or
nullwhen none has been set. -
isOpaque(
) → bool -
Whether geometry rendered with this material is fully opaque.
override
-
materialVertexShader(
String variant) → Shader? -
The vertex shader this material supplies for a geometry's
variant('unskinned'/'skinned'for the color pass,'depth'for the position-only depth/shadow pass; seeGeometry.materialVertexVariant), or null to use the engine's standard vertex shader for the geometry. -
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
setFragmentShader(
Shader shader) → void -
Assigns the fragment
shaderused when this material is drawn.inherited -
setFragmentShaderName(
String name, {String? cubeName}) → void -
Assigns the fragment shader by
namefrom baseShaderLibrary.inherited -
setRadianceCubeFragmentShader(
Shader? shader) → void -
Assigns the already-loaded variant built with
FLUTTER_SCENE_RADIANCE_CUBE, the counterpart of setFragmentShader for a material that samples the environment.inherited -
setTexture(
String name, Object? texture, {SamplerOptions? sampler, ShaderStage stage = ShaderStage.fragment}) → void - Assign a texture to a sampler uniform by name.
-
setUniformBlock(
String name, ByteData? bytes, {ShaderStage stage = ShaderStage.fragment}) → void - Assign the byte contents of a uniform block by name.
-
setUniformBlockFromFloats(
String name, List< double> floats, {ShaderStage stage = ShaderStage.fragment}) → void - Convenience wrapper around setUniformBlock that packs a list of float values. The caller is still responsible for std140 padding; see the class doc.
-
setVertexShader(
Shader? shader, {MeshVariant variant = MeshVariant.unskinned}) → void -
Assigns the vertex shader this material draws
variantmeshes with, or clears it whenshaderis null. -
toString(
) → String -
A string representation of this object.
inherited
-
vertexShaderFor(
MeshVariant variant) → Shader? -
The vertex shader assigned for
variant, or null when the engine's standard one runs.
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited