Primary target surface
These rendering routes are generated from canonical source. Native-WebGPU acceptance remains separate from entrypoint availability.
Procedural materials for coherent NodeMaterial PBR systems in Three.js WebGPU/TSL. Use when a task needs shared identities across PBR channels, must select UV, array, atlas, or projected mapping, needs footprint-filtered normals and specular AA, or needs dynamic per-instance material state with explicit output ownership.
These rendering routes are generated from canonical source. Native-WebGPU acceptance remains separate from entrypoint availability.
This skill contributes to the following cross-skill owner graphs.
Source hashes, claim verdicts, promoted same-lab media, fixed routes, exact tier contracts, and current limitations.
Materials are authored as PBR identity fields: albedo, roughness, and normal all derive from shared procedural causes. Surface normals come from height derivatives — screen-space derivatives give filtering for free:
$$\mathbf n = \operatorname{normalize}\!\big(\mathbf n_g - \partial_x h\,\mathbf t - \partial_y h\,\mathbf b\big)$$Specular antialiasing widens roughness where the normal field varies inside a pixel (Kaplanyan-style variance from derivatives), preventing distant sparkle:
$$\alpha' = \sqrt{\alpha^2 + \operatorname{clamp}\!\big(\|\partial_x \mathbf n\|^2 + \|\partial_y \mathbf n\|^2\big)}$$Triplanar projection blends three axis-aligned samples with a sharpened weight $w_i = |n_i|^k / \sum |n_j|^k$, and emissive surfaces (lava) map temperature through a blackbody-inspired ramp so brightness lives in scene-relative HDR units, not display units.
Only schema-v2 labs with accepted runtime and evidence contracts appear here. Other source directories remain visible through the demo registry without being promoted to runnable proof.
Every image identifies what it proves. Page screenshots demonstrate the published presentation only; generated inputs demonstrate asset channels only; rendering acceptance still requires same-lab readback and a schema-v2 bundle.
0 published imagesThe complete SKILL.md as loaded by agents, rendered verbatim.
Build a cause graph, not a collection of channel effects:
stable coordinates -> structural causes -> identity weights
-> causal modifiers -> filtered microstructure
-> NodeMaterial PBR slots -> final-image owner
Use MeshStandardNodeMaterial for standard opaque/emissive PBR and
MeshPhysicalNodeMaterial only when its extra lobes or transport properties are
part of the surface. Keep Three.js lighting, environment, shadows, and energy
handling by assigning node slots instead of replacing the whole fragment output.
For multi-system scenes, $threejs-choose-skills is an optional coordinator.
Fields own shared scalar/vector causes, geometry owns silhouettes, water owns
surface/transport, and the final-image pipeline owns tone mapping and display
conversion. Consume each dynamic or cross-system cause with declared units,
coordinate/frame convention, producer and consumer owners, revision,
spatial/temporal support and filter, validity domain, error bound, update
cadence, and staleness rule. A visual material state does not become another
simulation owner.
Initialize and gate the renderer before allocating storage, dispatching compute-written cause maps, or compiling storage-backed material branches:
await renderer.init();
if (renderer.backend.isWebGPUBackend !== true) {
throw new Error('Native WebGPU is required for procedural material GPU branches.');
}
const { features, limits } = renderer.backend.device;
Select sampled/storage bindings, writable formats, and filtering from those initialized features and limits.
Choose UV, object, world, radial, or generated-texture space from the physical or authored cause. Record scale in meters or declared art units. Mixing spaces is valid only for distinct causes, such as world-height wetness over object-space grain.
Define normalized material identity weights and a response bundle per identity:
linear base reflectance
roughness alpha and metal/dielectric endpoint
resolved height/normal spectrum plus removed variance
causal modifiers such as wetness, wear, heat, or coverage
semantic/material ID and diagnostic color
All channels use the same filtered weights. Hard semantic eligibility remains
separate from visible blend width. Blend alpha=roughness^2, then recover
roughness with sqrt(alpha) when one GGX lobe approximates a subpixel mixture.
When terrain or seabed is involved, read substrate and water ownership before wiring coast distance, wetness, shallow-water, foam, or caustics.
This step is complete when every PBR channel traces to named causes and identity weights in one coordinate/scale contract, with a hard semantic fallback for any zero-weight region.
Choose in this order:
Count bindings and executed samples separately. Installed r185
triplanarTexture() performs three projected samples per bound texture and
uses absolute-normal weights; it does not reorient tangent-space normals or
provide stochastic tiling. Arrays/atlases reduce bindings, not sample count.
Read mapping and filtering before using an atlas, texture array, triplanar mapping, or stochastic tiling.
This step is complete when the selected mapping solves the observed defect, every texture's color/data semantics and mip policy are explicit, and compiled binding/sample counts fit the target pipeline with measured value for added taps.
Own only the slots required by the material:
colorNode linear identity color and causal shifts
roughnessNode identity alpha plus filtered modifiers
metalnessNode conductor/dielectric identity
normalNode normalMap, texture bump, or shared-height gradient
aoNode local cavity/contact term
opacity/mask/alphaTest cutout or dissolve
emissiveNode actual scene-linear emitted radiance
positionNode visible local displacement
castShadowPositionNode matching caster displacement
castShadow/maskShadow matching cutout or dissolve
In r185, receivedShadowPositionNode is a separate world-space receiver
override; leave it unset unless that replacement is explicitly derived and
validated. Visible and caster displacement share one local-space cause. Emission
feeds the HDR material result; bloom and tone mapping remain downstream owners.
Data textures use NoColorSpace; authored color textures use
SRGBColorSpace; scene-linear generated color remains linear. Keep one tone-map
and output-conversion owner through RenderPipeline.outputColorTransform or one
renderOutput().
This step is complete when every owned slot has one cause, visible/shadow masks and displacement agree, color/data encodings are correct, and no material node duplicates final output conversion.
Filter height/normal bands before perturbing the normal. Fragment surface gradients run in derivative-uniform control flow; vertex/compute displacement uses analytic or stored gradients. Preserve normal mean plus variance across mips instead of normalizing the mean and discarding its length.
Three.js r185 already adds geometric-normal variation in getRoughness().
Custom specular AA adds only unresolved material-detail variance. Read
derivative normals and specular AA
before adding procedural bump, custom normal filtering, or roughness variance.
This step is complete when all retained bands pass the projected footprint, removed slope/normal variance is accounted for exactly once, and a no-post close/mid/far comparison rejects distance-dependent sharpening and grazing sparkle.
One material graph serves a batch. Static instance variation uses attributes; hot GPU-owned variation uses storage-backed instance data only when its measured update/access pattern wins. Dissolve, wetness, variant, or lifetime fields drive visible and shadow masks from the same stable object/world cause.
Cause maps use the procedural-fields direct-versus-bake gate. Static maps build
once; dynamic maps update at their owner cadence and invalidate dependent mips.
Compute submission precedes the consuming render. In r185, computeAsync() is
not a GPU-completion fence.
State generations remain immutable while referenced by a frame. Resize, material identity changes, coordinate changes, map encoding changes, and device loss invalidate their dependent history, bindings, and diagnostics. Every material, texture, storage resource, and generated variant has a disposal owner.
This step is complete when one owner advances each dynamic cause, each instance record has stable identity and reset behavior, and no per-object material clone or frame-critical CPU readback is needed.
Expose coordinate mode/scale, identity weights and fallback, each structural cause, mapping weights/mip/gutter, binding and sample counts, roughness before and after AA, normal mean/variance, visible/caster parity, raw emission, no-post beauty, and final post result.
Verify close/mid/far and motion views; conductor/dielectric endpoints; atlas gutters under selected filtering; compiled stage limits; color-space flags; stable instance/shadow behavior; and target whole-frame timing/bytes when performance is claimed.
This step is complete when every PBR identity, mapping branch, filtered-normal branch, dynamic state, shadow path, color conversion, resource lifetime, and claimed target budget has direct diagnostic evidence.
The material system is complete when one shared cause/identity graph feeds all owned PBR slots; mapping and filtering decisions are evidence-backed; material detail is stable across footprint and motion; dynamic state has one owner and reset path; and raw material output, shadows, post, and resource lifetimes agree.
Preserved concept proxies and generated-asset previews. They are excluded from primary completion counts and link to the canonical lab through the schema-v2 registry.