Skip to content

Commit 92ba71e

Browse files
AlexZ005claude
andcommitted
[docs] shader graph: a guide, a node reference, and the Set Shader Uniform node
Documents the shader graph editor landing on core's feat/shader-graph-spike branch. - shader-graph.md - the guide. Opening it, selection-as-scope (one object = its own material, nothing selected = the scene default), all eight Surface taps, vertex displacement with its two honest limitations (lighting is not recalculated for the new shape, and the shadow is cast by the undisplaced mesh), content-hash textures and why that means an image travels once, why animated shaders need no network traffic at all, live uniforms vs recompiles, what happens to a broken graph mid-edit, the four save paths, the glTF export honesty note, the multi-slot refusal, what the Material panel does while a shader is active, and backends. - shader-nodes.md - the node reference, one table per palette GROUP rather than a page per node: 26 of the 46 are Math one-liners, so a page each would be stubs, and a grouped reference matches how the palette and right-click menu are organised. Inputs, outputs, parameters and defaults per node, then deeper sections for the nine that carry a real concept. The tables are generated from the app's catalog and a suite in core asserts they stay in step, so this page cannot describe a node that does not exist or miss one that does. - nodes/setuniform.md - Set Shader Uniform, in the same per-node style as its siblings: how to find a uniform's name in the editor, that only numbers can be driven (and to use a Gradient or Mix for colour), why it needs no message of its own, and a worked example - a crystal that glows as you approach. - nav entries for all three. Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 7d7019c commit 92ba71e

4 files changed

Lines changed: 361 additions & 0 deletions

File tree

