raea/3d
raea's scene layer: models, physics, splats, matchmoves, instancing, custom shader passes and 3D text.
raea/3d holds what a scene uses beyond Bevy's own components: glTF models (<Model>, <Part>), physics and soft
bodies (<Physics>, <Body>, <Goo>), Gaussian splats (<Splat>), matchmoves, instancing and scattering, grass,
fire, decals, 3D text, and custom shader passes (<FramePass>, <MeshPass>, <Compute>). It also re-exports the
primitives and effects most scenes need, so a quick scene can import from one path. Bevy's camera, lights,
materials and meshes are under raea/camera, raea/light, raea/pbr and
raea/mesh, named as Bevy names them.
import { AbsoluteFill, staticFile } from "raea";
import { Model, Physics } from "raea/3d";
import { Camera3d } from "raea/camera";
import { DirectionalLight } from "raea/light";
import { Transform } from "raea/transform";
function Scene() {
return (
<AbsoluteFill style={{ background: "#14161c" }}>
<Camera3d transform={Transform.fromXyz(0, 1.6, 5).lookingAt([0, 0.5, 0])} />
<DirectionalLight transform={Transform.fromXyz(3, 5, 4).lookingAt([0, 0, 0])} illuminance={11200} shadow_maps_enabled />
<Model src={staticFile("media/chair.glb")} />
</AbsoluteFill>
);
}See 3D for building, lighting and checking a scene.
import { about, AmbientOcclusion, AntiAliasing, Atmosphere } from "raea/3d"raea/3d exports 70 components, 4 hooks, 26 functions, 3 classes, 12 values, 126 types. Source: sdk/raea/src/3d.tsx.
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
Bevy: bevy_pbr::ssao::ScreenSpaceAmbientOcclusion.
Takes AmbientOcclusionProps's props.
AntiAliasing
How the 3D's edges are smoothed. Put it inside the Canvas3D, once; the first frame's holds for the piece.
Bevy: bevy_anti_alias::smaa::Smaa, bevy_anti_alias::fxaa::Fxaa.
Takes AntiAliasingProps's props.
Atmosphere
A procedural sky: Bevy's physically based atmosphere (Earth's air), drawn behind everything and lit by the DirectionalLights, so a sun low on the horizon makes a sunset. Inside the Canvas3D, once.
Bevy: bevy_light::Atmosphere.
Takes AtmosphereProps's props.
BevyComponent
A Bevy component on the part it's inside (a Mesh, a Model, an ImagePlane, a light or the camera), applied through the TypeRegistry: how a compiled-in Bevy plugin is driven (sdk/raea/docs/bevy-plugins.md), and how any of Bevy's own reflected components reaches a part in every build. Agents use the generated, typed wrappers (one per component), not this directly.
| Prop | Type | What it does |
|---|---|---|
type (required) | string | the component's reflected type path, as Bevy's TypeRegistry names it ("avian3d::dynamics::rigid_body::RigidBody") |
value | unknown | its value as Bevy's reflect serde reads it: a struct an object (fields left out take the type's default, when it has one), a newtype its inner value, an enum "Unit" or { Variant:... }, a Vec3 [x, y, z] |
from | number | the frame it's added on (0, the start, by default); a plugin steps after it from that frame |
Used in: ui/widgets/viewport_node, 3d/3d_shapes, 3d/3d_scene, shader/automatic_instancing, shader/storage_buffer, shader/shader_prepass, shader/array_texture, shader/gpu_component_array_buffer, and 6 more.
BevyResource
A Bevy resource (a plugin's settings: gravity), applied through the TypeRegistry. Inside the Canvas3D.
| Prop | Type | What it does |
|---|---|---|
type (required) | string | the resource's Rust type path, as the TypeRegistry names it |
value (required) | unknown | its value as Bevy reflects it (JSON) |
Used in: shader_advanced/deferred_raymarch.
Bloom
Glow around bright parts (emissive materials, strong highlights). Put it inside the Canvas3D.
Bevy: bevy_post_process::bloom::settings::Bloom.
Takes BloomProps's props.
Used in: 3d/bloom_3d, 3d/mesh_ray_cast.
Body
A rigid body inside
| Prop | Type | What it does |
|---|---|---|
name (required) | string | the body's name, unique in its |
src | string | a glTF's nodes as the body (drawn as a |
nodes | string[] | the glTF nodes that make the body |
shape | Shape | "hull" (default for nodes), "box" (their bounds), "mesh" (exact triangles, fixed bodies only), or a shape |
centre | Vec3 | where a given shape's centre stands at rest, world (a nodes' body: the middle of their bounds) |
fixed | boolean | it never moves: a floor, a wall, a table |
mass | number | kg (else volume x density) |
density | number | kg/m³ (1000) |
friction | number | 0 slides, 1 grips (0.5) |
restitution | number | 0 lands dead, 1 bounces back fully (0.2) |
velocity | Vec3 | m/s at the start, world |
angularVelocity | Vec3 | radians a second at the start, world |
linearDamping | number | how fast its motion bleeds off (0) |
angularDamping | number | how fast its spin bleeds off (0.05) |
release | number | seconds: held where it is until then (a cup sits until it's knocked) |
impulses | Impulse[] | kicks at given seconds: an impulse, where it's applied, and a torque |
path | (t: number) => { position: Vec3; quaternion: Quat } | a kinematic mover: its rigid motion from rest at t seconds (see about); it pushes the others |
material | PartMaterial | drawn as the body's nodes are, or by its children (inside its motion: draw them where it stands at rest) |
glitch | Glitch | ((t: number) => Glitch | undefined) | how its part breaks up, or a function of seconds giving that |
castShadow | boolean | it casts shadows |
children | ReactNode | what draws the body, in place of its nodes |
BufferMesh
A mesh from its own vertex buffers, as the geometry of a
Bevy: bevy_mesh::mesh::Mesh.
Takes BufferMeshProps's props.
Used in: shader_advanced/specialized_mesh_pipeline.
Canvas3D
Only for layered: the 3D is drawn in the page's order, at the box of the nearest positioned element around it
(the whole frame when there's none; B3 H7), at that box's size and aspect:
Takes Canvas3DProps's props.
Used in: ui/images/image_node, ui/images/ui_texture_slice_flip_and_tile, ui/images/image_node_resizing, ui/images/ui_texture_atlas_slice, ui/images/ui_texture_slice, ui/images/ui_texture_atlas, ui/layout/grid, ui/layout/ghost_nodes, and 94 more.
Capsule
A capsule (Bevy's Capsule3d, three.js's CapsuleGeometry): [radius, length of the straight part], standing up (along y); its whole height is length + 2 x radius. A character's stand-in, a pill, a collider's look.
Also takes the props of CapsuleProps (args).
Capsule3d
From Bevy's bevy_shape::Capsule3d: A 3D capsule primitive centered on the origin A three-dimensional capsule is defined as a surface at a distance (radius) from a line
Also takes the props of Capsule3dProps (radius, half_length, args).
Compute
A compute over the frame, in the 3D beside the camera; several run in the order written, before the cameras draw.
Rust: raea_sys_compute::Computes.
Takes ComputeProps's props.
Used in: shader/compute_shader_game_of_life, shader_advanced/compute_mesh.
Cone
A cone: [radius, height], its point up (along y).
Bevy: bevy_shape::Cone.
Also takes the props of ConeProps (args, radius, height).
Cuboid
Bevy's Cuboid: <Cuboid half_size={[1, 0.5, 1]} /> is a Box of args [2, 1, 2].
Also takes the props of CuboidProps (half_size); BoxProps (args).
Cylinder
[radiusTop, radiusBottom, height], standing up (along y) as three.js has it.
Bevy: bevy_shape::Cylinder.
Also takes the props of CylinderProps (args, radius, half_height).
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.
DepthCopy
Inside a Camera3d: its depth buffer copied each frame, after its prepass and before its main pass, into a depth image a Material samples (Bevy's shader_advanced/render_depth_to_texture, whose depth-only camera has Bevy's DepthPrepass, RenderTarget::None and Msaa off).
Rust: raea_sys_phase::DepthCopy.
| Prop | Type | What it does |
|---|---|---|
image (required) | string | the depth image, "render:NAME:WxH:depth": the camera's depth is copied into it, and a Material's texture of that name is it (a texture_depth_2d with a sampler_comparison) |
Used in: shader_advanced/render_depth_to_texture.
DepthOfField
A lens's depth of field: what's nearer or farther than the camera's focus blurs. Put it inside the Canvas3D;
pull focus by animating the camera's focus. Inside a Camera3d it is Bevy's component on the camera, its
focal_distance the camera's focus.
Bevy: bevy_post_process::dof::DepthOfField.
Takes DepthOfFieldProps's props.
Echoes
Copies of a part trailing it: count echoes at offsets step apart (metres; or a function of the echo's number),
in a flat glowing material, so a fork "duplicates" along a line.
| Prop | Type | What it does |
|---|---|---|
count (required) | number | how many echoes trail the part |
step (required) | Vec3 | ((k: number) => Vec3) | metres between one echo and the next, or a function of the echo's number (1, 2,...) giving its offset |
echo | PartMaterial | the echoes' material (the part's by default): a flat glowing one reads as copies |
Also takes the props of PartProps.
Entities
A world's entities drawn by the engine (no React element per entity): every entity with a Mesh component ({shape:
a Manifold expression or a Solid's expr, color, roughness, metalness}) and a Transform ({x, y, z, rx, ry, rz in
radians, scale}) is a mesh, placed in world space (a child's Transform is in its parent's). Give it the world at the
frame: <Entities world={game.at(useCurrentFrame())} />. Needs the engine's tables.
| Prop | Type | What it does |
|---|---|---|
world (required) | { scene(): unknown[] } | the game's world at this frame: anything with `scene()` giving its entities |
Entity
A bare Bevy entity: a Transform where it's placed (static) and Visibility, and nothing else until its children add
Bevy's own components through the TypeRegistry. A Handle field takes an asset path ("ball.glb#Mesh0/Primitive0",
"wood.png"), an inline asset (a StandardMaterial's fields as an object) or, for a Mesh, a Manifold shape
("shape:box(1, 1, 1)"); an Entity field takes another part's name or row id, or entity bits. So Mesh3d,
MeshMaterial3d
| Prop | Type | What it does |
|---|---|---|
name | string | what an Entity field elsewhere names it by (a ChildOf's parent, an observer's target); unique in the scene |
position | Vec3 | where it stands, metres (x, y, z) |
rotation | Vec3 | Euler XYZ in radians |
scale | Vec3 | number | one number, or x, y and z |
transform | { translation?: Vec3; rotation?: [number, number, number, number]; scale?: Vec3 } | Bevy's Transform (Transform.fromXyz(..).withRotation(..)), in place of position, rotation and scale: the entity is then a parent whose children (meshes, lights, models, other entities) move with it, as Bevy's ChildOf children do (the old Group) |
pass | string | with transform: the composition pass of every part inside that doesn't name its own (Mesh's pass) |
children | ReactNode | its Bevy components (transform, also the parts it carries |
Used in: ui/widgets/viewport_node, 3d/3d_shapes, 3d/atmospheric_fog, 3d/3d_scene, 3d/parenting, stress_tests/many_foxes, camera/projection_zoom, animation/animated_transform, and 4 more.
Environment
Light from all around, out of a panorama: soft light from the sky and reflections of it in every glossy or metal
surface (image-based lighting), and with background the panorama as the sky. Put it inside the Canvas3D, once a
frame; its src, intensity, rotation and background may change from frame to frame (a cut from a hall to a street).
Bevy's EnvironmentMapLight with maps already filtered is background, drawn as the sky (engine/render
environment.rs):
Bevy: bevy_light::probe::GeneratedEnvironmentMapLight. Bevy's Skybox from its own cubemap is <Skybox>..
Takes EnvironmentProps's props.
EnvironmentMapLight
Bevy's EnvironmentMapLight with its own prefiltered maps, as Bevy's examples put one on the camera: light from all around and its reflections, from cubemaps already filtered (an
Bevy: bevy_light::probe::EnvironmentMapLight.
Takes EnvironmentMapLightProps's props.
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.
Fisheye
A fisheye lens on the camera: a pass over the 3D after tone mapping (the page over it stays straight). Every value
animates per frame; a lens's vignette and colour fringes are
Takes FisheyeProps's props.
Fog
Distance fog: far things fade into color. Inside the
Bevy: bevy_pbr::fog::DistanceFog.
Takes FogProps's props.
Used in: 3d/fog, 3d/atmospheric_fog.
FogVolume
A box of air that light shows in: dust in a sunbeam, smoke, a haze of blood. Needs a 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.
FramePass
A full-screen pass over the scene camera's frame, beside the camera; several run in the order written. With a
frame
Rust: raea_sys_framepass::FramePasses.
Takes FramePassProps's props.
Used in: shader_advanced/custom_post_processing, shader_advanced/fullscreen_material.
GBufferPass
Inside a Camera3d with Bevy's DepthPrepass and DeferredPrepass: your shader over the whole view, written into the deferred G-buffer after the deferred prepass (depth compared GreaterEqual), so Bevy's deferred lighting lights it as any surface, and into the shadow maps of the camera's lights (Bevy's shader_advanced/deferred_raymarch).
Rust: raea_sys_phase::GBufferPass.
| Prop | Type | What it does |
|---|---|---|
shader (required) | string | the shader file, compiled as written: staticFile("shaders/x.wesl"). Its entry points take Bevy's FullscreenVertexOutput; bind group 0 is the view uniform (binding 0) and Globals (binding 1) |
fragment | string | the entry point writing the G-buffer: its deferred vec4 |
shadow | string | the entry point writing a shadow view's frag_depth, so it casts shadows; none when left out |
Used in: shader_advanced/deferred_raymarch.
Gizmo
Debug lines drawn by Bevy's gizmo renderer (a retained bevy_gizmos Gizmo and its GizmoAsset), placed like a part: a path, a bounding box, an axis, a ray. They cast and take no light, and draw over nothing unless depthBias says.
Bevy: bevy_gizmos::retained::Gizmo.
Takes GizmoProps's props.
Used in: shader_advanced/render_depth_to_texture.
Goo
Objects melting into goo: the bake drawn by the frame (nothing before from).
| Prop | Type | What it does |
|---|---|---|
name | string | the entity's name, for picking and the inspector |
seconds (required) | number | how long, seconds, from from (a frame of the enclosing Sequence) |
from | number | the frame of the enclosing Sequence the bake starts at (0) |
objects (required) | GooObject[] | what goes in: solids that melt and liquids that pour |
colliders | { box: { min: Vec3; max: Vec3 }; friction?: number }[] | static boxes the goo lies on and runs off (world) |
cups | GooCup[] | hollow cylinders on a pose track (a mug lifted and tipped) that carry the goo and pour it (tools/goo's cups): radius inside, height foot to rim, base (the inside floor's height), wall, friction, and poses [t,...the cup's frame to world, 16 numbers column-major], t in seconds from the goo's start, its axis +y |
surface | { blur?: number; level?: number; flat?: number; maxTris?: number } | the surface drawn round the particles: blur (grid nodes, 1), iso level (of the rest density, 0.33) and flat (the blur across over the blur up, 1); a wider, flatter blur and a lower level close a thin spill into one sheet. maxTris (120000): past it the grid coarsens, which drops a film one particle thick; a wide one needs more |
solver | "mpm" | "sph" | "mpm" (the default: goo, melting things) or "sph": thin liquids that pour, splash and spread (coffee dumped on a counter, water from a tap), simulated by SPlisHSPlasH (tools/goo/sph.py); each object a liquid, from a cup, a block, a filled glTF or an emitter |
sph | { radius?: number; viscosity?: number; tension?: number; tensionBoundary?: number; tens… | the sph solver's settings: particle radius (m, 0.001), viscosity (0.002), surface tension (0: off; at millimetre particles the solver alone holds a spill 4-5 mm deep, as coffee is, and even 30 beads it into a ball) with how much the liquid wets what it lies on (0.5) and its damping (0.05), the largest time step (s, 0.001) |
obstacles | { src: string; nodes?: string[]; transform?: number[]; poses?: number[][] }[] | sph: glTF meshes the liquid runs over and around (all their meshes, or the named nodes, moved by transform), standing, or moved along poses like a cup's ([t, 16 numbers column-major], from where the glTF has them) |
fps | number | the bake's own frame rate (the composition's by default): one bake shared by compositions at different rates |
bounds | { min: Vec3; max: Vec3 } | the box it lives in: goo leaving it is gone |
dx | number | grid cell, metres (0.005): finer is slower and smoother |
seed | number | the random seed the particles are placed with: the same seed bakes the same goo (0) |
gravity | Vec3 | gravity, m/s² (0, -9.81, 0) |
roughness | number | the surface: glossy, a little light through it |
clearcoat | number | 0..1 clear varnish over the surface |
subsurface | number | 0..1 light let through the surface |
color | string | the goo's colour where an object gives none |
Grade
The camera's colour grade (lift, gamma, gain and saturation per range of light, before tone mapping), a lens vignette and colour fringes: one grade over every scene, so a film looks of a piece. Put it inside the Canvas3D.
Bevy: bevy_render::view::ColorGrading, bevy_post_process::effect_stack::chromatic_aberration::ChromaticAberration, bevy_post_process::effect_stack::vignette::Vignette.
Takes GradeProps's props.
Grass
A field of grass over area, made by the engine from the ground's functions (sampled once at resolution).
| Prop | Type | What it does |
|---|---|---|
name | string | the entity's name, for picking, the inspector and world.* |
area (required) | PlanBox | the ground the field covers: a box on the plan (x, z, metres) |
height (required) | (x: number, z: number) => number | the ground's height at (x, z): the clumps stand on it, tilted to its slope |
density (required) | number | ((x: number, z: number) => number) | clumps per square metre at (x, z) (0: bare) |
patch | (x: number, z: number) => number | which of tints the point (x, z) belongs to (0 everywhere without it) |
size | (x: number, z: number) => number | a multiple of the clumps' size at (x, z) (1 without it) |
tints | [string, string][] | each patch's root and tip colours: ["#2c4a1a", "#5f8a2c"] |
highlight | string | the tips' highlight colour ("#f2e7a0") and how much of it each tip takes (0.22) |
highlightMix | number | how much of the highlight each tip takes (0.22) |
blades | number | blades in a clump (14), their height in metres (0.3; each 0.55 to 1.3 times it), width range ([0.034, 0.05]) |
bladeHeight | number | their height in metres (0.3; each 0.55 to 1.3 times it) |
width | [number, number] | a blade's width range, metres ([0.034, 0.05]) |
spread | number | how far from its clump's centre a blade stands (0.06 m), and how far it leans over its height ([0.2, 0.7]) |
lean | [number, number] | how far a blade leans over its height ([0.2, 0.7]) |
scale | [number, number] | each clump's scale, a random pick between these ([0.85, 1.35]), times size |
seed | number | which randomness places the clumps |
resolution | number | grid points a metre the functions are sampled at (2) |
tile | number | a tile's side in metres (4) |
lod | GrassLod[] | the steps of detail, nearest first (the engine's: every clump within 5 m, half of them in 8 blades to 14 m, a fifth in 5 blades beyond) |
shadow | boolean | cast shadows (false) |
ImagePlane
A picture on a flat card in the scene, unlit (a poster, a screen, a sprite).
Bevy: bevy_image::image::Image.
Takes ImagePlaneProps's props.
Instances
One glTF (or one mesh) drawn at many placements, loaded once and drawn by the GPU as instances: a meadow's grass
and flowers, a forest, a suburb's houses. <Instances src={staticFile("daisy.glb")} at={scatter({...})} />. The
copies share one surface and can't play a clip.
Bevy: bevy_pbr::render::mesh::MeshPipeline (automatic batching of entities sharing a mesh and material).
Takes InstancesProps's props.
LensDistortion
Barrel or pincushion distortion (Brown-Conrady k1, k2) on the camera, a pass after tone mapping as Fisheye's. Put it inside the Canvas3D.
Bevy: bevy_post_process::LensDistortion.
Takes LensDistortionProps's props.
Look
The whole frame drawn as a model's look draws its model: every part of the scene in the one grain, its bloom, fog and blur inside it. Put it inside the Canvas3D. mode="paint" or "cartoon" draws every standard material as paint (engine/render paint.rs):
Bevy: bevy_pbr::mesh_material::MeshMaterial3d<bevy_pbr::extended_material::ExtendedMaterial<bevy_pbr::pbr_material::StandardMaterial, raea_render::engine::paint::Paint>>.
Takes LookProps's props.
Matchmove
Footage with real 3D standing in it: the clip behind, its camera solved and followed, the subject in front. Fills the frame (its camera's view is the frame's); its children are the 3D in the shot's world, lights included.
Takes MatchmoveProps's props.
MeshPass
The mesh it's inside drawn again by your shader, in a phase of its own after the camera's main opaque pass: onto
the colour target, with no depth test unless depth, back faces culled (Bevy's shader_advanced/custom_render_phase). It
reads the mesh's colours at location 1 under VERTEX_COLORS when the mesh has them.
Rust: raea_sys_phase::MeshPass.
| Prop | Type | What it does |
|---|---|---|
shader (required) | string | the shader file, compiled as written: staticFile("shaders/x.wesl"). Its vertex input is the mesh's position at location 0 (a vec4 compressed_position under VERTEX_POSITIONS_COMPRESSED), its bind groups Bevy's mesh view (0) and mesh (2) |
vertex | string | its entry points (Bevy's default names) |
fragment | string | the fragment entry point's name |
depth | boolean | whether it tests and writes the view's depth (GreaterEqual), as a mesh in Bevy's opaque phase does (Bevy's shader_advanced/specialized_mesh_pipeline); without, it draws over everything |
Used in: shader_advanced/specialized_mesh_pipeline, shader_advanced/custom_render_phase.
MeshSequence
A baked simulation, one mesh a frame.
Takes MeshSequenceProps's props.
MeshShaderPass
Inside a Camera3d: your task and mesh shaders make primitives on the GPU and your fragment shader draws them into the view's colour and depth (compared GreaterEqual) after the main opaque pass (Bevy's shader_advanced/mesh_shader_intro). It needs a GPU with mesh shaders, as Apple silicon's Metal has; elsewhere it draws nothing and says so.
Rust: raea_sys_phase::MeshShaderPass.
| Prop | Type | What it does |
|---|---|---|
task | string | the task (amplification) shader file, compiled as written; none when left out, and the draw's workgroups are the mesh shader's |
mesh (required) | string | the mesh shader file, compiled as written: it makes the primitives the fragment shader draws |
fragment (required) | string | the fragment shader file, compiled as written. Each file has the one entry point of its stage; bind group 0 is Globals (binding 0) and the view uniform (binding 1) in all three, and a file's import super::NAME reads NAME.wesl beside it |
groups | [number, number, number] | the draw's workgroup count, [x, y, z] (draw_mesh_tasks); [1, 1, 1] when left out |
Used in: shader_advanced/mesh_shader_intro.
Model
A glTF model. Its clips are the file's (@bevy bevy_animation::AnimationClip), played by animation, blended by
animations or composed by graph, each built by the engine into its AnimationGraph
(@bevy bevy_animation::graph::AnimationGraph; engine/render scene3d.rs). look draws the model in its own grain
(engine/render look.rs):
Bevy: bevy_pbr::mesh_material::MeshMaterial3d<raea_render::engine::look::LookMaterial>.
| Prop | Type | What it does |
|---|---|---|
src (required) | string | a glTF file in the media folder: staticFile("models/shoe.glb") |
name | string | the entity's name, for picking and the inspector |
sampler | SamplerSpec | how its own glTF textures are read: { filter: "nearest" } for hard pixels, whatever the file says; a sampler |
pass | string | the composition pass it draws in ("scene" by default): a frame-wide effect told to skip a pass ( |
cloth | { src: string; frame: number } | a skinned model's own vertices replaced each frame by a baked cloth simulation (docs/cloth.md K2): src a.rseq of the model's vertices in its bind pose, in the glTF's order (raea/body tools/cloth.ts --bind), frame the one drawn (keyed per frame). The skin poses them, so its materials, alpha, morphs and bones are kept. |
attach | { to: string; bone: string } | fixed to another model's bone (to: that model's name; bone: the node's name in its glTF, "Head"): it follows the bone's animated pose, and its position, rotation and scale are in the bone's space (a glTF's armature is often scaled, so a hat may need scale 0.01) |
bones | Record<string, string> | a skinned model's joints placed where other models are, by name: { pelvis: "hero-pelvis",... } puts the joint named pelvis wherever the model named hero-pelvis is each frame (its position and rotation; shrink it to hide it: scale 0.001, not 0, which takes the skin with it), so a ragdoll's bodies move one skin that bends at its joints rather than rigid pieces. The model's own placement stays at the origin. |
position | Vec3 | where it stands, metres (x, y, z) |
rotation | Vec3 | radians |
scale | number | Vec3 | one number, or x, y and z |
allowOverlap | boolean | it may pass through other parts on purpose (a blade into a body, a ghost through a wall): raea's clipping check leaves it out |
posed | boolean | set at an angle on purpose (a bowl knocked over, a mug on its side): raea scene lint doesn't call it tilted |
animation | string | number | a clip to play: its name in the file, or its index |
screens | ModelScreens | live pictures on its materials, by the glTF material's name: { monitor_screen: <Screen resolution={[384, 272]}> <Game /></Screen> } (or a bare <Game /> for the defaults). Each mesh with that material shows the screen, the picture fitted to the mesh's texture coordinates and stood upright |
hide | string[] | nodes of the glTF hidden, by name (a robot's painted-on eyes under the screen that replaces them) |
nodes | Record<string, { translation?: Vec3; rotation?: [number, number, number, number]; scale… | glTF nodes' local transforms, by name, set each frame (a joint turned by hand: Bevy's gltf_skinned_mesh turns GltfNode2). Bevy's loader names an unnamed node GltfNode{index}. A part left out stays as the file has it; give the same nodes and parts every frame |
grid | { cell: number; major?: number; color?: string; toon?: boolean } | graph paper over the model's surfaces, as MeshStandardMaterial's grid, but drawn in the model's own texture coordinates (taken as metres), so the lines stay on the surface as it moves; no outlines. toon: its light in three flat bands (toon shading) |
animations | { clip: string | number; time?: number; weight?: number }[] | several clips blended by weight (Bevy's AnimationGraph): each its name or index, its time in seconds (the Sequence's time by default) and weight (1 by default). A transition is weights moved over frames (interpolate one down as the next comes up); a layer is a second clip at a lower weight. Up to 4; not with animation |
graph | AnimGraphNode | an authored animation graph (Bevy's AnimationGraph): a clip node, or a blend (its children's weights normalised) or an additive node (each child times its weight, added on) over children; any node may leave the subtrees of the bones in its mask alone (a wave on the arm over a walk: { add: [{ clip: "walk" }, { clip: "wave", mask: ["leg_l", "leg_r"] }] }). Weights and clip times may change every frame. Up to 16 nodes; not with animation or animations |
morphs | Record<string, number> | number[] | morph target (blend shape) weights, 0 to 1: by target name ({ smile: 0.8 }) or index ([0.8, 0]); up to 64. The names are fixed when the model is made: pass the same set every frame (0 for a target at rest) |
time | number | seconds into the clip (by default the Sequence's time: frame / fps); the clip loops unless loop={false} |
loop | boolean | false plays the clip once and holds its last pose |
scene | number | which of the file's scenes (0 by default) |
look | "solid" | "pixel" | "site" | how the model itself is drawn (the rest of the scene is unchanged): "solid" (its own surfaces, the default), "pixel" (pixel art: a cell per pixelSize frame pixels, outlined in edgeColor) or "site" (raea.io's grain: the cells' light ordered-dithered into the site's six greys). It may change from frame to frame. |
flat | boolean | its surfaces without light: shape and colour alone, like a drawing (the site look keeps the light: its grain is made of it) |
shadow | boolean | false: its meshes cast no shadow (true by default) |
receiveShadow | boolean | false: no shadow falls on its meshes, its own included (true by default): a furry coat of many cards that would otherwise speckle itself in the shadow maps |
pixelSize | number | a cell's size in frame pixels for the pixel and site looks (6 by default) |
edgeColor | string | the pixel look's one-cell outline, a hex colour ("#000000" by default), or "none" |
theme | "dark" | "light" | the site look's greys: "dark" (light ink on black, the default) or "light" |
lift | number | the site look's ink: lift + light * gain, before the dither (0.28 and 0.9 by default; on the light greys light is inverted, 0.35 and 0.75) |
gain | number | the site look's ink gain: lift + light * gain (0.9 by default, 0.75 on the light greys) |
children | ReactNode | material) given the colour, texture or finish each gives, the rest kept |
Used in: 3d/lightmaps, 3d/split_screen, 3d/atmospheric_fog, stress_tests/many_foxes, camera/projection_zoom, animation/animated_mesh, gltf/gltf_skinned_mesh, gltf/load_gltf, and 1 more.
MotionBlur
Motion blur from each part's and the camera's motion over the frame before (Bevy's MotionBlur): with it, each frame is drawn after the one before it, so a frame's blur is the same in a render, a seek and play. A frame without it has none. Put it inside the Canvas3D.
Bevy: bevy_post_process::motion_blur::MotionBlur.
Takes MotionBlurProps's props.
Outline
Ink lines where the scene's depth steps or its surfaces turn, drawn before bloom and tone mapping; under a
Takes OutlineProps's props.
Part
A glTF's nodes drawn on their own, where they stood, moved by a rigid motion, glitched by the frame's values.
| Prop | Type | What it does |
|---|---|---|
name | string | the entity's name (the first node's by default) |
src (required) | string | the glTF (staticFile("x.glb")) and the nodes that make the part |
nodes (required) | string[] | the glTF nodes that make the part |
position | Vec3 | a rigid motion from where it stands in the file (see about): position, and a quaternion [x, y, z, w] |
quaternion | Quat | its turn as a quaternion [x, y, z, w] (see about) |
scale | number | a uniform scale (1) |
material | PartMaterial | a material over the part's own (colour, glow, opacity) |
glitch | Glitch | how the part breaks up this frame: explode, scramble, jitter, snap, smear |
castShadow | boolean | it casts shadows |
PhaseItem
Your own pipeline drawing your own buffers in each camera's Opaque3d phase.
Rust: raea_sys_phase::PhaseItem.
| Prop | Type | What it does |
|---|---|---|
shader (required) | string | the shader file, compiled as written: staticFile("shaders/x.wesl") |
vertex | string | its entry points (Bevy's default names) |
fragment | string | the fragment entry point's name |
stride (required) | number | the vertex buffer: each vertex stride bytes, its 32-bit words in order (a u32 pad of 0 is a 0) |
attributes (required) | PhaseAttribute[] | the vertex buffer's attributes |
words (required) | number[] | the vertex buffer's 32-bit words, every vertex's in order |
indices (required) | number[] | the index buffer (u32), drawn whole |
depth | { write?: boolean; compare?: "Never" | "Less" | "Equal" | "LessEqual" | "Greater" | "No… | its depth state: whether it writes depth, and its compare (Bevy's CompareFunction by name; Bevy's opaque default, Greater, when left out) |
aabb (required) | { center: [number, number, number]; half_extents: [number, number, number] } | its bounds, so the camera sees it (Bevy's Aabb): a centre and half extents |
position | [number, number, number] | where it is (a bare Entity's place) |
Used in: shader_advanced/custom_phase_item.
Physics
Rigid bodies, simulated once and played back by the frame: the
s among its children (directly, or in fragments). Beforefrom and after seconds they hold their first and last poses.
| Prop | Type | What it does |
|---|---|---|
seconds (required) | number | how long to simulate, seconds |
gravity | Vec3 | m/s² (0, -9.81, 0) |
substeps | number | steps per frame (8) |
colliders | { min: Vec3; max: Vec3; friction?: number; restitution?: number }[] | static boxes (world, metres): the floor, the table top |
from | number | the frame (of the enclosing Sequence) the simulation starts on (0); before it everything is at rest |
children | ReactNode | the elements to simulate, and anything else to draw |
Plane3d
From Bevy's bevy_shape::Plane3d: A bounded plane in 3D space. It forms a surface starting from the origin with a defined height and width.
Takes Plane3dProps's props.
Plate
Footage behind the 3D: the clip's frame filling the camera's whole view (its view when it has one), on the far
side of everything, unlit. Give the scene <ToneMapping mode="none" /> to keep its colours exact.
Takes PlateProps's props.
Refinish
Every 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
| Prop | Type | What it does |
|---|---|---|
materials (required) | MeshStandardMaterialProps[] | the finishes, each a material names |
children | ReactNode | the models refinished |
RichText
Text in the 3D world: every glyph a real lit, shaded entity (bevy_rich_text3d's mesh over its glyph atlas, a
StandardMaterial of its own), laid out as one line of shaped text (kerning, spans of other fonts and sizes) and
then moved, turned, scaled, recoloured, faded and revealed glyph by glyph with the motion code 2D uses: the named
moves staggered (enter="rise" each={2}), a typewriter's reveal, or a glyph function of the frame.
Takes RichTextProps's props.
Scene
A world drawn at the current frame: its mesh rows (shape, x y z, rot_x rot_y rot_z in radians, scale, color,
rough, metal), camera (x y z, look_x look_y look_z, fov), light (x y z, intensity) and ambient (intensity)
rows as the 3D elements above. Inside a Canvas3D.
| Prop | Type | What it does |
|---|---|---|
world (required) | World | the world whose rows are drawn; its systems run up to the current frame |
Screen
A live picture on a surface in the 3D scene: a nested composition or game (its children, or src, a video) at its
own resolution, drawn as a CRT (scanlines, mask, glow, the glass) or flat. Inside a Canvas3D on its own it's a
free-standing quad; on a model, give it to the Model: <Model src={...} screens={{ monitor_screen: <Screen resolution={[384, 272]}><Game /></Screen> }} />. A screen doesn't light the room: put a dim light of its colour in
front of it.
Bevy: bevy_pbr::mesh_material::MeshMaterial3d<raea_render::engine::screen::CrtMaterial>.
| Prop | Type | What it does |
|---|---|---|
name | string | what the screen is called; screens on one page need different names ("screen" by default) |
position | Vec3 | a free-standing screen's place: a quad of size metres ([1.6] wide by default, its height from the resolution) |
rotation | Vec3 | radians |
scale | number | Vec3 | its scale: one number, or x, y and z |
size | [number] | [number, number] | [width] or [width, height] in metres ([1.6], its height from the resolution) |
pass | string | the composition pass it draws in (Mesh's pass; "scene" by default): pass="ui" with <Look skip={["ui"]}> keeps a page crisp under a paint look |
Also takes the props of ScreenSource.
ShaderInstances
The mesh it's inside drawn once per instance in one draw, by your shader, in the camera's Transparent3d phase, a
vertex buffer of your words stepped per instance (Bevy's shader_advanced/custom_shader_instancing). Its instances
aren't in the mesh's bounds: give the mesh Bevy's NoFrustumCulling (
Rust: raea_sys_phase::ShaderInstances.
| Prop | Type | What it does |
|---|---|---|
shader (required) | string | the shader file, compiled as written: staticFile("shaders/x.wesl"). Its vertex reads the mesh's position, normal and uv at locations 0 to 2 and the instance's attributes at theirs; its bind groups are Bevy's mesh pipeline's |
stride (required) | number | each instance's bytes (a multiple of 4) |
attributes (required) | PhaseAttribute[] | what the shader reads of an instance: Bevy's VertexFormat, its byte offset and |
words (required) | number[] | every instance's 32-bit words in order, stride / 4 of them each |
Used in: shader_advanced/custom_shader_instancing.
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.
Shadows
Shadow quality for every light in the Canvas3D: map size, the sun's cascades, biases, filtering. Put it inside the Canvas3D, once; the first frame's holds for the piece. mapSize sets both shadow maps' size, filter the camera's filtering, and the cascade props the sun's cascades (engine/render scene3d.rs):
Bevy: bevy_light::directional_light::DirectionalLightShadowMap, bevy_light::point_light::PointLightShadowMap, bevy_light::ShadowFilteringMethod, bevy_light::cascade::CascadeShadowConfig.
Takes ShadowsProps's props.
Used in: 3d/shadow_caster_receiver, 3d/atmospheric_fog, gltf/load_gltf, shader_advanced/deferred_raymarch.
Shape2D
A flat shape in 2D, over the 3D, in one colour: Bevy's Mesh2d with a ColorMaterial (raea-sys-sprite). Put it inside the Canvas3D.
Bevy: bevy_sprite_render::mesh2d::color_material::ColorMaterial, bevy_sprite_render::mesh2d::material::MeshMaterial2d<bevy_sprite_render::mesh2d::color_material::ColorMaterial>, bevy_mesh::components::Mesh2d.
Takes Shape2DProps's props.
Skybox
Bevy's Skybox: a cubemap drawn behind everything, as Bevy's examples put one on the camera. Put it inside the
Canvas3D, once; its brightness and rotation may change each frame (an background is the sky of
a panorama raea filters).
Bevy: bevy_light::probe::Skybox.
Takes SkyboxProps's props.
Span
A run of a
Takes SpanProps's props.
Sphere
Also takes the props of SphereProps (args, radius, ico, uv).
Used in: 3d/bloom_3d.
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.
Sprite
A picture in 2D, over the 3D: Bevy's Sprite, drawn as a quad with its sprite material, a sprite sheet's cells cut by a texture atlas (raea-sys-sprite). Put it inside the Canvas3D.
Bevy: bevy_sprite::sprite::Sprite, bevy_sprite_render::sprite_mesh::sprite_mesh_material::SpriteMeshMaterial, bevy_sprite_render::mesh2d::material::MeshMaterial2d<bevy_sprite_render::sprite_mesh::sprite_mesh_material::SpriteMeshMaterial>, bevy_sprite_render::sprite_mesh::sprite_extended_material::SpriteMaterial, bevy_image::texture_atlas::TextureAtlasLayout.
Takes SpriteProps's props.
Used in: camera/pan_camera_controller, camera/2d_on_ui, shader/compute_shader_game_of_life, shader/sprite_material, 2d/rotation, 2d/move_sprite, 2d/sprite_slice, 2d/rotate_to_cursor, and 8 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.
Text3D
Solid 3D letters (Manifold's text3d), as a Mesh's geometry: <Mesh><Text3D size={0.6}>SALE</Text3D>...</Mesh>.
Takes Text3DProps'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.
ToneMapping
The camera's tone mapping and exposure. Put it inside the Canvas3D.
Bevy: bevy_render::view::Tonemapping, bevy_camera::camera::Exposure.
Takes ToneMappingProps's props.
Used in: 3d/rotate_environment_map, 3d/bloom_3d, 3d/mesh_ray_cast.
Torus
From Bevy's bevy_shape::Torus: A torus primitive, often representing a ring or donut shape The set of points some distance from a circle centered at the origin
Also takes the props of TorusProps (args, major_radius, minor_radius).
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 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.
ZFight
The part drawn twice in the same place, the second a hair turned, in another material: the two surfaces fight
for the depth buffer and flicker in stripes (z-fighting), stronger with amount (radians, ~0.002).
| Prop | Type | What it does |
|---|---|---|
amount (required) | number | radians the second copy is turned (~0.002): more is stronger stripes |
other | PartMaterial | the second copy's material |
Also takes the props of PartProps.
Hooks
useBake
The bake for these props (made once and kept).
function useBake(props: PhysicsProps): BakeduseGoo
The goo's bake for these props (made once and kept), and the frame (of the enclosing Sequence) at which each object's own part should go, the goo having taken it over.
function useGoo(p: GooProps): GooBake & { gone: (name: string) => boolean; frame: number; }useMatchmove
The solve and this frame's camera, inside a
function useMatchmove(): MatchmoveStateusePhysics
Inside
function usePhysics(): { baked: Baked; frame: number; t: number; }Functions
about
A rigid motion of a part about a point (about, its rest centre): turn by q there, then move by move. As a
function about(about: Vec3, q: Quat, move?: Vec3): { position: Vec3; quaternion: Quat; }bodyPose
A body's rigid motion from rest at the current frame.
function bodyPose(baked: Baked, name: string, k: number): { position: Vec3; quaternion: Quat; }checkMatchmove
Checks a Matchmove's props; throws a TypeError or RangeError naming the prop.
function checkMatchmove(p: MatchmoveProps): voidcheckPass
A part's composition pass, checked: a name, letters first (up to 32 of letters, digits, _ and -).
function checkPass(owner: string, pass: unknown): voidclipEvents
The clip events that fire between two frames (Bevy's AnimationClip events, as data): an event time seconds into
the clip fires on the frame whose clip time first reaches it, that is when it lies in (prev, now], once per loop
when the clip loops (duration its length). Give the previous frame's clip time and this frame's, as a time runs; on the first frame pass prev -1 so an event at 0 fires.
function clipEvents<E extends { time: number; }>(events: E[], prev: number, now: number, duration: number, loop?: boolean): E[]dofOf
Bevy's DepthOfField fields as the old ones; their defaults are Bevy's (f/1, where the old one is f/2.8)
function dofOf(owner: string, props: DepthOfFieldProps): DepthOfFieldPropseulerOf
A part's Euler angles of a quaternion: a composition's rotation [x, y, z] is composed as three.js composes it,
Quat::from_euler(EulerRot::XYZ, x, y, z) (runtime/scene local; the YXZ rot_x/rot_y/rot_z of
raea-render's rows are read back from the world matrix), so this is that order's inverse.
function eulerOf(q: [number, number, number, number]): Vec3gooSpec
The spec tools/goo bakes for these props at the composition's fps: what physics goo SPEC.json takes, and the bake's
key, so a script can bake (or check) a goo without rendering.
function gooSpec(p: GooProps, fps: number): Record<string, unknown>hash01
0..1 from integers, the same on every run
function hash01(...xs: number[]): numberlastBeat
The last of times at or before t: its index (-1 before the first) and how long ago it was, seconds.
function lastBeat(t: number, times: readonly number[]): { index: number; since: number; time: number; }matchmoveIndex
The solve's frame at a time in the clip: the latest at or before it, clamped to the solve.
function matchmoveIndex(solve: MatchmoveSolve, time: number): numbermatchmoveView
The footage's view in a frame of another shape: the whole view's size (the footage scaled to cover the frame, times zoom) and the frame's window in it, in frame pixels.
function matchmoveView(footage: { width: number; height: number; }, frame: { width: number; height: number; }, crop?: number | [number, number], zoom?: number): { width: number; height: number; x: number; y: number; }part
glTF nodes cut out as their own file, standing where they stood (made once, kept in the asset store).
function part(src: string, nodes: string[], material?: PartMaterial): PartInfophysicsRequest
The simulation's request: every body's props as Rapier takes them, events in frames.
function physicsRequest(props: PhysicsProps, fps: number): Record<string, unknown>pick
The nearest part under the pointer, or null. size is the frame's (useVideoConfig's width and height), whose
pixels the pointer is in.
function pick(pointer: { x: number; y: number; }, camera: PickCamera, parts: readonly Pickable[], size: { width: number; height: number; }): Hit | nullplace
function place(o: { objects: Record<string, V3 | PlaceObject>; rules: PlaceRule[]; room?: { min: [number, number]; max: [number, number]; } | undefined; }): LayoutpointerRay
The pointer's ray: from the camera through the pointer (x, y in the frame's pixels, y down), as the engine draws it (Bevy's looking_at, with +Z for up when the camera looks straight up or down, as rdb does).
function pointerRay(pointer: { x: number; y: number; }, camera: PickCamera, size: { width: number; height: number; }): { origin: Vec3; direction: Vec3; }quatAxis
The quaternion [x, y, z, w] turning angle radians about axis, as Bevy's Quat::from_axis_angle.
function quatAxis(axis: Vec3, angle: number): QuatquatMul
The product a × b of two quaternions [x, y, z, w], b applied first, as Bevy's Quat * Quat.
function quatMul(a: Quat, b: Quat): QuatsamplerSpec
A sampler checked (a TypeError or RangeError naming the owner and the part).
function samplerSpec(owner: string, s: SamplerSpec): SamplerSpecscatter
Points scattered over an area for an spacing apart, clear of avoid and clearOf, on the ground y gives, kept by density. A spatial hash keeps
thousands quick. Call it once at module level, not per frame.
function scatter(o: ScatterOptions): Instance[]snapPose
Positions snapped to a grid (step metres): a physics engine's position quantised.
function snapPose(p: Vec3, step: number): Vec3surfaceShader
A surface shader checked and given as the row's spec (its source, uniforms, textures).
function surfaceShader(owner: string, sh: SurfaceShaderSpec, hook?: RegExp, hooks?: string): Record<string, unknown>surfaceTurn
The turn that takes +y to normal, with the picture's top (a decal's -z) toward world up on a wall, toward -z on a
floor, turned spin about the normal: a quaternion [x, y, z, w].
function surfaceTurn(normal: Vec3, spin?: number): [number, number, number, number]teleport
A position that jumps to a new seeded spot on each beat in times (within radius, metres, on the axes axes
scales) and holds it, back home hold seconds after the beat (Infinity: until the next).
function teleport(t: number, times: readonly number[], o: { radius: number; seed?: number; hold?: number; axes?: Vec3; }): Vec3toHex
A colour as the 3D renderer takes it (#rrggbb): hex, rgb()/rgba() or a common name; CSS variables throw.
function toHex(owner: string, k: string, v: unknown): stringClasses
CrossSection
A 2D shape (Manifold's CrossSection), held by value: its contours (counter-clockwise solid, clockwise holes), area and bounds. Offset, combine and move it, then extrude or revolve it into a Solid.
| Member | What it does |
|---|---|
CrossSection.from(a: SectionAnswer): CrossSection | From an engine answer (a slice, a projection, an operation). |
CrossSection.of(polygons: Polygons): CrossSection | Contours, overlaps merged and self-crossings resolved (Manifold's positive fill rule). |
.polygons: Polygons | its contours, each a list of [x, y] points: counter-clockwise solid, clockwise holes |
.area: number | its area, m² |
.contours: number | how many contours it has |
.bounds: { min: [number, number]; max: [number, number]; } | its bounding box's low and high corners |
.union(...others: CrossSection[]): CrossSection | This and the others together. |
.minus(...others: CrossSection[]): CrossSection | This with the others cut away. |
.intersect(...others: CrossSection[]): CrossSection | Only where this and every other overlap. |
.hull(...others: CrossSection[]): CrossSection | The convex hull of this and the others. |
.offset(delta: number, o?: { join?: JoinType | undefined; miterLimit?: number | undefined; segments?: number | undefined; }): CrossSection | Grown outward by delta (shrunk when negative), corners joined round (default), square, miter or bevel. |
.minkowski(other: CrossSection): CrossSection | Swept by another shape (the 2D Minkowski sum). |
.simplify(epsilon?: number): CrossSection | Fewer points: those within epsilon of a straight line dropped. |
.move(x: number, y: number): CrossSection | Moved by (x, y). |
.rotate(degrees: number): CrossSection | Turned by degrees about the origin. |
.scale(x: number, y?: number): CrossSection | Scaled uniformly, or per axis. |
.mirror(nx: number, ny: number): CrossSection | Mirrored across the line through the origin with this normal. |
.warp(fn: (x: number, y: number) => [number, number]): CrossSection | Every point moved by fn, then re-unioned (crossings resolved). |
.decompose(): CrossSection[] | Its separate pieces (each outline with its holes). |
.isEmpty(): boolean | Whether nothing is left. |
.extrude(height: number, o?: { divisions?: number | undefined; twist?: number | undefined; scaleTop?: [number, number] | undefined; }): Solid | Extruded along z into a Solid (see manifold.extrude). |
.revolve(o?: { degrees?: number | undefined; segments?: number | undefined; }): Solid | Revolved about the z axis into a Solid (see manifold.revolve). |
Field
A signed distance field (negative inside), as the text raea-core-sdf reads. Y is up; sizes are metres.
| Member | What it does |
|---|---|
new Field(text: string) | A field from its text, as raea-core-sdf reads it. |
.text: string | the field as the text raea-core-sdf reads |
.move(x: number, y: number, z: number): Field | The field moved by (x, y, z) metres. |
.rotate(x: number, y: number, z: number): Field | Degrees about x, then y, then z (as a Solid's rotate). |
.scale(s: number): Field | The field scaled by s about its origin. |
.mirrorX(): Field | Both sides: the field and its mirror across x = 0 (a body's left and right from one). |
.round(r: number): Field | Grown outward by r, every edge rounded by it. |
.shell(t: number): Field | Hollow: a skin 2t thick on the surface. |
.displace(amp: number, freq: number, octaves?: number, seed?: number): Field | Roughened by fractal noise: amp metres, freq cycles a metre (bark, rock, a lumpy creature). |
.solid(step?: number | undefined): Solid | The field meshed (marching tetrahedra, step metres a cell: by default a 96th of its size) as a closed solid. |
Solid
A handle to a native solid. Free it when done with many (or let the run end).
| Member | What it does |
|---|---|
new Solid(id: number, expr: string) | A handle to native solid id, which expr rebuilds; the shape functions make these, rarely you. |
.id: number | the native solid's handle |
.expr: string | the expression that rebuilds this solid (what a mesh row draws) |
.union(...others: Solid[]): Solid | This and the others together. |
.minus(...others: Solid[]): Solid | This with the others cut away. |
.intersect(...others: Solid[]): Solid | Only where this and every other overlap. |
.hull(...others: Solid[]): Solid | The convex hull of this and the others. |
.move(x: number, y: number, z: number): Solid | Moved by (x, y, z). |
.rotate(x: number, y: number, z: number): Solid | Turned by x, y and z degrees. |
.scale(s: number, y?: number | undefined, z?: number | undefined): Solid | Scaled uniformly, or per axis. |
.volume(): number | Its volume. |
.bounds(): Bounds | Its bounding box. |
.triangles(): number | How many triangles its mesh has. |
.isEmpty(): boolean | Whether nothing is left (a boolean that removed everything). |
.slice(z: number): Section | Its cross-section at height z (in a space-time mask, z is the frame). |
.mirror(nx: number, ny: number, nz: number): Solid | Mirrored across the plane through the origin with this normal. |
.transform(m: number[]): Solid | Transformed by a 3x4 matrix given column by column (x axis, y axis, z axis, translation). |
.trim(nx: number, ny: number, nz: number, offset?: number): Solid | What's on the normal's side of the plane n. p = offset. |
.splitByPlane(nx: number, ny: number, nz: number, offset?: number): [Solid, Solid] | Cut in two by the plane n. p = offset: [the normal's side, the other side]. |
.split(cutter: Solid): [Solid, Solid] | Cut in two by another solid: [inside it, outside it]. |
.refine(n: number): Solid | Each triangle cut into n x n. |
.smooth(o?: { angle?: number | undefined; smoothness?: number | undefined; refine?: number | undefined; }): Solid | Edges sharper than angle degrees kept, the rest rounded (smoothness 0..1 for the sharp ones too), then refined. |
.minkowski(other: Solid): Solid | This swept by another solid (the Minkowski sum): rounded by a sphere, thickened by a box. |
.minkowskiDiff(other: Solid): Solid | This eroded by another solid (the Minkowski difference). |
.mesh(): { verts: Float32Array<ArrayBufferLike>; tris: Uint32Array<ArrayBufferLike>; } | Its triangles: positions (x y z) and indices by threes. |
.warp(fn: (x: number, y: number, z: number) => [number, number, number]): Solid | Every vertex moved by fn (the topology kept): a bend, a twist, a wave. |
.simplify(tolerance: number): Solid | The mesh coarsened: vertices closer than tolerance merged where the shape allows. |
.refineToLength(length: number): Solid | Refined until no edge is longer than length. |
.refineToTolerance(tolerance: number): Solid | Refined until its smoothed surface is within tolerance of the true curve. |
.crossSection(z: number): CrossSection | Its cross-section at height z as a CrossSection (to offset, combine or extrude again). |
.project(): CrossSection | Its silhouette seen from above (+z), on the x-y plane. |
.decompose(): Solid[] | Its disconnected pieces, each a Solid. |
.minGap(other: Solid, searchLength: number): number | The smallest gap between this and another, looking no further than searchLength (which it answers when nothing is closer). |
.rayCast(from: Vec3, to: Vec3): { distance: number; position: Vec3; normal: Vec3; }[] | Where the segment from from to to crosses the surface, nearest first (distance 0..1 along it). |
.area(): number | Its surface area. |
.genus(): number | Its genus (how many holes go through it: a torus has 1). |
.export(path: string, format?: "obj" | "glb" | undefined): number | Written as OBJ or glTF binary (by the extension, or format); the file's size. |
.free(): void | Let the engine drop it. |
Values
ATTRIBUTE_COLOR
Bevy's Mesh::ATTRIBUTE_COLOR: a vertex's linear RGBA colour (id 5, Float32x4)
ATTRIBUTE_NORMAL
Bevy's Mesh::ATTRIBUTE_NORMAL: a vertex's normal (id 1, Float32x3)
ATTRIBUTE_POSITION
Bevy's Mesh::ATTRIBUTE_* (ids 0 to 5), as a Material's vertex buffer names them.
ATTRIBUTE_TANGENT
Bevy's Mesh::ATTRIBUTE_TANGENT: a vertex's tangent, its w the bitangent's sign (id 4, Float32x4)
ATTRIBUTE_UV_0
Bevy's Mesh::ATTRIBUTE_UV_0: a vertex's first texture coordinates (id 2, Float32x2)
ATTRIBUTE_UV_1
Bevy's Mesh::ATTRIBUTE_UV_1: a vertex's second texture coordinates, as a lightmap's (id 3, Float32x2)
crossSection
2D shapes as CrossSections, made natively.
grow
Generated growth as Solids, built natively: tree, loft, terrain, boulder, rosette and the rest. Draw one
with <Mesh shape={solid}>; cut, join, measure and place it like any other Solid.
manifold
MeshVertexAttribute
A vertex attribute: its name, its unique id (a high random one for your own, as Bevy asks, so it sorts after the built-in ones) and its format. MeshVertexAttribute.new("BlendColor", 988540917, "Float32x4") is Bevy's MeshVertexAttribute::new; Mesh's own are ATTRIBUTE_POSITION and the rest.
Bevy: bevy_mesh::MeshVertexAttribute.
outline
2D outlines for extrude and revolve.
sdf
Types
AlphaMode2d
bevy_sprite_render's AlphaMode2d
type AlphaMode2d = "Opaque" | "Blend" | { Mask: number }AmbientOcclusionProps
| Field | Type | What it is |
|---|---|---|
quality | "low" | "medium" | "high" | "ultra" | how many samples a pixel takes: "low" (4), "medium" (8, the default), "high" (18), "ultra" (54) |
thickness | number | how thick, in metres, a surface is taken to be behind what the camera sees (0.25 by default): larger darkens more behind thin things |
Animate3d
A 3D node's declared animation: tracks by property, or a move.
type Animate3d = Record<string, TrackSpec | TrackSpec[] | Keys> | MoveAnimGraphNode
A node of a
type AnimGraphNode = | { clip: string | number; time?: number; weight?: number; mask?: string[] } | { blend: AnimGraphNode[]; weight?: number; mask?: string[] } | { add: AnimGraphNode[]; weight?: number; mask?: string[] }AntiAliasingProps
| Field | Type | What it is |
|---|---|---|
mode (required) | "msaa" | "smaa" | "fxaa" | "none" | "msaa" (4x multisampling, the default), "smaa" (morphological, high preset: the default with AmbientOcclusion, which can't multisample), "fxaa" (cheapest, softest) or "none". Each draws a frame from that frame alone, so a render equals its play (temporal anti-aliasing isn't offered: it needs the frames before) |
AtmosphereProps
| Field | Type | What it is |
|---|---|---|
light | boolean | it lights the scene too, as a sky does (ambient and reflections from the sky it draws) |
groundAlbedo | number | the ground's brightness the air's scattering sees, 0..1 (0.3 by default) |
Baked
| Field | Type | What it is |
|---|---|---|
fps (required) | number | the frame rate it was baked at |
frames (required) | number | how many frames it holds |
file (required) | string | the bake's file in the asset store |
bodies (required) | Record<string, { p: number[]; q: number[]; centre: Vec3 }> | each body's track by name: positions and quaternions a frame, flat, and its rest centre |
BevyComponentProps
The props of BevyComponent, tabled there.
BevyParts
What a light or camera holds: Bevy's own reflected components on it (
| Field | Type | What it is |
|---|---|---|
children | ReactNode | Bevy components on it: |
layers | number[] | a camera: the render layers it draws ([0] by default); a light: the layers it lights (Bevy's RenderLayers) |
BloomProps
| Field | Type | What it is |
|---|---|---|
intensity | number | 1 is a natural glow, 2 strong; 0 none |
threshold | number | only what's brighter than this glows (0 = everything a little; 1 = only emissive parts and highlights) |
skip | string[] | composition passes (a part's pass) left out of it: they neither glow nor take the glow |
passes | Record<string, number> | each named pass's share of it, 0 (as skip) to 1 (all of it, as "scene" has) |
BodyProps
The props of Body, tabled there.
Bounds
| Field | Type | What it is |
|---|---|---|
min (required) | Vec3 | the low corner |
max (required) | Vec3 | the high corner |
BufferMeshProps
| Field | Type | What it is |
|---|---|---|
positions (required) | number[] | x, y, z of each vertex |
indices | number[] | three vertex indices a triangle (counter-clockwise seen from its front); without them each three positions are one. With normals too it is Bevy's indexed Mesh, its index buffer kept, as a compute that writes a mesh expects |
normals | number[] | x, y, z of each vertex's normal (without them each face is flat, facing its front) |
uvs | number[] | u, v of each vertex (without them a picture map is projected onto the mesh's bounds) |
colors | number[] | string[] | each vertex's colour: r, g, b, a (linear, 0 to 1) per vertex, or one "#rrggbb" per vertex; the material's colour is multiplied by it (Bevy's ATTRIBUTE_COLOR), so leave the material white to see them as given |
attributes | Record<string, { size: number; values: number[] }> | a mesh's own attributes beyond those, for a three.js shader that reads them ( |
Canvas3DProps
| Field | Type | What it is |
|---|---|---|
layered | boolean | the 3D takes its place in the page's tree order instead of lying under the whole page: page elements before the Canvas3D (and the backgrounds of the elements holding it) are under the 3D, showing wherever it has nothing, and hidden by its parts; positioned elements after it are over it. The 3D's background is transparent. Put the Canvas3D straight in a full-frame AbsoluteFill. |
clearColor | string | only with layered: the 3D clears to this CSS colour instead of transparent, so its translucent parts blend over it in linear light, as Bevy's do over its ClearColor (a Bevy 2D scene's rgb(43, 44, 47)), not over the page in sRGB. The 3D then lies under the whole page, as Bevy's camera output lies under all its UI (a GlobalZIndex(-1) too). |
children | ReactNode | the 3D scene: cameras, lights and parts |
Capsule3dProps
Bevy's Capsule3d: radius and half_length, the straight part's half (0.5 each by Bevy's default), standing up.
| Field | Type | What it is |
|---|---|---|
radius | number | metres (0.5) |
half_length | number | half the straight part's length, metres (0.5) |
args | [number, number] | [radius, length of the straight part] |
CapsuleProps
| Field | Type | What it is |
|---|---|---|
args | [number, number] | [radius, length of the straight part] ([0.5, 1]) |
ComputeProps
A compute shader (raea-sys-compute). Its source has one @compute entry point and reads time() (seconds),
u_NAME() for each uniform, each buffer as NAME: array<f32> (read and written) and each image as
NAME: texture_storage_2d<rgba8unorm, write>.
| Field | Type | What it is |
|---|---|---|
file | string | a shader file compiled as written, staticFile("shaders/x.wesl"), in place of wesl: its @group(0) storage textures and uniforms its own, as a Bevy example's render-graph node binds them |
entry | string | null | a file's entry point this frame (null or left out: nothing dispatched), as a node picks its pipeline |
bind | Record<string, string> | a file's storage textures this frame, each an image's key ({ input: "a", output: "b" }), as a node picks its bind group (a ping-pong swaps them frame by frame) |
wesl | string | the source in WESL (a superset of WGSL) |
wgsl | string | the same in plain WGSL |
workgroups (required) | number[] | how many workgroups a frame dispatches: [x], [x, y] or [x, y, z] |
uniforms | Record<string, number | number[] | string | Record<string, number | number[] | string |… | up to 16, as a surface shader's; a file's struct field may be { start: NAME } or { end: NAME }: the range of the mesh buffer NAME binds in its slab, in its array's elements (compute_mesh's range.start * 8) |
buffers | Record<string, { size: number } | number[] | StorageValue | MeshSlab> | up to 4, the compute's own, kept from frame to frame: { size } (that many f32s, zeroed) or its first contents. A file's: each var<storage> it declares, its first contents in its type's layout or a mesh's slab |
images | Record<string, string | { src: string; sampler?: SamplerSpec }> | up to 4 "render:NAME" (or "render:NAME:WxH") images it writes, which any shader's texture reads by that name (a file's may be { src, sampler }: the sampler it is drawn with) |
defs | ShaderDefs | shader defs, as a surface shader's |
ConeProps
| Field | Type | What it is |
|---|---|---|
args | [number, number] | [radius, height] |
radius | number | the base's radius, metres (0.5) |
height | number | metres (1) |
CrtSettings
How the tube draws the picture. Every value is optional; crt={false} on the Screen draws it flat and sharp.
| Field | Type | What it is |
|---|---|---|
curvature | number | barrel distortion, 0 (none) to about 0.3: a flat quad's stand-in for curved glass (a model's curved glass curves the picture already; 0 by default) |
scanlines | number | how dark the gaps between scanlines are, 0 to 1 (0.55); they fade where they'd be finer than the frame's pixels |
mask | number | how strongly the phosphor mask shows, 0 to 1 (0.35) |
maskKind | "aperture" | "shadow" | "none" | "aperture" (a Trinitron's vertical stripes, the default), "shadow" (offset triads) or "none" |
maskSize | number | mask triads per source pixel (1), or per line when lines is set |
lines | number | the tube's own scanlines, top to bottom (0, the default: one per row of the picture). Set it when the picture is sharper than the tube: a 1440x1044 desktop on a 1702 monitor shows its scanlines and mask at lines: 270, where its own 1044 rows are finer than the frame's pixels and fade out |
glow | number | the phosphor's halo around bright parts, 0 to 1 (0.35) |
convergence | number | how far apart the beam's red and blue land, in source pixels, growing toward the edges (0.35) |
vignette | number | the tube's edges and corners darkened, 0 to 1 (0.35) |
flicker | number | brightness flicker and a faint rolling hum bar, seeded by the frame, 0 to 1 (0.04) |
brightness | number | how strongly the picture glows (2.5 for a CRT, 1.4 flat): above 1 it blooms under a |
glass | string | the dark tube's own colour, hex (a grey-green) |
reflect | number | the glass's sheen toward grazing angles, 0 to 1 (0.5) |
smudge | number | fingerprints, a wiped arc and dust specks on the glass, 0 (clean, the default) to 1: seen mostly in the sheen and as a faint lift of the dark glass, barely over the picture; the pattern is fixed per screen (seeded by its name), so it holds still from frame to frame. 0.3 is a lived-in set seen on a second look |
overscan | number | the picture grown past the glass's edge, 0 to 0.3 (0) |
CuboidProps
Bevy's Cuboid: half its size along each axis ([0.5, 0.5, 0.5], a 1 m cube, as Bevy's default).
| Field | Type | What it is |
|---|---|---|
half_size | [number, number, number] | half its size along x, y and z, metres ([0.5, 0.5, 0.5]) |
CylinderProps
args, or Bevy's Cylinder fields: radius and half_height (0.5 each by Bevy's default).
| Field | Type | What it is |
|---|---|---|
args | [number, number, number] | [radius top, radius bottom, height], as three.js's args |
radius | number | metres (0.5) |
half_height | number | half its height, metres (0.5) |
DecalProps
| Field | Type | What it is |
|---|---|---|
src (required) | string | the picture pressed onto the surface: staticFile("label.png"); its clear parts show the surface through |
name | string | the entity's name, for picking, the inspector and world.* |
normalMap | string | a normal map pressed with the picture: the label's relief |
size | number | [number, number] | width by height in metres (a number: a square) |
position | Vec3 | where it stands, metres (x, y, z) |
normal | Vec3 | which 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 |
spin | number | a turn about the normal (radians) |
rotation | Vec3 | radians, the decal's +y out of the surface (rather than normal) |
color | string | a tint times the picture (keyed: a stain darkening) |
opacity | number | 0 to 1 (keyed: a label fading in) |
roughness | number | 0..1, smooth to matte |
metalness | number | 0..1, a dielectric to a metal |
unlit | boolean | drawn in its flat colour, without light or shade |
fade | number | how 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 |
DepthCopyProps
The props of DepthCopy, tabled there.
DepthOfFieldProps
| Field | Type | What it is |
|---|---|---|
aperture | number | the lens's f-number: lower blurs more (1.4 dreamy, 2.8 cinematic, 8 nearly sharp); 2.8 by default |
mode | "bokeh" | "gaussian" | "bokeh" (round, as a real lens; the default) or "gaussian" (soft, cheaper) |
maxBlur | number | the largest blur, in pixels of the frame (64 by default) |
focal_distance | number | Bevy's fields, as Bevy's DepthOfField component on a Camera3d (inside it), Bevy's defaults: the distance in focus (10; the camera's focus), the f-number (1), the largest blur in pixels (64), "Bokeh" or "Gaussian" |
aperture_f_stops | number | the f-number (1): lower is a shallower focus |
max_circle_of_confusion_diameter | number | the largest blur, in px (64) |
EntityProps
The props of Entity, tabled there.
EnvironmentMapLightProps
| Field | Type | What it is |
|---|---|---|
diffuse_map (required) | string | the prefiltered diffuse (irradiance) cubemap, a.ktx2 file: staticFile("environment_maps/pisa_diffuse_rgb9e5_zstd.ktx2") |
specular_map (required) | string | the prefiltered specular (radiance) cubemap with its mips, a.ktx2 file |
intensity | number | cd/m² (Bevy's default 1) |
rotation | [number, number, number, number] | its turn, glam's Quat [x, y, z, w] (Bevy's identity): Quat.from_rotation_y(0.2 * t) turns it each frame |
EnvironmentProps
| Field | Type | What it is |
|---|---|---|
src (required) | string | an equirectangular panorama in the media folder: a Radiance.hdr (Poly Haven's), an OpenEXR.exr, or an 8-bit.png/.jpg. Change it between frames to cut from one place to another |
intensity | number | how strongly it lights the scene (1 by default: a sky about as bright as an AmbientLight of 2.5 overall); animate it, or set 0 to switch it off for a shot |
rotation | number | a turn about the vertical axis, in radians, for both the light and the sky: puts the sun where the shot wants it |
background | boolean | draw the panorama as the sky behind everything (off by default: light only) |
backgroundIntensity | number | the sky's brightness, when it should differ from the light's (intensity by default) |
FireProps
| Field | Type | What it is |
|---|---|---|
name | string | parts are matched by name across frames: name a fire that comes and goes |
position | Vec3 | the flame's foot: where it stands on its fuel |
scale | number | Vec3 | its size in metres: one number for its height (it's half as wide), or [width, height, depth] (1 by default) |
intensity | number | how 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 |
color | string | the flame's body (orange, "#ff7a1f", by default); its edges go deep red and its core yellow-white |
seed | number | which flame: fires with different seeds don't flicker together (0 by default) |
speed | number | how fast its tongues rise, 1 by default (a big fire's rise more slowly than a small one's on their own) |
time | number | seconds on its clock (by default the Sequence's time: frame / fps) |
steps | number | samples along each ray through it (48 by default): fewer is cheaper and blurrier |
opacity | number | how 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 |
light | number | the light it casts on what's around it: a flickering PointLight's intensity (1 by default; 0 for none) |
FisheyeProps
| Field | Type | What it is |
|---|---|---|
strength | number | 0..1 (1 by default): 0 is the camera's own picture, pixel for pixel; ramp it in and out on beats |
mode | "equidistant" | "stereographic" | "equidistant" (the default) or "stereographic" (gentler at the edges) |
fov | number | the vertical field of view, in degrees, the camera widens to at strength 1 (its own by default): 100-150 for a real fisheye; the picture is still remapped corner to corner, so nothing goes black |
zoom | number | above 1 crops in, below 1 shows past the picture's edge (see edges) |
edges | "clamp" | "black" | what shows where the lens looks past the picture: its edge pixels ("clamp", the default) or "black" |
animate | Animate3d | declared animation of its numbers (strength, fov, k1, k2, zoom) |
FogColor
a fog colour: "#rrggbb" (or #rrggbbaa), or Bevy's Srgba or LinearRgba (raea/color)
type FogColor = string | { red: number; green: number; blue: number; alpha: number }FogFalloff
bevy_pbr's FogFalloff as it reflects; FogFalloff's constructors (raea/pbr) make one from a visibility distance
type FogFalloff = | { Linear: { start: number; end: number } } | { Exponential: { density: number } } | { ExponentialSquared: { density: number } } | { Atmospheric: { extinction: [number, number, number]; inscattering: [number, number, number] } }FogProps
| Field | Type | What it is |
|---|---|---|
color | FogColor | what far things fade into: match the background |
near | number | linear fog from near to far (in the Canvas3D 5 and 20 by default; on the camera Bevy's 0 and 100) |
far | number | where linear fog is full, from the camera (20 in the Canvas3D, 100 on a camera) |
density | number | or exponential fog of this density (0.05-0.3), instead of near and far |
falloff | FogFalloff | on the camera: Bevy's FogFalloff, in place of near, far and density (Bevy's default Linear 0 to 100) |
directional_light_color | FogColor | on the camera: the sun's colour in the fog looking towards it, its alpha its strength (Bevy's default none) |
directional_light_exponent | number | on the camera: how tight the sun's glow is (Bevy's default 8) |
FogVolumeProps
| Field | Type | What it is |
|---|---|---|
name | string | parts are matched by name across frames: name a volume that comes and goes |
position | Vec3 | the box's centre |
rotation | Vec3 | radians |
scale | number | Vec3 | the box's size in metres: one number for a cube, or [x, y, z] (1 by default) |
density | number | how 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) |
color | string | the fog's own colour, what light scattering out of it takes on (white by default; a dark red for blood in the air) |
absorption | number | how much light it swallows (0.3 by default): higher reads as soot or smoke |
scattering | number | how much light it throws back toward the eye (0.3 by default): higher reads as bright dust or mist |
anisotropy | number | how far forward it scatters, -1 to 1 (0.5 by default): near 1 the shafts glow when you look toward the light |
falloff | number | how 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 |
density_texture | string | Bevy'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 |
FramePassProps
A shader over the whole frame. Its source defines
fn shade(in: FullscreenVertexOutput) -> vec4
| Field | Type | What it is |
|---|---|---|
file | string | a shader file compiled as written, staticFile("shaders/x.wesl"), in place of wesl: its @group(0) bindings its own, as custom_post_processing's pipeline binds them: each texture_2dframe names) or an image of textures, each sampler Bevy's default (nearest) or samplers' one, each varuniforms (which may change frame by frame) |
frame | string | a file's texture that reads the frame as drawn so far |
entry | string | a file's fragment entry point ("fragment" by default) |
samplers | Record<string, SamplerSpec> | a file's samplers by name |
wesl | string | the source in WESL (a superset of WGSL) |
wgsl | string | the same in plain WGSL |
uniforms | Record<string, number | number[] | string | StorageValue> | up to 16, as a surface shader's (a file's: each var |
textures | Record<string, string | Record<string, unknown>> | up to 4, as a surface shader's, each read with its own sampler |
defs | ShaderDefs | shader defs, as a surface shader's |
at | "before-tonemap" | "after-tonemap" | "after-tonemap" (display colours; the default) or "before-tonemap" (the HDR frame, after bloom) |
prepass | boolean | { depth?: boolean; normal?: boolean } | the camera's depth and normal prepasses, for depth(uv) and normal(uv) (turns its multisampling off) |
GBufferPassProps
The props of GBufferPass, tabled there.
GizmoColor
a gizmo point's colour: "#rrggbb", linear [r, g, b, a], or Bevy's LinearRgba / Srgba (bevy3d's colours)
type GizmoColor = string | [number, number, number, number] | { red: number; green: number; blue: number; alpha?: number }GizmoProps
| Field | Type | What it is |
|---|---|---|
lines | [Vec3, Vec3][] | segments, each [from, to] |
strip | (Vec3 | null)[] | one line through these points (null breaks it) |
color | GizmoColor | GizmoColor[] | one colour for every point, or one per point of lines (two per segment) then strip: "#rrggbb", Bevy's LinearRgba (above 1 for HDR, as bevy_gizmos takes it) or Srgba, or linear [r, g, b, a] |
width | number | line width in pixels (Bevy's default 2) |
depthBias | number | -1 always in front of geometry, 0 depth-tested as it is (Bevy's GizmoLineConfig and depth_bias) |
position | Vec3 | where it stands, metres (x, y, z) |
rotation | Vec3 | its rotation, Euler angles in radians (x, y, z) |
scale | Vec3 | number | its scale: one number, or x, y and z |
name | string | the entity's name, for picking, the inspector and world.* |
Glitch
| Field | Type | What it is |
|---|---|---|
explode | number | triangles thrown out from the centre and turned (0 whole, 1 about the part's size away) |
scramble | number | 0..1: that share of the vertices pulled to other vertices of the part (spikes across it) |
jitter | number | metres of per-triangle noise |
snap | number | metres: the vertices snapped to a grid that size |
smear | Vec3 | metres, world: the trailing side dragged back along it (motion smear) |
seed | number | which randomness (change it on a beat for a new pattern) |
GlyphInfo
What a glyph is, for a glyph function.
| Field | Type | What it is |
|---|---|---|
index (required) | number | its place among the drawn glyphs (spaces aren't glyphs), from 0 |
count (required) | number | how many glyphs the block has |
char (required) | string | the character it draws |
word (required) | number | its word's place among the words, from 0, and how many there are |
words (required) | number | how many words the block has |
inWord (required) | number | its place in its word, and the word's glyph count |
wordLength (required) | number | how many glyphs its word has |
line (required) | number | its line (by the newlines in the text), from 0 |
span (required) | number | its run: the it's in (0 for text outside any, counted in order) |
GlyphStyle
A glyph's motion this frame, about its own centre, in the block's space: added to (position, rotation), multiplied into (scale, opacity) or replacing (color, visible) what the block's moves give it.
| Field | Type | What it is |
|---|---|---|
position | Vec3 | metres, from its place in the block |
rotation | Vec3 | radians, XYZ |
scale | number | Vec3 | multiplies its size: one number, or x, y and z |
color | string | replaces its colour |
opacity | number | multiplies its opacity, 0..1 |
visible | boolean | false hides it this frame |
GooBake
| Field | Type | What it is |
|---|---|---|
file (required) | string | the baked.rseq this goo plays |
stats (required) | { objects?: { name: string; hideFrame: number }[]; [k: string]: unknown } | what the bake measured, with each object's name and the frame its original model should go |
GooObject
| Field | Type | What it is |
|---|---|---|
name (required) | string | the object's name; the bake's stats list it, with the frame its original model should go |
src | string | a glTF's nodes (world space as they stand in it), moved by transform (column-major 4x4) if given; or, with no src, cup and level: a liquid filling one of the goo's cups to level metres above its foot |
nodes | string[] | the glTF nodes it's made of (all of them when left out) |
cup | number | with no src: the index of the cup in cups it fills |
level | number | with no src: metres above the cup's foot it's filled to |
transform | number[] | a column-major 4x4 that moves the glTF's nodes |
liquid | "water" | "coffee" | "tea" | "milk" | "juice" | "oil" | "syrup" | "honey" | sph: what it is ("water" by default: coffee, tea, milk, juice, oil, syrup, honey set its colour, density and viscosity), and where it comes from if not a cup or a glTF (filled): a box of it, or an emitter pouring a round stream from at along dir (down) at speed m/s, radius m (6 mm) across, from start to end seconds |
block | { min: Vec3; max: Vec3 } | sph: a box of liquid, world min and max corners |
emitter | { at: Vec3; dir?: Vec3; radius?: number; speed?: number; start?: number; end?: number } | sph: a round stream poured from at along dir, radius m across, at speed m/s, from start to end seconds |
start (required) | number | seconds from the goo's start when it begins to soften, and how long until it runs (mpm) |
melt | number | seconds from start until it runs (2) |
stiffness | number | of the solid (3e4) and the fluid it becomes (4) |
viscosity | number | how thick the fluid it becomes is (4) |
density | number | its density, kg/m³ (1000) |
cohesion | number | the share of its pressure it keeps under tension (0.6): goo holds together in strands, a liquid (0.02) barely |
residual | number | the share of its shear stiffness a fluid keeps (0.12) and the strain it must pass to flow (0.005): 0 and 0 for a liquid |
yield | number | the strain a fluid must pass to flow (0.005; 0 for a liquid) |
fill | "solid" | "shell" | "solid" fills its volume; "shell" a skin thickness thick (plates, petals) |
thickness | number | with fill: "shell": the skin's thickness, metres |
color | string | its goo's colour (else its texture's) |
GooProps
The props of Goo, tabled there.
GradeProps
| Field | Type | What it is |
|---|---|---|
temperature | number | warmer (+) or cooler (-): a shift of the CIE x chromaticity, about -0.3 to 0.3 |
tint | number | magenta (+) or green (-) |
saturation | number | the whole frame's saturation after tone mapping (1 keeps it) |
shadows | GradeSection | the grade on the shadows: saturation, contrast, gamma, gain, lift |
midtones | GradeSection | the grade on the midtones |
highlights | GradeSection | the grade on the highlights |
vignette | number | { intensity?: number; radius?: number; smoothness?: number; color?: string } | the corners darkened: 0 none, 1 black; or {intensity, radius (0.75), smoothness (5), color} |
aberration | number | a lens's colour fringes at edges, as a fraction of the frame (0.005 subtle, 0.02 strong) |
skip | string[] | composition passes (a part's pass) the grade leaves as drawn: no fringes or vignette on them, and on an untonemapped camera (a paint Look's) no colour grading either |
passes | Record<string, number> | each named pass's share of the grade, 0 (as skip) to 1 |
GradeSection
| Field | Type | What it is |
|---|---|---|
saturation | number | 1 keeps the colour; 0 grey; above 1 richer |
contrast | number | 1 keeps it; above 1 harder |
gamma | number | 1 keeps it; above 1 darker mids |
gain | number | a multiplier: 1 keeps it |
lift | number | added: 0 keeps it, positive lifts the blacks |
GrassLod
One step of detail: tiles nearer than to metres draw keep of their clumps (0 to 1), each with its first
blades blades in segments segments, widen times as wide.
| Field | Type | What it is |
|---|---|---|
to (required) | number | tiles nearer than this many metres take this step |
keep (required) | number | the share of their clumps they draw, 0 to 1 |
blades (required) | number | how many of each clump's blades they draw |
segments (required) | number | segments each blade is drawn in |
widen (required) | number | how many times as wide each blade is drawn, to fill in for the ones left out |
GrassProps
The props of Grass, tabled there.
Hit
| Field | Type | What it is |
|---|---|---|
name (required) | string | the pickable it hit |
distance (required) | number | metres from the camera (from its near plane's point, for an orthographic one) along the ray |
point (required) | Vec3 | where the ray first meets it, in world space |
ImagePlaneProps
| Field | Type | What it is |
|---|---|---|
src (required) | string | a picture in the media folder: staticFile("poster.png") |
name | string | the entity's name, for picking and the inspector |
width | number | width in scene units (1 by default); height follows the picture unless given |
height | number | in scene units (follows the picture's shape by default) |
position | Vec3 | where its centre stands, metres (x, y, z) |
rotation | Vec3 | radians |
scale | number | Vec3 | one number, or x, y and z |
quaternion | [number, number, number, number] | a turn as a quaternion [x, y, z, w], instead of rotation (a card turned to face a point) |
shadow | boolean | false: the card casts no shadow (a cursor or a UI floating in the scene); true by default |
cutout | boolean | the picture cut out at half alpha instead of blended: its clear parts are no surface at all (no fog on them, no sorting) and its shadow is the picture's shape, not the card's. For hard-edged pictures: a baked cloud, a sprite |
grid | [number, number] | a sprite sheet: the picture is [columns, rows] frames of equal size, read left to right, top to bottom, and the card shows one cell (its height follows one cell's shape). A texture atlas of a regular grid |
frame | number | with grid: which cell shows (0 is the top left; whole numbers, wrapping); animate it to play the sheet, as Bevy's TextureAtlas index does: frame={Math.floor(f / 3)} |
Impulse
| Field | Type | What it is |
|---|---|---|
t (required) | number | seconds from the simulation's start |
impulse | Vec3 | N·s, world |
at | Vec3 | where it's applied (world, metres): off the centre it spins the body too |
torque | Vec3 | an angular impulse, N·m·s, world |
Instance
One copy's placement in an
| Field | Type | What it is |
|---|---|---|
position (required) | Vec3 | where this copy stands, metres, in the Instances' space |
rotation | Vec3 | its rotation, Euler angles in radians (x, y, z) |
scale | number | Vec3 | its scale: one number, or x, y and z |
InstancesProps
| Field | Type | What it is |
|---|---|---|
src | string | a glTF file drawn at every placement: staticFile("models/house.glb"). Without it, a geometry child (or shape) and a material child draw a mesh at every placement |
at (required) | Instance[] | where each copy stands. Fixed for the shot: the first frame's list is drawn on every frame (move, turn, scale, hide or recolour the whole set by the Instances' own props) |
name | string | the entity's name, for picking, the inspector and world.* |
position | Vec3 | where it stands, metres (x, y, z) |
rotation | Vec3 | radians |
scale | number | Vec3 | its scale: one number, or x, y and z |
scene | number | of a glTF: which of its scenes (0 by default) |
shape | string | Solid | a Manifold solid or its expression for the mesh form; wins over the geometry child |
shadow | boolean | false: the copies cast no shadow (true by default). Grass and flowers by the thousand usually want false |
receiveShadow | boolean | false: no shadow falls on the copies |
pass | string | the composition pass it draws in ("scene" by default) |
children | ReactNode | the mesh form: a geometry and a material (MeshStandardMaterial, MeshPhysicalMaterial or MeshBasicMaterial). The glTF form: MeshStandardMaterial children re-covering its materials, as on a Model |
Layout
type Layout = Record<string, Placed> & { readonly found: PlaceFinding[]; readonly errors: number }LensCommon
| Field | Type | What it is |
|---|---|---|
edges | "clamp" | "black" | what shows where the lens looks past the picture: its edge pixels ("clamp", the default) or "black" |
animate | Animate3d | declared animation of its numbers (strength, fov, k1, k2, zoom) |
LensDistortionProps
| Field | Type | What it is |
|---|---|---|
k1 | number | Brown-Conrady: r' = r (1 + k1 r^2 + k2 r^4), r a share of the half-diagonal. Above 0 barrel, below 0 pincushion |
k2 | number | the r^4 term of the distortion |
zoom | number | by default just enough for a barrel's corners to stay inside the picture (1 for pincushion) |
edges | "clamp" | "black" | what shows where the lens looks past the picture: its edge pixels ("clamp", the default) or "black" |
animate | Animate3d | declared animation of its numbers (strength, fov, k1, k2, zoom) |
LoftOutline
type LoftOutline = string | [number, number][]LookPass
One composition pass's own paint (
| Field | Type | What it is |
|---|---|---|
rag | number | how far its edges wander, px (the Look's by default) |
grain | number | its paper grain, 0 to 1 |
palette | boolean | false: its pixels aren't snapped to the palette |
bands | number | how many flat tones the light makes on its surfaces, 1-8 |
edge | number | how far its cast shadows' edges tear, 0 to 0.5 |
stroke | number | brush strokes on its surfaces, 0 to 1 |
saturate | number | its colour past (above 1) or toward grey (below 1) its own |
wash | number | its textures' colour taken as their patch average, 0 to 1 |
LookProps
MatchmoveCamera
| Field | Type | What it is |
|---|---|---|
t (required) | number | seconds into the clip |
position (required) | Vec3 | where the camera is, in the solved world (metres) |
quaternion (required) | [number, number, number, number] | camera to world, [x, y, z, w]; the camera looks down its -Z with +Y up |
solved (required) | boolean | false: COLMAP didn't register this frame and its pose was interpolated |
MatchmoveProps
| Field | Type | What it is |
|---|---|---|
src (required) | string | the footage: staticFile("clip.mp4") |
from | number | where in the clip the shot starts, and how long it runs (seconds; 0 = to the end) |
seconds | number | how long the shot runs, seconds (0: to the clip's end) |
subject | [number, number, number, number] | the subject to keep in front of the 3D and out of the solve: a box around it on the first frame, [x, y, w, h] in 0..1 of the frame (EdgeTAM tracks it from there) |
height | number | the camera's height over the ground in metres (1.6 by default: handheld) |
fov | number | the vertical field of view in degrees, for a shot without parallax (a tripod, a pan); a solve with structure finds its own |
smooth | number | frames of smoothing on the solved path (1 by default; 0 for none) |
solve | MatchmoveSolve | a solve to draw from instead of solving (raea track CLIP -o solve.json, imported) |
crop | number | [number, number] | when the frame's shape isn't the footage's (9:16 from 16:9), where the frame sits across it: 0 its left edge, 1 its right, 0.5 the middle (the default); [x, y] for both axes. It may change from frame to frame |
zoom | number | 1 or more: a tighter window on the footage (a punch-in), still locked |
cutout | boolean | draw the subject's cut-out over the 3D (true by default when there's a subject) |
toneMapping | "none" | "tony" | "aces" | "agx" | "neutral" | "reinhard" | the scene's tone mapping: "none" by default, which leaves the footage's colours as they are |
children | ReactNode | the 3D that stands in the shot, in the solved world |
MatchmoveSolve
What raea track writes and
| Field | Type | What it is |
|---|---|---|
mode (required) | "sfm" | "rotation" | "static" | "sfm": a full solve with structure; "rotation": the camera only turns (too little parallax, or too few frames registered); "static": it doesn't move |
width (required) | number | the footage's size in pixels, and its frame rate |
height (required) | number | the footage's height in pixels |
fps (required) | number | the footage's frame rate |
from (required) | number | where in the clip the solve starts, seconds |
seconds (required) | number | how long it runs, seconds |
frames (required) | number | how many frames it solved |
fov (required) | number | vertical field of view, degrees; focal length in pixels; the lens's radial distortion |
focal (required) | number | the focal length in pixels, at the footage's full size |
k1 (required) | number | the lens's radial distortion |
registered (required) | number | how many frames COLMAP registered; the rest were interpolated |
error (required) | number | null | mean reprojection error in pixels (null without structure) |
camera_height (required) | number | the camera's height over the ground, metres, that set the world's scale |
cameras (required) | MatchmoveCamera[] | the camera a frame |
points (required) | Vec3[] | the sparse points, in the solved world |
ground (required) | { y: number; normal: Vec3 } | the ground plane: its height (0) and normal (+Y) |
cut (required) | string | null | the subject's cut-outs, a path with %04d for the frame (1-based), or null |
notes (required) | string[] | what the solver noticed: fallbacks, an assumed field of view, interpolated frames |
MatchmoveState
Each frame's state under a
| Field | Type | What it is |
|---|---|---|
solve (required) | MatchmoveSolve | the solve it draws from |
index (required) | number | the solve's frame shown now (0-based), and the clip's time |
time (required) | number | the clip's time at this frame, seconds |
camera (required) | MatchmoveCamera | the solve's camera for this frame |
project (required) | (p: Vec3) => [number, number, number] | where a point of the solved world lands in the composition, in pixels ([x, y], and its distance in front of the camera; behind it when that's 0 or less) |
MeshAttribute
One attribute's values on a mesh: one a vertex, each a number or a list of the format's size.
type MeshAttribute = [MeshVertexAttribute, (number | number[])[]]MeshPassProps
The props of MeshPass, tabled there.
MeshSequenceProps
| Field | Type | What it is |
|---|---|---|
name | string | the entity's name, for picking and the inspector |
src (required) | string | a.rseq (tools/goo writes them; raea_render::meshseq) |
frame (required) | number | which of its frames (clamped) |
position | Vec3 | where it stands, metres (x, y, z) |
rotation | Vec3 | its rotation, Euler angles in radians (x, y, z) |
scale | number | a uniform scale |
color | string | multiplies the vertex colours |
roughness | number | 0..1, smooth to matte |
metalness | number | 0..1, a dielectric to a metal |
clearcoat | number | 0..1 strength of a clear varnish layer over the surface |
clearcoatRoughness | number | 0..1 roughness of that clear layer |
reflectance | number | 0..1 specular strength at normal incidence (0.5: 4%, a dielectric's) |
subsurface | number | 0..1 light let through (diffuse transmission): a jelly's glow |
thickness | number | how thick the mesh is, metres, for the light let through |
transmission | number | 0..1 light let straight through and bent (a clear liquid: water, tea, juice), with its index of refraction (1.33 water) and, for a tinted one, the colour it takes after attenuationDistance metres through it. Screen space: it refracts what's on screen behind it, and one clear layer doesn't show another through it |
ior | number | the index of refraction of what light passes through (1.33 water) |
attenuationColor | string | the colour light takes after attenuationDistance metres through it |
attenuationDistance | number | metres through it until light has taken attenuationColor |
opacity | number | 0..1, see-through to solid |
map | string | a picture over its texture coordinates |
doubleSided | boolean | draw the back faces too (an open shell, a petal) |
MeshShaderPassProps
The props of MeshShaderPass, tabled there.
MeshSlab
A mesh's vertex or index buffer in Bevy's MeshAllocator, bound as a file's storage buffer (array<f32 | u32 | i32>)
for its compute to write (shader_advanced/compute_mesh): the mesh the part named mesh holds, a
Bevy: bevy_render::mesh::allocator::MeshBufferSlice.
| Field | Type | What it is |
|---|---|---|
mesh (required) | string | the mesh's name |
slab (required) | "vertices" | "indices" | which of its buffers: vertices or indices |
ModelProps
The props of Model, tabled there.
ModelScreens
A Model's screens prop: each material's screen, as a
type ModelScreens = Record<string, ReactElement>MotionBlurProps
| Field | Type | What it is |
|---|---|---|
shutterAngle | number | the fraction of a frame the shutter is open (0.5 by default, a 180-degree shutter); above 1 smears further |
samples | number | samples each way per pixel (4 by default) |
animate | Animate3d | declared animation of its numbers |
OutlineProps
| Field | Type | What it is |
|---|---|---|
color | string | the line's colour, a hex colour (black by default) |
depth | number | a silhouette: how far behind the nearer surface (a fraction of its distance) a neighbour must be (0.04) |
normal | number | a crease: how far the surface must turn between neighbours, 1 - cos of the angle (0.3, about 45 degrees; 0 for none) |
width | number | the line's width in pixels (1 by default; a cartoon's line is about 6) |
far | number | how far from the camera lines reach, in metres: they fade out over its last third, so a far field meeting the sky draws no line along the horizon (no limit by default) |
skip | string[] | composition passes (a part's pass) drawn with no line: none on their pixels and no crease against them (a scene object's silhouette in front of one still draws, on the object) |
PartInfo
| Field | Type | What it is |
|---|---|---|
file (required) | string | the part's own.glb in the asset store |
centre (required) | Vec3 | the middle of its bounds, metres, where it stands in the source file |
lo (required) | Vec3 | its bounds' low corner |
hi (required) | Vec3 | its bounds' high corner |
tris (required) | number | how many triangles it has |
PartMaterial
| Field | Type | What it is |
|---|---|---|
missing | boolean | the magenta-and-black checker of a texture that didn't load |
color | string | a colour over its own |
emissive | string | the colour it glows with |
opacity | number | 0..1, see-through to solid |
roughness | number | 0..1, smooth to matte |
unlit | boolean | drawn in its flat colour, without light or shade |
PartProps
The props of Part, tabled there.
PhaseAttribute
A vertex attribute: Bevy's VertexFormat by name, its byte offset in a vertex and its shader
| Field | Type | What it is |
|---|---|---|
format (required) | "Float32" | "Float32x2" | "Float32x3" | "Float32x4" | "Uint32" | "Uint32x2" | "Uint32x3… | the attribute's VertexFormat, by name |
offset (required) | number | its byte offset in a vertex |
location (required) | number | its shader |
PhaseItemProps
The props of PhaseItem, tabled there.
PhysicsProps
The props of Physics, tabled there.
Pickable
Something the pointer can hit: an axis-aligned box or a sphere, in world space.
type Pickable = { name: string; box: { min: Vec3; max: Vec3 } } | { name: string; sphere: { center: Vec3; radius: number } }PickCamera
The camera as a scene sets it: a PerspectiveCamera's props (fov in degrees, vertical) or an OrthographicCamera's.
| Field | Type | What it is |
|---|---|---|
position | Vec3 | where it stands, metres (x, y, z) |
lookAt | Vec3 | the point it faces |
fov | number | vertical field of view in degrees (50 by default); ignored when height is set |
height | number | an orthographic camera's view height in metres |
up | Vec3 | which way is up for it (+Y) |
Place2dProps
Where a 2D part is: composition px from the frame's top left, y down (as the page's), its centre there; and its pointer and drag handlers, called as a 3D part's are (2D parts are picked first, the top one by z).
| Field | Type | What it is |
|---|---|---|
name | string | the entity's name, for picking, the inspector and world.* |
x | number | px from the frame's left edge to the part's centre |
y | number | px from the frame's top edge to the part's centre, down positive |
rotation | number | radians, clockwise (as CSS rotate) |
quat | Quat | Bevy's rotation as it is, a quaternion [x, y, z, w] in Bevy's axes (y up, z toward the viewer), in place of rotation: a turn out of the frame's plane too, as a Sprite's Transform takes it (camera/2d_on_ui) |
scale | number | [number, number] | 1 by default; [x, y] to stretch |
z | number | draw order among the 2D parts: higher draws over lower (0 by default) |
opacity | number | 0 to 1 (1 by default) |
onClick | (e: Event3d) => void | a press and release over the part |
onPointerDown | (e: Event3d) => void | a button pressed over the part |
onPointerUp | (e: Event3d) => void | a button released over the part |
onPointerOver | (e: Event3d) => void | the pointer came over the part (bubbles, as the DOM's) |
onPointerOut | (e: Event3d) => void | the pointer left the part (bubbles) |
onPointerEnter | (e: Event3d) => void | the pointer came over the part (doesn't bubble) |
onPointerLeave | (e: Event3d) => void | the pointer left the part (doesn't bubble) |
onPointerMove | (e: Event3d) => void | the pointer moved over the part |
onWheel | (e: Event3d) => void | the wheel turned over the part (deltaX, deltaY) |
onDragStart | (e: Event3d) => void | a drag began on the part pressed |
onDrag | (e: Event3d) => void | the part pressed is being dragged, each frame it moves |
onDragEnd | (e: Event3d) => void | the drag of the part pressed ended |
onDragEnter | (e: Event3d) => void | a dragged part came over this one (dragged names it) |
onDragOver | (e: Event3d) => void | a dragged part is over this one |
onDragLeave | (e: Event3d) => void | a dragged part left this one |
onDrop | (e: Event3d) => void | a dragged part was dropped on this one |
Placed
| Field | Type | What it is |
|---|---|---|
base (required) | V3 | the centre of its bottom face |
center (required) | V3 | its middle, where a centred Cuboid goes |
yaw (required) | number | its turn about y, radians (its front is +z before the turn) |
size (required) | V3 | its width, height and depth, metres |
PlaceFinding
| Field | Type | What it is |
|---|---|---|
part (required) | string | the object it's about |
check (required) | string | the rule that couldn't hold |
level (required) | string | "ok", or how bad it is ("error" when the rule broke) |
says (required) | string | what's wrong, in words |
PlaceObject
| Field | Type | What it is |
|---|---|---|
size (required) | V3 | its width, height and depth, metres |
at | V3 | a start (or, with fixed, the place) for its bottom centre |
yaw | number | degrees |
fixed | boolean | it stays at at: the rules move the others round it |
PlaceRule
type PlaceRule = | { on: string; of: string } | { against: string; wall: Side } | { beside: string; of: string; side: Side; gap?: number } | { near: string; of: string; dist?: number } | { apart: string; of: string; min?: number } | { facing: string; of: string } | { align: string; of: string; axis: "x" | "z" } |…PlanBox
A box on the plan (x, z, metres): the room SDK's Footprint, or any { min, max }.
| Field | Type | What it is |
|---|---|---|
min (required) | [number, number] | the low corner (x, z), metres |
max (required) | [number, number] | the high corner (x, z), metres |
Plane3dProps
Bevy's Plane3d: a flat rectangle facing normal (Bevy's default +Y, a floor), half_size its half extent along
its two axes ([0.5, 0.5]), laid out as Bevy's PlaneMeshBuilder does: facing +Z it is a Plane of args
[2 x half_size]. The normal is along an axis; a tilted plane is a rotated Mesh3d.
| Field | Type | What it is |
|---|---|---|
normal | Vec3 | the way it faces, along an axis (+Y by default, a floor) |
half_size | [number, number] | half its extent along its two axes, metres ([0.5, 0.5]) |
PlateProps
| Field | Type | What it is |
|---|---|---|
src (required) | string | a video in the media folder: staticFile("clip.mp4") |
name | string | the entity's name, for picking, the inspector and world.* |
time | number | the clip's time on this frame, in seconds (by default the Sequence's: frame / fps) |
k1 | number | the lens's radial distortion (SIMPLE_RADIAL's k1, from a solve): the plate is drawn undistorted, so the footage's straight lines are straight where the 3D's are |
Polygons
A 2D outline: contours of [x, y] points (counter-clockwise for solid, clockwise for a hole).
type Polygons = [number, number][][]RichTextProps
| Field | Type | What it is |
|---|---|---|
name | string | what it's called across frames, and its glyphs' names over world.* (${name}:${index}) |
pass | string | the composition pass it draws in ("scene" by default): a frame-wide effect told to skip a pass ( |
position | Vec3 | where the block's origin is, metres (x, y, z) |
rotation | Vec3 | the block's rotation, radians (x, y, z) |
scale | number | Vec3 | the block's scale: one number, or x, y and z |
size | number | the em in metres (0.5 by default) |
font | string | a family (raea's bundled faces: Inter by default, Montserrat, Oswald, Playfair Display...; or one on this machine) |
weight | number | 100..900 (700 by default) |
italic | boolean | slanted (false by default) |
color | string | each glyph's colour unless its gives one |
align | "left" | "center" | "right" | where the origin is: the left edge, the middle (default) or the right edge of the lines; the block's middle vertically |
lineHeight | number | times the em (1.2 by default) |
maxWidth | number | wrapped at this width in metres (no wrapping by default) |
roughness | number | 0..1, smooth to matte |
metalness | number | 0..1, a dielectric to a metal |
emissive | string | the colour it glows with |
emissiveIntensity | number | how strongly it glows (1 by default; 2-10 with bloom) |
unlit | boolean | drawn in its flat colour, without light or shade |
castShadow | boolean | letter-shaped shadows (true by default) |
receiveShadow | boolean | other things' shadows fall on it |
layers | number[] | the render layers it's on ([0] by default): a camera draws only the layers it's given |
enter | MoveLike | each glyph's (or word's) entrance: a move's name, a move or several (rise, pop, slam, slide, fade... the 2D ones, their px read at 100 an em, their degrees as degrees), each frames apart from at |
each | number | frames between one glyph's (or word's) entrance and the next (2 by default) |
by | "letter" | "word" | the entrance and exit staggered by letter (default) or by word |
at | number | the local frame the first entrance starts (0) |
exit | MoveLike | each glyph's (or word's) exit: a move or its name, played backwards from exitAt |
exitAt | number | the local frame the first exit starts; an exit needs it |
exitEach | number | frames between exits (0: together) |
reveal | number | how many glyphs are shown, a typewriter's count: the next one fades in over its fraction |
glyph | (g: GlyphInfo) => GlyphStyle | each glyph's own motion this frame, from anything the frame gives (useCurrentFrame, spring, interpolate) |
children | ReactNode | the text: strings and runs |
SamplerSpec
How a texture is read (Bevy's ImageSamplerDescriptor; raea-sys-sampler). Each part is optional, over the texture's own default. A texture file loaded with two samplers is drawn with the last (the load says so).
| Field | Type | What it is |
|---|---|---|
filter | "nearest" | "linear" | "nearest": hard pixels; "linear": smoothed (a material map's default) |
mipmap | "nearest" | "linear" | "none" | between mip levels; "none" reads the full-size texture only |
wrap | SamplerWrap | [SamplerWrap, SamplerWrap] | past the edge: one mode, or [u, v] |
anisotropy | number | 1 to 16 (a map's default is 16); needs every filter linear, so nearest turns it off |
SamplerWrap
type SamplerWrap = "repeat" | "clamp" | "mirror"ScatterOptions
| Field | Type | What it is |
|---|---|---|
area (required) | PlanBox | where the points fall: a box on the plan (x, z) |
count (required) | number | how many (fewer when the area fills up: spacing and avoid leave no room) |
spacing | number | the least distance between two points, metres (0: none) |
avoid | PlanBox[] | boxes on the plan to keep clear of, grown by margin |
margin | number | how far to stay off each avoided box (spacing / 2 by default) |
clearOf | Instance[] | points kept off already-placed ones too: a second scatter (flowers) clear of the first (stones) by spacing |
seed | number | 1 by default; the same seed gives the same points, every frame, render and play |
yaw | boolean | number | [number, number] | each point's turn about y (radians): true (the default) any, false none, a number that one, [lo, hi] between |
tilt | number | a lean off upright, radians: each point tipped by up to this much in a random direction (0 by default) |
scale | number | [number, number] | a scale, or [lo, hi] between (uniform) |
y | number | ((x: number, z: number) => number) | the ground's height: a number (0), or the terrain's height at (x, z) |
density | (x: number, z: number) => number | how likely a point is kept at (x, z), 0 to 1: a density map (a path worn bare, a patch thicker by the chair) |
SceneProps
The props of Scene, tabled there.
ScreenProps
The props of Screen, tabled there.
ScreenSource
| Field | Type | What it is |
|---|---|---|
resolution | [number, number] | the picture's size in pixels, [width, height] ([320, 200]); the nested composition lays out at it |
crt | boolean | CrtSettings | draw it as a CRT (true, the default; or its settings) or flat (false: an LCD) |
power | number | the tube's power, 0 (off) to 1 (on, the default): animate it to switch the set on, a line opening to the picture |
from | number | the frame of this Sequence the nested composition's frame 0 falls on (0) |
background | string | behind the picture ("#000000"). A see-through one ("#ffffff00", "transparent", rgba(..., 0.5)) makes the screen see-through where its page paints nothing, so what's behind it in the scene shows (a flat screen: a layer of a page pulled apart in 3D); an opaque one keeps the screen opaque, which writes depth for DepthOfField |
brightness | number | a flat screen's (crt={false}) light: 1, the default, draws its page at the page's own colours, unlit (scene lights don't touch it); above 1 it glows, and blooms under a crt.brightness |
src | string | a video to show instead of children: staticFile("clip.mp4"), filling the picture |
app | string | an app to show instead of children: a module's path from the composition's folder ("chat.tsx"), its default export a React component given {width, height}. It runs on real react-dom in a document of its own, so npm's React libraries work on it (assistant-ui, Radix; installed with raea add). In play the pointer reaches it through the 3D, where it lands on the picture, and a press on it gives it the keys (the game doesn't get them) until a press elsewhere or Escape; in a render it runs on the frame's clock, so the render repeats |
children | ReactNode | the nested composition or game |
Section
A cross-section of a solid at a height: its area, how many contours, and the contours themselves.
| Field | Type | What it is |
|---|---|---|
area (required) | number | the section's area, m² |
contours (required) | number | how many outlines it has |
polygons (required) | [number, number][][] | the outlines, each a list of [x, y] points in the section's plane |
ShaderInstancesProps
The props of ShaderInstances, tabled there.
ShaderMeshProps
| Field | Type | What 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 }) |
wesl | string | WESL (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 |
wgsl | string | the same in plain WGSL (compiled as WESL, its superset: Bevy 0.20 has no naga_oil, so no #import) |
uniforms | Record<string, number | number[] | string> | up to 16: a number (f32), [x, y], [x, y, z], [x, y, z, w] or "#rrggbb" (a linear vec4) |
textures | Record<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 |
defs | ShaderDefs | shader 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 |
doubleSided | boolean | draw the back faces too |
name | string | the entity's name, for picking, the inspector and world.* |
position | Vec3 | where it stands, metres (x, y, z) |
rotation | Vec3 | its rotation, Euler angles in radians (x, y, z) |
scale | Vec3 | number | its scale: one number, or x, y and z |
ShadowsProps
| Field | Type | What it is |
|---|---|---|
mapSize | 1024 | 2048 | 4096 | 8192 | each shadow map's size in texels (4096 by default; 8192 is sharper still, at four times the memory and about 2-3 ms a frame at 1080p) |
distance | number | how far from the camera the sun's shadows reach, in metres (150 by default): the shorter, the sharper they are |
firstCascade | number | where the sun's first, sharpest cascade ends, in metres (8 by default): the distance of the nearest subject |
cascades | number | how many cascades split the distance (4 by default, 1-4) |
overlap | number | how much neighbouring cascades overlap, 0-1 (0.3 by default) so the seam between them doesn't show |
bias | number | depth bias: raise it if surfaces facing the light show stripes of their own shadow (acne); too high and shadows detach from what casts them (0.02 by default for the sun, as Bevy's) |
normalBias | number | normal bias, in texels: the same trade-off along the surface's normal (1.8 by default for the sun) |
filter | "gaussian" | "hardware" | "gaussian" (the default: soft, smooth edges) or "hardware" (2x2, crisper and cheaper) |
Shape
type Shape = "hull" | "box" | "mesh" | { box: Vec3 } | { sphere: number } | { capsule: [number, number] }Shape2DProps
| Field | Type | What it is |
|---|---|---|
shape | "rect" | "circle" | "ellipse" | "triangle" | "polygon" | a rect by default; a polygon has sides (5 by default) |
size | [number, number] | [width, height] in px ([100, 100] by default); a circle's and a polygon's diameter is the width |
sides | number | a polygon's number of sides (5) |
color | string | a CSS colour (white by default); with a texture, it tints it |
srgb | [number, number, number] | the colour as a Bevy Srgba's [r, g, b], unrounded, over color (a Mesh2d's ColorMaterial gives it) |
texture | string | { path: string; sampler: SamplerSpec } | a picture on it, mapped by the mesh's UVs (Bevy's ColorMaterial texture), or one with its own sampler (Bevy's load_with_settings: { path, sampler: { wrap: "repeat" } }) |
uv_transform | { scale: [number, number]; angle: number; translation: [number, number] } | the texture's UVs scaled, turned and moved (ColorMaterial's uv_transform, glam's Affine2 as raea/transform's) |
alpha_mode | AlphaMode2d | Bevy's AlphaMode2d: "Blend" (Bevy's default), "Opaque", or { Mask: cutoff } |
vertex_colors | [number, number, number, number][] | one linear [r, g, b, a] per vertex of the shape's mesh (Bevy's Mesh::ATTRIBUTE_COLOR): the material's colour and texture are multiplied by them. A rect has 4 (top right, top left, bottom left, bottom right), a triangle 3. |
shader | Record<string, unknown> | its own Material2d in place of the ColorMaterial: the spec a |
primitive | Record<string, unknown> | one of Bevy's 2D primitives in place of shape, its reflected fields over Bevy's default: { primitive: "Capsule2d", radius: 25, half_length: 25 }; a 2D shape given inner (the same shape's fields) is Bevy's Ring, or given ring: thickness its to_ring (raea-sys-mesh primitive_mesh). A Mesh2d's primitive child makes it. |
name | string | the entity's name, for picking, the inspector and world.* |
x | number | px from the frame's left edge to the part's centre |
y | number | px from the frame's top edge to the part's centre, down positive |
rotation | number | radians, clockwise (as CSS rotate) |
quat | Quat | Bevy's rotation as it is, a quaternion [x, y, z, w] in Bevy's axes (y up, z toward the viewer), in place of rotation: a turn out of the frame's plane too, as a Sprite's Transform takes it (camera/2d_on_ui) |
scale | number | [number, number] | 1 by default; [x, y] to stretch |
z | number | draw order among the 2D parts: higher draws over lower (0 by default) |
opacity | number | 0 to 1 (1 by default) |
onClick | (e: Event3d) => void | a press and release over the part |
onPointerDown | (e: Event3d) => void | a button pressed over the part |
onPointerUp | (e: Event3d) => void | a button released over the part |
onPointerOver | (e: Event3d) => void | the pointer came over the part (bubbles, as the DOM's) |
onPointerOut | (e: Event3d) => void | the pointer left the part (bubbles) |
onPointerEnter | (e: Event3d) => void | the pointer came over the part (doesn't bubble) |
onPointerLeave | (e: Event3d) => void | the pointer left the part (doesn't bubble) |
onPointerMove | (e: Event3d) => void | the pointer moved over the part |
onWheel | (e: Event3d) => void | the wheel turned over the part (deltaX, deltaY) |
onDragStart | (e: Event3d) => void | a drag began on the part pressed |
onDrag | (e: Event3d) => void | the part pressed is being dragged, each frame it moves |
onDragEnd | (e: Event3d) => void | the drag of the part pressed ended |
onDragEnter | (e: Event3d) => void | a dragged part came over this one (dragged names it) |
onDragOver | (e: Event3d) => void | a dragged part is over this one |
onDragLeave | (e: Event3d) => void | a dragged part left this one |
onDrop | (e: Event3d) => void | a dragged part was dropped on this one |
SkyboxProps
| Field | Type | What it is |
|---|---|---|
image (required) | string | the sky's cubemap, a.ktx2 file (Bevy's examples use the specular map: environment_maps/pisa_specular_rgb9e5_zstd.ktx2) |
brightness | number | cd/m² (Bevy's default 0, a black sky: Bevy's examples give it 1000 to 5000) |
rotation | [number, number, number, number] | its turn, glam's Quat [x, y, z, w] (Bevy's identity) |
SpanProps
| Field | Type | What it is |
|---|---|---|
children | ReactNode | the run's text |
font | string | a family (raea's bundled faces: Inter, Montserrat, Oswald, Playfair Display...; or one on this machine) |
weight | number | 100..900 (the block's by default) |
italic | boolean | slanted (the block's by default) |
size | number | times the block's size |
color | string | the run's colour (the block's by default) |
SphereProps
args, or Bevy's Sphere field: radius (0.5 by Bevy's default). Its mesh is Bevy's Sphere::mesh(): an icosphere of 5
subdivisions, or ico of them (Bevy's .ico(n), 0 to 80), or a UV sphere of uv = [sectors, stacks] (.uv(s, t)).
| Field | Type | What it is |
|---|---|---|
args | [number] | [radius], as three.js's args |
radius | number | metres (0.5) |
ico | number | an icosphere of this many subdivisions (5 by default; 0 to 80) |
uv | [number, number] | a UV sphere instead: [sectors, stacks] |
SplatMorph
| Field | Type | What it is |
|---|---|---|
to (required) | string | the splat file it becomes |
amount (required) | number | 0 this splat, 1 the other (each splat flies to the one matched to it) |
crop | number | only the other's splats this many metres from its centre (a trained scene's subject without its surroundings) |
SplatProps
| Field | Type | What it is |
|---|---|---|
name | string | parts are matched by name across frames: name a splat that comes and goes |
src (required) | string | the 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 |
position | Vec3 | where it stands, metres (x, y, z) |
rotation | Vec3 | radians, Euler XYZ |
scale | number | Vec3 | its scale: one number, or x, y and z |
splatScale | number | every gaussian's size times this (1 by default): below 1 the scene breaks into points |
opacity | number | 0..1, multiplying every gaussian's |
brightness | number | grade: colour times brightness, saturation and contrast about mid grey, times tint |
saturation | number | 1 as trained; 0 grey, above 1 richer |
contrast | number | 1 as trained; about mid grey |
tint | string | a colour every gaussian's is multiplied by |
reveal | number | reveal 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 |
revealFrom | Vec3 | the point the reveal grows outward from (the centre by default) |
revealAxis | Vec3 | a direction: the reveal sweeps a plane along it instead of growing from a point |
revealSoft | number | how wide the front is, as a share of the sweep (0.15) |
revealGlow | number | the front's glow (0 none, 1 bright), in glowColor |
glowColor | string | the colour of reveal and pulse glows (warm white) |
disperse | number | disperse 0..1: blown off on a curl-noise wind, the upwind side first, shrinking to specks |
assemble | number | assemble 0..1: from a cloud of dust round the scene into its shape (1 whole) |
wind | Vec3 | the wind's direction ([1, 0.15, 0]) |
curl | number | how much the wind curls (1) |
spread | number | the dust cloud's radius in metres (the splat's own size, before scale; 1.6 times its size by default) |
explode | number | explode 0..1: thrown out from the centre, falling and fading |
wave | SplatWave | a ripple running out through the splats: amplitude, wavelength and phase |
twist | number | radians a metre about the vertical through the centre |
morph | SplatMorph | becomes another splat file: to and amount 0..1 |
pulse | number | a value the composition passes (a beat's envelope 0..1): bigger by pulseScale, brighter by pulseGlow |
pulseScale | number | how much bigger a full pulse makes it |
pulseGlow | number | how much brighter a full pulse makes it |
crop | number | nothing past this many metres from the centre (trims a trained scene's floaters) |
bands | number | the light in this many flat bands (0 none); a paint or cartoon |
paint | number | 0..1: the splats themselves painted (flat bands, grown into strokes with hard edges), for a painted shot in a timeline whose frame |
seed | number | which randomness: the scatter, the jitter (0) |
SplatWave
| Field | Type | What it is |
|---|---|---|
amplitude (required) | number | how high the ripple lifts the splats, metres |
wavelength | number | from crest to crest, metres (1 by default) |
phase | number | where the ripple is in its cycle, radians: animate it (frame * 0.2) to run it outward |
SpriteProps
| Field | Type | What it is |
|---|---|---|
src (required) | string | a picture in the media folder: staticFile("hero.png"), or a "render:NAME" image a camera or a |
width | number | size in px (the picture's, or one cell's, by default); one given, the other follows the picture's shape |
height | number | in px; given alone, the width follows the picture's shape |
grid | [number, number] | a sprite sheet: the picture is [columns, rows] cells of equal size, read left to right, top to bottom |
atlasPick | number | one picture of a built atlas (TextureAtlasBuilder's sources.handle gives it with its src): its index in the atlas's list |
frame | number | with grid: which cell shows (0 is the top left); animate it to play the sheet: frame={Math.floor(f / 3)} |
flipX | boolean | mirrored left to right |
flipY | boolean | mirrored top to bottom |
color | string | a tint multiplied over the picture (white by default) |
tileX | boolean | Bevy's SpriteImageMode::Tiled: the picture repeats across the sprite's width (tileX) or height (tileY) instead of stretching to it, a tile every tileStretch x the picture's size (1 by default): a floor, a fence, a wall. Animate width and height to show more or fewer tiles |
tileY | boolean | tile the picture down its height instead of stretching it |
tileStretch | number | a tile every this many times the picture's size (1) |
image_mode | SpriteImageMode | Bevy's SpriteImageMode, as its reflected value: "Auto" (stretched to the size), { Scale: "FillCenter" } (and FillStart, FillEnd, FitCenter, FitStart, FitEnd: the picture kept to its shape, cropped or fitted), { Sliced: TextureSlicer } (nine-slice: border a number of px or { min_inset: [x, y], max_inset: [x, y] }; center_scale_mode and sides_scale_mode "Stretch" or { Tile: { stretch_value } }; max_corner_scale) or { Tiled: { tile_x, tile_y, stretch_value } }. Not with tileX or tileY |
sampler | SamplerSpec | the picture's sampler (Bevy's load_with_settings: { filter, mipmap, wrap, anisotropy }), Bevy's default (linear) otherwise; { filter: "nearest" } is pixel art as Bevy's ImagePlugin::default_nearest() draws it |
children | ReactNode | your own |
name | string | the entity's name, for picking, the inspector and world.* |
x | number | px from the frame's left edge to the part's centre |
y | number | px from the frame's top edge to the part's centre, down positive |
rotation | number | radians, clockwise (as CSS rotate) |
quat | Quat | Bevy's rotation as it is, a quaternion [x, y, z, w] in Bevy's axes (y up, z toward the viewer), in place of rotation: a turn out of the frame's plane too, as a Sprite's Transform takes it (camera/2d_on_ui) |
scale | number | [number, number] | 1 by default; [x, y] to stretch |
z | number | draw order among the 2D parts: higher draws over lower (0 by default) |
opacity | number | 0 to 1 (1 by default) |
onClick | (e: Event3d) => void | a press and release over the part |
onPointerDown | (e: Event3d) => void | a button pressed over the part |
onPointerUp | (e: Event3d) => void | a button released over the part |
onPointerOver | (e: Event3d) => void | the pointer came over the part (bubbles, as the DOM's) |
onPointerOut | (e: Event3d) => void | the pointer left the part (bubbles) |
onPointerEnter | (e: Event3d) => void | the pointer came over the part (doesn't bubble) |
onPointerLeave | (e: Event3d) => void | the pointer left the part (doesn't bubble) |
onPointerMove | (e: Event3d) => void | the pointer moved over the part |
onWheel | (e: Event3d) => void | the wheel turned over the part (deltaX, deltaY) |
onDragStart | (e: Event3d) => void | a drag began on the part pressed |
onDrag | (e: Event3d) => void | the part pressed is being dragged, each frame it moves |
onDragEnd | (e: Event3d) => void | the drag of the part pressed ended |
onDragEnter | (e: Event3d) => void | a dragged part came over this one (dragged names it) |
onDragOver | (e: Event3d) => void | a dragged part is over this one |
onDragLeave | (e: Event3d) => void | a dragged part left this one |
onDrop | (e: Event3d) => void | a dragged part was dropped on this one |
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.
| Field | Type | What 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 |
alphaCutoff | number | with 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
| Field | Type | What it is |
|---|---|---|
wesl | string | the source in WESL (Bevy 0.20's shader language, a superset of WGSL) |
wgsl | string | the same in plain WGSL |
fragment | string | the 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 |
uniforms | Record<string, number | number[] | string> | up to 16: a number (f32), [x, y], [x, y, z], [x, y, z, w] or "#rrggbb" (a linear vec4) |
textures | Record<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 |
defs | ShaderDefs | shader 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 |
own | OwnMaterialFields | a |
buffers | Record<string, StorageValue> | the material's storage buffers by binding name; set by |
Text3DProps
| Field | Type | What it is |
|---|---|---|
children | string | the words, extruded |
text | string | the words, when they aren't its child (no quotes or backslashes) |
size | number | letter height in scene units (default 0.5) |
depth | number | extrusion depth (default 0.2) |
font | string | a family (Inter by default, or another of raea's bundled faces) |
weight | number | 100..900 (800 by default) |
ThreeShaderMaterialProps
| Field | Type | What 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 |
uniforms | Record<string, ThreeUniform> | each uniform's value this frame |
textures | Record<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) |
transparent | boolean | blended 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 |
depthWrite | boolean | it writes the depth buffer |
depthTest | boolean | it's hidden behind what's nearer |
alphaTest | number | pixels less opaque than this are dropped |
time | [number, number, number] | three's clock this frame: [seconds, delta, frame] |
color | string | the colour it's drawn in where its shader can't run (named in the render's warnings) |
ThreeUniform
A uniform's value: a number, a boolean, or its numbers in order (a vector's, a matrix's column by column as three's
elements, an array's elements one after another)
type ThreeUniform = number | boolean | number[]ToneMappingProps
| Field | Type | What it is |
|---|---|---|
mode | "tony" | "aces" | "agx" | "neutral" | "reinhard" | "none" | how bright light maps to the screen: "tony" (Bevy's default), "aces" (filmic, contrasty), "agx", "neutral", "reinhard", "none" |
exposure | number | stops brighter (+) or darker (-) than the default exposure |
ToonBand
| Field | Type | What it is |
|---|---|---|
at (required) | number | where 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 |
color | string | the band's colour; left out, it's mixed (in Oklab) between the shadow colour and color by its place |
ToonHighlight
| Field | Type | What it is |
|---|---|---|
intensity | number | 0..1 (1 by default) |
color | string | "#ffffff" by default |
size | number | 0..1: the highlight's angular radius, up to half a radian (0.2 by default) |
ToonOutline
| Field | Type | What it is |
|---|---|---|
width | number | pixels at the composition's size, the same near and far (2 by default) |
color | string | ink colour; by default the surface colour's hue, very dark |
ToonRim
| Field | Type | What it is |
|---|---|---|
intensity | number | 0..1, how much the rim colour covers the band (1 by default) |
color | string | "#ffffff" by default |
width | number | 0..1 of the Fresnel range from the silhouette inwards (0.3 by default) |
TorusProps
args, or Bevy's Torus fields: major_radius (0.75) and minor_radius (0.25), the tube's.
| Field | Type | What it is |
|---|---|---|
args | [number, number] | [major radius, minor radius] |
major_radius | number | from the centre to the middle of the tube, metres (0.75) |
minor_radius | number | the tube's radius, metres (0.25) |
TreeOptions
| Field | Type | What it is |
|---|---|---|
height | number | metres (6) |
trunk | number | the clear trunk below the crown, a share of the height (0.35) |
width | number | the crown's width over its height (0.9) |
crown | "dome" | "sphere" | "cone" | "column" | "umbrella" | "vase" | the crown's shape: dome (an oak), sphere, cone (a pine), column (a cypress), umbrella or vase |
points | number | attraction points: more is a denser, twiggier crown (1200) |
step | number | a growth step, a share of the height (0.03) |
base | number | the trunk's radius at the ground (a fortieth of the height) |
tip | number | the outer twigs' radius (0.006) |
tropism | number | branches turn up (+) or droop (-) as they grow (0.15) |
leaves | number | leaves per outer twig node (3; 0 is bare) |
leaf | number | a leaf's length (0.09) |
sides | number | sides of each branch's tube (7; 3 to 24) |
seed | number | which randomness it uses: the same seed gives the same result |
Vec3
type Vec3 = [number, number, number]VertexFormat
A vertex attribute's format, as Bevy's VertexFormat names it.
type VertexFormat = "Float32" | "Float32x2" | "Float32x3" | "Float32x4" | "Uint32" | "Uint32x2" | "Uint32x3" | "Uint32x4" | "Sint32" | "Sint32x4"VolumeCommon
| Field | Type | What it is |
|---|---|---|
name | string | parts are matched by name across frames |
time | number | seconds on the simulation's clock (the Sequence's time, frame / fps, by default) |
resolution | number | cells along the box's longest side (64 by default; 32 is a quarter the cost a step, 96 finer) |
seed | number | the same seed simulates the same volume (0) |
colors | [string, string, string] | its tones under a paint look: [lit, mid, dark] |
threshold | number | the density its painted surface sits at (0.12): lower is fatter, higher thinner |
erode | number | how much noise tears the painted surface's edge (0.08), and the tears' size in metres (0.6) |
erodeSize | number | the tears' size in metres (0.6) |
absorb | number | how much light a unit of it stops (its shadow on itself; 1.2) |
wind | Vec3 | the 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) |
windPull | number | how fast the volume takes up the wind, a second (1.2 smoke, 0.6 otherwise) |
windHeight | number | the height the wind is full from, metres; weaker below (0: full everywhere) |
drag | number | velocity the still air takes away a second (0.4) |
vorticity | number | curl kept curling (6); a drifting turbulent force, m/s² (0), and its size in metres (2) |
turbulence | number | a drifting turbulent force, m/s² (0) |
turbulenceSize | number | the turbulence's size in metres (2) |
steps | number | samples along each ray (96) |
shadow | boolean | number | its 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 softShadow (2-4 for clouds) |
VolumeProps
| Field | Type | What it is |
|---|---|---|
position | Vec3 | the box's foot (the centre of its floor), metres ([0, 0, 0]) |
size (required) | Vec3 | the box it lives in, [width, height, depth] in metres: what leaves it is cut |
sources | VolumeSource[] | 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 |
buoyancy | number | heat'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 |
weight | number | the density's weight, m/s² a unit (0.4) |
cooling | number | the heat lost a second, a fraction (0.8) |
dissipation | number | the density lost a second, a fraction (0.02) |
fire | [string, string, string] | false | fire 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]) |
name | string | parts are matched by name across frames |
time | number | seconds on the simulation's clock (the Sequence's time, frame / fps, by default) |
resolution | number | cells along the box's longest side (64 by default; 32 is a quarter the cost a step, 96 finer) |
seed | number | the same seed simulates the same volume (0) |
colors | [string, string, string] | its tones under a paint look: [lit, mid, dark] |
threshold | number | the density its painted surface sits at (0.12): lower is fatter, higher thinner |
erode | number | how much noise tears the painted surface's edge (0.08), and the tears' size in metres (0.6) |
erodeSize | number | the tears' size in metres (0.6) |
absorb | number | how much light a unit of it stops (its shadow on itself; 1.2) |
wind | Vec3 | the 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) |
windPull | number | how fast the volume takes up the wind, a second (1.2 smoke, 0.6 otherwise) |
windHeight | number | the height the wind is full from, metres; weaker below (0: full everywhere) |
drag | number | velocity the still air takes away a second (0.4) |
vorticity | number | curl kept curling (6); a drifting turbulent force, m/s² (0), and its size in metres (2) |
turbulence | number | a drifting turbulent force, m/s² (0) |
turbulenceSize | number | the turbulence's size in metres (2) |
steps | number | samples along each ray (96) |
shadow | boolean | number | its 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 softShadow (2-4 for clouds) |
VolumeSource
where density and heat come in: a burner, or an engine moving at -> to (a contrail)
| Field | Type | What it is |
|---|---|---|
at (required) | Vec3 | where (metres from the box's foot), and where it has moved to by until if it moves |
to | Vec3 | where a moving source has got to by until |
from | number | when it puts out, seconds ([0, Infinity]) |
until | number | when it stops putting out, seconds (Infinity) |
radius | number | its 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]) |
rate | number | the density it puts out a second at its centre (4) |
heat | number | the heat it puts out a second at its centre (4) |
speed | Vec3 | the velocity it pushes out with, m/s ([0, 0, 0]) |
VolumetricFogProps
| Field | Type | What it is |
|---|---|---|
steps | number | mode="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 |
dither | boolean | mode="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 |
resolution | number | mode="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 |
ambient | number | light 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 |
ambientColor | string | that 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 |
slices | number | the grid's cells along the view, spaced evenly in log depth from the camera to the farthest volume (64 by default; 32 to 256) |
tile | number | the grid's cells across the frame, in pixels a side (16 by default; 4, 8 or 16) |
samples | number | points 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) |
hero | boolean | the 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 |