luv

Workshop wiki

shaders.lisp

luft/render/shaders.lisp

system luft/renderer · 93 definitions · on GitHub

in-package#:luft.render.shaders

Site-stream rendering. One UVec4 instance selects a lattice base and a canonical fixed-stride template; the template vertex is a small exact offset plus geometric attributes. The CPU classifies sites and the vertex shader realizes the renderer-global triangle and quad populations.

eval-when
:compile-toplevel:load-toplevel:execute
defvar*stock-tooth*0.055
defvar*paper-variation*0.11
defvar*local-ambient-occlusion-strength*0.28
defvar*screen-ambient-occlusion-strength*0.38
defvar*screen-ambient-occlusion-radius*0.95
defvar*ambient-pigment-strength*0.82
defvar*earth-set-stone-strength*0.72

Match Luvcraft's scene-linear lens defaults. luft uses the same bright signal and gain while retaining its compact presentation gather.

defvar*highlight-glow-threshold*1.5
defvar*highlight-glow-strength*0.22
define-shader-functionpaper-hash
let*
scattered
shift
dotscattered
+
swizzlescattered:zyx
vec331.3231.3231.32
folded
+scattered
vec3shiftshiftshift
fract
*
+
swizzlefolded:x
swizzlefolded:y
swizzlefolded:z
define-shader-functionpaper-noise
point
let*
lattice
floorpoint
offset
fractpoint
weight
*offset
*offset
-
vec33.03.03.0
*offset2.0
u
swizzleweight:x
v
swizzleweight:y
w
swizzleweight:z
near-low
mix
paper-hashlattice
paper-hash
+lattice
vec31.00.00.0
u
near-high
mix
paper-hash
+lattice
vec30.01.00.0
paper-hash
+lattice
vec31.01.00.0
u
far-low
mix
paper-hash
+lattice
vec30.00.01.0
paper-hash
+lattice
vec31.00.01.0
u
far-high
mix
paper-hash
+lattice
vec30.01.01.0
paper-hash
+lattice
vec31.01.01.0
u
mix
mixnear-lownear-highv
mixfar-lowfar-highv
w
define-shader-functionpaper-space
point

Rotate the material field away from the voxel axes. Because this is a single world-space transform, adjacent facets still meet without seams.

let*
x
swizzlepoint:x
y
swizzlepoint:y
z
swizzlepoint:z
vec3
+
*x0.36
*y0.48
*z-0.80
+
*x-0.80
*y0.60
+
*x0.48
*y0.64
*z0.60
define-shader-functionstock-tooth
point
let*
paper-point
coarse
paper-noise
+
vec3
*
swizzlepaper-point:x
7.7
*
swizzlepaper-point:y
11.3
*
swizzlepaper-point:z
9.1
vec313.73.121.9
fine
paper-noise
+
vec3
*
swizzlepaper-point:z
27.1
*
swizzlepaper-point:x
33.7
*
swizzlepaper-point:y
23.9
vec34.329.111.7
+1.0
*#.*stock-tooth*
-
+
*0.55coarse
*0.45fine
0.5
define-shader-functionearth-set-stone-tone
pointnormalambient-occlusioncontact-variantstone-tonesoil-tonesubsoil-tone
"Weather one stone chamfer from its packed incident-substrate reading."
let*
turf-set-p
if
<
abscontact-variant
0.5
1.00.0
soil-set-p
if
<
abs
-contact-variant1.0
0.5
1.00.0
deep-set-p
if
<
abs
-contact-variant2.0
0.5
1.00.0
clump
paper-noise
+
*point
vec31.251.254.5
vec37.119.33.7
grit
paper-noise
+
*point9.0
vec331.75.913.1
break
paper-noise
+
*point
vec33.13.17.7
vec32.941.317.1
coverage
+
*turf-set-p0.50
*soil-set-p0.67
*deep-set-p0.82
breakup
smoothstep0.430.61
+
*0.52clump
*0.20grit
*0.24break
*-0.13
max0.0
swizzlenormal:z
#.*earth-set-stone-strength*-0.60
earth-weight
clamp
+coverage
*0.30
-breakup0.5
0.01.0
earth-pigment
mix
mixsoil-tonesubsoil-tone
+
*0.18grit
*0.34break
*0.22soil-set-p
subsoil-tone
*deep-set-p
+0.45
*0.25grit
weathered-stone
mixstone-tonesoil-tone
+0.16
*0.10grit
*
mixweathered-stoneearth-pigmentearth-weight
-1.0
*0.20
*earth-weightclump
define-shader-functionturf-edge-tone
pointnormalgrass-tonesoil-tone
"Roll a grassy top into soil with a world-stable broken fringe."
let*
fray
paper-noise
+
*point4.2
vec311.73.129.3
turf-weight
smoothstep0.420.78
+
max0.0
swizzlenormal:z
*0.24
-fray0.5
mixsoil-tonegrass-toneturf-weight
define-shader-functionfoundation-stone-tone
pointstone-tonesoil-tonesubsoil-tone
"Let terrain climb an irregular fraction of its lowest exposed stone course."
let*
weather
paper-noise
+
*point
vec31.91.93.7
vec323.38.75.1
clump
paper-noise
+
*point
vec30.630.631.15
vec33.727.114.3
grit
paper-noise
+
*point8.0
vec35.717.937.1
earth
-1.0
smoothstep0.070.61
+height
*0.32
-weather0.5
*0.20
-clump0.5
weathered-stone
mixstone-tonesoil-tone
+0.16
*0.10grit
earth-pigment
mixsoil-tonesubsoil-tone
+0.25
*0.45grit
*
mixweathered-stoneearth-pigmentearth
-1.0
*0.12earth
define-shader-functionmaterial-frame-point
pointoriginx-axisy-axisz-axis
"Express POINT in the authored material placement's coordinate frame."
let*
relative
-pointorigin
vec3
dotrelativex-axis
dotrelativey-axis
dotrelativez-axis
define-shader-functionmaterial-relief
pointprofile
"One continuous height field used for pigment, normal, and roughness."
let*
granular
+
*0.62
paper-noise
+
*point2.7
vec311.35.723.9
*0.38
paper-noise
+
*point9.1
vec33.129.77.3
stone-grain
paper-noise
+
*point3.8
vec331.17.913.7
stone-pit
paper-noise
+
*
swizzlepoint:zxy
10.7
vec35.319.137.7
weathered-stone
+
*0.72stone-grain
*0.28stone-pit
-
if
<profile1.5
granularweathered-stone
0.5
define-shader-functiondressed-stone-tone
pointnormalstone-tone
"Suggest laid courses and hand-dressed blocks without texture coordinates."
let*
x
swizzlepoint:x
y
swizzlepoint:y
z
swizzlepoint:z
course-coordinate
*z2.0
course
floorcourse-coordinate
jitter
-
paper-noise
+
*point1.7
vec317.14.39.7
0.5
tangent
if
>
abs
swizzlenormal:x
abs
swizzlenormal:y
yx
stagger
*0.5
fract
*course0.5
course-phase
fract
+course-coordinate
*jitter0.085
joint-phase
fract
+
/tangent1.35
stagger
*jitter0.11
course-distance
mincourse-phase
-1.0course-phase
joint-distance
minjoint-phase
-1.0joint-phase
vertical-face
-1.0
smoothstep0.550.85
abs
swizzlenormal:z
horizontal-mortar
-1.0
smoothstep0.0180.052course-distance
vertical-mortar
*vertical-face
-1.0
smoothstep0.0160.046joint-distance
broken-joint
smoothstep0.460.78
paper-noise
+
vec3
floor
+xstagger
floor
+ystagger
course
vec35.321.711.9
mortar
clamp
+horizontal-mortar
*vertical-mortarbroken-joint
0.01.0
block-value
paper-noise
+
*
floor
+point
vec3staggerstagger0.0
0.73
vec329.17.73.1
dressed
*stone-tone
+0.90
*0.20block-value
*0.05jitter
mortar-tone
*stone-tone0.78
mixdressedmortar-tone
*mortar0.58
define-shader-functionnatural-earth-tone
pointnormalearth-tonedepth
"Break exposed earth into continuous strata, clumps, and damp recesses."
let*
broad
paper-noise
+
*point
vec30.380.380.72
vec37.319.12.7
clump
paper-noise
+
*point
vec32.32.33.7
vec331.75.113.9
stratum
paper-noise
vec3
*
swizzlepoint:x
0.18
*
swizzlepoint:y
0.18
+
*
swizzlepoint:z
1.65
*broad0.75
side-weight
-1.0
smoothstep0.480.86
abs
swizzlenormal:z
value
+0.84
*broad0.18
*clump0.10
*side-weight
-stratum0.5
0.22
*depth-0.06
*earth-tonevalue
define-shader-functionpaper-tonemap
radiance
let*
numerator
*radiance
+
*radiance2.51
vec30.030.030.03
denominator
+
*radiance
+
*radiance2.43
vec30.590.590.59
vec30.140.140.14
clamp
/numeratordenominator
vec30.00.00.0
vec31.01.01.0
define-shader-functionpaper-grade
color
"Keep cool shade and warm paper luminous after highlight compression."
let*
luminance
dotcolor
vec30.21260.71520.0722
temperature
smoothstep0.300.78luminance
split-tone
mix
vec30.930.991.08
vec31.081.010.88
temperature
toned
*colorsplit-tone
toned-luminance
dottoned
vec30.21260.71520.0722
grey
vec3toned-luminancetoned-luminancetoned-luminance
saturated
+grey
*
-tonedgrey
1.12
curved
*saturated
*saturated
-
vec33.03.03.0
*saturated2.0
contrasted
mixsaturatedcurved0.14
black
vec30.00.00.0
white
vec31.01.01.0
clampcontrastedblackwhite
define-shader-functionhighlight-energy
value
"Keep only genuinely luminous scene-linear colour for the paper glow."
let*
color
swizzlevalue:xyz
luminance
dotcolor
vec30.21260.71520.0722
gate
smoothstep#.*highlight-glow-threshold*1.55luminance
*colorgate
define-shader-functionmesh-view-clip
pointpositionrightupforwardprojectiondivisor
let*
relative
view-x
dotrelative
swizzleright:xyz
view-y
dotrelative
swizzleup:xyz
view-z
dotrelative
swizzleforward:xyz
vec4
*view-x
swizzleprojection:x
-
*view-y
swizzleprojection:y
+
*view-z
swizzleprojection:z
swizzleprojection:w
mix1.0view-zdivisor
define-shader-functionmesh-temporal-motion
previous-clipcurrent-clip

