Documentation / Node reference / mat nodes

mat/MeshSDF

Tunes how SDF objects are raymarched.

Sdf

Assign it to SDF objects with a geo/Material node. SDF objects already render without it, on these same defaults; this node is what makes the march tunable and adds the debug views. Every param is a uniform, so dragging one never recompiles the shader. Raise `maxStepsCount` when a shape shows holes or soft edges where the rays run out of steps, and lower it when a scene gets slow: the step-count debug view shows where the budget actually goes, silhouette rays being the expensive ones. Lower `surfaceDistance` for a crisper surface at the cost of more steps. `isoValue` moves which surface is drawn, so one tree can be looked at at several levels without touching it. It also carries the self-lighting the object gets from its own field: `shadowSoftness` for soft shadows where one part of the shape shadows another, on by default and scaling the width each light asks for with its own `softness`, and `aoStrength` for darkened creases, off by default. Both are per-object: neither sees any other object in the scene. `gridFiltering` is the one param that only some trees read: a field built from a volume (geo/SDFCreate) is a grid of voxels, and TRICUBIC reads between them with a continuous gradient, which is what removes the per-voxel faceting an imported model shows. A 2D field is not marched at all, it is painted as a distance-field visualization, so the only params it reads are `bandSpacing` and `isoValue`. `color`, `roughness`, `metallic` and `emissive` here are the DEFAULT surface, and an object that carries a shading record of its own overrides them: what a geo/MaterialAttributes wrote wins, per region of the field (see geo/SDFBoolean). Everything else on this node stays the object's, record or not. Drop a geo/Environment into the scene and SDF objects light from it like every other surface, with no wiring and without this node: the map is the scene's, so there is nothing here to point at it.

Parameters

Name Type What it does
maxStepsCount UInt32 How many sphere-trace steps a ray may take before giving up. Too few shows as holes and soft edges near silhouettes.
maxDistance Float How far along a ray the march goes before giving up. The object's bounds usually stop it first.
surfaceDistance Float How close to the surface counts as a hit. Smaller is crisper and costs more steps.
normalsBias Float Offset of the central-difference samples the normal is built from, in OBJECT units. 0 is AUTO, the default: an object whose tree holds a grid field (geo/SDFCreate on a volume) uses its largest voxel, since a smaller offset reads the per-voxel ripple as faceting that swims with the camera, and a tree of analytic primitives uses 0.01. Set it above 0 to override: larger smooths the shading and hides small details.
color Color Surface colour.
roughness Float Surface roughness. It also picks how blurred the scene environment's reflection is, when the scene carries a geo/Environment: 0 is a mirror, 1 spreads it over the whole surface.
metallic Float How metallic the surface is. A metal takes its colour from what it reflects, so on a metal SDF object the scene environment is most of what there is to see.
emissive Color A colour the surface gives off by itself, added after the lighting. It brightens this surface only and casts no light on anything else, so it is for something that should read as lit from within. Black, the default, adds nothing. An object carrying an EMISSION attribute overrides it, per region of the field.
debugView UInt8 NONE · STEP_COUNT · NORMAL · BOUNDS · AMBIENT_OCCLUSION Replaces the shading: STEP_COUNT is a cost heatmap (cool to hot, including the rays that never hit), NORMAL shows the surface normal, BOUNDS draws the edges of the box the march is clamped to, AMBIENT_OCCLUSION shows the `aoStrength` factor as grey (white is open, black is fully occluded, and it is all white while `aoStrength` is 0).
bandSpacing Float 2D fields only: the distance between two bands of the field visualization, in world units. It is a scene-scale setting rather than something read off the object's bounds, so translating one operand of a boolean never changes the frequency of the bands. It also sets how fast the colour darkens toward the surface.
isoValue Float Draw the surface where the field equals this value instead of the zero set: positive inflates the shape, negative erodes it. The proxy box grows with it, so an inflated surface is not clipped. It is a uniform, so sweeping it never recompiles the shader. It changes what is DRAWN, not the field itself; geo/SDFTriangulate has the same param for the meshed form.
shadowSoftness Float Soft shadows the object casts on ITSELF, marched through its own field, for every light. How WIDE each penumbra is belongs to the light, which carries its own `softness`, and this scales them all for this object: 1 leaves every light as authored, 2 doubles the spread, 0.5 halves it. A blocker far from the surface it shadows always spreads wider than one close to it, whatever this is set to. While it is above 0 the field is the object's ONLY shadow: the shadow atlas is not read for this surface, so nothing can stack into a double shadow, and equally an SDF plate does not receive the shadow of a mesh standing on it. Set it to 0 to go back to the atlas instead, which is the only way to receive shadows from other objects until the scene trace lands. Setting a LIGHT's softness to 0 does something else: that light keeps its shadow here, with a hard edge.
shadowStepsCount UInt32 The shadow march's step budget. It is a safety cap, not a reach: the march always crosses the whole ray whatever this is set to, and spending more of it only buys a finer march. Lower it first when self-shadowing costs too much, since there is one shadow ray per light per pixel.
aoStrength Float Darkens creases of the object using its own field, sampled along the normal (ambient occlusion). 0 turns it off, 1 is the full effect. It scales the ambient and hemisphere lights only, which is where ambient occlusion belongs, so a scene with neither shows no change.
aoRadius Float How far from the surface the ambient-occlusion samples reach, in OBJECT units. Roughly the size of the crease it responds to: small values catch fine detail, large ones darken whole concave regions.
gridFiltering UInt8 TRILINEAR · TRICUBIC How a grid field in the tree is read between its voxels. A grid field is what geo/SDFCreate makes from a volume, so a tree of analytic primitives never looks at this. TRILINEAR, the default, is 8 samples per read and has a gradient that jumps at every voxel face: the normal is that gradient, so an imported model shows one facet per voxel, and no `normalsBias` removes it, it only blurs it. TRICUBIC is 64 samples per read and has a continuous gradient, so the faceting goes rather than gets filtered. Switch to it when a model looks blocky under the light and leave it on TRILINEAR while framing a scene, since the cost is per march STEP.

See also

This page is generated from the engine, so it describes the release you can download. The same text is in the editor's Help panel next to the node itself.