renzora
Game Engine

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 WGSL in material/codegen.rs. There are 13 categories and roughly 124 node types.

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.
  • 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/uvUVuv (Vec2), u, v (Float)The mesh's texture coordinates (0–1). u/v are the split channels.
input/uv_scaleUV Scaleuv (Vec2), scale (Vec2 = 2,2), offset (Vec2 = 0,0)uv (Vec2)Tiling: uv * scale + offset.
input/uv_polarPolar 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_rotatorUV Rotatoruv (Vec2), angle (Float = 0, radians), center (Vec2 = 0.5,0.5)uv (Vec2)Rotates UVs around center.
input/uv_pannerUV 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_positionWorld Positionposition (Vec3), x, y, z (Float)Fragment world-space position.
input/world_normalWorld Normalnormal (Vec3), x, y, z (Float)Fragment world-space surface normal.
input/view_directionView Directiondirection (Vec3)Normalized fragment → camera direction.
input/timeTimetime, sin_time, cos_time (Float)Seconds since start, plus its sine and cosine for cheap oscillation.
input/vertex_colorVertex Colorcolor (Color), r, g, b, a (Float)Per-vertex color attribute (defaults to white on meshes without one).
input/camera_positionCamera Positionposition (Vec3)World-space camera position.
input/object_positionObject Positionposition (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 may declare up to 32 parameters. Header color: purple.

NodeInputsOutputsWhat it does
param/floatFloat Parametername (String), default (Float)value (Float)Overridable scalar.
param/colorColor Parametername (String), default (Color)value (Color)Overridable color.
param/vec2Vec2 Parametername (String), default (Vec2)value (Vec2)Overridable 2-vector.
param/vec3Vec3 Parametername (String), default (Vec3)value (Vec3)Overridable 3-vector.
param/vec4Vec4 Parametername (String), default (Vec4)value (Vec4)Overridable 4-vector.
param/boolBool 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/sampleSample Textureuv (Vec2 = mesh UV)color (Color), rgb (Vec3), r, g, b, a (Float)Standard 2D textureSample.
texture/sample_normalSample Normal Mapuv (Vec2 = mesh UV), strength (Float = 1)normal (Vec3)Samples and decodes a tangent-space normal map (rgb*2-1), scales XY by strength, renormalizes.
texture/triplanarTriplanar 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_lodSample 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_gradSample 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_cubemapSample 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_arraySample 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_3dSample 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/addAdda, ba + b
math/subtractSubtracta, ba - b
math/multiplyMultiplya, ba * b
math/divideDividea, ba / b (guards against divide-by-zero)
math/powerPowerbase, exppow(abs(base), exp)
math/minMina, bmin(a, b)
math/maxMaxa, bmax(a, b)
math/moduloModuloa, bfloating-point remainder a mod b
math/atan2Atan2y, xatan2(y, x) in radians
math/clampClampvalue, min, maxclamp(value, min, max)
math/lerpLerpa, b, tmix(a, b, t) — linear blend
math/smoothstepSmoothstepedge0, edge1, valueHermite ease between the edges
math/stepStepedge, value0 if value < edge, else 1
math/remapRemapvalue, in_min, in_max, out_min, out_maxRescales from one range to another

Unary

NodeWhat it doesNodeWhat it does
math/absAbsabsolute valuemath/negateNegate-value
math/one_minusOne Minus1 - valuemath/fractFractfractional part
math/floorFloorround downmath/ceilCeilround up
math/saturateSaturateclamp to 0..1math/signSign-1 / 0 / +1
math/truncTrunctruncate toward zeromath/roundRoundround to nearest
math/expExpe^xmath/logLogln(x) (guards x>0)
math/sqrtSqrtsqrt(max(x,0))math/reciprocalReciprocal1 / value
math/sinSinsinemath/cosCoscosine
math/tanTantangentmath/asinAsinarcsine (input clamped ±1)
math/acosAcosarccosine (input clamped ±1)math/radiansTo Radiansdegrees → radians
math/degreesTo Degreesradians → degrees

Vector

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

NodeInputsOutputsWhat it does
vector/split_vec2Split Vec2vector (Vec2)x, y (Float)Unpack a Vec2.
vector/split_vec3Split Vec3vector (Vec3)x, y, z (Float)Unpack a Vec3.
vector/combine_vec2Combine Vec2x, y (Float)vector (Vec2)Pack a Vec2.
vector/combine_vec3Combine Vec3x, y, z (Float)vector (Vec3)Pack a Vec3.
vector/combine_vec4Combine Vec4x, y, z, w (Float, w = 1)vector (Vec4)Pack a Vec4.
vector/dotDot Producta, bresult (Float)dot(a, b).
vector/crossCross Producta (Vec3 = 1,0,0), b (Vec3 = 0,1,0)result (Vec3)cross(a, b).
vector/normalizeNormalizevectorresultUnit-length vector.
vector/distanceDistancea, bresult (Float)distance(a, b).
vector/lengthLengthvectorresult (Float)length(vector).
vector/reflectReflectincident, normalresult (Vec3)reflect(incident, normal).
vector/refractRefractincident, normal (=0,1,0), eta (Float = 1)result (Vec3)refract(...) with index-of-refraction ratio eta.
vector/swizzleSwizzlevector (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/constantColorcolor (Color value)color, rgb, r, g, b, aA constant color (edited with a picker).
color/floatFloatvaluevalue (Float)A constant scalar.
color/vec2Vec2valuevalue (Vec2)A constant Vec2.
color/vec3Vec3valuevalue (Vec3)A constant Vec3.
color/lerpColor Lerpa, b (Color), t (Float)color (Color)mix(a, b, t) between two colors.
color/cosine_paletteCosine 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/fresnelFresnelpower (Float = 5)result (Float)pow(1 - max(dot(view, normal), 0), power) — bright at grazing angles. Rim light, water edges.
color/srgb_to_linearsRGB → LinearcolorresultPiecewise sRGB → linear decode.
color/linear_to_srgbLinear → sRGBcolorresultPiecewise linear → sRGB encode.
color/rgb_to_hsvRGB → HSVrgb (Vec3)hsv, h, s, vConvert to hue/saturation/value.
color/hsv_to_rgbHSV → RGBhsv (Vec3)rgb (Vec3)Convert back to RGB.
color/hue_shiftHue Shiftrgb (Vec3), shift (Float)rgb (Vec3)Rotate hue by shift (0..1 = full circle).
color/luminanceLuminancergb (Vec3)value (Float)Rec.709 perceptual brightness.
color/gammaGammacolor, gamma (Float = 2.2)resultpow(color, gamma) per channel.
color/brightness_contrastBrightness / Contrastcolor, brightness (=0), contrast (=1)resultAdditive brightness, contrast pivoted on 0.5 grey.
color/saturationSaturationcolor, saturation (=1)resultMix toward luminance: 0 = greyscale, 1 = original, >1 = supersaturated.
color/blendBlendbase, 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_perlinPerlin Noiseuv (=mesh UV), scale (Float = 10)value (Float)Smooth gradient noise, 0..1.
procedural/noise_simplexSimplex Noiseuv, scale (=10)valueGradient noise with fewer directional artifacts.
procedural/noise_voronoiVoronoiuv, 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_fbmFBM Noiseuv, scale (=5), octaves (=4), lacunarity (=2), persistence (=0.5)valueFractal Brownian Motion — layered noise for clouds, terrain, marble.
procedural/noise_ridgedRidged FBMuv, scale, octaves, lacunarity, persistencevalueSharp crests — mountain ridges, cumulus billows, cracks.
procedural/noise_turbulenceTurbulencesame as FBMvalue|noise| accumulated — fire, smoke, turbulent flow.
procedural/noise_billowBillow Noisesame as FBMvalue|noise|² accumulated — puffy cumulus clouds, stone pores.
procedural/noise_whiteWhite Noiseuv, scale (=50)valueUncorrelated random per UV — grain, sparkle.
procedural/noise_curlCurl 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_fbmTriplanar FBMSeamless FBM on spheres, terrain, sculpts.
procedural/noise_triplanar_ridgedTriplanar RidgedSeamless mountain/cumulus ridges.
procedural/noise_triplanar_turbulenceTriplanar TurbulenceSeamless fire/smoke/flow.
procedural/noise_triplanar_billowTriplanar BillowSeamless puffy cumulus / stone pores.
procedural/noise_triplanar_voronoiTriplanar VoronoiSeamless cracked-surface / cell pattern. Outputs distance, cell_id.

Patterns & gradients

NodeInputsOutputsWhat it does
procedural/checkerboardCheckerboarduv, scale (=8)valueAlternating 0/1 checker.
procedural/gradientGradientuvu, v (Float)Raw 0..1 ramp along U or V.
procedural/brickBrickuv, scale (Vec2 = 4,8), mortar (Float = 0.05)valueRow-offset brick pattern with mortar lines.
procedural/gradient_radialRadial Gradientuv, center, radius (=0.5), softness (=0.3)value0 at center → 1 at radius, soft falloff.
procedural/gradient_linearLinear Gradientuv, angle, centervalueRamp along a direction (angle radians, 0 = +X).
procedural/gradient_angularAngular Gradientuv, center, offsetvalueSweeps 0..1 around the center — pie / compass / clock wipes.
procedural/gradient_diamondDiamond Gradientuv, center, size (=0.5)valueDiamond (Manhattan-distance) falloff.

Height, warp & anti-tiling

NodeInputsOutputsWhat it does
procedural/normal_from_heightNormal 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_heightWorld 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_warpDomain 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_offsetBump 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_tileHex 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_scrollUV Scrolluv, speed (Vec2 = 0.1,0)uv (Vec2)uv + speed * time.
animation/flow_mapFlow 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_waveSine Wavefrequency (=1), amplitude (=1), offset (=0)value (Float)sin(time·frequency + offset) · amplitude.
animation/ping_pongPing Pongspeed (=1)value (Float)Triangular 0 → 1 → 0 wave.
animation/windWindstrength (=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_uvFlipbook 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_maskWorld Position Maskheight (=10), falloff (=2)mask (Float)Mask by world Y height — snow on peaks, water lines.
utility/slope_maskSlope Maskthreshold (=0.5), falloff (=0.2)mask (Float)Mask by surface slope — cliffs vs flat ground (smoothstep on world_normal.y).
utility/depth_fadeDepth Fadedistance (=1)fade (Float)Simple height-based fade. For true scene-depth proximity fade use scene/depth_fade.
utility/dpdxDDXvalueresultScreen-space derivative along X.
utility/dpdyDDYvalueresultScreen-space derivative along Y.
utility/fwidthFWidthvalueresultabs(ddx) + abs(ddy) — pixel footprint for anti-aliasing.
utility/ditherDithervalue (Float)4×4 Bayer ordered dither from screen position — transparency-to-coverage.
utility/hashHashvalue (Vec2)result (Float)Deterministic 0..1 pseudo-random hash.

Control

Branching and boolean logic. Header color: yellow.

NodeInputsOutputsWhat it does
control/ifIfcondition, 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_switchStatic 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_maskComponent Maskvector (Vec4), keep_r/g/b/a (Bool)vector (Vec4)Zeroes the channels you toggle off.
control/greater_thanGreater Thana, bresult1.0 if a > b, else 0.0.
control/less_thanLess Thana, bresult1.0 if a < b, else 0.0.
control/equalEquala, b, epsilon (=0.001)result1.0 if |a-b| < epsilon.
control/not_equalNot Equala, b, epsilon (=0.001)result1.0 if |a-b| ≥ epsilon.
control/andAnda, bresultmin(a, b) — float-boolean AND.
control/orOra, bresultmax(a, b) — float-boolean OR.
control/notNotvalueresult1 - 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.

NodeInputsOutputsWhat it does
scene/pixel_depthPixel Depthdepth (Float)This fragment's linear view-space depth (distance from camera).
scene/scene_depthScene Depthdepth (Float)The opaque-pass depth buffer at this fragment. Needs DepthPrepass; returns a large value otherwise.
scene/depth_fadeScene 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_normalScene Normalnormal (Vec3)World normal from the normal prepass. Needs NormalPrepass; returns +Y otherwise. Wetness masks, edge detection.
scene/motion_vectorMotion Vectorvelocity (Vec2), speed (Float)Screen-space motion (Δ NDC since last frame). Needs MotionVectorPrepass. Motion blur masks, speed lines.
scene/refraction_uv_offsetRefraction UV Offsetnormal (Vec3), strength (=0.05)offset (Vec2)Screen-UV offset from a distorting normal, for refraction.
scene/screen_uvScreen UVuv (Vec2)Fragment screen-space UV (0,0 top-left → 1,1 bottom-right).
scene/scene_colorScene 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_sampleEnvironment 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_reflectEnvironment 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_pointFunction Inputsin_0in_3 (Vec4)Inside a function only: the call site's four inputs. Use split_vec* to unpack scalars.
function/output_pointFunction Outputsout_0out_3 (Vec4)Inside a function only: what the function returns.
function/callFunction Callin_0in_3 (Vec4)out_0out_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
normalVec3Surface normal
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
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.


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.