Return the unjittered previous-minus-current motion MetalFX expects.

The scaler receives the current sampling offset independently through JITTER-OFFSET-{X,Y}. Its default contract consumes these vectors directly, so adding either frame's Halton offset here would invent screen-wide motion for completely static geometry.

-
mesh-clip-uvprevious-clip
mesh-clip-uvcurrent-clip
define-shader-functionmesh-world-position
instancetemplate-vertex
"Decode the one world position shared by the scene and shadow passes."
/
+
*
vec3
float
swizzleinstance:x
float
swizzleinstance:y
float
swizzleinstance:z
8.0
-
vec3
float
swizzletemplate-vertex:x
float
swizzletemplate-vertex:y
float
swizzletemplate-vertex:z
vec32048.02048.02048.0
8.0
define-shader-functionlight-clip-position
world-positionrow-xrow-yrow-zrow-w
let*
vec4
dotpointrow-x
dotpointrow-y
dotpointrow-z
dotpointrow-w
define-shader-functionsoft-shadow-visibility
shadow-mapshadow-samplershadow-samplenormalsunshadow-control
"Five comparison-filtered taps forming one restrained paper-soft shadow."
let*
uv
swizzleshadow-sample:xy
depth
swizzleshadow-sample:z
u
v
in-bounds
*
step0.0u
stepu1.0
step0.0v
stepv1.0
step0.0depth
stepdepth1.0
facing
max0.0
dotnormalsun
bias
+
swizzleshadow-control:z
*0.00125
-1.0facing
radius
*
swizzleshadow-control:xy
swizzleshadow-control:w
visibility
/
+
sample-compareshadow-mapshadow-sampleruv
-depthbias
sample-compareshadow-mapshadow-sampler
+uv
vec2
swizzleradius:x
0.0
-depthbias
sample-compareshadow-mapshadow-sampler
-uv
vec2
swizzleradius:x
0.0
-depthbias
sample-compareshadow-mapshadow-sampler
+uv
vec20.0
swizzleradius:y
-depthbias
sample-compareshadow-mapshadow-sampler
-uv
vec20.0
swizzleradius:y
-depthbias
5.0
mix1.0visibilityin-bounds

A small, rounded traveler for the sanctuary bridge. The proxy is only a conservative raster bound; every visible contour below comes from this analytic field. luft is Z-up, unlike luvcraft's first-person figures.

define-shader-functionplayer-sdf-smooth-union
let*
safe-width
blend
clamp
+0.5
*0.5
/
-secondfirst
safe-width
0.01.0
-
mixsecondfirstblend
*width
*blend
-1.0blend
define-shader-functionplayer-wizard-orb-distance
point

The hermit's little captured firework: a true SDF sphere and four sparks.

The staff gets a visible payoff even before a cast is in flight. Keeping the sparks in the same field means they clip and shade with the body rather than becoming transparent billboard confetti.

min
player-sdf-spherepoint
vec30.6400.1953.34
0.235
min
player-sdf-spherepoint
vec30.6400.1953.69
0.052
min
player-sdf-spherepoint
vec30.9650.1953.34
0.044
min
player-sdf-spherepoint
vec30.3600.1953.34
0.044
player-sdf-spherepoint
vec30.6400.1953.00
0.040
define-shader-functionplayer-sdf-ellipsoid
pointcenterradii
let*
offset
/
-pointcenter
radii
gradient
/
*outer
-outer1.0
maxgradient1e-6
define-shader-functionplayer-sdf-capsule
pointbeginningendradius
let*
offset
-pointbeginning
axis
-endbeginning
fraction
-radius

Motion vocabulary. Authored channels name the five readable walk poses, while contact placement and two-bone IK remain hard constraints beneath them. The same segment primitive can drive idle, gesture, attack or interaction channels without coupling their timing to the locomotion math.

define-shader-functionplayer-motion-ease
amount
"Quintic ease with zero velocity and acceleration at both ends."
let*
time
clampamount0.01.0
*
*time
*timetime
+10.0
*time
+-15.0
*6.0time
define-shader-functionplayer-motion-segment
phasebeginningendbeginning-valueend-value
let*
amount
/
-phasebeginning
max
-endbeginning
1e-5
mixbeginning-valueend-value
define-shader-functionplayer-walk-pose-channel
phasecontactdownpassingupnext-contact
"Sample a semantic contact/down/passing/up/contact animation channel."
if
<phase0.16
player-motion-segmentphase0.00.16contactdown
if
<phase0.50
player-motion-segmentphase0.160.50downpassing
if
<phase0.72
player-motion-segmentphase0.500.72passingup
player-motion-segmentphase0.721.0upnext-contact
define-shader-functionplayer-foot-rocker-pitch
cycle-phase
"Heel rocker, flat ankle rocker, forefoot rocker, then swing dorsiflexion."
let*
stance-time
*cycle-phase2.0
swing-time
*
-cycle-phase0.5
2.0
if
<cycle-phase0.5
if
<stance-time0.18
player-motion-segmentstance-time0.00.180.170.0
if
<stance-time0.72
0.0
player-motion-segmentstance-time0.721.00.0-0.30
if
<swing-time0.32
player-motion-segmentswing-time0.00.32-0.300.10
if
<swing-time0.78
0.10
player-motion-segmentswing-time0.781.00.100.17
define-shader-functionplayer-pelvis-lift
gait

Height of a fixed-length leg over the active stance contact.

Each half-step advances the root by 0.75 cells. The support foot sits at the half-step midpoint, so its fore-aft lever runs symmetrically from +D/2 to -D/2 and the pelvis rises naturally over mid-stance.

let*
step-length0.75
half-step
*step-length0.5

The ankle centre is Z=.26 and the hip is Z=1.27 at double support. This reach therefore makes the stance constraint agree with the actual SDF joint centres, rather than merely producing a plausible amount of bob.

leg-length1.07737
support-offset
*step-length
-0.5phase
height
sqrt
max
-
*leg-lengthleg-length
*support-offsetsupport-offset
0.0
contact-height
sqrt
-
*leg-lengthleg-length
*half-stephalf-step
+
-heightcontact-height

Loading sinks after contact; maximum authored rise follows the passing pose. This rides on the inverted-pendulum constraint rather than replacing it.

player-walk-pose-channelphase0.0-0.0350.00.0180.0
define-shader-functionplayer-walk-pose
pointgait
"Move a sample with the pelvis lift and a quiet support-side weight shift."
let*
side-shift
player-walk-pose-channelphase0.0-0.0200.0300.0180.0
forward-set
player-walk-pose-channelphase0.0-0.0180.0120.0060.0
vec3
-
swizzlepoint:x
side-shift
-
swizzlepoint:y
forward-set
define-shader-functionplayer-head-pose
pointgait
"Independent slow sway, glance and tilt keep the head out of marching time."
let*
slow-phase
*gait0.5
wander-phase
*gait0.25
roll
*0.055
sinslow-phase
cosine
cosroll
sine
sinroll
translated
-point
vec3
*0.035
sinslow-phase
*0.022
sinwander-phase
*0.016
sin
*gait1.5
centered
-translated
vec30.00.02.10
+
vec30.00.02.10
vec3
+
*cosine
swizzlecentered:x
*sine
swizzlecentered:z
swizzlecentered:y
-
*cosine
swizzlecentered:z
*sine
swizzlecentered:x

The traveler's parts.

He is the sanctuary's own hermit: hat, beard, mantle, staff, and the copper lozenge the whole site is inlaid with, worn as embroidery. The vocabulary is deliberately the one luvcraft's garden gnome already uses (LUVCRAFT/AGENT/SHADERS.LISP) -- a round cone for anything conical, a leaning hat frame, a nose that is a frank sphere -- rotated into luft's Z-up frame and given the walking legs that fellow does not have.

define-shader-functionplayer-sdf-round-cone
pointbase-heighttop-heightbase-radiustop-radius

A cone capped by a sphere at each end, standing on the Z axis.

The lateral surface is tangent to both caps, so the silhouette has no crease where the cone meets its rounding.

let*
height
max
-top-heightbase-height
1e-4
axial
-
swizzlepoint:z
base-height
slope
clamp
/
-base-radiustop-radius
height
-0.9990.999
run
sqrt
max
-1.0
*slopeslope
1e-6
side
+
*radial
-slope
*axialrun
if
-base-radius
if
-top-radius
-
+
*radialrun
*axialslope
base-radius
define-shader-functionplayer-sdf-lozenge
pointcenterradii

An octahedron scaled by RADII: the site's diamond, as a solid.

The exact octahedron distance is scaled back by the smallest half-extent so the warped field stays a lower bound and the march cannot overstep it.

let*
folded
abs
/
-pointcenter
radii
extent
+
+
swizzlefolded:x
swizzlefolded:y
swizzlefolded:z
smallest
min
min
swizzleradii:x
swizzleradii:y
swizzleradii:z
*
*
-extent1.0
0.57735026
smallest
define-shader-functionplayer-hat-point
point

The hat's own frame: a domain warp that leans the cone's tip forward.

A straight cone is a traffic cone. The lean is what makes it a hat someone is wearing, and it costs one smoothstep.

let*
rise
smoothstep2.263.34
swizzlepoint:z
lean
*riserise
vec3
-
swizzlepoint:x
*0.075lean
-
swizzlepoint:y
*0.235lean
swizzlepoint:z
define-shader-functionplayer-brim-point
point

The brim's frame: a quadratic droop that curls its edge down.

A flat disc reads as a plate balanced on his head. Lifting the sample with the square of its radius is enough to make the felt sag under its own weight, and the extra gradient it costs is paid back by the 0.9 below.

let*
radial
+
*
swizzlepoint:x
swizzlepoint:x
*
swizzlepoint:y
swizzlepoint:y
vec3
swizzlepoint:x
swizzlepoint:y
+
swizzlepoint:z
*0.30radial
define-shader-functionplayer-hat-distance
point

