Hazel

Material Node Reference

The complete catalog of every node in the Renzora material graph, grouped by category, with each node's inputs, outputs, and exactly what it computes.

This page is the per-node companion to the Material API (file format, instances, domains) and the Material Editor (how to wire nodes). To add a brand-new built-in node, see Custom Material Nodes.

All nodes live in renzora_shader — declared in material/nodes.rs (ALL_NODES) and compiled to WESL in material/codegen.rs. There are 13 categories and 161 node types. Every generated fragment shader (one synthetic graph per node type, plus every .material shipped under assets/materials/) is compiled in the test suite the way the engine compiles it: by the WESL compiler against bevy_pbr's own shader sources, then validated by naga. A .material saved before r1-alpha8 embeds the old #import dialect and is translated to WESL first. Imports resolve to the real thing, so a node whose codegen drifts invalid is a CI failure rather than a silent runtime fallback.

Reading the catalogue from code

This page is written by hand and the compiler does not check it. renzora_shader also publishes the same list at runtime, as data, into renzora::MaterialNodeCatalog — node type, category, description, and each pin's name, type and direction:

fn pick_a_noise(catalogue: Res<renzora::MaterialNodeCatalog>) {
    for node in catalogue.iter().filter(|n| n.category == "Procedural") {
        let inputs: Vec<&str> = node.inputs().map(|pin| pin.name.as_str()).collect();
        info!("{} takes {inputs:?}", node.node_type);
    }
}

That exists because the definitions cannot leave renzora_shader — a PinTemplate carries a PinValue, which is the compiler's own vocabulary — while a native plugin links only bevy, renzora and renzora_ember. Prefer it over transcribing this page: a copied list drifts, and the drift shows up as a graph that will not compile rather than as a mismatch anyone can see.

How to read this page

Every node is identified by a category/name string (e.g. math/multiply). For each node you'll see its inputs, outputs, and what it does. Inputs are written name (type = default); an input with no default takes whatever you wire into it (or a zero/identity value if left unconnected).

A few rules apply everywhere:

  • Pin types coerce automatically. Float, Vec2, Vec3, Vec4, and Color are freely inter-connectable. Wiring a scalar into a vector copies it across every lane; wiring a wider vector into a narrower pin takes the leading components. So a math/multiply works on floats or colors with no extra nodes. Bool is the exception: it is not part of the numeric family, so the editor refuses to wire it into a numeric pin. Graphs saved before that gate still compile — the compiler casts, turning true into 1.0 and false into 0.0.
  • Unconnected UV inputs default to the mesh UVs. Texture and pattern nodes that take a uv pin fall back to the mesh's UV attribute (mat_uv) when you leave it empty, so the simplest possible graph still works.
  • Most nodes are component-wise. Math nodes operate per-channel on whatever type flows through them.
  • Nodes are compile-time. Each node emits a WGSL snippet; the graph compiles to one shader. "Runtime branch" vs "compile-time branch" (see Control) is the one place this distinction is visible.

Input

Sources of per-fragment data. Header color: blue. None of these have inputs unless noted; they're where data enters the graph.