docs/nodes/setuniform.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Set Shader Uniform
2+
3+
Writes one number inside an object's [shader graph](../shader-graph.md), so a trigger, a
4+
timer or a counter can drive how the material looks — a panel that heats up when you stand
5+
near it, a glow that pulses when something is picked up, dissolve that runs on a countdown.
6+
7+
**Output:** effect (wire into an [Object Selector](objectselector.md))
8+
9+
## Parameters
10+
11+
| Parameter | Default | Meaning |
12+
|---|---|---|
13+
| uniform | *(empty)* | the name of the value to write, as shown in the Shader editor |
14+
| value | 0 | the number to write (usually wired, not typed) |
15+
16+
## Finding the uniform name
17+
18+
A shader graph's numbers, colours and vectors each compile to a named value. To find the
19+
name:
20+
21+
1. open the **Shader editor** on the object,
22+
2. click the node whose parameter you want to drive (a **Float** node, say),
23+
3. read the **uniforms** list in the ⓘ info pane on the right — it shows names like
24+
`u_rgh_value`,
25+
4. paste that into this node's *uniform* field.
26+
27+
Only **numbers** can be driven this way. Colours and vectors are not yet supported, so to
28+
animate a colour, drive a number and turn it into a colour inside the graph — a
29+
[Gradient](../shader-nodes.md#gradient) or a **Mix** between two colours does this well,
30+
and is usually nicer to author anyway.
31+
32+
## How it behaves
33+
34+
Writing a uniform does **not** recompile the shader, so this is cheap enough to run every
35+
frame.
36+
37+
Each peer writes the value **locally**, and no message is sent. It does not need one: the
38+
value arrives through the flow graph, which is already deterministic and replicated, so
39+
every peer computes the same number and writes the same result. This is the same approach
40+
[Set Color](setcolor.md) takes.
41+
42+
If the object has no shader graph, or the name does not match anything in it, the node does
43+
nothing — it will not error or break the material.
44+
45+
## Practical example
46+
47+
A crystal that glows brighter as you approach:
48+
49+
1. Give the crystal a shader graph: **Float** (`0`) → Surface **emissive**, and a
50+
**Colour** → Surface **albedo**.
51+
2. Select the Float node and copy its uniform name from the ⓘ pane.
52+
3. In the crystal's flow: **Proximity** (radius 4) → **Map Range** (0–1 in, 3–0 out) →
53+
**Set Shader Uniform** (paste the name) → **Object Selector** picking the crystal.
54+
4. Walk towards it. The glow rises as you close in, on every peer's screen at once.
55+
56+
Swap Proximity for a [Timer](timer.md) or a [Counter](counter.md) and the same wiring
57+
gives you a timed dissolve or a charge-up that steps each time something happens.

docs/shader-graph.md

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# Shader Graph
2+
3+
Build a material out of nodes instead of sliders. A shader graph replaces what a
4+
material looks like — its colour, glow, roughness, surface detail, transparency, even
5+
where its vertices sit — and everything you author replicates to your peers and saves
6+
with the scene.
7+
8+
For the node-by-node reference, see [Shader Nodes](shader-nodes.md).
9+
10+
## Opening it
11+
12+
The Shader editor is a tab in the bottom dock, beside the Node editor, Explorer, UV
13+
editor and Animation:
14+
15+
- click **+** in the dock tab strip and choose **Shader editor**, or
16+
- right-click an object and pick **Edit shader**, or
17+
- open the object's properties and press **Open in Shader editor** in the Material
18+
section.
19+
20+
## Scope: this object, or the whole scene
21+
22+
There is no scope control to get wrong — **the selection is the control**:
23+
24+
| Selection | What you are editing |
25+
|---|---|
26+
| one object | that object's own material |
27+
| nothing selected | the **scene default**, which drives every object with no graph of its own |
28+
29+
The header always says which. An object with its own graph ignores the scene default,
30+
so the order is *own graph → scene default → the object's real material*.
31+
32+
## The Surface node
33+
34+
Every graph ends at one **Surface** node. Each of its inputs replaces one part of the
35+
material, and **anything you leave unconnected keeps the material's own value** — so a
36+
graph that only wires `roughness` changes nothing else.
37+
38+
| Input | What it replaces |
39+
|---|---|
40+
| albedo | the base colour (multiplied into it, like a texture would be) |
41+
| emissive | glow, added after lighting |
42+
| roughness | how rough or polished the surface is |
43+
| metalness | how metallic it is |
44+
| normal | surface detail — the direction the surface *appears* to face |
45+
| opacity | transparency; wiring it switches the material to blending |
46+
| ao | shades the indirect (ambient) light only |
47+
| position | moves the vertices themselves — see below |
48+
49+
### Vertex displacement
50+
51+
`position` is different from the others: it runs while the mesh's vertices are being
52+
placed, not while its pixels are being shaded. Wire a vector into it and every vertex
53+
moves by that amount, so **Noise → position** ripples a surface and **Vector 3 →
54+
position** shifts the whole object.
55+
56+
Because it happens at a different point in the pipeline, three things follow:
57+
58+
- **Normal** gives you the object-space normal there, which is what you displace *along*
59+
(multiply Noise by Normal to push a surface outwards rather than sideways).
60+
- **View direction**, **Fresnel** and **Normal map** cannot be used — there is no camera
61+
vector and no screen-space information while vertices are being placed. Wiring one in
62+
is refused with a message rather than producing a broken shader.
63+
- **UV** gives you the mesh's raw texture coordinates.
64+
65+
Two honest limitations, both shared with three.js's own displacement:
66+
67+
- lighting is **not** recalculated for the new shape, so a heavily displaced surface can
68+
look flatter than it is;
69+
- the **shadow** is cast by the undisplaced mesh.
70+
71+
## Textures
72+
73+
The **Texture** node samples an image from your [Explorer](explorer.md) library. Assign
74+
one by clicking the swatch on the node and picking a file, or by dragging an Explorer
75+
image card onto it. Hovering the swatch shows a bigger preview with the image's
76+
dimensions and size.
77+
78+
What the graph stores is the image's **content hash**, not the image. That means the
79+
picture travels to your peers **once** and is then reused — it is not re-sent every time
80+
you nudge a slider. A peer who does not have the image yet asks for it and shows the
81+
object untextured (not black) until it arrives.
82+
83+
Textures **tile** by default, which is what makes [Tiling & offset](shader-nodes.md#uv)
84+
and [Panner](shader-nodes.md#uv) work.
85+
86+
## Animated shaders stay in sync
87+
88+
Anything driven by the **Time** node — or by **Panner**, which uses the same shared clock —
89+
reads the time from a clock all peers agree on. Nobody sends "the shader is now at 3.2 seconds": each
90+
peer works it out and arrives at the same answer. That is why a scrolling texture or a
91+
pulsing glow looks identical on every screen with no network traffic at all.
92+
93+
## Editing while it runs
94+
95+
Numbers, colours and vectors on a node are **live uniforms**: dragging one changes the
96+
picture immediately without recompiling anything. Adding or rewiring nodes recompiles,
97+
which takes well under a millisecond.
98+
99+
If a graph is broken mid-edit, the object **keeps the last material that worked** and the
100+
error appears in a strip at the top of the tab, naming the node and the problem.
101+
102+
## Driving a shader from a behaviour graph
103+
104+
The [Set Shader Uniform](nodes/setuniform.md) node in the [Node editor](node-system.md)
105+
writes one of a graph's numbers, so a proximity trigger, a timer or a counter can drive a
106+
shader parameter. Select the node in the Shader editor and its info pane lists the uniform
107+
names to paste in.
108+
109+
## Saving, sharing and undo
110+
111+
- The **graph** is what replicates and what gets saved — never the compiled result — so
112+
the same graph produces the same pixels everywhere.
113+
- Graphs are stored in `.tpscene` files and sessions, and in the autosave.
114+
- A **glTF export** cannot carry a node material: the object is exported with the
115+
material it had before the graph, and a toast tells you what was dropped.
116+
- Every change is undoable, and a slider drag is one undo step rather than dozens.
117+
118+
## When an object cannot take a graph
119+
120+
Objects with **more than one material slot** are declined with an explanation rather than
121+
half-supported. Convert or split the mesh first if you need per-slot shaders.
122+
123+
## The Material section while a shader is active
124+
125+
Once a graph drives an object, its properties panel says so and hides the ordinary
126+
colour, material-type and texture rows — they would be editing a result that the next
127+
recompile discards. You get **Open in Shader editor** and **Detach** instead. Cast and
128+
receive shadow stay editable, because those are properties of the object rather than of
129+
the material.
130+
131+
Detach removes the object's own graph. If the look came from the **scene default** there
132+
is no per-object graph to remove, and the panel says so — edit or remove the scene graph
133+
instead.
134+
135+
## Compile backends
136+
137+
Graphs compile locally on every peer. The built-in compiler patches three.js's own
138+
shader, so lighting, shadows and fog keep working and adding a light to the scene affects
139+
shader-driven objects like everything else.
140+
141+
A module can register another compiler (a different lighting model, or a heavier one it
142+
ships itself). A graph remembers which backend it was authored for; a peer without that
143+
module compiles it with the built-in instead of failing, and gets the intended result as
144+
soon as the module is present.

0 commit comments

Comments
 (0)