The tall leaning cone and the drooping brim it sits on.

The brim is wide enough to keep his eyes in shadow from the sanctuary's high camera: what the player sees under it is a nose and a beard, which is the whole of what this fellow is willing to say about himself.

let*
cone
brim
*
player-sdf-ellipsoid
vec30.00.0152.30
vec30.7350.7350.075
0.9
define-shader-functionplayer-hatband-distance
point
"The copper band around the crown, standing a little proud of the felt."
define-shader-functionplayer-head-distance
point
"Head and nose. Almost all of the head is hat, brim, or beard."
let*
head
player-sdf-ellipsoidpoint
vec30.0-0.012.09
vec30.2950.2850.295
nose
player-sdf-spherepoint
vec30.00.3452.015
0.17
define-shader-functionplayer-beard-distance
point

A broad beard with a blunt point: the mass that gives him his gravity.

Its top edge is the lower bound of his face, so it sits just under the nose, and its point falls to the middle of his chest.

let*
body
player-sdf-ellipsoidpoint
vec30.00.1851.815
vec30.3350.260.545

Cut level under the moustache and rounded off there. An uncut ellipsoid is widest at its middle, which puts a beard's broadest point at his chest and its narrowest at his cheeks -- a cloud rather than a beard.

mass
player-sdf-smooth-cutbody
-
swizzlepoint:z
1.955
0.13
moustache
player-sdf-ellipsoidpoint
vec30.00.3051.90
vec30.2350.1550.072
hair
player-sdf-smooth-unionmassmoustache0.055
define-shader-functionplayer-sdf-smooth-cut
solidlimitwidth
"SOLID intersected with a half space, with a rounded arris at the join."
define-shader-functionplayer-sixfold-cosine
point

cos 6*theta around the figure's own axis, without an inverse tangent.

The horizontal direction is squared three times over; what comes out is exactly the sixth harmonic, so a flute stays on the cloth when the figure turns instead of sliding around it like a projected stripe.

let*
x
swizzlepoint:x
y
swizzlepoint:y
radial
max1e-4
cosine
/xradial
sine
/yradial
cosine-2
-
*cosinecosine
*sinesine
sine-2
*2.0
*cosinesine
cosine-4
-
*cosine-2cosine-2
*sine-2sine-2
sine-4
*2.0
*cosine-2sine-2
-
*cosine-4cosine-2
*sine-4sine-2
define-shader-functionplayer-linen-fold
point

Six vertical folds in hanging linen, deepening toward the hem.

Their depth is the difference between a robe and a lampshade, so it is the number to reach for first. A twelfth harmonic rides on the sixth at a third of its depth: the linen then has a coarse drape and a fine crease rather than one honest sine wave.

let*
twelve
-
*2.0
*sixsix
1.0
depth
smoothstep1.880.28
swizzlepoint:z
*depth
+
*0.042six
*0.013twelve
define-shader-functionplayer-beard-comb
point

Strands combed down a beard, and the part a man leaves in the middle.

Measured about the same axis as the robe's flutes, the twelfth harmonic crosses the beard's front about three times, which is a beard. Any more and it is corduroy.

let*
twelve
-
*2.0
*sixsix
1.0
twenty-four
-
*2.0
*twelvetwelve
1.0
strands
*
+
*0.011twelve
*0.006twenty-four
smoothstep1.941.16
swizzlepoint:z

A shallow part. Carved any deeper it stopped being a parting and started being a window onto the robe underneath.

part
*0.007
-1.0
smoothstep0.00.09
abs
swizzlepoint:x
-strandspart
define-shader-functionplayer-robe-point
pointgait

The robe's own frame: hung from the shoulders, resting on the deck.

Above the waist the cloth rides with the body. At the hem it stays where gravity left it, so the walk reads as a hem that swings and trails rather than as a garment sliding up and down the figure. The pelvis lift is subtracted back out with the same weight, which is what keeps a floor-length robe on the floor while its wearer bobs over his stance foot.

let*
drape
carried
-1.0drape
lift
side-shift
*
player-walk-pose-channelphase0.0-0.0200.0300.0180.0
carried
forward-set
*
player-walk-pose-channelphase0.0-0.0180.0120.0060.0
carried
swing
*
*0.105
singait
drape
trail
*drape
+0.125
*0.05
cosgait
vec3
-
-
swizzlepoint:x
side-shift
swing
+
-
swizzlepoint:y
forward-set
trail
define-shader-functionplayer-robe-distance
pointgait

A floor-length linen robe: fitted at the chest, flaring to a swept hem.

The bell is a round cone, cut level just above the deck with a rounded arris so the cloth pools rather than ending in a pastry edge, and fluted by player-linen-fold. The 0.78 pays for the warps: the fold, the sway and the drape each steepen the field a little, and the march must never be told the surface is further away than it is.

let*
framed
bell
player-sdf-round-coneframed0.132.000.6250.365
chest
player-sdf-ellipsoidframed
vec30.00.01.86
vec30.3950.3050.335
cloth
fluted
*
player-sdf-smooth-cutfluted
-0.115
swizzleframed:z
0.10
0.78
define-shader-functionplayer-mantle-point
pointgait
"The mantle's frame: a shoulder cape whose skirt trails behind the walk."
let*
drape
smoothstep2.201.48
swizzlepoint:z
vec3
-
swizzlepoint:x
*
*0.065
singait
drape
+
swizzlepoint:y
*0.335drape
swizzlepoint:z
define-shader-functionplayer-mantle-distance
pointgait

A short traveling cape over the robe, open at the throat.

Its hem is the edge the sanctuary's own camera sees most, so the lozenge braid the walls are inlaid with is embroidered along it.

let*
framed
cape
player-sdf-round-coneframed1.542.100.5350.315
fluted
-cape
*
player-sdf-smooth-cutfluted
-1.575
swizzleframed:z
0.075
0.82
define-shader-functionplayer-cowl-distance
point
"The mantle's rolled collar, gathered under the beard."
player-sdf-ellipsoidpoint
vec30.0-0.032.135
vec30.3950.3150.125
define-shader-functionplayer-one-boot-distance
pointgaitdirectionsideparity

One boot on the contact solver's own foot, with nothing above the ankle.

The legs themselves are gone: under a floor-length robe they were a two-bone chain nobody could see, paid for at every march step. What survives is the part that touches the world, so the stance foot still stands still.

let*
step-length0.75
step-coordinate

One foot cycle spans two half-steps. Its first half is stance; its second half is the swing to the next fixed contact.

cycle
*0.5
-step-coordinateparity
cycle-index
floorcycle
swing-time
clamp
*2.0
-phase0.5
0.01.0
swing-weight
contact-step
+parity
*2.0cycle-index
foot-world
*step-length
+
+contact-step0.5
*2.0swing-weight
root-world
*step-lengthstep-coordinate
swing
*direction
-foot-worldroot-world
lift
*0.19
sin
*3.14159265swing-time
pitch-cosine
cosfoot-pitch
pitch-sine
sinfoot-pitch
baseline-center
vec3
*side0.185
+swing0.09
+0.135lift

During stance the boot pivots around a stationary heel, lies flat through weight acceptance, then pivots around a stationary toe. During swing its centre follows the authored clearance arc.

stance-time
clamp
*phase2.0
0.01.0
pivot
if
<phase0.5
if
<stance-time0.55
vec3
*side0.185
-
+swing0.09
0.20
0.0
vec3
*side0.185
+
+swing0.09
0.21
0.0
baseline-center
center-offset
-baseline-centerpivot
boot-center
+pivot
vec3
swizzlecenter-offset:x
-
*pitch-cosine
swizzlecenter-offset:y
*pitch-sine
swizzlecenter-offset:z
+
*pitch-sine
swizzlecenter-offset:y
*pitch-cosine
swizzlecenter-offset:z
boot-offset
-pointboot-center
boot-point
+boot-center
vec3
swizzleboot-offset:x
+
*pitch-cosine
swizzleboot-offset:y
*pitch-sine
swizzleboot-offset:z
-
*pitch-cosine
swizzleboot-offset:z
*pitch-sine
swizzleboot-offset:y
player-sdf-ellipsoidboot-pointboot-center
vec30.1550.2350.135
define-shader-functionplayer-boot-distance
pointgaitdirection

Evaluate both fields everywhere. Selecting a foot from POINT.x used to put a discontinuity through the centre plane, visibly slicing the screen-left boot open whenever its silhouette crossed that plane.

min
player-one-boot-distancepointgaitdirection-1.00.0
player-one-boot-distancepointgaitdirection1.01.0
define-shader-functionplayer-arm-distance
pointgait

One arm swinging free and one closed around the staff.

Both run under the mantle, so what the silhouette actually shows is a sleeve cuff and a mitten: the shoulders belong to the garment.

let*
free-shoulder
vec3-0.3750.01.96
free-elbow
vec3-0.545
*swing0.42
1.66
free-hand
vec3-0.635swingfree-height
free
player-sdf-smooth-union
player-sdf-capsulepointfree-shoulderfree-elbow0.135
player-sdf-capsulepointfree-elbowfree-hand0.125
0.055
grip-shoulder
vec30.3750.01.96
grip-elbow
vec30.5400.0751.71
grip-hand
vec30.6250.1951.505
grip
player-sdf-smooth-union
player-sdf-capsulepointgrip-shouldergrip-elbow0.135
player-sdf-capsulepointgrip-elbowgrip-hand0.125
0.055
minfreegrip
define-shader-functionplayer-staff-point
point
"The staff's own frame, with its head raked back over the walker."
let*
rise
clamp
/
-
swizzlepoint:z
0.10
3.10
0.01.0
vec3
-
swizzlepoint:x
*0.055rise
+
swizzlepoint:y
*0.115rise
swizzlepoint:z
define-shader-functionplayer-staff-distance
point

A copper-shod walking staff, carried plumb while the walker bobs past it.

The shaft is evaluated outside the pelvis pose on purpose: a staff that rose and fell with the hips would be a staff nobody was leaning on.