NodeInputsOutputsWhat it does
input/uv — UV—uv (Vec2), u, v (Float)The mesh's texture coordinates (0–1). u/v are the split channels.
input/uv_scale — UV Scaleuv (Vec2), scale (Vec2 = 2,2), offset (Vec2 = 0,0)uv (Vec2)Tiling: uv * scale + offset.
input/uv_polar — Polar UVuv (Vec2), center (Vec2 = 0.5,0.5)uv (Vec2), angle, radius (Float)Cartesian → polar around center. angle is 0..1, radius is distance. For spirals, pies, radial sweeps.
input/uv_rotator — UV Rotatoruv (Vec2), angle (Float = 0, radians), center (Vec2 = 0.5,0.5)uv (Vec2)Rotates UVs around center.
input/uv_panner — UV Panneruv (Vec2), speed (Vec2 = 0.1,0), time_offset (Float = 0)uv (Vec2)Time-driven scroll: uv + speed * (time + offset). Matches Unreal's Panner.
input/world_position — World Position—position (Vec3), x, y, z (Float)Fragment world-space position.
input/world_normal — World Normal—normal (Vec3), x, y, z (Float)Fragment world-space surface normal.
input/view_direction — View Direction—direction (Vec3)Normalized fragment → camera direction.
input/time — Time—time, sin_time, cos_time (Float)Seconds since start, plus its sine and cosine for cheap oscillation.
input/vertex_color — Vertex Color—color (Color), r, g, b, a (Float)Per-vertex color attribute (defaults to white on meshes without one).
input/sprite_color — Sprite Coloruv (Vec2, the sprite's UV when unwired)color (Color), rgb (Vec3), a (Float)The sprite's own texture at a UV, with its flip, tiling and slicing applied. Wire a distorted UV in for waves or wobble. Sprite materials only; white elsewhere, with a warning.
input/camera_position — Camera Position—position (Vec3)World-space camera position.
input/object_position — Object Position—position (Vec3)The object's pivot in world space (handy for wind anchoring).

Parameter

Named graph-boundary inputs. The name pin is the identifier a material instance or a MaterialOverrides component overrides by name; the default pin is the value baked into the master shader. A graph can declare up to 32 parameters. Past the cap the extra names alias the last slot, and the Problems panel shows a warning. Header color: purple.

NodeInputsOutputsWhat it does
param/float — Float Parametername (String), default (Float)value (Float)Overridable scalar.
param/color — Color Parametername (String), default (Color)value (Color)Overridable color.
param/vec2 — Vec2 Parametername (String), default (Vec2)value (Vec2)Overridable 2-vector.
param/vec3 — Vec3 Parametername (String), default (Vec3)value (Vec3)Overridable 3-vector.
param/vec4 — Vec4 Parametername (String), default (Vec4)value (Vec4)Overridable 4-vector.
param/bool — Bool Parametername (String), default (Bool)value (Bool)Overridable flag.

Give a parameter a stable name — that string is the key instances use to override it. Anything wired downstream of a parameter becomes tweakable per instance without recompiling the shader.


Texture

Sample images. Each texture node holds its own texture reference (a TexturePath), set in the inspector. 2D nodes default the uv pin to the mesh UVs. Header color: tan.

All texture slots in a graph share one sampler — the first 2D texture's filter/wrap settings (or a default linear sampler). This keeps the fragment stage under the 16-sampler limit that Metal and baseline Vulkan/WebGPU impose.

NodeInputsOutputsWhat it does
texture/sample — Sample Textureuv (Vec2 = mesh UV)color (Color), rgb (Vec3), r, g, b, a (Float)Standard 2D textureSample.
texture/sample_normal — Sample Normal Mapuv (Vec2 = mesh UV), strength (Float = 1), flip_green (Bool = false)normal (Vec3)Samples and decodes a tangent-space normal map (rgb*2-1), scales XY by strength, renormalizes. Decoding assumes the OpenGL convention; flip_green negates Y for a DirectX map.
texture/triplanar — Triplanar Samplescale (Float = 1), sharpness (Float = 2)color (Color), rgb (Vec3)Projects the texture along world X/Y/Z and blends by the world normal — no UVs, no seams. sharpness tightens the blend.
texture/sample_lod — Sample Texture LODuv (Vec2 = mesh UV), lod (Float = 0)color, rgb, r, g, b, atextureSampleLevel at an explicit mip. Blur reflections with a roughness-driven LOD, or sample mip 0 inside a branch/loop where automatic derivatives are invalid.
texture/sample_grad — Sample Texture Graduv (Vec2 = mesh UV), ddx (Vec2), ddy (Vec2)color, rgb, r, g, b, atextureSampleGrad with explicit derivatives. Fixes mip selection when UVs are rotated or polar-warped — crisp anisotropic filtering.
texture/sample_cubemap — Sample Cubemapdirection (Vec3 = 0,1,0), lod (Float = 0)color, rgb, aSamples a material-local cubemap along a direction. Separate from the scene env map, so a graph can carry its own stylized sky/reflection. lod = glossiness.
texture/sample_2d_array — Sample 2D Arrayuv (Vec2 = mesh UV), layer (Float = 0)color, rgb, r, g, b, aLayered array; layer (rounded to nearest int) picks the slice. For terrain layer stacks, skin/variant atlases, mask banks.
texture/sample_3d — Sample 3D Textureuvw (Vec3 = 0.5,0.5,0.5)color, rgb, r, g, b, aSamples a volume texture at a 0..1³ coordinate. For volume fog, caustic/scattering LUTs, 3D color grading.

Math

Every Math node is component-wise and type-generic — the same math/multiply multiplies two floats, two colors, or a float and a vector. Each has a single result output. Header color: grey.

Binary / multi-input

NodeInputsWhat it does
math/add — Adda, ba + b
math/subtract — Subtracta, ba - b
math/multiply — Multiplya, ba * b
math/divide — Dividea, ba / b (guards against divide-by-zero)
math/power — Powerbase, exppow(abs(base), exp)
math/min — Mina, bmin(a, b)
math/max — Maxa, bmax(a, b)
math/modulo — Moduloa, bfloating-point remainder a mod b
math/atan2 — Atan2y, xatan2(y, x) in radians
math/clamp — Clampvalue, min, maxclamp(value, min, max)
math/lerp — Lerpa, b, tmix(a, b, t) — linear blend
math/smoothstep — Smoothstepedge0, edge1, valueHermite ease between the edges
math/step — Stepedge, value0 if value < edge, else 1
math/remap — Remapvalue, in_min, in_max, out_min, out_maxRescales from one range to another

Unary

NodeWhat it doesNodeWhat it does
math/abs — Absabsolute valuemath/negate — Negate-value
math/one_minus — One Minus1 - valuemath/fract — Fractfractional part
math/floor — Floorround downmath/ceil — Ceilround up
math/saturate — Saturateclamp to 0..1math/sign — Sign-1 / 0 / +1
math/trunc — Trunctruncate toward zeromath/round — Roundround to nearest
math/exp — Expe^xmath/log — Logln(x) (guards x>0)
math/sqrt — Sqrtsqrt(max(x,0))math/reciprocal — Reciprocal1 / value
math/sin — Sinsinemath/cos — Coscosine
math/tan — Tantangentmath/asin — Asinarcsine (input clamped ±1)
math/acos — Acosarccosine (input clamped ±1)math/radians — To Radiansdegrees → radians
math/degrees — To Degreesradians → degrees

Vector

Build, split, and operate on vectors. Header color: green.

NodeInputsOutputsWhat it does
vector/split_vec2 — Split Vec2vector (Vec2)x, y (Float)Unpack a Vec2.
vector/split_vec3 — Split Vec3vector (Vec3)x, y, z (Float)Unpack a Vec3.
vector/combine_vec2 — Combine Vec2x, y (Float)vector (Vec2)Pack a Vec2.
vector/combine_vec3 — Combine Vec3x, y, z (Float)vector (Vec3)Pack a Vec3.
vector/combine_vec4 — Combine Vec4x, y, z, w (Float, w = 1)vector (Vec4)Pack a Vec4.
vector/dot — Dot Producta, bresult (Float)dot(a, b).
vector/cross — Cross Producta (Vec3 = 1,0,0), b (Vec3 = 0,1,0)result (Vec3)cross(a, b).
vector/normalize — NormalizevectorresultUnit-length vector.
vector/distance — Distancea, bresult (Float)distance(a, b).
vector/length — Lengthvectorresult (Float)length(vector).
vector/reflect — Reflectincident, normalresult (Vec3)reflect(incident, normal).
vector/refract — Refractincident, normal (=0,1,0), eta (Float = 1)result (Vec3)refract(...) with index-of-refraction ratio eta.
vector/swizzle — Swizzlevector (Vec4), out_x/y/z/w (Int)vector (Vec4)Rearranges channels — each output picks 0=X, 1=Y, 2=Z, 3=W, 4=zero, 5=one.

Color

Constants, color-space conversion, and grading. Header color: amber.

NodeInputsOutputsWhat it does
color/constant — Colorcolor (Color value)color, rgb, r, g, b, aA constant color (edited with a picker).
color/float — Floatvaluevalue (Float)A constant scalar.
color/vec2 — Vec2valuevalue (Vec2)A constant Vec2.
color/vec3 — Vec3valuevalue (Vec3)A constant Vec3.
color/lerp — Color Lerpa, b (Color), t (Float)color (Color)mix(a, b, t) between two colors.
color/cosine_palette — Cosine Palettet (Float), a, b, c, d (Vec3)color (Vec3)IQ cosine palette a + b·cos(2π(c·t + d)) — smooth procedural gradients from four control vectors.
color/fresnel — Fresnelpower (Float = 5)result (Float)pow(1 - max(dot(view, normal), 0), power) — bright at grazing angles. Rim light, water edges.
color/srgb_to_linear — sRGB → LinearcolorresultPiecewise sRGB → linear decode.
color/linear_to_srgb — Linear → sRGBcolorresultPiecewise linear → sRGB encode.
color/rgb_to_hsv — RGB → HSVrgb (Vec3)hsv, h, s, vConvert to hue/saturation/value.
color/hsv_to_rgb — HSV → RGBhsv (Vec3)rgb (Vec3)Convert back to RGB.
color/hue_shift — Hue Shiftrgb (Vec3), shift (Float)rgb (Vec3)Rotate hue by shift (0..1 = full circle).
color/luminance — Luminancergb (Vec3)value (Float)Rec.709 perceptual brightness.
color/gamma — Gammacolor, gamma (Float = 2.2)resultpow(color, gamma) per channel.
color/brightness_contrast — Brightness / Contrastcolor, brightness (=0), contrast (=1)resultAdditive brightness, contrast pivoted on 0.5 grey.
color/saturation — Saturationcolor, saturation (=1)resultMix toward luminance: 0 = greyscale, 1 = original, >1 = supersaturated.
color/blend — Blendbase, blend (Color), opacity (=1), mode (Int = 0)resultPhotoshop-style composite. mode: 0 normal, 1 multiply, 2 screen, 3 overlay, 4 add, 5 subtract, 6 soft-light, 7 hard-light, 8 difference, 9 divide.

Procedural

Patterns generated in-shader — no texture needed. Header color: violet.

Noise

NodeInputsOutputsWhat it does
procedural/noise_perlin — Perlin Noiseuv (=mesh UV), scale (Float = 10)value (Float)Smooth gradient noise, 0..1.
procedural/noise_simplex — Simplex Noiseuv, scale (=10)valueGradient noise with fewer directional artifacts.
procedural/noise_voronoi — Voronoiuv, scale (=5)distance (F1), f2 (F2), edge, cell_idCell/Worley noise — nearest-point distance, second-nearest, edge distance, and a per-cell random id.
procedural/noise_fbm — FBM Noiseuv, scale (=5), octaves (=4), lacunarity (=2), persistence (=0.5)valueFractal Brownian Motion — layered noise for clouds, terrain, marble.
procedural/noise_ridged — Ridged FBMuv, scale, octaves, lacunarity, persistencevalueSharp crests — mountain ridges, cumulus billows, cracks.
procedural/noise_turbulence — Turbulencesame as FBMvalue|noise| accumulated — fire, smoke, turbulent flow.
procedural/noise_billow — Billow Noisesame as FBMvalue|noise|² accumulated — puffy cumulus clouds, stone pores.
procedural/noise_white — White Noiseuv, scale (=50)valueUncorrelated random per UV — grain, sparkle.
procedural/noise_curl — Curl Noiseuv, scale (=3), epsilon (=0.01)flow (Vec2)Divergence-free 2D flow field for fluid-like advection and swirly UV distortion.

Triplanar noise

World-space noise projected onto X/Y/Z planes and blended by the world normal — no UVs, no seams, works on any topology. All take scale (=1), octaves, lacunarity (=2), persistence (=0.5), sharpness (=4) and output value.

NodeWhat it does
procedural/noise_triplanar_fbm — Triplanar FBMSeamless FBM on spheres, terrain, sculpts.
procedural/noise_triplanar_ridged — Triplanar RidgedSeamless mountain/cumulus ridges.
procedural/noise_triplanar_turbulence — Triplanar TurbulenceSeamless fire/smoke/flow.
procedural/noise_triplanar_billow — Triplanar BillowSeamless puffy cumulus / stone pores.
procedural/noise_triplanar_voronoi — Triplanar VoronoiSeamless cracked-surface / cell pattern. Outputs distance, cell_id.

Patterns & gradients

NodeInputsOutputsWhat it does
procedural/checkerboard — Checkerboarduv, scale (=8)valueAlternating 0/1 checker.
procedural/gradient — Gradientuvu, v (Float)Raw 0..1 ramp along U or V.
procedural/brick — Brickuv, scale (Vec2 = 4,8), mortar (Float = 0.05)valueRow-offset brick pattern with mortar lines.
procedural/gradient_radial — Radial Gradientuv, center, radius (=0.5), softness (=0.3)value0 at center → 1 at radius, soft falloff.
procedural/gradient_linear — Linear Gradientuv, angle, centervalueRamp along a direction (angle radians, 0 = +X).
procedural/gradient_angular — Angular Gradientuv, center, offsetvalueSweeps 0..1 around the center — pie / compass / clock wipes.
procedural/gradient_diamond — Diamond Gradientuv, center, size (=0.5)valueDiamond (Manhattan-distance) falloff.

Height, warp & anti-tiling

NodeInputsOutputsWhat it does
procedural/normal_from_height — Normal From Height (tangent)height, strength (=1)normal (Vec3)Tangent-space normal (Z = up) from a height value via screen-space derivatives.
procedural/world_normal_from_height — World Normal From Heightheight, strength (=1)normal (Vec3)World-space perturbed normal — reconstructs a tangent frame per fragment, so it works on any orientation. Wire straight into Surface Output's normal (water, stone, procedural displacement).
procedural/domain_warp — Domain Warpuv, scale (=1.5), strength (=0.35), offset (Vec2 = 5.2,1.3)uv (Vec2)Distorts UVs with FBM noise — organic cloud / marble / fluid shapes.
procedural/bump_offset — Bump Offsetuv, height, reference (=0.5), strength (=0.05)uv (Vec2)Cheap parallax — displaces UVs along the view vector by a height value for fake depth.
procedural/hex_tile — Hex Tile UVuv, scale (=1), variation (=1)uv1, uv2, uv3 (Vec2), w1, w2, w3 (Float)Hexagonal anti-tiling — sample one texture with all three UVs and blend by the weights to kill visible repetition. variation = rotation scramble.

Animation

Time-driven motion. Header color: teal.

NodeInputsOutputsWhat it does
animation/uv_scroll — UV Scrolluv, speed (Vec2 = 0.1,0)uv (Vec2)uv + speed * time.
animation/flow_map — Flow Mapuv, flow (Vec2), speed (=1), strength (=0.1)uv1, uv2 (Vec2), blend (Float)Two-phase distortion + crossfade weight for realistic flowing water. Sample twice and mix by blend.
animation/sine_wave — Sine Wavefrequency (=1), amplitude (=1), offset (=0)value (Float)sin(time·frequency + offset) · amplitude.
animation/ping_pong — Ping Pongspeed (=1)value (Float)Triangular 0 → 1 → 0 wave.
animation/wind — Windstrength (=0.3), speed (=1), direction (Vec2 = 1,0), turbulence (=0.2), mask (=1)displacement (Vec3)Vegetation sway. Vertex domain — wire into a Vegetation Output's vertex_offset.
animation/flipbook_uv — Flipbook UVuv, frame, cols (=4), rows (=4)uv (Vec2)Sub-rect UV for one frame of a cols × rows sprite sheet. Drive frame by time·fps to play.

Utility

Masks, derivatives, and helpers. Header color: slate.

NodeInputsOutputsWhat it does
utility/world_pos_mask — World Position Maskheight (=10), falloff (=2)mask (Float)Mask by world Y height — snow on peaks, water lines.
utility/slope_mask — Slope Maskthreshold (=0.5), falloff (=0.2)mask (Float)Mask by surface slope — cliffs vs flat ground (smoothstep on world_normal.y).
utility/depth_fade — Depth Fadedistance (=1)fade (Float)Simple height-based fade. For true scene-depth proximity fade use scene/depth_fade.
utility/dpdx — DDXvalueresultScreen-space derivative along X.
utility/dpdy — DDYvalueresultScreen-space derivative along Y.
utility/fwidth — FWidthvalueresultabs(ddx) + abs(ddy) — pixel footprint for anti-aliasing.
utility/dither — Dither—value (Float)4×4 Bayer ordered dither from screen position — transparency-to-coverage.
utility/hash — Hashvalue (Vec2)result (Float)Deterministic 0..1 pseudo-random hash.

Control

Branching and boolean logic. Header color: yellow.

NodeInputsOutputsWhat it does
control/if — Ifcondition, threshold (=0.5), if_true (Vec4 = 1,1,1,1), if_false (Vec4 = 0,0,0,1)result (Vec4)Runtime select: condition > threshold ? if_true : if_false. Both branches execute.
control/static_switch — Static Switcha (Vec4), b (Vec4), use_a (Bool = true)result (Vec4)Compile-time branch — the unused side's subgraph is stripped from the shader entirely. Use for shader permutations. Set use_a in the node's values.
control/component_mask — Component Maskvector (Vec4), keep_r/g/b/a (Bool)vector (Vec4)Zeroes the channels you toggle off.
control/greater_than — Greater Thana, bresult1.0 if a > b, else 0.0.
control/less_than — Less Thana, bresult1.0 if a < b, else 0.0.
control/equal — Equala, b, epsilon (=0.001)result1.0 if |a-b| < epsilon.
control/not_equal — Not Equala, b, epsilon (=0.001)result1.0 if |a-b| ≥ epsilon.
control/and — Anda, bresultmin(a, b) — float-boolean AND.
control/or — Ora, bresultmax(a, b) — float-boolean OR.
control/not — Notvalueresult1 - value.

Scene

Read render-pass buffers and the environment. These need the matching prepass enabled on the camera (depth/normal/motion); when a prepass is missing they return a safe sentinel rather than failing. Header color: cyan.

A Sprite material can use Pixel Depth, Screen UV and Refraction UV Offset. The others read the 3D view's prepasses, environment map or transmission texture, which the 2D pipeline does not have, so they are a compile error there that names the node.

NodeInputsOutputsWhat it does
scene/pixel_depth — Pixel Depth—depth (Float)This fragment's linear view-space depth (distance from camera).
scene/scene_depth — Scene Depth—depth (Float)The opaque-pass depth buffer at this fragment. Needs DepthPrepass; returns a large value otherwise.
scene/depth_fade — Scene Depth Fadedistance (=1)fade (Float)Proximity fade to the nearest opaque surface: 0 at contact → 1 when distance units behind. Shoreline foam, soft intersections.
scene/scene_normal — Scene Normal—normal (Vec3)World normal from the normal prepass. Needs NormalPrepass; returns +Y otherwise. Wetness masks, edge detection.
scene/motion_vector — Motion Vector—velocity (Vec2), speed (Float)Screen-space motion (Δ NDC since last frame). Needs MotionVectorPrepass. Motion blur masks, speed lines.
scene/refraction_uv_offset — Refraction UV Offsetnormal (Vec3), strength (=0.05)offset (Vec2)Screen-UV offset from a distorting normal, for refraction.
scene/screen_uv — Screen UV—uv (Vec2)Fragment screen-space UV (0,0 top-left → 1,1 bottom-right).
scene/scene_color — Scene Color (stub)uvcolor, rgbNot generally implemented — Bevy doesn't expose a grab-pass to custom-material shaders without a render-graph node. Returns magenta as a placeholder.
scene/env_map_sample — Environment Map Sampledirection (Vec3 = 0,1,0), mip_level (=0)color, rgbSamples the scene environment cubemap along a direction. Works with loaded skyboxes and the procedural atmosphere. mip_level = blur/roughness.
scene/env_map_reflect — Environment Map Reflectnormal (Vec3), mip_level (=0)color, rgbReflects the view direction off normal and samples the env map — mirror/glossy reflection. mip_level = glossiness.

Custom

The escape hatch when no node expresses what you need. Header color: red.

custom/code — Custom Code. Inputs: code (String, default result = a;), a, b, c, d (Vec4). Outputs: result (Vec4), rgb (Vec3), x, y, z, w (Float). Your snippet runs inside a generated helper mat_custom_<id>(a,b,c,d) with the four inputs in scope and result pre-seeded to opaque black; assign result to produce the output.

result = a * b + vec4<f32>(sin(c.x), 0.0, 0.0, 1.0);

It's the in-graph counterpart to a full code shader — reach for it when you only need a few lines of WGSL inside an otherwise node-based material.


Functions (reusable subgraphs)

A material function packages graph logic as a reusable node without writing Rust. It's a named subgraph saved as a .material_function file (in assets/material_functions/), bracketed by input/output point nodes and invoked by a call node. These appear in the editor under the Control menu.

NodeInputsOutputsWhat it does
function/input_point — Function Inputs—in_0…in_3 (Vec4)Inside a function only: the call site's four inputs. Use split_vec* to unpack scalars.
function/output_point — Function Outputsout_0…out_3 (Vec4)—Inside a function only: what the function returns.
function/call — Function Callin_0…in_3 (Vec4)out_0…out_3 (Vec4)Invokes a function by name (set input_values["function"]). At compile time it inlines the function's WGSL helper at module scope, so it composes like any node. Recursive cycles are detected and reported.

Output

Every graph has exactly one output node, fixed by its domain. It can't be deleted, and it's where the material's final channels are assembled. A pin only takes effect when it's connected (or has an override) — disconnected pins keep Bevy's StandardMaterial defaults. Header color: dark red.

output/surface — Surface Output

The full PBR master; maps 1:1 onto Bevy's StandardMaterial.

PinTypeDefaultDrives
base_colorColor0.8, 0.8, 0.8, 1Albedo
metallicFloat0Dielectric ↔ metal
roughnessFloat0.5Smooth ↔ matte
normalVec3—Surface normal
displacementFloat0Height for parallax occlusion mapping (white = peak). Only a connection does anything; needs mesh tangents
displacement_scaleFloat0.05Parallax depth — a loop constant, read as a literal rather than an expression
emissiveVec30Self-illumination
aoFloat1Ambient occlusion
alphaFloat1Opacity
reflectanceVec30.5Dielectric specular reflectance
specular_transmissionFloat0Refraction (glass, water)
diffuse_transmissionFloat0Light through thin surfaces (foliage, skin)
thicknessFloat0Volume thickness
iorFloat1.5Index of refraction
attenuation_distanceFloat1e37Volume attenuation distance
attenuation_colorVec31Colour light attenuates toward over that distance
clearcoatFloat0Second specular layer (car paint)
clearcoat_roughnessFloat0.5Clearcoat roughness
anisotropy_strengthFloat0Directional specular (brushed metal, hair)
anisotropy_rotationFloat0Anisotropy direction

Connecting either transmission pin makes the resolver flip on Bevy's transmissive pass automatically.

output/terrain_layer — Terrain Layer Output

A paintable terrain layer, blended through the splatmap. Pins: base_color, metallic, roughness, normal, height (=0.5). Compiles to the layer functions the terrain shader blends per-pixel.

output/vegetation — Vegetation Output

Surface PBR plus a vertex_offset (Vec3 = 0) pin. When vertex_offset is connected, a custom vertex shader is generated that displaces the world position — wire animation/wind (or any Vec3) into it for sway. All the surface pins above also apply.

output/unlit — Unlit Output

Flat, lighting-free color. Pins: color (Color = 1,1,1,1), alpha (Float = 1). The resolver sets unlit = true so lighting is skipped — for UI bits, holograms, and stylized effects.

output/sprite — Sprite Output

A 2D sprite's color. Pins: color (Color), alpha (Float), both without a default: an unwired color is the sprite's own texture, and an unwired alpha keeps that colour's alpha. So an empty Sprite graph draws the sprite unchanged, and a graph only describes what it changes. The sprite's tint and alpha mode apply on top, as they would without a material.


See also

  • Material API — the .material file format, pin types, material instances, and code shaders.
  • Material Editor — the visual workflow for wiring these nodes.
  • Custom Material Nodes — how to add a new built-in node to the engine, and how the codegen works.