raea/pbr

Materials and volumes: StandardMaterial, extended and toon materials, custom shaders, decals, fog and fire.

View as Markdown

<StandardMaterial> is Bevy's physically based material, with its fields named as Bevy names them (base_color, perceptual_roughness, metallic, emissive and the rest). An ExtendedMaterial adds a shader extension on top of it; ToonMaterial and the paint and wear extensions give stylised looks; ShaderMesh and SurfaceShader take your own shader. Fog, volumetric fog, decals and fire are here too.

TSX
import { Sphere } from "raea/3d";
import { Mesh3d } from "raea/mesh";
import { StandardMaterial } from "raea/pbr";

const Ball = () => (
  <Mesh3d>
    <Sphere radius={0.5} />
    <StandardMaterial base_color="#c03030" perceptual_roughness={0.2} metallic={0.1} clearcoat={1} />
  </Mesh3d>
);
TS
import { AmbientOcclusion, Decal, ExtendedMaterial, Fire } from "raea/pbr"

raea/pbr exports 22 components, 1 function, 1 value, 35 types. Bevy's counterpart: bevy_pbr, bevy_material. Source: sdk/raea/src/pbr.ts.

Components

AmbientOcclusion

Screen-space ambient occlusion: creases, corners and the ground under things darken where the sky's and the room's light can't reach. It darkens ambient and environment light (an , an ), not the direct light of a sun or a lamp. Turns multisampling off, so the edges are smoothed by SMAA instead (see ). Put it inside the Canvas3D, once; the first frame's holds for the piece.

Bevy: bevy_pbr::ssao::ScreenSpaceAmbientOcclusion.

Takes AmbientOcclusionProps's props.

Decal