player-sdf-capsule
vec30.6400.1950.06
vec30.6400.1953.14
0.045
define-shader-functionplayer-staff-head-distance
point
"The lozenge finial: a copper frame with the site's own diamond set in it."
let*
frame
player-sdf-lozengeframed
vec30.6400.1953.34
vec30.1950.0550.295
collar
player-sdf-sphereframed
vec30.6400.1953.07
0.065
define-shader-functionplayer-distance
pointgaitdirection
let*
posed
head-posed

The two garments hang from the shoulders in their own frames, so they take the unposed sample and carry the walk themselves.

boots
player-boot-distancepointgaitdirection

The staff is held, not grown: it meets the mitten with a hard edge rather than a fillet, and stands outside the walk pose.

define-shader-functionplayer-normal
pointgaitdirection
let*
reach0.004
a
vec31.0-1.0-1.0
b
vec3-1.0-1.01.0
c
vec3-1.01.0-1.0
d
vec31.01.01.0
normalize
+
+
*a
player-distance
+point
*areach
gaitdirection
*b
player-distance
+point
*breach
gaitdirection
+
*c
player-distance
+point
*creach
gaitdirection
*d
player-distance
+point
*dreach
gaitdirection
define-shader-functionplayer-linen-tooth
point
"Low-contrast local-space warp, weft and irregular fibre for woven cloth."
let*
warp
sin
*
swizzlepoint:x
47.0
weft
sin
*
swizzlepoint:z
53.0
fibre
-
paper-noise
*point18.0
0.5
+1.0
+
*0.018
*warpweft
*0.065fibre
define-shader-functionplayer-beard-tooth
point
"Strands, sampled in a domain stretched the way a beard actually hangs."
+1.0
*0.10
-
paper-noise
*point
vec326.026.06.0
0.5

The lozenge braid. Colour is settled once, at the confirmed hit, so the pattern can afford to be a real pattern rather than a stripe.

define-shader-functionplayer-lozenge-figure
firstsecond
"One diamond lattice cell's outline weight, in a plane of two coordinates."
let*
across
-
fractfirst
0.5
along
radius
+
absacross
absalong
*
smoothstep0.1150.185radius
-1.0
smoothstep0.2650.335radius
define-shader-functionplayer-lozenge-braid
pointpitch

The site's diamond motif, wrapped around the figure without a seam.

Two planar lattices -- one read across his front, one along his flank -- blended by which of them the surface actually faces. A single planar lattice smears into stripes exactly where the body turns away from it.

let*
x
*pitch
swizzlepoint:x
y
*pitch
swizzlepoint:y
z
*pitch
swizzlepoint:z
sideness
/
abs
swizzlepoint:y
max
+
abs
swizzlepoint:x
abs
swizzlepoint:y
1e-4
mixfrontflank
smoothstep0.350.75sideness
define-shader-functionplayer-face-detail
pointalbedoskin-weight

Two dark eyes and a heavy brow, placed by direction from the head centre.

They live almost entirely in the brim's shadow. That is the intent: the sanctuary's camera should find a nose and a beard, and only a closer look should find somebody looking back.

let*
mirrored
vec3
abs
swizzlepoint:x
swizzlepoint:y
swizzlepoint:z
direction
normalize
-mirrored
vec30.0-0.012.09
eye-direction
normalize
vec30.340.860.16
eye
player-sdf-length
-directioneye-direction
pupil
-1.0
smoothstep0.1050.145eye
brow-direction
normalize
vec30.350.820.32
brow
-1.0
smoothstep0.1150.185
player-sdf-length
*
-directionbrow-direction
vec30.450.91.9
eyed
mixalbedo
vec30.0450.0380.048
*pupilskin-weight
browed
mixeyed
vec30.720.700.665
*brow
*skin-weight0.85
browed
define-shader-functionplayer-albedo
pointgaitdirection

The nearest part decides the colour.

Cream linen, warm copper and one red stone: the walls of the sanctuary, worn. The copper appears only where the site's own inlay would -- along a hem, around a crown, set in a finial -- so the figure and the architecture read as the same culture rather than as a doll placed on a bridge.

let*
posed
head-posed
robe-posed
mantle-posed
mantle
beard
hat
hatband
sleeves
boots
player-boot-distancepointgaitdirection
linen
strand
copper
vec30.5350.2150.075

Copper braid along both hems: a deep embroidered band at the robe's skirt and a narrower one where the cape is cut. The site's own tonemap compresses hard above half albedo, so the parts that must separate separate by a wide value step and by hue, not by a polite shade apart.

placket
*
*
-1.0
smoothstep0.0280.062
abs
swizzlerobe-posed:x
smoothstep0.040.30
swizzlerobe-posed:y
smoothstep0.160.45
swizzlerobe-posed:z
robe-braid
max
max
*
player-hem-band
swizzlerobe-posed:z
0.460.27
player-hem-band
swizzlerobe-posed:z
0.1650.055
placket
mantle-braid
max
*
player-lozenge-braidmantle-posed4.4
player-hem-band
swizzlemantle-posed:z
1.7350.10
player-hem-band
swizzlemantle-posed:z
1.6050.038
robe-color
mix
*
vec30.5750.5150.410
linen
copperrobe-braid
mantle-color
mix
*
vec30.2350.1100.080
linen
coppermantle-braid
cowl-color
*
vec30.2150.0980.072
linen
skin-color
vec30.6050.3850.245
beard-color
*
vec30.7550.7450.725
strand
hat-color
mix
*
vec30.3950.3400.255
linen
copper
band-color
*copper0.92
sleeve-color
*
vec30.2350.1100.080
linen
boot-color
*
vec30.0850.0620.050
leather
staff-color
*
vec30.3950.1750.062
leather
gem-color
vec30.4550.0400.070

A running nearest-so-far, folded by hand: step answers one when the candidate is at least as near, and mix takes it.

color-1
mixrobe-colormantle-color
stepmantlerobe
near-1
minrobemantle
color-2
mixcolor-1sleeve-color
stepsleevesnear-1
near-2
minnear-1sleeves
color-3
mixcolor-2cowl-color
stepcowlnear-2
near-3
minnear-2cowl
color-4
mixcolor-3skin-color
stepskinnear-3
near-4
minnear-3skin
color-5
mixcolor-4beard-color
stepbeardnear-4
near-5
minnear-4beard
color-6
mixcolor-5hat-color
stephatnear-5
near-6
minnear-5hat
color-7
mixcolor-6band-color
stephatbandnear-6
near-7
minnear-6hatband
color-8
mixcolor-7boot-color
stepbootsnear-7
near-8
minnear-7boots
color-9
mixcolor-8staff-color
stepstaffnear-8
near-9
minnear-8staff
color-10
mixcolor-9gem-color
stepgemnear-9

How much of this point is face, for the details painted on it.

skin-weight
-1.0
smoothstep0.00.03
-skin
minnear-9gem
player-face-detailhead-posedcolor-10skin-weight
define-shader-functionplayer-sample-local
originraycentertravel
"The figure's own coordinates for a point TRAVEL along a world ray."
let*
relative
-
+origin
*raytravel
center
vec3
swizzlerelative:x
swizzlerelative:y
+
swizzlerelative:z
1.48
define-shader-functionplayer-march-advance
ray-distanceoriginraycentergaitdirection
"One sphere-tracing step, or the answer negated once the surface is met."
define-shader-functionplayer-march-step
ray-distanceoriginraycentergaitdirectionbound

player-march-advance, guarded by whether this ray is already finished.

A finished march carries its answer negated, so both endings -- the surface found and the bound passed -- are visible here before the figure's field is sampled. The billboard is much wider than the body for the sake of the shadow it casts, and nearly every fragment on it is a ray that misses him; without this guard each of those paid fifty-eight whole evaluations of a figure it never touched.

define-shader-functionplayer-contact-shade
originraycentersunground-height

How dark the traveler's own shadow lies on the deck at this ray.

The figure is drawn as a billboard over a bridge that is flat where he walks, so the shadow he owes the deck can be found analytically: intersect the ray with the deck plane and measure the ground point against the segment the sun would sweep his body along. It is a stylised smear, not a projection -- the sanctuary's real occluders already have a shadow map, and what this repays is the one thing the map cannot give a billboard, which is that he is standing on something.

let*
descent
min
swizzleray:z
-1e-4
travel
/
-ground-height
swizzleorigin:z
descent
ground-point
+
swizzleorigin:xy
*
swizzleray:xy
travel

The sun's drift across the deck per unit of height, held to a plausible maximum so a low sun cannot throw the smear off the bridge entirely.

drift
/
swizzlesun:xy
max
swizzlesun:z
0.55
foot
swizzlecenter:xy
crown
-foot
*drift1.55
offset
-ground-pointfoot
axis
-crownfoot
along
across

The puddle is deliberately a little wider than he is: an isometric camera hides the deck directly under a robed figure, so a shadow exactly his size is a shadow nobody ever sees.

width
mix1.300.40along
edge
-acrosswidth
shape
-1.0
smoothstep-0.400.10edge
fade
mix0.820.34along
behind
step0.0travel
*
*shapefade
behind
define-shader-functionplayer-world-direction
localheading
"Rotate a player-local direction into the horizontal world frame."
define-live-shaderplayer-sdf-vertex-specification
:stage:vertex:inputs
vertex-index:uint:built-in:vertex-index
instance-index:uint:built-in:instance-index
:outputs
clip-position:vec4:built-in:position
proxy-world-position-output:vec3:location0
center-radius-output:vec4:location1
current-clip-output:vec4:location2
previous-clip-output:vec4:location3
:resources
camera-state:uniform-block:binding0:members
camera-position:vec4
camera-right:vec4
camera-up:vec4
camera-forward:vec4
camera-projection:vec4
render-parameters:vec4
previous-camera-position:vec4
previous-camera-right:vec4
previous-camera-up:vec4
previous-camera-forward:vec4
previous-camera-projection:vec4
temporal-parameters:vec4
inspection-parameters:vec4
character-parameters:vec4
sun-vector:vec4
sun-color-vector:vec4
sky-color-vector:vec4
ground-color-vector:vec4
shadow-row-x:vec4
shadow-row-y:vec4
shadow-row-z:vec4
shadow-row-w:vec4
shadow-control:vec4
previous-character-parameters:vec4
character-direction:vec4
ball-parameters:vec4
previous-ball-parameters:vec4
shadow-map:depth-texture-2d:binding1
shadow-sampler:sampler:binding2
let*
index
floatvertex-index
right-corner
if
=index2.0
1.0
if
=index3.0
1.0
if
=index5.0
1.00.0
bottom-corner
if
=index1.0
1.0
if
=index4.0
1.0
if
=index5.0
1.00.0

The quad is not square. The body needs a little over nine tenths of the radius above its centre and no more; the shadow it casts needs the deck below and beside it, which is where the extra room goes rather than into a square nobody looks at.

across
-
*right-corner2.0
1.0
vertical
-
*bottom-corner2.0
1.0
ball-p
>
floatinstance-index
0.5
corner
ifball-p
vec2acrossvertical
vec2
*across1.45
if
>vertical0.0
*vertical1.85
vertical
center
ifball-p
swizzleball-parameters:xyz
swizzlecharacter-parameters:xyz
previous-center
ifball-p
swizzleprevious-ball-parameters:xyz
swizzleprevious-character-parameters:xyz
radius
ifball-p
swizzleball-parameters:w
2.05
proxy-world-position
+
-center
*
swizzlecamera-forward:xyz
radius
+
*
swizzlecamera-right:xyz
*
swizzlecorner:x
radius
*
swizzlecamera-up:xyz
*
swizzlecorner:y
radius
previous-proxy-world-position
+
-previous-center
*
swizzleprevious-camera-forward:xyz
radius
+
*
swizzleprevious-camera-right:xyz
*
swizzlecorner:x
radius
*
swizzleprevious-camera-up:xyz
*
swizzlecorner:y
radius
current-clip
mesh-view-clipproxy-world-positioncamera-positioncamera-rightcamera-upcamera-forwardcamera-projection
swizzlerender-parameters:z
previous-clip
mesh-view-clipprevious-proxy-world-positionprevious-camera-positionprevious-camera-rightprevious-camera-upprevious-camera-forwardprevious-camera-projection
swizzlerender-parameters:z
jitter
swizzletemporal-parameters:xy
set-outputclip-position
vec4
+
swizzlecurrent-clip:x
*
swizzlejitter:x
swizzlecurrent-clip:w
+
swizzlecurrent-clip:y
*
swizzlejitter:y
swizzlecurrent-clip:w
swizzlecurrent-clip:z
swizzlecurrent-clip:w
set-outputproxy-world-position-outputproxy-world-position
set-outputcenter-radius-output
vec4centerradius
set-outputcurrent-clip-outputcurrent-clip
set-outputprevious-clip-outputprevious-clip
define-live-shaderplayer-sdf-fragment-specification
:stage:fragment:inputs
proxy-world-position:vec3:location0
center-radius:vec4:location1
current-clip:vec4:location2
previous-clip:vec4:location3
:outputs
color-output:vec4:location0
motion-output:vec2:location1
:resources
camera-state:uniform-block:binding0:members
camera-position:vec4
camera-right:vec4
camera-up:vec4
camera-forward:vec4
camera-projection:vec4
render-parameters:vec4
previous-camera-position:vec4
previous-camera-right:vec4
previous-camera-up:vec4
previous-camera-forward:vec4
previous-camera-projection:vec4
temporal-parameters:vec4
inspection-parameters:vec4
character-parameters:vec4
sun-vector:vec4
sun-color-vector:vec4
sky-color-vector:vec4
ground-color-vector:vec4
shadow-row-x:vec4
shadow-row-y:vec4
shadow-row-z:vec4
shadow-row-w:vec4
shadow-control:vec4
previous-character-parameters:vec4
character-direction:vec4
ball-parameters:vec4
previous-ball-parameters:vec4
shadow-map:depth-texture-2d:binding1
shadow-sampler:sampler:binding2
let*
center
swizzlecenter-radius:xyz
radius
swizzlecenter-radius:w
ball-p
<radius1.0
gait
swizzlecharacter-parameters:w
spell-flash
swizzlecharacter-direction:w

The game controller rotates world space into the traveler's local forward frame below, so the hermit's authored stride always runs along local +Y.

direction1.0
heading
normalize
swizzlecharacter-direction:xy
ray
if
<
swizzlerender-parameters:z
0.5
normalize
swizzlecamera-forward:xyz
normalize
-proxy-world-position
swizzlecamera-position:xyz
originproxy-world-position

The hermit's field is rotated into his live walking heading. The branch study's shortcut marched in world axes, which diverged as soon as a player turned and left a transparent robe behind.

travel
counted-fold
march58.0ray-distance0.0
let*
world-point
relative
-world-pointcenter
relative-xy
swizzlerelative:xy
local
vec3
dotrelative-xyplayer-right
dotrelative-xyheading
+
swizzlerelative:z
1.48
distance
ifball-p
-
sqrt
dot
-world-pointcenter
-world-pointcenter
radius
world-point
+origin
*raytravel
relative
-world-pointcenter
ball-offset
-world-pointcenter
relative-xy
swizzlerelative:xy
local
vec3
dotrelative-xyplayer-right
dotrelative-xyheading
+
swizzlerelative:z
1.48
player-surface-distance
ifball-p
-
sqrt
dotball-offsetball-offset
radius
player-distancelocalgaitdirection
orb-surface-distance
ifball-p1000.0
orb-p
ifball-p
<radius0.0
<orb-surface-distanceplayer-surface-distance
surface-distance
ifball-pplayer-surface-distance
minplayer-surface-distanceorb-surface-distance
coverage
-1.0
step0.006surface-distance
local-normal
iforb-p

The central sphere owns the visible normal. Its tiny firework motes use the same radial answer, which makes the glow read as one spell instead of pixel speckle.

normalize
-local
vec30.6400.1953.34
player-normallocalgaitdirection
normal
ifball-p
normalize
-world-pointcenter
albedo
ifball-p
vec30.920.160.075
iforb-p
vec30.420.881.0
player-albedolocalgaitdirection
sun
swizzlesun-vector:xyz
sun-color
swizzlesun-color-vector:xyz
sky
swizzlesky-color-vector:xyz
ground
swizzleground-color-vector:xyz
facing
dotnormalsun
direct-shape
smoothstep0.00.72
max0.0facing
light-clip
light-clip-positionworld-pointshadow-row-xshadow-row-yshadow-row-zshadow-row-w
player-shadow-sample
vec3
+
*
swizzlelight-clip:x
0.5
0.5
+
*
swizzlelight-clip:y
0.5
0.5
swizzlelight-clip:z
sampled-shadow
soft-shadow-visibilityshadow-mapshadow-samplerplayer-shadow-samplenormalsunshadow-control
direct-visibility
mix1.0sampled-shadow
smoothstep0.030.18
max0.0facing
upness
swizzlenormal:z
sky-weight
+0.5
*0.5upness
ground-weight
-0.5
*0.5upness
indirect
+
*sky
+0.15
*0.54sky-weight
*ground
+0.05
*0.34ground-weight
warm-return
*sun-color
*0.085direct-shape
-1.0direct-visibility
lit
*albedo
+
*sun-color
*direct-shapedirect-visibility
indirectwarm-return
paper
*lit1.08
rim
expt
-1.0
max0.0
dotnormal
*ray-1.0
3.0
radiance
+paper
*
vec30.200.420.48
*rim0.07

A real source of color: the orb is blue-white at the core, warmed by a small peach firework halo.

iforb-p
+
*
vec30.320.851.10
+1.0
*spell-flash6.0
*
vec31.00.340.10
*
+1.0
*spell-flash5.0
smoothstep0.020.11
absorb-surface-distance
vec30.00.00.0

Where the body was missed, the same billboard still owes the deck his shadow. Its own sample of the sun's shadow map keeps him from darkening ground the sanctuary is already shading.

deck-height
-
swizzlecenter:z
1.48
deck-point
+origin
*ray
/
-deck-height
swizzleorigin:z
min
swizzleray:z
-1e-4

Lifted clear of the deck before it is looked up: sampling the sun's depth map at a point lying exactly on the surface that wrote it is the textbook way to shadow a floor with itself.

deck-clip
light-clip-position
+deck-point
vec30.00.00.09
shadow-row-xshadow-row-yshadow-row-zshadow-row-w
deck-lit
soft-shadow-visibilityshadow-mapshadow-sampler
vec3
+
*
swizzledeck-clip:x
0.5
0.5
+
*
swizzledeck-clip:y
0.5
0.5
swizzledeck-clip:z
vec30.00.01.0
sunshadow-control
contact
ifball-p0.0
*
*
player-contact-shadeoriginraycentersundeck-height
deck-lit
-1.0coverage
shade-color
*
vec30.1550.1400.205
contact
composite-alpha
+coveragecontact
set-outputcolor-output
vec4
+
*radiancecoverage
shade-color
composite-alpha
set-outputmotion-output
mesh-temporal-motionprevious-clipcurrent-clip
define-live-shadermesh-vertex-specification
:stage:vertex:inputs
vertex-index:uint:built-in:vertex-index
instance-index:uint:built-in:instance-index
:outputs
clip-position:vec4:built-in:position
world-position-output:vec3:location0
mesh-normal-output:vec3:location1:interpolation:flat
assembly-output:float:location2:interpolation:flat
barycentric-output:vec3:location3
current-clip-output:vec4:location4
previous-clip-output:vec4:location5
shadow-sample-output:vec3:location6
boundary-edge-mask-output:uint:location7:interpolation:flat
ambient-occlusion-output:float:location8:interpolation:flat
:resources
instances:storage-buffer:binding0:element:uvec4
template-vertices:storage-buffer:binding1:element:uvec4
camera-state:uniform-block:binding2:members
camera-position:vec4
camera-right:vec4
camera-up:vec4
camera-forward:vec4
camera-projection:vec4
render-parameters:vec4
previous-camera-position:vec4
previous-camera-right:vec4
previous-camera-up:vec4
previous-camera-forward:vec4
previous-camera-projection:vec4
temporal-parameters:vec4
inspection-parameters:vec4
character-parameters:vec4
sun-vector:vec4
sun-color-vector:vec4
sky-color-vector:vec4
ground-color-vector:vec4
shadow-row-x:vec4
shadow-row-y:vec4
shadow-row-z:vec4
shadow-row-w:vec4
shadow-control:vec4
let*
instance
buffer-elementinstancesinstance-index
template-id
uint
ldb
byte160
swizzleinstance:w
template-index
+
*template-id
uint6.0
vertex-index
template-vertex
buffer-elementtemplate-verticestemplate-index
attributes
swizzletemplate-vertex:w
world-position
mesh-world-positioninstancetemplate-vertex
mesh-normal
vec3
-
float
ldb
byte20
attributes
1.0
-
float
ldb
byte22
attributes
1.0
-
float
ldb
byte24
attributes
1.0
assembly-id
float
ldb
byte1216
swizzleinstance:w
barycentric-index
uint
ldb
byte26
attributes
boundary-edge-mask
uint
ldb
byte310
attributes
barycentric
if
=barycentric-index
uint0.0
vec31.00.00.0
if
=barycentric-index
uint1.0
vec30.01.00.0
vec30.00.01.0
current-clip
mesh-view-clipworld-positioncamera-positioncamera-rightcamera-upcamera-forwardcamera-projection
swizzlerender-parameters:z
previous-clip
mesh-view-clipworld-positionprevious-camera-positionprevious-camera-rightprevious-camera-upprevious-camera-forwardprevious-camera-projection
swizzlerender-parameters:z
light-clip
light-clip-positionworld-positionshadow-row-xshadow-row-yshadow-row-zshadow-row-w
jitter
swizzletemporal-parameters:xy