A picture pressed onto whatever surface it lies across: a label on a jar, a stain on a counter, tiles on a wall, a sticker on a laptop (Bevy's forward decal; the camera gets a depth prepass for it). Placed and keyed like any part, so it moves and fades with a render's clock and a game's play alike.

Bevy: bevy_pbr::mesh_material::MeshMaterial3d<bevy_pbr::extended_material::ExtendedMaterial<bevy_pbr::pbr_material::StandardMaterial, bevy_pbr::decal::forward::ForwardDecalMaterialExt>>.

Takes DecalProps's props.

ExtendedMaterial

Bevy's ExtendedMaterial: a StandardMaterial with one of raea's extensions (GridExtension, PaintExtension, ToonExtension) drawn on it.

<ExtendedMaterial base={} extension={} />

Bevy: bevy_pbr::ExtendedMaterial.

PropTypeWhat it does
base (required)ReactElementa , or another to put a second extension on (grid and paint both)
extension (required)ReactElementa , or

Used in: shader/extended_material, shader/extended_material_bindless.

Fire

A fire: a flame drawn as a volume, its tongues rising, curling and tearing off as it burns, with a flickering light on its surroundings. Every pixel of it is a function of the frame (rising 3D noise in a tapering envelope), so a render of any frame equals its play. Stand it on its fuel (a pyre, a brazier); put embers and smoke round it yourself.

Bevy: bevy_pbr::mesh_material::MeshMaterial3d<raea_render::engine::fire::FireMaterial>.

Takes FireProps's props.

Fog

Distance fog: far things fade into color. Inside the it is Bevy's DistanceFog on that camera, with all of Bevy's fields (an atmospheric falloff, the sun's colour); inside the Canvas3D it fogs the scene's camera by near, far or density.

Bevy: bevy_pbr::fog::DistanceFog.

Takes FogProps's props.

FogVolume

A box of air that light shows in: dust in a sunbeam, smoke, a haze of blood. Needs a in the Canvas3D; lights marked volumetric throw shafts through it, and every light's glow fills it softly. A part, so it keeps its name across frames: animate its density, colour and placement.

Bevy: bevy_light::volumetric::FogVolume.

Takes FogVolumeProps's props.

Used in: 3d/fog_volumes.

GridExtension

raea's grid over a StandardMaterial, as an ExtendedMaterial's extension (engine/render grid.rs):

Bevy: bevy_pbr::mesh_material::MeshMaterial3d<bevy_pbr::extended_material::ExtendedMaterial<bevy_pbr::pbr_material::StandardMaterial, raea_render::engine::grid::Grid>>.

PropTypeWhat it does
cell (required)numberworld units between grid lines
majornumbercells between heavier lines (4)
colorstringthe lines' colour
edgestringthe colour each Box face is outlined in ("" for none)

Lightmap

A light bake on the meshes of a its mesh names, lighting them in place of the scene's lights, scaled by their material's lightmap_exposure (a in the same Model, by material). Goes in a .

Bevy: bevy_pbr::lightmap::Lightmap.

PropTypeWhat it does
mesh (required)stringthe glTF mesh it lies on, by name (Bevy's GltfMeshName): every primitive of it
image (required)stringthe bake: a.ktx2 (or other picture) file, staticFile("lightmaps/room.ktx2"), sampled by the mesh's second UVs
uv_rect{ min: [number, number]; max: [number, number] }the rect in the image those UVs are relative to, for meshes packed in one atlas ({ min: [0, 0], max: [1, 1] } by default)
bicubic_samplingbooleanbicubic sampling: smoother, slower, may leak light (false by default)

Used in: 3d/lightmaps.

PaintExtension

PropTypeWhat it does
breakupnumberhow far tone boundaries wander (0.5)
scalenumberthe noise's size in metres (1)
colorstringthe colour patches take
amountnumberhow far toward color the patches go (0.6)

ProceduralExtension

raea's procedural surface over a StandardMaterial, as an ExtendedMaterial's extension (systems/procmat):

<ExtendedMaterial base={} extension={} />

Bevy: bevy_pbr::mesh_material::MeshMaterial3d<bevy_pbr::extended_material::ExtendedMaterial<bevy_pbr::pbr_material::StandardMaterial, raea_sys_procmat::Procedural>>.

PropTypeWhat it does
pattern (required)ProceduralSurface["pattern"]what it draws: noise, wood, marble, stone, brick, tiles, fabric, brushed or plaster
colors[string, string]the pattern's two colours
scalenumberhow many metres across its features are
rough_anumberthe first colour's roughness, 0..1
rough_bnumberthe second colour's roughness, 0..1
bumpnumberhow deep the pattern's relief looks (0 or more)
tile[number, number]brick and tiles: a cell's [width, height] in metres
gapnumberbrick and tiles: the joints' width in metres
gap_colorstringthe joints' colour
dustnumber0..1 dust on what faces up
dirtnumber0..1 dirt in joints, hollows, undersides and along the floor line
edgesnumber0..1 wear on the edges, lighter
dust_colorstringthe dust's colour
dirt_colorstringthe dirt's colour
seednumberwhich randomness the pattern uses

Refinish

Every inside re-covered: each of its glTF materials (all, or the one each names by material) given the colour, texture or finish each gives, the rest of it kept (a run of cabinets painted, the doors and drawers with them; map: null takes the wood's picture off). A model's own children go first.

PropTypeWhat it does
materials (required)MeshStandardMaterialProps[]the finishes, each a 's props, over every glTF material or the one its material names
childrenReactNodethe models refinished

ShaderExtension

Also takes the props of SurfaceShaderSpec.

Used in: shader/extended_material, shader/extended_material_bindless.

ShaderMesh

A mesh drawn by a material written here in WESL or WGSL: one generic Bevy material (rdb's ShaderMaterial, an AsBindGroup of 16 uniform slots and 4 textures) whose fragment shader is this source, so a dissolve, a toon ramp, a hologram or a procedural pattern needs no Rust. Uniforms may change from frame to frame (they're set again on any frame where they change); the shader isn't compiled again (#28).

Bevy: bevy_pbr::mesh_material::MeshMaterial3d<raea_sys_material::shader_material::ShaderMaterial>.

Takes ShaderMeshProps's props.

Splat

A gaussian splat: a reconstructed scene or object, drawn back to front for the frame's camera, behind any mesh in front of it, through the frame's look. Animate it with reveal, assemble, disperse, explode, wave, twist, morph and pulse, all values of the frame.

Bevy: bevy_pbr::mesh_material::MeshMaterial3d<raea_render::engine::splat::SplatMaterial>, bevy_pbr::mesh_material::MeshMaterial3d<raea_render::engine::splat::SplatMask>.

Takes SplatProps's props.

StandardMaterial

Bevy's StandardMaterial for the Mesh3d it's inside. Unlit draws as MeshBasicMaterial; a clearcoat or transmission as MeshPhysicalMaterial; anything else as MeshStandardMaterial, all on Bevy's StandardMaterial in the engine.

Bevy: bevy_pbr::pbr_material::StandardMaterial.

Also takes the props of StandardMaterialProps.

Used in: ui/render_ui_to_texture, ui/widgets/viewport_node, 3d/fog, 3d/vertex_colors, 3d/rotate_environment_map, 3d/transparency_3d, 3d/spherical_area_lights, 3d/lightmaps, and 41 more.

SurfaceShader

One shader over every lit standard surface in the scene that has none of its own (meshes, Models' materials, Characters), so the whole scene shares one look. Unlit, toon, paint, flat and looked surfaces and ShaderMesh keep theirs. In the 3D beside the camera; one per scene.

Bevy: bevy_pbr::mesh_material::MeshMaterial3d<bevy_pbr::extended_material::ExtendedMaterial<bevy_pbr::pbr_material::StandardMaterial, raea_sys_shader::ShaderExt>>.

Takes SurfaceShaderSpec's props.

ThreeShaderMaterial

A three.js shader on the mesh it's in, as it is: a ShaderMaterial's GLSL (or a node material's WGSL) with its uniforms, drawn by raea's engine with three's built-ins. <R3F> makes these from an R3F scene's materials.

Takes ThreeShaderMaterialProps's props.

ToonExtension

Also takes the props of ToonExtensionProps.

ToonMaterial

raea's ToonMaterial: a StandardMaterial's colour, texture and emission drawn in bands, as <ExtendedMaterial base={<StandardMaterial />} extension={<ToonExtension />} /> is (the old MeshToonMaterial).

Bevy: bevy_pbr::mesh_material::MeshMaterial3d<bevy_pbr::extended_material::ExtendedMaterial<bevy_pbr::pbr_material::StandardMaterial, raea_render::engine::toon::ToonExt>>, bevy_pbr::mesh_material::MeshMaterial3d<raea_render::engine::toon::OutlineMaterial>.

Also takes the props of StandardMaterialProps (material, base_color, base_color_texture, emissive, alpha_mode); ToonExtensionProps.

Volume

A simulated volume: density and heat in a box, put in by its sources and puffs, lifted by heat, weighed down, carried by the wind and its own curls, drawn lit and shadowed by itself. Smoke, a cloud or a contrail is a choice of these (examples/volumes). Simulated and raymarched by engine/render volume.rs:

Bevy: bevy_pbr::mesh_material::MeshMaterial3d<raea_render::engine::volume::VolumeMaterial>.

Takes VolumeProps's props.

VolumetricFog

Volumetric fog on the camera: light in the air, drawn inside every , with shafts from the lights marked volumetric. Put it inside the Canvas3D, once; without it fog volumes draw nothing.

Bevy: bevy_light::volumetric::VolumetricFog, bevy_light::volumetric::VolumetricLight.

Takes VolumetricFogProps's props.

Used in: 3d/fog_volumes.

WearExtension

raea's chips, grime and rust over a StandardMaterial, as an ExtendedMaterial's extension (systems/wear):

Bevy: bevy_pbr::mesh_material::MeshMaterial3d<bevy_pbr::extended_material::ExtendedMaterial<bevy_pbr::pbr_material::StandardMaterial, raea_sys_wear::Wear>>.

PropTypeWhat it does
amount (required)numberhow worn it is, 0-1
scalenumbera blotch's size in metres (0.08)
chipsnumberchips on edges and a few spots, 0-1 of the wear (0.6)
grimenumbergrime low and underneath, 0-1 of the wear (0.5)
rustnumberrust run down in streaks, 0-1 of the wear (0.25)
seednumbermoves the pattern
chip_colorstringwhat chips show beneath the paint
grime_colorstringthe grime's colour
rust_colorstringthe rust's colour

Functions

volumeShadow

a volume's shadow as the row's number: 1 by default, 0 for none

TS
function volumeShadow(owner: string, v: unknown): number

Values

FogFalloff

FogFalloff's constructors: the visibility distance (5% contrast left at it by default) to a density

Used in: 3d/atmospheric_fog.

Types

AlphaMode

Bevy's AlphaMode, as it reflects.

TS
type AlphaMode = "Opaque" | "Blend" | "Premultiplied" | "Add" | "Multiply" | "AlphaToCoverage" | { Mask: number }

AmbientOcclusionProps

FieldTypeWhat it is
quality"low" | "medium" | "high" | "ultra"how many samples a pixel takes: "low" (4), "medium" (8, the default), "high" (18), "ultra" (54)
thicknessnumberhow thick, in metres, a surface is taken to be behind what the camera sees (0.25 by default): larger darkens more behind thin things

DecalProps

FieldTypeWhat it is
src (required)stringthe picture pressed onto the surface: staticFile("label.png"); its clear parts show the surface through
namestringthe entity's name, for picking, the inspector and world.*
normalMapstringa normal map pressed with the picture: the label's relief
sizenumber | [number, number]width by height in metres (a number: a square)
positionVec3where it stands, metres (x, y, z)
normalVec3which way the surface faces at the decal (out of it; [0, 1, 0], a floor or counter, by default): turns the decal so the picture lies on it, upright on a wall, its top toward -z on a floor. Instead of rotation
spinnumbera turn about the normal (radians)
rotationVec3radians, the decal's +y out of the surface (rather than normal)
colorstringa tint times the picture (keyed: a stain darkening)
opacitynumber0 to 1 (keyed: a label fading in)
roughnessnumber0..1, smooth to matte
metalnessnumber0..1, a dielectric to a metal
unlitbooleandrawn in its flat colour, without light or shade
fadenumberhow far off its plane (metres) it still lies on a surface, fading to nothing there (0.05 by default). Anything nearer the plane than this takes it, a cabinet's side or a fridge's as well as the wall: keep it small

ExtendedMaterialProps

The props of ExtendedMaterial, tabled there.

FireProps

FieldTypeWhat it is
namestringparts are matched by name across frames: name a fire that comes and goes
positionVec3the flame's foot: where it stands on its fuel
scalenumber | Vec3its size in metres: one number for its height (it's half as wide), or [width, height, depth] (1 by default)
intensitynumberhow bright its core is, as a material's emissiveIntensity (6 by default): 3 a guttering fire, 10-20 a roaring one in the dark. Values over 1 bloom under a
colorstringthe flame's body (orange, "#ff7a1f", by default); its edges go deep red and its core yellow-white
seednumberwhich flame: fires with different seeds don't flicker together (0 by default)
speednumberhow fast its tongues rise, 1 by default (a big fire's rise more slowly than a small one's on their own)
timenumberseconds on its clock (by default the Sequence's time: frame / fps)
stepsnumbersamples along each ray through it (48 by default): fewer is cheaper and blurrier
opacitynumberhow much of what's behind it its body hides (1 by default): raise it (3-6) in daylight, where a bright wall behind would wash out a flame that only adds light
lightnumberthe light it casts on what's around it: a flickering PointLight's intensity (1 by default; 0 for none)

FogProps

FieldTypeWhat it is
colorFogColorwhat far things fade into: match the background
nearnumberlinear fog from near to far (in the Canvas3D 5 and 20 by default; on the camera Bevy's 0 and 100)
farnumberwhere linear fog is full, from the camera (20 in the Canvas3D, 100 on a camera)
densitynumberor exponential fog of this density (0.05-0.3), instead of near and far
falloffFogFalloffon the camera: Bevy's FogFalloff, in place of near, far and density (Bevy's default Linear 0 to 100)
directional_light_colorFogColoron the camera: the sun's colour in the fog looking towards it, its alpha its strength (Bevy's default none)
directional_light_exponentnumberon the camera: how tight the sun's glow is (Bevy's default 8)

FogVolumeProps

FieldTypeWhat it is
namestringparts are matched by name across frames: name a volume that comes and goes
positionVec3the box's centre
rotationVec3radians
scalenumber | Vec3the box's size in metres: one number for a cube, or [x, y, z] (1 by default)
densitynumberhow thick the air is (0.1 by default: dusty; 0.02 a faint haze; 0.5 smoke). Animate it to let dust settle, smoke roll in or a volume vanish (0)
colorstringthe fog's own colour, what light scattering out of it takes on (white by default; a dark red for blood in the air)
absorptionnumberhow much light it swallows (0.3 by default): higher reads as soot or smoke
scatteringnumberhow much light it throws back toward the eye (0.3 by default): higher reads as bright dust or mist
anisotropynumberhow far forward it scatters, -1 to 1 (0.5 by default): near 1 the shafts glow when you look toward the light
falloffnumberhow fast it thins going up, per metre from the box's floor (0 by default: even throughout): 0.5 is a ground fog that's a third as thick two metres up. A box wide and tall with a falloff is height fog. Only draws it; the march draws the box evenly
density_texturestringBevy's density_texture: a 3D.ktx2 image in the media folder whose values scale the density through the box (a cloud, a bunny of smoke); the box draws evenly without one. Only the march draws it

GridExtensionProps

raea's extension of StandardMaterial (a Bevy MaterialExtension of raea's): graph paper over the surface for greybox levels, lines every cell world units (fixed in the world, so they run on across shapes), a heavier one every major cells (4), in color, and each face of a Box outlined in edge ("" for no outlines). Its colours are the first frame's. It goes in an ExtendedMaterial's extension.

The props of GridExtension, tabled there.

LightmapProps

The props of Lightmap, tabled there.

MetallicRoughnessMaps

Separate greyscale maps packed into Bevy's metallic_roughness_texture when they load: the roughness map's grey as its green, the metalness map's as its blue (white without one, so metallic is its factor exactly). Poly Haven's "_rough" sets come this way; a packed "_arm" map is a plain path.

FieldTypeWhat it is
roughnessstringa greyscale roughness map (white rough)
metalnessstringa greyscale metalness map (white metal)

PaintExtensionProps

raea's extension of StandardMaterial for a paint look (): the surface broken up by world-space noise of scale metres (1), its tone boundaries wandering by breakup (0.5) and patches of it taking color (amount, 0.6, of the way): a mottled field, rust, a wall's uneven paint. It goes in an ExtendedMaterial's extension.

The props of PaintExtension, tabled there.

ProceduralExtensionProps

raea's extension of StandardMaterial that draws a pattern on the GPU in place of its flat colour (the engine's Procedural MaterialExtension, systems/procmat): pattern (noise, wood, marble, stone, brick, tiles, fabric, brushed, plaster) in colors with roughness rough_a/rough_b, features scale metres across, a bump; brick and tiles in tile [w, h] metre cells with gap metre joints in gap_color. Over it, each 0-1: dust on what faces up, dirt in joints, hollows, undersides and the floor line, edges worn lighter. The pattern overrides the base's colour and roughness; its lighting stays. It goes in an ExtendedMaterial's extension, alone.

The props of ProceduralExtension, tabled there.

SampledImage

A picture read with its own sampler: Bevy's load_with_settings, whose ImageLoaderSettings give the Image its ImageSamplerDescriptor ({ path: "checker.png", sampler: { filter: "nearest" } } for hard pixels).

FieldTypeWhat it is
path (required)stringthe picture, in the media folder
sampler (required)SamplerSpechow it's sampled: filter, address modes

ShaderExtensionProps

raea's extension of StandardMaterial written in WESL: its fn surface runs before Bevy's lighting and its fn lit after it, on the base's inputs, so the surface stays lit and shadowed. raea/3d's is the same thing; the spec is SurfaceShaderSpec. It goes in an ExtendedMaterial's extension, alone.

Bevy: bevy_pbr::extended_material::ExtendedMaterial<bevy_pbr::pbr_material::StandardMaterial, raea_sys_shader::ShaderExt>.

The props of ShaderExtension, tabled there.

ShaderMeshProps

FieldTypeWhat it is
shape (required)string | ({ primitive: string } & Record<string, unknown>)its geometry: a Manifold shape ("box(1, 1, 1)") or one of Bevy's primitives ({ primitive: "Sphere", radius: 1 })
weslstringWESL (Bevy 0.20's standard; give this or wgsl): a fn shade(in: VertexOutput) -> vec4<f32> (in.uv, in.world_position, in.world_normal), or a module with its own
wgslstringthe same in plain WGSL (compiled as WESL, its superset: Bevy 0.20 has no naga_oil, so no #import)
uniformsRecord<string, number | number[] | string>up to 16: a number (f32), [x, y], [x, y, z], [x, y, z, w] or "#rrggbb" (a linear vec4)
texturesRecord<string, string | Record<string, unknown>>up to 4: an asset path, a picture made in code ({ width, height, pixels }) or "render:NAME"; and one array, { layers: [picture,...] } or { src, layers: N }, read as texture_2d_array tex_NAME by layer
defsShaderDefsshader defs: each NAME a WESL condition for @if(NAME), and a whole number also constants::NAME
alpha"opaque" | "blend" | "add" | "premultiplied"how it blends: opaque, blend, add or premultiplied
doubleSidedbooleandraw the back faces too
namestringthe entity's name, for picking, the inspector and world.*
positionVec3where it stands, metres (x, y, z)
rotationVec3its rotation, Euler angles in radians (x, y, z)
scaleVec3 | numberits scale: one number, or x, y and z

SplatMorph

FieldTypeWhat it is
to (required)stringthe splat file it becomes
amount (required)number0 this splat, 1 the other (each splat flies to the one matched to it)
cropnumberonly the other's splats this many metres from its centre (a trained scene's subject without its surroundings)

SplatProps

FieldTypeWhat it is
namestringparts are matched by name across frames: name a splat that comes and goes
src (required)stringthe splat file (staticFile("x.ply")): a 3DGS.ply (spherical harmonics up to degree 3), a.splat or a.spz. A x.ply.json beside it (raea splat train writes one) places it: +Y up, centred, metres
positionVec3where it stands, metres (x, y, z)
rotationVec3radians, Euler XYZ
scalenumber | Vec3its scale: one number, or x, y and z
splatScalenumberevery gaussian's size times this (1 by default): below 1 the scene breaks into points
opacitynumber0..1, multiplying every gaussian's
brightnessnumbergrade: colour times brightness, saturation and contrast about mid grey, times tint
saturationnumber1 as trained; 0 grey, above 1 richer
contrastnumber1 as trained; about mid grey
tintstringa colour every gaussian's is multiplied by
revealnumberreveal 0..1: each splat scales in as a front passes it, from revealFrom (a point; the centre by default) outward, or along revealAxis (a plane sweeping through) when that's given
revealFromVec3the point the reveal grows outward from (the centre by default)
revealAxisVec3a direction: the reveal sweeps a plane along it instead of growing from a point
revealSoftnumberhow wide the front is, as a share of the sweep (0.15)
revealGlownumberthe front's glow (0 none, 1 bright), in glowColor
glowColorstringthe colour of reveal and pulse glows (warm white)
dispersenumberdisperse 0..1: blown off on a curl-noise wind, the upwind side first, shrinking to specks
assemblenumberassemble 0..1: from a cloud of dust round the scene into its shape (1 whole)
windVec3the wind's direction ([1, 0.15, 0])
curlnumberhow much the wind curls (1)
spreadnumberthe dust cloud's radius in metres (the splat's own size, before scale; 1.6 times its size by default)
explodenumberexplode 0..1: thrown out from the centre, falling and fading
waveSplatWavea ripple running out through the splats: amplitude, wavelength and phase
twistnumberradians a metre about the vertical through the centre
morphSplatMorphbecomes another splat file: to and amount 0..1
pulsenumbera value the composition passes (a beat's envelope 0..1): bigger by pulseScale, brighter by pulseGlow
pulseScalenumberhow much bigger a full pulse makes it
pulseGlownumberhow much brighter a full pulse makes it
cropnumbernothing past this many metres from the centre (trims a trained scene's floaters)
bandsnumberthe light in this many flat bands (0 none); a paint or cartoon sets it
paintnumber0..1: the splats themselves painted (flat bands, grown into strokes with hard edges), for a painted shot in a timeline whose frame isn't paint
seednumberwhich randomness: the scatter, the jitter (0)

SplatWave

FieldTypeWhat it is
amplitude (required)numberhow high the ripple lifts the splats, metres
wavelengthnumberfrom crest to crest, metres (1 by default)
phasenumberwhere the ripple is in its cycle, radians: animate it (frame * 0.2) to run it outward

StandardMaterialAnimate

The StandardMaterial fields animate takes, each a track of its own kind of value. An emissive brighter than white is LinearRgba keys of one colour: track({ 0: E.mul(0), 30: E.mul(2.5) }) with E = LinearRgba.from(Srgba.hex(c)).

FieldTypeWhat it is
base_colorTrackSpec<string>a track of base_color, sampled each frame
emissiveTrackSpec<string> | TrackSpec<LinearRgba>a track of emissive, sampled each frame
perceptual_roughnessTrackSpec<number>a track of perceptual_roughness, sampled each frame
metallicTrackSpec<number>a track of metallic, sampled each frame
emissive_exposure_weightTrackSpec<number>a track of emissive_exposure_weight, sampled each frame
reflectanceTrackSpec<number>a track of reflectance, sampled each frame
specular_tintTrackSpec<string>a track of specular_tint, sampled each frame
diffuse_transmissionTrackSpec<number>a track of diffuse_transmission, sampled each frame
specular_transmissionTrackSpec<number>a track of specular_transmission, sampled each frame
thicknessTrackSpec<number>a track of thickness, sampled each frame
iorTrackSpec<number>a track of ior, sampled each frame
attenuation_distanceTrackSpec<number>a track of attenuation_distance, sampled each frame
attenuation_colorTrackSpec<string>a track of attenuation_color, sampled each frame
clearcoatTrackSpec<number>a track of clearcoat, sampled each frame
clearcoat_perceptual_roughnessTrackSpec<number>a track of clearcoat_perceptual_roughness, sampled each frame
anisotropy_strengthTrackSpec<number>a track of anisotropy_strength, sampled each frame
anisotropy_rotationTrackSpec<number>a track of anisotropy_rotation, sampled each frame
depth_biasTrackSpec<number>a track of depth_bias, sampled each frame
parallax_depth_scaleTrackSpec<number>a track of parallax_depth_scale, sampled each frame
max_parallax_layer_countTrackSpec<number>a track of max_parallax_layer_count, sampled each frame
lightmap_exposureTrackSpec<number>a track of lightmap_exposure, sampled each frame

StandardMaterialProps

Bevy's StandardMaterial fields (colours as CSS colours, textures as file paths), with Bevy's defaults.

FieldTypeWhat it is
base_colorstring | Srgbaa colour, or Bevy's Srgba (its alpha shows with alpha_mode "Blend": Srgba.hex("#88ccff").with_alpha(0.5))
base_color_textureTex | nulla picture in the media folder; null (Bevy's None) inside a Model drops the model's own base map
emissivestring | LinearRgbaa colour, or Bevy's LinearRgba for one brighter than white (LinearRgba.from(Srgba.hex("#ff8800")).mul(3))
emissive_textureTexBevy: The emissive map, multiplies pixels with emissive to get the final "emitting" color of a surface.
perceptual_roughnessnumber0.5 by Bevy's default
metallicnumberBevy: How "metallic" the material appears, within [0.0, 1.0].
metallic_roughness_textureTex | MetallicRoughnessMapsBevy: Metallic and roughness maps, stored as a single texture.
normal_map_textureTexBevy: Used to fake the lighting of bumps and dents on a material.
occlusion_textureTexBevy: Specifies the level of exposure to ambient light.
uv_transformAffine2every texture's UVs scaled, turned and moved (Affine2.fromScale([5, 5]) tiles a map five times across each face; a scaled texture repeats)
reflectancenumber0.5 by Bevy's default
clearcoatnumberBevy: An extra thin translucent layer on top of the main PBR layer. This is typically used for painted surfaces.
clearcoat_perceptual_roughnessnumberBevy: The roughness of the clearcoat material. This is specified in exactly the same way as the StandardMaterial::perceptual_roughness.
clearcoat_normal_textureTexthe clearcoat layer's own normal map, read as data (not sRGB), as Bevy's examples load it with is_srgb false
specular_transmissionnumberBevy: The amount of light transmitted specularly through the material (i.e. via refraction).
iornumberBevy: The index of refraction of the material.
thicknessnumberBevy: Thickness of the volume beneath the material surface.
unlitbooleanBevy: Whether to apply only the base color to this material.
alpha_modeAlphaModeBevy: How to apply the alpha channel of the base_color_texture.
double_sidedbooleanBevy: Support two-sided lighting by automatically flipping the normals for "back" faces within the PBR lighting shader.
cull_mode"Back" | "Front" | nullthe faces not drawn: "Back" (Bevy's default), "Front", or null for neither
materialstringin a : the glTF material it re-covers, as MeshStandardMaterial's
fog_enabledbooleanfalse: left out of the scene's
specular_tintstringthe highlight's colour, over reflectance
anisotropy_strengthnumberstretched highlights (brushed metal, hair), 0..1, turned anisotropy_rotation radians along the tangent
anisotropy_rotationnumberBevy: The direction of increased roughness, in radians relative to the mesh tangent.
attenuation_distancenumberlight absorbed through a transmissive volume (with specular_transmission and thickness)
attenuation_colorstringBevy: The resulting (non-absorbed) color after white light travels through the attenuation distance.
depth_mapTexa greyscale height map (white deep) the parallax fields carve a flat face with
parallax_depth_scalenumber0.1 by Bevy's default
parallax_mapping_method"Occlusion" | { Relief: { max_steps: number } }"Occlusion" (Bevy's default) or { Relief: { max_steps } }
max_parallax_layer_countnumber16 by Bevy's default
depth_biasnumberdrawn this much nearer in depth (a decal-like layer over a coplanar face)
opaque_render_method"Forward" | "Deferred""Forward" or "Deferred" (in the deferred pass, with a camera that has one)
diffuse_transmissionnumberlight passed through and scattered (leaves, paper, wax), 0..1; lightmap_exposure: a 's bake times this
lightmap_exposurenumberBevy: The exposure (brightness) level of the lightmap, if present.
animateStandardMaterialAnimateits fields' tracks, sampled by the engine from the frame clock: { base_color: track({ 0: "#3060ff", 30: "#ff4070" }) }

SurfaceDrawProps

How a surface's alpha and faces draw (Bevy's StandardMaterial alpha_mode, alpha cutoff, double_sided and cull_mode), from the first frame.

FieldTypeWhat it is
alphaMode"opaque" | "blend" | "mask" | "add" | "multiply" | "premultiplied" | "coverage""opaque" (the default), "blend" (what transparent gives), "mask" (cut out where the alpha is under alphaCutoff: leaves, chain-link, a sprite's edge; no sorting), "add" (glows add up: sparks, light beams), "multiply" (darkens what's behind: stained glass, a shadow decal), "premultiplied", "coverage" (soft cut-out edges from the alpha over MSAA's samples: hair cards, foliage; needs , without it draws solid)
alphaCutoffnumberwith alphaMode="mask": the alpha under which it's cut away, 0..1 (0.5)
side"front" | "back" | "double"which faces draw: "front" (the default), "back" (the inside only: a sky dome, a room seen from outside), "double" (both, lit on both: a leaf, a flag, a sheet of paper)

SurfaceShaderSpec

FieldTypeWhat it is
weslstringthe source in WESL (Bevy 0.20's shader language, a superset of WGSL)
wgslstringthe same in plain WGSL
fragmentstringthe source as an asset path (staticFile("shaders/x.wesl")), as Bevy's MaterialExtension::fragment_shader names one: read as written but for its own bindings' numbers (any, in the order declared: one uniform struct, which gets its uniforms packed in its layout, up to 4 texture_2d and their one sampler; one under
uniformsRecord<string, number | number[] | string>up to 16: a number (f32), [x, y], [x, y, z], [x, y, z, w] or "#rrggbb" (a linear vec4)
texturesRecord<string, ShaderTexture | ShaderTexture[]>up to 4: an asset path, a picture made in code ({ width, height, pixels }) or "render:NAME"; with a sampler, { src, sampler } (or a picture with its sampler). One more may be an array, read as texture_2d_array by layer: { layers: [picture,...] } (one size and format) or { src, layers: N } (N layers stacked top to bottom). A 's may also bind one binding_array<texture_2d>, a list of 1 to 16 pictures (Bevy's texture_binding_array; a GPU without texture binding arrays refuses it)
defsShaderDefsshader defs: each NAME a WESL condition for @if(NAME) (a number is true), and a whole number also constants::NAME; each set of defs compiles its own pipeline
ownOwnMaterialFieldsa 's own: what its Material methods give, and its storage buffers; set by only
buffersRecord<string, StorageValue>the material's storage buffers by binding name; set by only

ThreeShaderMaterialProps

FieldTypeWhat it is
glsl{ vertex: string; fragment: string; raw?: boolean; vertexColors?: boolean }a ShaderMaterial's GLSL, its #includes expanded and its defines as #define lines in front; raw for a RawShaderMaterial (which declares three's built-ins itself), vertexColors as the material's
wgsl{ vertex: string; fragment: string; uniforms?: { name: string; type: string; array?: nu…a node material's WGSL, as three's TSL builder writes it for raea (sdk/r3f's input/tsl.ts): the contract's three_vertex and three_fragment, its uniforms' types, the mesh attributes it reads beyond the standard four
uniformsRecord<string, ThreeUniform>each uniform's value this frame
texturesRecord<string, string | { src: string; colorSpace?: "srgb" | "linear"; sampler?: Record…each sampler's picture: a file, a data URL, "render:NAME" (at most four); colorSpace: "linear" for one three samples raw (NoColorSpace: a distance field, a data map), "srgb" (the default) for a colour picture
output"display" | "linear""display": its colour is what three's canvas shows (a ShaderMaterial's); "linear": scene light, tone-mapped as the rest of the frame is (a node material's)
transparentbooleanblended over what's behind it, as three's `transparent`
blending"normal" | "additive" | "add" | "multiply" | "none"how it blends: normal, additive (add), multiply or none
side"front" | "back" | "double"which faces draw: front, back or double
depthWritebooleanit writes the depth buffer
depthTestbooleanit's hidden behind what's nearer
alphaTestnumberpixels less opaque than this are dropped
time[number, number, number]three's clock this frame: [seconds, delta, frame]
colorstringthe colour it's drawn in where its shader can't run (named in the render's warnings)

ToonBand

FieldTypeWhat it is
at (required)numberwhere the band starts, as r: the share of the light reaching a point that it faces (0 faces none of it, 1 faces every light); the first band starts at 0 whatever this says
colorstringthe band's colour; left out, it's mixed (in Oklab) between the shadow colour and color by its place

ToonExtensionAnimate

FieldTypeWhat it is
shadow_colorTrackSpec<string>a track of shadow_color, sampled each frame
rim_intensityTrackSpec<number>a track of rim_intensity, sampled each frame
highlight_intensityTrackSpec<number>a track of highlight_intensity, sampled each frame
outline_widthTrackSpec<number>a track of outline_width, sampled each frame

ToonExtensionProps

raea's extension of StandardMaterial that cel-shades it (the engine's ToonExt; three.js's MeshToonMaterial): the scene's lights in steps hard bands (2; bands for an explicit ramp, darkest first), the bottom one shadow_color (the base colour darker, nudged towards violet), with an optional rim, highlight and ink outline (true for their defaults). Its base gives base_color, base_color_texture, emissive, alpha_mode and material; a toon surface has no roughness or metal. It goes in an ExtendedMaterial's extension, alone.

FieldTypeWhat it is
stepsnumberhow many hard bands the light falls into (2)
bandsToonBand[]an explicit ramp of bands, darkest first, in place of steps
shadow_colorstringthe bottom band's colour (the base colour darker, nudged towards violet)
rimboolean | ToonRima rim light on the silhouette: true for its default, or its settings
highlightboolean | ToonHighlighta hard specular highlight: true for its default, or its settings
outlineboolean | ToonOutlinean ink outline: true for its default, or its settings
rim_intensitynumberhow bright the rim is
highlight_intensitynumberhow bright the highlight is
outline_widthnumberthe outline's width
animateToonExtensionAnimateits fields' tracks, as a StandardMaterial's animate (its base animates base_color and emissive)

ToonHighlight

FieldTypeWhat it is
intensitynumber0..1 (1 by default)
colorstring"#ffffff" by default
sizenumber0..1: the highlight's angular radius, up to half a radian (0.2 by default)

ToonMaterialProps

The props of ToonMaterial, tabled there.

ToonOutline

FieldTypeWhat it is
widthnumberpixels at the composition's size, the same near and far (2 by default)
colorstringink colour; by default the surface colour's hue, very dark

ToonRim

FieldTypeWhat it is
intensitynumber0..1, how much the rim colour covers the band (1 by default)
colorstring"#ffffff" by default
widthnumber0..1 of the Fresnel range from the silhouette inwards (0.3 by default)

VolumeCommon

FieldTypeWhat it is
namestringparts are matched by name across frames
timenumberseconds on the simulation's clock (the Sequence's time, frame / fps, by default)
resolutionnumbercells along the box's longest side (64 by default; 32 is a quarter the cost a step, 96 finer)
seednumberthe same seed simulates the same volume (0)
colors[string, string, string]its tones under a paint look: [lit, mid, dark]
thresholdnumberthe density its painted surface sits at (0.12): lower is fatter, higher thinner
erodenumberhow much noise tears the painted surface's edge (0.08), and the tears' size in metres (0.6)
erodeSizenumberthe tears' size in metres (0.6)
absorbnumberhow much light a unit of it stops (its shadow on itself; 1.2)
windVec3the wind, m/s ([0, 0, 0]); how fast the volume takes it up, a second (1.2 smoke, 0.6 otherwise); the height it's full from, metres, weaker below (0: full everywhere)
windPullnumberhow fast the volume takes up the wind, a second (1.2 smoke, 0.6 otherwise)
windHeightnumberthe height the wind is full from, metres; weaker below (0: full everywhere)
dragnumbervelocity the still air takes away a second (0.4)
vorticitynumbercurl kept curling (6); a drifting turbulent force, m/s² (0), and its size in metres (2)
turbulencenumbera drifting turbulent force, m/s² (0)
turbulenceSizenumberthe turbulence's size in metres (2)
stepsnumbersamples along each ray (96)
shadowboolean | numberits shadow, cast in the scene's light as a mesh's is (on by default): soft moving shadows on the ground, meshes and models under it, and, with a volumetric sun and a under , the sun's shafts breaking through the gaps between clouds. The shadow is where the volume has stopped half the sun; a number scales the density it sees: 1 as drawn, more reaches into its thinner parts (a fatter shadow; up to 4, a thin contrail's made to show), less keeps to the dense cores. false or 0 casts none. Under a paint look the shadow is the painted shape. Soften its edge with the sun's softShadow (2-4 for clouds)

VolumeProps

FieldTypeWhat it is
positionVec3the box's foot (the centre of its floor), metres ([0, 0, 0])
size (required)Vec3the box it lives in, [width, height, depth] in metres: what leaves it is cut
sourcesVolumeSource[]where density and heat come in over time, and the puffs of density it starts with ([x, y, z, radius] in metres from the foot)
puffs[number, number, number, number][]density it starts with: [x, y, z, radius] in metres from the foot
buoyancynumberheat's lift (4) and the density's weight (0.4), m/s² a unit; the heat lost a second (0.8) and the density lost a second (0.02), fractions
weightnumberthe density's weight, m/s² a unit (0.4)
coolingnumberthe heat lost a second, a fraction (0.8)
dissipationnumberthe density lost a second, a fraction (0.02)
fire[string, string, string] | falsefire where it's hot: three colours [red, orange, yellow] (paint's by default), or false for none; and the heat (a fraction of the hottest source's) each colour starts at ([0.35, 0.6, 0.85])
fireAt[number, number, number]the heat (a fraction of the hottest source's) each fire colour starts at ([0.35, 0.6, 0.85])
namestringparts are matched by name across frames
timenumberseconds on the simulation's clock (the Sequence's time, frame / fps, by default)
resolutionnumbercells along the box's longest side (64 by default; 32 is a quarter the cost a step, 96 finer)
seednumberthe same seed simulates the same volume (0)
colors[string, string, string]its tones under a paint look: [lit, mid, dark]
thresholdnumberthe density its painted surface sits at (0.12): lower is fatter, higher thinner
erodenumberhow much noise tears the painted surface's edge (0.08), and the tears' size in metres (0.6)
erodeSizenumberthe tears' size in metres (0.6)
absorbnumberhow much light a unit of it stops (its shadow on itself; 1.2)
windVec3the wind, m/s ([0, 0, 0]); how fast the volume takes it up, a second (1.2 smoke, 0.6 otherwise); the height it's full from, metres, weaker below (0: full everywhere)
windPullnumberhow fast the volume takes up the wind, a second (1.2 smoke, 0.6 otherwise)
windHeightnumberthe height the wind is full from, metres; weaker below (0: full everywhere)
dragnumbervelocity the still air takes away a second (0.4)
vorticitynumbercurl kept curling (6); a drifting turbulent force, m/s² (0), and its size in metres (2)
turbulencenumbera drifting turbulent force, m/s² (0)
turbulenceSizenumberthe turbulence's size in metres (2)
stepsnumbersamples along each ray (96)
shadowboolean | numberits shadow, cast in the scene's light as a mesh's is (on by default): soft moving shadows on the ground, meshes and models under it, and, with a volumetric sun and a under , the sun's shafts breaking through the gaps between clouds. The shadow is where the volume has stopped half the sun; a number scales the density it sees: 1 as drawn, more reaches into its thinner parts (a fatter shadow; up to 4, a thin contrail's made to show), less keeps to the dense cores. false or 0 casts none. Under a paint look the shadow is the painted shape. Soften its edge with the sun's softShadow (2-4 for clouds)

VolumeSource

where density and heat come in: a burner, or an engine moving at -> to (a contrail)

FieldTypeWhat it is
at (required)Vec3where (metres from the box's foot), and where it has moved to by until if it moves
toVec3where a moving source has got to by until
fromnumberwhen it puts out, seconds ([0, Infinity])
untilnumberwhen it stops putting out, seconds (Infinity)
radiusnumberits radius (0.5 m); the density and heat it puts out a second at its centre (4 and 4); the velocity it pushes out with, m/s ([0, 0, 0])
ratenumberthe density it puts out a second at its centre (4)
heatnumberthe heat it puts out a second at its centre (4)
speedVec3the velocity it pushes out with, m/s ([0, 0, 0])

VolumetricFogProps

FieldTypeWhat it is
stepsnumbermode="march": samples along each ray through a fog volume (64 by default): too few stair-step a shaft's edges, so 128 for a render with hard-edged shafts, or 32 with dither; about 0.1 ms a step at 1920x1080 on an M5 Pro
ditherbooleanmode="march": start each pixel's march a fraction of a step in, by a fixed noise seeded from the pixel and the frame number (false by default): the shafts' steps become fine grain instead of bands, so fewer steps look smooth. The noise is a function of the frame, so a render still equals its play
resolutionnumbermode="march": the fraction of the frame's resolution the fog is marched at (1 by default): 0.5 marches a quarter of the pixels and puts the result over the frame guided by depth, so an edge in front of a shaft keeps no fog from what's behind it. 0.5, 1/3 or 0.25; each frame on its own, so a render still equals its play
ambientnumberlight the fog has everywhere, lit or not (0 by default). Bevy lights a volume's whole box with it whatever its density, so the box's edges show: keep it 0, or small with the camera inside the volume
ambientColorstringthat light's colour (white by default)
mode"march" | "froxel"how the fog is drawn: "froxel" (the default: every volume written into one grid of cells along the view, lit once a cell and integrated front to back once, with the hero lights' shafts integrated exactly along epipolar lines: no steps, no dither, its cost the grid's whatever the resolution or the number of volumes, overlapping volumes mixed as one medium, see-through surfaces fogged at their own depth) or "march" (Bevy's ray march through each volume, as before). steps, dither and resolution are the march's; slices, tile, samples and hero the grid's
slicesnumberthe grid's cells along the view, spaced evenly in log depth from the camera to the farthest volume (64 by default; 32 to 256)
tilenumberthe grid's cells across the frame, in pixels a side (16 by default; 4, 8 or 16)
samplesnumberpoints lit in each cell, spread along its depth (1 by default; 1 to 8): more keeps thin shadows in the grid's soft light (a hero light's shafts don't need them)
herobooleanthe grid's shafts: true (the default) integrates the first two volumetric spot lights and the first two volumetric directional lights exactly, over their shadow maps texel by texel, so a blind's bars or a doorway's edge are as crisp as the shadow map: integrated at samples along lines from the light across the frame (Chen et al.'s epipolar sampling), more of them where the depth or the light changes, and each pixel read from the samples either side of it at its depth; false lights them in the grid's cells with the rest

WearExtensionProps

raea's extension of StandardMaterial that wears it (the engine's Wear MaterialExtension, systems/wear): its paint mottled, chipped back to chip_color on edges and a few spots, grime gathered low and underneath and rust run down in streaks, fixed in the part's own space as it moves. amount 0-1; chips, grime and rust each 0-1 of it (0.6, 0.5, 0.25); scale a blotch's size in metres (0.08); seed moves the pattern. It goes in an ExtendedMaterial's extension.

The props of WearExtension, tabled there.