Do not emulate face culling by moving a vertex off screen. The facing test is per vertex, so a triangle crossing its threshold turns into an enormous sliver as the camera moves. The closed surface's normal depth test already hides its far side coherently.

set-outputclip-position
vec4
+
swizzlecurrent-clip:x
*
swizzlejitter:x
swizzlecurrent-clip:w
+
swizzlecurrent-clip:y
*
swizzlejitter:y
swizzlecurrent-clip:w
swizzlecurrent-clip:z
swizzlecurrent-clip:w
set-outputworld-position-outputworld-position
set-outputmesh-normal-outputmesh-normal
set-outputassembly-outputassembly-id
set-outputbarycentric-outputbarycentric
set-outputcurrent-clip-outputcurrent-clip
set-outputprevious-clip-outputprevious-clip
set-outputshadow-sample-output
vec3
+
*
swizzlelight-clip:x
0.5
0.5
+
*
swizzlelight-clip:y
0.5
0.5
swizzlelight-clip:z
set-outputboundary-edge-mask-outputboundary-edge-mask
set-outputambient-occlusion-outputambient-occlusion
define-live-shadermesh-fragment-specification
:stage:fragment:inputs
world-position:vec3:location0
mesh-normal:vec3:location1:interpolation:flat
assembly-id:float:location2:interpolation:flat
barycentric:vec3:location3
current-clip:vec4:location4
previous-clip:vec4:location5
shadow-sample:vec3:location6
boundary-edge-mask:uint:location7:interpolation:flat
ambient-occlusion:float:location8:interpolation:flat
:outputs
color-output:vec4:location0
motion-output:vec2:location1
:resources
camera-state:uniform-block:binding2:members
camera-position:vec4
camera-right:vec4
camera-up:vec4
camera-forward:vec4
camera-projection:vec4
render-parameters:vec4
previous-camera-position:vec4
previous-camera-right:vec4
previous-camera-up:vec4
previous-camera-forward:vec4
previous-camera-projection:vec4
temporal-parameters:vec4
inspection-parameters:vec4
character-parameters:vec4
sun-vector:vec4
sun-color-vector:vec4
sky-color-vector:vec4
ground-color-vector:vec4
shadow-row-x:vec4
shadow-row-y:vec4
shadow-row-z:vec4
shadow-row-w:vec4
shadow-control:vec4
material-descriptors:storage-buffer:binding3:element:vec4
shadow-map:depth-texture-2d:binding4
shadow-sampler:sampler:binding5
let*
normal
if
<
dotgeometric-normalmesh-normal
0.0
*geometric-normal-1.0
geometric-normal
descriptor-row
uint
*assembly-id7.0
primary
buffer-elementmaterial-descriptorsdescriptor-row
secondary
buffer-elementmaterial-descriptors
+descriptor-row
uint1.0
tertiary
buffer-elementmaterial-descriptors
+descriptor-row
uint2.0
frame-origin
buffer-elementmaterial-descriptors
+descriptor-row
uint3.0
frame-x
buffer-elementmaterial-descriptors
+descriptor-row
uint4.0
frame-y
buffer-elementmaterial-descriptors
+descriptor-row
uint5.0
frame-z
buffer-elementmaterial-descriptors
+descriptor-row
uint6.0
material-point
material-frame-pointworld-position
swizzleframe-origin:xyz
swizzleframe-x:xyz
swizzleframe-y:xyz
swizzleframe-z:xyz
relief-profile
swizzleframe-origin:w
relief-height
material-reliefmaterial-pointrelief-profile
shading-normalnormal
roughness
clamp
+
swizzletertiary:w
*0.06
absrelief-height
0.160.99
paper-point
paper-spacematerial-point
primary-tone
swizzleprimary:xyz
secondary-tone
swizzlesecondary:xyz
tertiary-tone
swizzletertiary:xyz

`kernel` is a Metal address-space keyword, so keep the closed material-kernel discriminator explicit in generated MSL.

kernel-code
swizzleprimary:w
contact-variant
swizzlesecondary:w
earth-set-p
if
<
abs
-kernel-code1.0
0.5
1.00.0
tone
if
<kernel-code0.5
primary-tone
if
<kernel-code1.5
earth-set-stone-tonematerial-pointnormalambient-occlusioncontact-variantprimary-tonesecondary-tonetertiary-tone
if
<kernel-code2.5
turf-edge-tonematerial-pointnormalprimary-tonesecondary-tone
if
<kernel-code3.5
foundation-stone-tonematerial-pointprimary-tonesecondary-tonetertiary-tone
if
<kernel-code4.5
dressed-stone-tonematerial-pointnormalprimary-tone
if
<kernel-code5.5
natural-earth-tonematerial-pointnormalprimary-tone0.0
if
<kernel-code6.5
natural-earth-tonematerial-pointnormalprimary-tone1.0
natural-earth-tonematerial-pointnormalprimary-tone-0.5
bloom
paper-noise
+
*paper-point0.17
vec32.717.18.3
mottle
paper-noise
+
*
swizzlepaper-point:yzx
0.61
vec319.77.33.1
fiber
paper-noise
+
vec3
*
swizzlepaper-point:x
2.3
*
swizzlepaper-point:y
5.1
*
swizzlepaper-point:z
3.7
vec35.923.314.1
value
+1.0
*#.*paper-variation*
+
*0.90
-bloom0.5
*0.55
-mottle0.5
*0.25
-fiber0.5
warmth
mix
vec30.9650.991.04
vec31.041.010.96
smoothstep0.180.82mottle
base
*tone
*warmth
*value
+1.0
*relief-height0.028
sun
swizzlesun-vector:xyz
sun-color
swizzlesun-color-vector:xyz
sky
swizzlesky-color-vector:xyz
ground
swizzleground-color-vector:xyz
facing
dotshading-normalsun
direct-shape
smoothstep0.00.72
max0.0facing
sampled-shadow
soft-shadow-visibilityshadow-mapshadow-samplershadow-sampleshading-normalsunshadow-control
direct-visibility
mix1.0sampled-shadow
smoothstep0.030.18
max0.0facing
upness
swizzleshading-normal:z
sky-weight
+0.5
*0.5upness
ground-weight
-0.5
*0.5upness
indirect-light

Sky and earth are illumination, not gray absence-of-sun. The constant terms keep vertical and turned-away planes chromatic; the hemispheric terms still tell us which environment they see.

+
*sky
+0.15
*0.54sky-weight
*ground
+0.05
*0.34ground-weight
ambient-accessibility
-1.0
*#.*local-ambient-occlusion-strength*ambient-occlusion

A sun-facing receiver inside a cast shadow still sees warm light returned by the illuminated world around it. This little wash is deliberately conditional on occlusion: it animates sun patches without turning north-facing planes orange.

warm-return
*sun-color
*0.085direct-shape
-1.0direct-visibility
light
+
*sun-color
*direct-shapedirect-visibility
*indirect-lightambient-accessibility
warm-return
view-direction
half-vector
normalize
+view-directionsun
n-dot-v
max0.0
dotshading-normalview-direction
n-dot-h
max0.0
dotshading-normalhalf-vector
n-dot-l
maxfacing0.0
v-dot-h
max0.0
dotview-directionhalf-vector
alpha
*roughnessroughness
alpha-squared
*alphaalpha
distribution-denominator
+
*
*n-dot-hn-dot-h
-alpha-squared1.0
1.0
distribution
/alpha-squared
max0.0001
*3.14159265
*distribution-denominatordistribution-denominator
visibility-light
*n-dot-v
sqrt
+
*
*n-dot-ln-dot-l
-1.0alpha-squared
alpha-squared
visibility-view
*n-dot-l
sqrt
+
*
*n-dot-vn-dot-v
-1.0alpha-squared
alpha-squared
visibility
/0.5
max0.0001
+visibility-lightvisibility-view
fresnel
+0.04
*0.96
expt
-1.0v-dot-h
5.0
specular
*sun-color
*
*0.34direct-visibility
*distribution
*visibility
*fresneln-dot-l
lit
+
*base
*light
stock-toothmaterial-point
specular

Keep scene radiance linear and HDR here. The universal presentation pass blooms, tone maps, and grades it exactly once.

mapped-paper
*lit1.08
camera-delta
-world-position
swizzlecamera-position:xyz
distance
sqrt
dotcamera-deltacamera-delta
fog
paper
mixmapped-paperskyfog
barycentric-dx
derivative-xbarycentric
barycentric-dy
derivative-ybarycentric
barycentric-width
+
absbarycentric-dx
absbarycentric-dy
edge-x
/
swizzlebarycentric:x
max
swizzlebarycentric-width:x
0.000001
edge-y
/
swizzlebarycentric:y
max
swizzlebarycentric-width:y
0.000001
edge-z
/
swizzlebarycentric:z
max
swizzlebarycentric-width:z
0.000001
edge-pixels
min
minedge-xedge-y
edge-z
boundary-edge-pixels
min
min
if
=
ldb
byte10
boundary-edge-mask
uint1.0
edge-x10000.0
if
=
ldb
byte11
boundary-edge-mask
uint1.0
edge-y10000.0
if
=
ldb
byte12
boundary-edge-mask
uint1.0
edge-z10000.0
all-wire
-1.0
smoothstep0.451.15edge-pixels
boundary-wire
-1.0
smoothstep0.451.15boundary-edge-pixels
construction-wire
*
swizzlerender-parameters:y
min1.0
+
*all-wire0.18
*boundary-wire0.82
fragment-uv
mesh-clip-uvcurrent-clip
pointer-delta
/
-fragment-uv
swizzleinspection-parameters:xy
max
swizzleinspection-parameters:zw
vec20.0000010.000001
pointer-pixels
sqrt
dotpointer-deltapointer-delta
pointer-enabled
swizzlerender-parameters:w
ring
*pointer-enabled
-1.0
smoothstep0.351.25
abs
-pointer-pixels11.0
center
*pointer-enabled
-1.0
smoothstep0.71.8pointer-pixels
reticle
maxcenterring
construction-ink
vec30.0550.160.22
blueprint
vec30.300.900.94
drafted
mixpaperconstruction-inkconstruction-wire
radiance
mixdraftedblueprintreticle
set-outputcolor-output
vec4radiance1.0
set-outputmotion-output
mesh-temporal-motionprevious-clipcurrent-clip
define-live-shadershadow-vertex-specification
:stage:vertex:inputs
vertex-index:uint:built-in:vertex-index
instance-index:uint:built-in:instance-index
:outputs
clip-position:vec4:built-in:position
:resources
instances:storage-buffer:binding0:element:uvec4
template-vertices:storage-buffer:binding1:element:uvec4
camera-state:uniform-block:binding2:members
camera-position:vec4
camera-right:vec4
camera-up:vec4
camera-forward:vec4
camera-projection:vec4
render-parameters:vec4
previous-camera-position:vec4
previous-camera-right:vec4
previous-camera-up:vec4
previous-camera-forward:vec4
previous-camera-projection:vec4
temporal-parameters:vec4
inspection-parameters:vec4
character-parameters:vec4
sun-vector:vec4
sun-color-vector:vec4
sky-color-vector:vec4
ground-color-vector:vec4
shadow-row-x:vec4
shadow-row-y:vec4
shadow-row-z:vec4
shadow-row-w:vec4
shadow-control:vec4
let*
instance
buffer-elementinstancesinstance-index
template-id
uint
ldb
byte160
swizzleinstance:w
template-index
+
*template-id
uint6.0
vertex-index
template-vertex
buffer-elementtemplate-verticestemplate-index
world-position
mesh-world-positioninstancetemplate-vertex
set-outputclip-position
light-clip-positionworld-positionshadow-row-xshadow-row-yshadow-row-zshadow-row-w
define-live-shaderlattice-point-vertex-specification
:stage:vertex:inputs
vertex-index:uint:built-in:vertex-index
instance-index:uint:built-in:instance-index
:outputs
clip-position:vec4:built-in:position
marker-coordinate-output:vec2:location0
current-clip-output:vec4:location1
previous-clip-output:vec4:location2
marker-kind-output:float:location3:interpolation:flat
:resources
lattice-points:storage-buffer:binding0:element:uvec4
camera-state:uniform-block:binding1:members
camera-position:vec4
camera-right:vec4
camera-up:vec4
camera-forward:vec4
camera-projection:vec4
render-parameters:vec4
previous-camera-position:vec4
previous-camera-right:vec4
previous-camera-up:vec4
previous-camera-forward:vec4
previous-camera-projection:vec4
temporal-parameters:vec4
inspection-parameters:vec4
character-parameters:vec4
let*
record
buffer-elementlattice-pointsinstance-index
index
floatvertex-index
right
if
=index2.0
1.0
if
=index3.0
1.0
if
=index5.0
1.00.0
bottom
if
=index1.0
1.0
if
=index4.0
1.0
if
=index5.0
1.00.0
coordinate
vec2
-
*right2.0
1.0
-
*bottom2.0
1.0
marker-kind
float
swizzlerecord:w
current-clip
mesh-view-clipworld-positioncamera-positioncamera-rightcamera-upcamera-forwardcamera-projection
swizzlerender-parameters:z
previous-clip
mesh-view-clipworld-positionprevious-camera-positionprevious-camera-rightprevious-camera-upprevious-camera-forwardprevious-camera-projection
swizzlerender-parameters:z
pixel-size
swizzleinspection-parameters:zw
radius
if
>marker-kind1.5
8.5
if
>marker-kind0.5
6.52.6
jitter
swizzletemporal-parameters:xy
set-outputclip-position
vec4
+
+
swizzlecurrent-clip:x
*
swizzlejitter:x
swizzlecurrent-clip:w
*
swizzlecoordinate:x
*
*radius2.0
swizzlepixel-size:x
swizzlecurrent-clip:w
+
+
swizzlecurrent-clip:y
*
swizzlejitter:y
swizzlecurrent-clip:w
*
swizzlecoordinate:y
*
*radius2.0
swizzlepixel-size:y
swizzlecurrent-clip:w
-
swizzlecurrent-clip:z
*0.00015
swizzlecurrent-clip:w
swizzlecurrent-clip:w
set-outputmarker-coordinate-outputcoordinate
set-outputcurrent-clip-outputcurrent-clip
set-outputprevious-clip-outputprevious-clip
set-outputmarker-kind-outputmarker-kind
define-live-shaderlattice-point-fragment-specification
:stage:fragment:inputs
marker-coordinate:vec2:location0
current-clip:vec4:location1
previous-clip:vec4:location2
marker-kind:float:location3:interpolation:flat
:outputs
color-output:vec4:location0
motion-output:vec2:location1
let*
radius
sqrt
dotmarker-coordinatemarker-coordinate
coverage
-1.0
smoothstep0.821.0radius
vertex-site
if
>marker-kind1.5
1.00.0
mesh-point
if
>marker-kind0.5
1.00.0
center
-1.0
smoothstep
if
>mesh-point0.5
0.400.18
if
>mesh-point0.5
0.620.52
radius
rim
vec30.0350.0750.095
ink
vec31.00.300.10
site
vec30.200.951.0
color
mix
mixriminkcenter
sitevertex-site
alpha
*coverage0.96
set-outputcolor-output
vec4
*coloralpha
alpha
set-outputmotion-output
-
mesh-clip-uvprevious-clip
mesh-clip-uvcurrent-clip
define-live-shaderpresent-vertex-specification
:stage:vertex:inputs
vertex-index:uint:built-in:vertex-index
:outputs
clip-position:vec4:built-in:position
ndc-output:vec2:location0
let*
index
floatvertex-index
x
if
<index0.5
-1.0
if
<index1.5
3.0-1.0
y
if
<index1.5
-1.03.0
set-outputclip-position
vec4xy0.01.0
set-outputndc-output
define-shader-functionview-depth
depthprojectiondivisor
if
<divisor0.5
/
-depth
swizzleprojection:w
swizzleprojection:z
/
swizzleprojection:w
-depth
swizzleprojection:z
define-shader-functiondepth-occlusion
centresampleradius
let*
delta
-centresample
near
smoothstep0.025
*radius0.42
delta
far
-1.0
smoothstep
*radius0.62
radiusdelta
*nearfar
define-shader-functionsky-view-ray
ndccamera-rightcamera-upcamera-forwardcamera-projectiondivisor
let*
perspective-ray
normalize
+
swizzlecamera-forward:xyz
*
swizzlecamera-right:xyz
/
swizzlendc:x
swizzlecamera-projection:x
*
swizzlecamera-up:xyz
/
swizzlecamera-projection:y
isometric-ray
normalize
+
swizzlecamera-forward:xyz
*
swizzlecamera-up:xyz
*0.38
mixisometric-rayperspective-raydivisor
define-shader-functionpainted-sky-radiance
ndccamera-rightcamera-upcamera-forwardcamera-projectiondivisorsun-vectorsun-color-vectorsky-color-vector
"Return view-stable late-afternoon HDR radiance before exposure or grading."
let*
ray
sky-view-rayndccamera-rightcamera-upcamera-forwardcamera-projectiondivisor
upness
horizon-weight
base-sky
swizzlesky-color-vector:xyz
horizon
vec30.580.781.06
zenith
*base-sky
vec30.340.580.94
horizon-haze
atmosphere
mix
mixhorizonzenithhorizon-weight
vec31.120.680.38
*horizon-haze0.13

Broad directional noise makes sparse watercolor cloud banks. The envelope keeps them above the haze and below the clear zenith.

cloud-point
vec3
*
swizzleray:x
5.0
*
swizzleray:y
5.0
cloud-coarse
paper-noise
+cloud-point
vec33.111.75.3
cloud-fine
paper-noise
+
*cloud-point
vec32.32.31.4
vec317.92.731.1
cloud-shape
smoothstep0.520.72
+
*cloud-coarse0.72
*cloud-fine0.28
cloud-height
*
smoothstep0.050.20upness
-1.0
smoothstep0.580.90upness
sun
normalize
swizzlesun-vector:xyz
sun-facing
max0.0
dotraysun
sun-halo
smoothstep0.9650.9992sun-facing
sun-disc
smoothstep0.999250.99982sun-facing
cloud-light
mix
vec30.760.881.10
vec31.340.780.42
smoothstep0.720.98sun-facing
clouded
mixatmospherecloud-light
*cloud-shapecloud-height0.26
radiance
+clouded
*
swizzlesun-color-vector:xyz
+
*sun-halo0.10
*sun-disc2.8
radiance
define-live-shadersky-fragment-specification
:stage:fragment:inputs
ndc:vec2:location0
:outputs
color-output:vec4:location0
:resources
camera-state:uniform-block:binding0:members
camera-position:vec4
camera-right:vec4
camera-up:vec4
camera-forward:vec4
camera-projection:vec4
render-parameters:vec4
previous-camera-position:vec4
previous-camera-right:vec4
previous-camera-up:vec4
previous-camera-forward:vec4
previous-camera-projection:vec4
temporal-parameters:vec4
inspection-parameters:vec4
character-parameters:vec4
sun-vector:vec4
sun-color-vector:vec4
sky-color-vector:vec4
let*
radiance
painted-sky-radiancendccamera-rightcamera-upcamera-forwardcamera-projection
swizzlerender-parameters:z
sun-vectorsun-color-vectorsky-color-vector
set-outputcolor-output
vec4radiance1.0
define-live-shadersky-temporal-fragment-specification
:stage:fragment:inputs
ndc:vec2:location0
:outputs
color-output:vec4:location0
motion-output:vec2:location1
:resources
camera-state:uniform-block:binding0:members
camera-position:vec4
camera-right:vec4
camera-up:vec4
camera-forward:vec4
camera-projection:vec4
render-parameters:vec4
previous-camera-position:vec4
previous-camera-right:vec4
previous-camera-up:vec4
previous-camera-forward:vec4
previous-camera-projection:vec4
temporal-parameters:vec4
inspection-parameters:vec4
character-parameters:vec4
sun-vector:vec4
sun-color-vector:vec4
sky-color-vector:vec4
let*
divisor
swizzlerender-parameters:z
ray
sky-view-rayndccamera-rightcamera-upcamera-forwardcamera-projectiondivisor
radiance
painted-sky-radiancendccamera-rightcamera-upcamera-forwardcamera-projectiondivisorsun-vectorsun-color-vectorsky-color-vector
previous-z
dotray
swizzleprevious-camera-forward:xyz
previous-clip
vec4
*
dotray
swizzleprevious-camera-right:xyz
swizzleprevious-camera-projection:x
-
*
dotray
swizzleprevious-camera-up:xyz
swizzleprevious-camera-projection:y
0.0
mix1.0previous-zdivisor
current-clip
vec4
swizzlendc:x
swizzlendc:y
0.01.0
set-outputcolor-output
vec4radiance1.0
set-outputmotion-output
mesh-temporal-motionprevious-clipcurrent-clip
define-live-shaderexposure-probe-fragment-specification
:stage:fragment:inputs
ndc:vec2:location0
:outputs
color-output:vec4:location0
:resources
scene:texture-2d:binding0:sample-transfer:identity
scene-sampler:sampler:binding1
let*
uv
+
*ndc0.5
vec20.50.5

Match Moppe's broad five-tap probe footprint before the 32x16 reduction. Encoding log luminance into UNORM makes the geometric mean portable through the HAL's compact RGBA8 readback contract.

offset
vec20.0080.014
average
*
+
swizzle
samplescenescene-sampleruv
:xyz
swizzle
samplescenescene-sampler
+uvoffset
:xyz
swizzle
samplescenescene-sampler
-uvoffset
:xyz
swizzle
samplescenescene-sampler
+uv
vec2
swizzleoffset:x
-
swizzleoffset:y
:xyz
swizzle
samplescenescene-sampler
+uv
vec2
-
swizzleoffset:x
swizzleoffset:y
:xyz
0.2
luminance
max
dotaverage
vec30.21260.71520.0722
0.0001
encoded
clamp
/
+
logluminance
9.21034
11.98293
0.01.0
set-outputcolor-output
vec4encodedencodedencoded1.0
define-live-shaderpresent-fragment-specification
:stage:fragment:inputs
ndc:vec2:location0
:outputs
color-output:vec4:location0
:resources
scene:texture-2d:binding0:sample-transfer:identity
scene-sampler:sampler:binding1
scene-depth:depth-texture-2d:binding2
camera-state:uniform-block:binding3:members
camera-position:vec4
camera-right:vec4
camera-up:vec4
camera-forward:vec4
camera-projection:vec4
render-parameters:vec4
previous-camera-position:vec4
previous-camera-right:vec4
previous-camera-up:vec4
previous-camera-forward:vec4
previous-camera-projection:vec4
temporal-parameters:vec4
inspection-parameters:vec4
character-parameters:vec4
sun-vector:vec4
sun-color-vector:vec4
sky-color-vector:vec4
let*
uv
+
*ndc0.5
vec20.50.5
value
samplescenescene-sampleruv
auto-exposure
swizzlesky-color-vector:w
texel
swizzleinspection-parameters:zw
near
*texel3.0
far
*texel11.0

One low-cost, deliberately broad gather. Linear sampling and the two rings make luminous paper bleed across an edge without erasing the edge itself or turning the whole frame into fog.

Geometry depth carries the subpixel projection jitter consumed by MetalFX; presentation UVs do not. Sample depth at the same current geometry location so the AO does not crawl across a resolved edge.

depth-uv
+uv
*
swizzletemporal-parameters:xy
0.5
depth
swizzle
samplescene-depthscene-samplerdepth-uv
:x
divisor
swizzlerender-parameters:z
centre
view-depthdepthcamera-projectiondivisor
perspective-scale
if
<divisor0.5
1.0
/1.0centre
outer
*
swizzlecamera-projection:xy
*0.5#.*screen-ambient-occlusion-radius*perspective-scale
inner
*outer0.42
diagonal
*outer0.70710678
occlusion
*
/1.012.0
+
depth-occlusioncentre
view-depth
swizzle
samplescene-depthscene-sampler
+depth-uv
vec2
swizzleinner:x
0.0
:x
camera-projectiondivisor
#.*screen-ambient-occlusion-radius*
depth-occlusioncentre
view-depth
swizzle
samplescene-depthscene-sampler
+depth-uv
vec2
-
swizzleinner:x
0.0
:x
camera-projectiondivisor
#.*screen-ambient-occlusion-radius*
depth-occlusioncentre
view-depth
swizzle
samplescene-depthscene-sampler
+depth-uv
vec20.0
swizzleinner:y
:x
camera-projectiondivisor
#.*screen-ambient-occlusion-radius*
depth-occlusioncentre
view-depth
swizzle
samplescene-depthscene-sampler
+depth-uv
vec20.0
-
swizzleinner:y
:x
camera-projectiondivisor
#.*screen-ambient-occlusion-radius*
depth-occlusioncentre
view-depth
swizzle
samplescene-depthscene-sampler
+depth-uv
vec2
swizzleouter:x
0.0
:x
camera-projectiondivisor
#.*screen-ambient-occlusion-radius*
depth-occlusioncentre
view-depth
swizzle
samplescene-depthscene-sampler
+depth-uv
vec2
-
swizzleouter:x
0.0
:x
camera-projectiondivisor
#.*screen-ambient-occlusion-radius*
depth-occlusioncentre
view-depth
swizzle
samplescene-depthscene-sampler
+depth-uv
vec20.0
swizzleouter:y
:x
camera-projectiondivisor
#.*screen-ambient-occlusion-radius*
depth-occlusioncentre
view-depth
swizzle
samplescene-depthscene-sampler
+depth-uv
vec20.0
-
swizzleouter:y
:x
camera-projectiondivisor
#.*screen-ambient-occlusion-radius*
depth-occlusioncentre
view-depth
swizzle
samplescene-depthscene-sampler
+depth-uvdiagonal
:x
camera-projectiondivisor
#.*screen-ambient-occlusion-radius*
depth-occlusioncentre
view-depth
swizzle
samplescene-depthscene-sampler
-depth-uvdiagonal
:x
camera-projectiondivisor
#.*screen-ambient-occlusion-radius*
depth-occlusioncentre
view-depth
swizzle
samplescene-depthscene-sampler
+depth-uv
vec2
swizzlediagonal:x
-
swizzlediagonal:y
:x
camera-projectiondivisor
#.*screen-ambient-occlusion-radius*
depth-occlusioncentre
view-depth
swizzle
samplescene-depthscene-sampler
+depth-uv
vec2
-
swizzlediagonal:x
swizzlediagonal:y
:x
camera-projectiondivisor
#.*screen-ambient-occlusion-radius*
accessibility
if
<depth0.9999
-1.0
*#.*screen-ambient-occlusion-strength*
min1.0
*occlusion1.6
1.0
pooling
*#.*ambient-pigment-strength*
min1.0
*occlusion1.6

A common cool shadow pigment makes the depth signal read as an illustrated wash rather than neutral post-process darkening.

shadow-pigment
vec30.760.881.03
shadowed
*
swizzlevalue:xyz
accessibility
pigmented
*shadowed
mix
vec31.01.01.0
shadow-pigmentpooling

A gentle screen-space tilt shift holds the player's projected height crisp and gives the near/far route a miniature depth cue. It is deliberately only a five-tap gather after MetalFX resolves.

player-clip
mesh-view-clip
swizzlecharacter-parameters:xyz
camera-positioncamera-rightcamera-upcamera-forwardcamera-projectiondivisor
focus-y
+
swizzle
mesh-clip-uvplayer-clip
:y
*
swizzletemporal-parameters:y
0.5
tilt
smoothstep0.160.52
abs
-focus-y
blur-radius
*texel2.6
blurred
*0.2
+
swizzlevalue:xyz
swizzle
samplescenescene-sampler
+uv
vec2
swizzleblur-radius:x
0.0
:xyz
swizzle
samplescenescene-sampler
-uv
vec2
swizzleblur-radius:x
0.0
:xyz
swizzle
samplescenescene-sampler
+uv
vec20.0
swizzleblur-radius:y
:xyz
swizzle
samplescenescene-sampler
-uv
vec20.0
swizzleblur-radius:y
:xyz
bloomed
+
swizzlepigmented:xyz
*glow#.*highlight-glow-strength*
glowing
mixbloomedblurred
*tilt0.52

MetalFX has already reconstructed GLowing at this point. Grade it once, with a little exposure headroom for the sunlit grass and the wizard's HDR spell rather than clipping both into parchment. Sky is now HDR scene radiance, so it participates in metering and receives exactly the same exposure and paper grade as geometry. Keep geometry-only AO and tilt-shift out of background pixels.

radiance
if
<depth0.9999
glowing
swizzlevalue:xyz
presented
paper-grade
paper-tonemap
*radianceauto-exposure
set-outputcolor-output
vec4presented1.0