Back to the referenceShader composer
Writing a shader as typed values, and the node graph a .shader file holds.
74 symbols
#compileShaderfunctionnacatamalon
compileShader(graph: TShaderGraph<S>) => TCompiledShader<S>
Turns a composed graph into the fields a material takes, in both languages.
The result spreads straight into createMaterial, and whichever backend draws it takes the half
it speaks. Nothing at the call site names a backend, and that is the point: the values are
typed, so the second language is a second walk over the graph rather than a translation, and the
two halves cannot drift apart because nobody wrote either.
On the way it works out anything used twice only once, reads each leaf the way its stage offers
it (and refuses one read where it does not exist), gathers every parameter into uniforms, and
writes each noise function once.
The family comes back in the type, so the result spreads into a material for sprites or for
models and the material knows which it is.
A sprite shader needs color and has no vertex stage. A model shader takes color, position
or both, and a stage left out keeps the engine's own. color may be a vec3 (alpha 1) or a
vec4; position is a vec3.
Parameters
graphTShaderGraph<S>The family, and the results.
Example
const Level = () => {
const glow = compileShader({
shader: 'mesh3d',
color: composerMix(composerSurface(), composerVec4(0.3, 0.7, 1, 1), composerFresnel(3)),
position: composerAdd(composerVertexPosition(), composerMul(composerVertexNormal(), composerUniform('swell', 0.1))),
});
const material = createMaterial({ tint: getColor('#e08a3a'), ...glow });
createMesh({ geometry: useIcoSphereGeometry(), material });
return createScene();
};
View source · shader_composer/compile_shader.ts:120#compileShaderGraphfunctionnacatamalon
compileShaderGraph(doc: TShaderGraphDoc, src: string) => TParsedShader
Compiles a .shader file into what a material needs: its hooks in both languages, its
parameters and their types. The same shape reading a .wgsl gives, so nothing that uses a
shader file can tell the two apart.
It writes no shader code of its own. It turns the file into the same values the composer
functions build and hands them to compileShader, so a graph drawn on a canvas and the same
graph written in code cannot drift, and every check the composer functions make applies to a
wired graph too.
Only what reaches an output is built: a node nothing is wired to adds nothing, so a canvas with a
few loose nodes on it still compiles. A loop is caught and named. An output left unwired keeps
the engine's own for that stage, so a new file is valid and its material draws with the engine's
shader until something is connected.
Parameters
docTShaderGraphDocThe graph, from parseShaderGraph.
srcstringWhere it came from, for the error messages.
Example
const src = '/shaders/glow.shader';
const parsed = compileShaderGraph(parseShaderGraph(await (await fetch(src)).text(), src), src);
View source · shader_composer/compile_shader_graph.ts:42#composerAbsvariablenacatamalon
composerAbs: (a: TComposerInput) => TComposerNode
The value without its sign, lane by lane.
View source · shader_composer/math.ts:143#composerAddvariablenacatamalon
composerAdd: TComposerBinaryOp
Adds lane by lane, a number spreading over a vector (composerAdd(color, 0.1) lightens every
channel). Two vectors of different sizes are an error.
View source · shader_composer/math.ts:106#composerCellularNoisefunctionnacatamalon
composerCellularNoise(pos: TComposerNode) => TComposerNode
Cell noise (f32): the distance to the nearest of a scatter of random points, which gives
cells, cracks or scales. Takes a vec2 or a vec3.
Parameters
posTComposerNodeWhere to read it: a vec2 or a vec3.
View source · shader_composer/noise.ts:180#composerCelShadefunctionnacatamalon
composerCelShade(value: TComposerNode, steps: TComposerInput) => TComposerNode
Cuts a gradient into steps flat bands, the cartoon look. Put the light through it for hard
lighting, or any other gradient. Same type in as out; more steps is smoother.
Parameters
valueTComposerNodeThe gradient to cut.
stepsTComposerInputHow many bands. Default 3.
View source · shader_composer/effects.ts:38#composerClampfunctionnacatamalon
composerClamp(value: TComposerInput, lo: TComposerInput, hi: TComposerInput) => TComposerNode
Keeps value between lo and hi, lane by lane. Numbers as bounds spread over value.
Parameters
valueTComposerInputWhat to keep inside.
loTComposerInputThe lowest it may be.
hiTComposerInputThe highest it may be.
View source · shader_composer/math.ts:335#composerCosvariablenacatamalon
composerCos: (a: TComposerInput) => TComposerNode
Cosine of each lane, in radians.
View source · shader_composer/math.ts:180#composerCrossfunctionnacatamalon
composerCross(a: TComposerNode, b: TComposerNode) => TComposerNode
A vector at right angles to two vec3s.
View source · shader_composer/math.ts:277#composerDistancefunctionnacatamalon
composerDistance(a: TComposerNode, b: TComposerNode) => TComposerNode
How far apart two points of the same size are (f32).
View source · shader_composer/math.ts:242#composerDivvariablenacatamalon
composerDiv: TComposerBinaryOp
Divides lane by lane, a number spreading over a vector.
View source · shader_composer/math.ts:134#composerDotfunctionnacatamalon
composerDot(a: TComposerNode, b: TComposerNode) => TComposerNode
The dot product of two vectors of the same size (f32): how much they point the same way, and
the heart of any lighting sum.
Parameters
bTComposerNodeThe other, the same size.
View source · shader_composer/math.ts:260#composerEmissivefunctionnacatamalon
composerEmissive() => TComposerNode
The light the material gives off by itself (vec3), so a graph can rebuild the engine's own
look exactly. Models only, colour stage.
View source · shader_composer/inputs.ts:106#composerFbmfunctionnacatamalon
composerFbm(pos: TComposerNode, octaves: number) => TComposerNode
Layers of noise, each twice as fine and half as strong as the one before (f32): the detailed,
natural kind, for terrain, smoke or lava. octaves is written into the shader, so it is a small
fixed number (4 unless you say). Takes a vec2 or a vec3.
Parameters
posTComposerNodeWhere to read it: a vec2 or a vec3.
octavesnumberHow many layers. Default 4.
View source · shader_composer/noise.ts:140#composerFloatfunctionnacatamalon
composerFloat(value: number) => TComposerNode
A constant number. The only kind of constant: vectors are made with composerVec2,
composerVec3 and composerVec4, which wrap their plain numbers in this on their own.
View source · shader_composer/constructors.ts:34#composerFloorvariablenacatamalon
composerFloor: (a: TComposerInput) => TComposerNode
The largest whole number not above each lane.
View source · shader_composer/math.ts:152#composerFractvariablenacatamalon
composerFract: (a: TComposerInput) => TComposerNode
What is left after the whole part (x - floor(x)), lane by lane: the basis of anything that
repeats or tiles.
View source · shader_composer/math.ts:162#composerFresnelfunctionnacatamalon
composerFresnel(power: TComposerInput) => TComposerNode
The rim term, from 0 where the surface faces the camera to 1 where it turns away (f32): the
start of a rim light, a hologram or a force field. A higher power pulls the rim in to the
silhouette.
It reads which way the surface faces and where the camera is, so it only exists in a model's
colour stage, and the compiler says so anywhere else.
Parameters
powerTComposerInputHow tightly the rim hugs the silhouette. Default 3.
View source · shader_composer/effects.ts:24#composerLengthfunctionnacatamalon
composerLength(a: TComposerNode) => TComposerNode
How long a vector is (f32).
View source · shader_composer/math.ts:225#composerLightfunctionnacatamalon
composerLight() => TComposerNode
How much light reaches this point, and of what colour (vec3).
It is handed over on its own so a graph can light things its own way, in hard bands or with
a rim. The engine's own look is the surface times this, plus composerEmissive. The light is
worked out at the corners and blended in between, as the consoles of the era did. Models only,
colour stage.
View source · shader_composer/inputs.ts:95#composerMaxvariablenacatamalon
composerMax: TComposerBinaryOp
The larger of two values, lane by lane. A number spreads over a vector.
View source · shader_composer/math.ts:317#composerMinvariablenacatamalon
composerMin: TComposerBinaryOp
The smaller of two values, lane by lane. A number spreads over a vector.
View source · shader_composer/math.ts:303#composerMixfunctionnacatamalon
composerMix(a: TComposerInput, b: TComposerInput, t: TComposerInput) => TComposerNode
Blends from a to b by t: 0 gives a, 1 gives b. a and b are the same size, and t
is either a number or that size too.
Parameters
aTComposerInputWhat 0 gives.
bTComposerInputWhat 1 gives.
tTComposerInputHow far from a to b.
View source · shader_composer/math.ts:352#composerModvariablenacatamalon
composerMod: TComposerBinaryOp
The remainder the way shader authors expect it, x - y * floor(x / y), which always takes the
sign of y. Built from the pieces above, because WGSL's own % keeps the sign of x instead
and the two backends would disagree on negative numbers. A number as y spreads over x.
View source · shader_composer/math.ts:426#composerMulvariablenacatamalon
composerMul: TComposerBinaryOp
Multiplies lane by lane, a number spreading over a vector (composerMul(color, 2) doubles the
brightness; two vectors multiply lane by lane).
View source · shader_composer/math.ts:125#composerNormalizefunctionnacatamalon
composerNormalize(a: TComposerNode) => TComposerNode
The same direction, one unit long. Vectors only.
View source · shader_composer/math.ts:209#composerOneMinusfunctionnacatamalon
composerOneMinus(a: TComposerInput) => TComposerNode
1 - x, lane by lane: the opposite of a mask or of a falloff, in one step of a pipe.
View source · shader_composer/math.ts:441#composerPipefunctionnacatamalon
composerPipe(seed: TComposerInput, steps: TComposerStep[]) => TComposerNode
Passes a value through a list of steps, left to right, so a long expression reads in the order
it happens instead of from the inside out.
composerPipe(x, composerMul(2), composerAdd(1), composerSin) reads "take x, double it, add one,
then the sine", and is exactly composerSin(composerAdd(composerMul(x, 2), 1)). Any one-operand
function is a step as it is, and the two-operand ones that put the value on the left
(composerAdd, composerMul, composerPow...) become one when given a single operand. For
anything else, a small function (n) => ... is a step too.
Parameters
seedTComposerInputThe value to start with.
stepsTComposerStep[]What to do to it, in order.
Example
// 0.5 + 0.5 * sin(uv.y * lineCount + time * speed)
const bands = composerPipe(
composerY(composerUv()),
composerMul(composerUniform('lineCount', 120)),
composerAdd(composerMul(composerTime(), composerUniform('speed', 6))),
composerSin,
composerMul(0.5),
composerAdd(0.5),
);
View source · shader_composer/pipe.ts:34#composerPowvariablenacatamalon
composerPow: TComposerBinaryOp
base to the power of exp, lane by lane. A number as exp spreads over base.
View source · shader_composer/math.ts:291#composerReflectfunctionnacatamalon
composerReflect(i: TComposerNode, n: TComposerNode) => TComposerNode
Bounces the direction i off a surface facing n. Both vectors of the same size.
Parameters
iTComposerNodeThe direction that arrives.
nTComposerNodeThe way the surface faces.
View source · shader_composer/math.ts:410#composerResolutionfunctionnacatamalon
composerResolution() => TComposerNode
The game's size in pixels (vec2), which the engine writes for every material. For keeping a
pattern square, or for effects measured in pixels.
View source · shader_composer/inputs.ts:37#composerSaturatefunctionnacatamalon
composerSaturate(a: TComposerInput) => TComposerNode
Keeps each lane between 0 and 1, in one step of a pipe. Short for composerClamp(x, 0, 1).
View source · shader_composer/math.ts:452#composerSignvariablenacatamalon
composerSign: (a: TComposerInput) => TComposerNode
The sign of each lane: -1, 0 or +1.
View source · shader_composer/math.ts:198#composerSimplexNoisefunctionnacatamalon
composerSimplexNoise(pos: TComposerNode) => TComposerNode
Smooth noise at a position (f32, 0 to 1): the usual source of anything organic, like clouds,
flowing water or a dissolve mask. Takes a vec2 or a vec3. Scale the position to change how
busy it is, and add composerTime() to move it.
Parameters
posTComposerNodeWhere to read it: a vec2 or a vec3.
View source · shader_composer/noise.ts:125#composerSinvariablenacatamalon
composerSin: (a: TComposerInput) => TComposerNode
Sine of each lane, in radians.
View source · shader_composer/math.ts:171#composerSmoothstepfunctionnacatamalon
composerSmoothstep(edge0: TComposerInput, edge1: TComposerInput, value: TComposerInput) => TComposerNode
A soft cut: eases from 0 to 1 as value goes from edge0 to edge1. Numbers as edges spread
over value.
Parameters
edge0TComposerInputWhere the ramp starts.
edge1TComposerInputWhere it ends.
valueTComposerInputWhat is ramped.
View source · shader_composer/math.ts:391#composerSqrtvariablenacatamalon
composerSqrt: (a: TComposerInput) => TComposerNode
Square root of each lane.
View source · shader_composer/math.ts:189#composerStepfunctionnacatamalon
composerStep(edge: TComposerInput, value: TComposerInput) => TComposerNode
A hard cut: 0 where value is below edge, 1 from there on, lane by lane. A number as edge
spreads over value.
Parameters
edgeTComposerInputWhere the cut is.
valueTComposerInputWhat is cut.
View source · shader_composer/math.ts:374#composerSubvariablenacatamalon
composerSub: TComposerBinaryOp
Subtracts lane by lane, a number spreading over a vector.
View source · shader_composer/math.ts:115#composerSurfacefunctionnacatamalon
composerSurface() => TComposerNode
The colour the engine would have drawn here (vec4): the picture, already read and already
tinted (and on a model, painted by its corners' colour), before any light. Where most colour effects start. Colour stage only.
View source · shader_composer/inputs.ts:48#composerSwizzlefunctionnacatamalon
composerSwizzle(value: TComposerNode, mask: string) => TComposerNode
Picks components of a vector by their letters ('bgr', 'xy'). The number of letters, one to
four, is the size of the result, and a single letter gives a plain number.
The letters come from one set, xyzw or rgba, never both in one mask, and each must exist in
the value it reads: both are checked here rather than left to the card.
Parameters
valueTComposerNodeThe vector to read.
maskstringOne to four letters from xyzw or rgba.
View source · shader_composer/constructors.ts:105#composerTextureSamplefunctionnacatamalon
composerTextureSample(coord: TComposerNode) => TComposerNode
Reads the material's own picture, tinted, at any coordinate (vec4). What waves, pixelation, a
colour split or a blur are made of: composerSurface() is this read at the fragment's own
coordinate. Colour stage only.
Parameters
coordTComposerNodeWhere to read the picture, in 0-1.
View source · shader_composer/inputs.ts:156#composerTimefunctionnacatamalon
composerTime() => TComposerNode
Seconds since the game started (f32), which the engine writes for every material. Anything that
moves on its own is driven by this, with no code per frame.
View source · shader_composer/inputs.ts:26#composerUniformfunctionnacatamalon
composerUniform(name: string, value: number | number[]) => TComposerNode
A parameter with a name, which the game can change while it runs.
What value looks like sets its type (a number, or a list of two, three or four) and is what it
starts at. compileShader gathers every parameter of the graph into the material's uniforms,
so writing material.uniforms.<name> moves it on the next frame. time and resolution are
taken: the engine writes those, and they are read with composerTime and composerResolution.
Parameters
namestringWhat the game calls it: material.uniforms.<name>.
valuenumber | number[]What it starts at. A number, or a list of two, three or four.
View source · shader_composer/inputs.ts:173#composerUvfunctionnacatamalon
composerUv() => TComposerNode
The texture coordinate (vec2). There in every stage; in a model's vertex graph it is the
corner's own.
View source · shader_composer/inputs.ts:15#composerVec2functionnacatamalon
composerVec2(args: TComposerInput[]) => TComposerNode
A vector of two. Two numbers, one vec2, or one number copied into both.
Parameters
argsTComposerInput[]Two numbers or nodes, one vec2, or one number for both.
View source · shader_composer/constructors.ts:65#composerVec3functionnacatamalon
composerVec3(args: TComposerInput[]) => TComposerNode
A vector of three, the everyday one for colours and directions. Three numbers, a vec2 and a
number, one vec3, or one number copied into all three.
Parameters
argsTComposerInput[]Three numbers or nodes, a smaller vector and the rest, or one number for all.
View source · shader_composer/constructors.ts:77#composerVec4functionnacatamalon
composerVec4(args: TComposerInput[]) => TComposerNode
A vector of four, usually a colour with its alpha. Four numbers, a vec3 and a number (colour
and alpha), one vec4, or one number copied into all four.
Parameters
argsTComposerInput[]Four numbers or nodes, smaller vectors and the rest, or one number for all.
View source · shader_composer/constructors.ts:89#composerVertexColorfunctionnacatamalon
composerVertexColor() => TComposerNode
The colour painted on the model's corners (vec4), smeared across each triangle. Models only, in
either stage.
It is already part of composerSurface. On its own it is for using the paint as something other
than colour: how much a corner sways in the wind, or how much of a second picture shows through,
which is how the era blended grass into a dirt path without a second texture pass.
View source · shader_composer/inputs.ts:143#composerVertexNormalfunctionnacatamalon
composerVertexNormal() => TComposerNode
Which way the corner faces, in the model's own space (vec3). Moving a corner along it swells
the model. Models only, vertex stage.
View source · shader_composer/inputs.ts:128#composerVertexPositionfunctionnacatamalon
composerVertexPosition() => TComposerNode
Where the corner is, in the model's own space (vec3): the value a position graph moves, to
make it wobble, swell or jitter. Models only, vertex stage.
View source · shader_composer/inputs.ts:117#composerViewDirfunctionnacatamalon
composerViewDir() => TComposerNode
The direction from this point towards the camera, one unit long (vec3). What a rim or a shine
is worked out from. Models only, colour stage.
View source · shader_composer/inputs.ts:80#composerWfunctionnacatamalon
composerW(value: TComposerNode) => TComposerNode
The fourth component of a vector, as a number. Short for composerSwizzle(v, 'w').
Parameters
valueTComposerNodeThe vector.
View source · shader_composer/constructors.ts:166#composerWorldNormalfunctionnacatamalon
composerWorldNormal() => TComposerNode
Which way the surface faces, in the world (vec3). Models only, colour stage; in a vertex graph
use composerVertexNormal.
View source · shader_composer/inputs.ts:59#composerWorldPosfunctionnacatamalon
composerWorldPos() => TComposerNode
Where this point of the surface is, in the world (vec3). Models only, colour stage.
View source · shader_composer/inputs.ts:69#composerXfunctionnacatamalon
composerX(value: TComposerNode) => TComposerNode
The first component of a vector, as a number. Short for composerSwizzle(v, 'x').
Parameters
valueTComposerNodeThe vector.
View source · shader_composer/constructors.ts:133#composerYfunctionnacatamalon
composerY(value: TComposerNode) => TComposerNode
The second component of a vector, as a number. Short for composerSwizzle(v, 'y').
Parameters
valueTComposerNodeThe vector.
View source · shader_composer/constructors.ts:144#composerZfunctionnacatamalon
composerZ(value: TComposerNode) => TComposerNode
The third component of a vector, as a number. Short for composerSwizzle(v, 'z').
Parameters
valueTComposerNodeThe vector.
View source · shader_composer/constructors.ts:155#parseShaderGraphfunctionnacatamalon
parseShaderGraph(source: unknown, src: string) => TShaderGraphDoc
Reads a .shader file and checks its shape.
It takes the text of the file or JSON already parsed, because both callers exist: a game loading
it has text in hand, and an editor holds a graph it has just changed and wants checked before it
writes it. A broken shape (a node with no id, a place that is not two numbers, an unknown family)
is refused here, naming the node. What the graph means (a kind of node nobody knows, a wire
into an input that does not exist, a loop) is compileShaderGraph's, which knows the catalogue.
Parameters
sourceunknownThe file's text, or its JSON.
srcstringWhere it came from, for the error messages.
Example
const graph = parseShaderGraph(await (await fetch('/shaders/glow.shader')).text(), '/shaders/glow.shader');
View source · shader_composer/document.ts:164#SHADER_GRAPH_FORMATvariablenacatamalon
SHADER_GRAPH_FORMAT: 1
The version of the .shader format. It only goes up for a change an older reader could not
survive; a new optional field does not move it.
View source · shader_composer/document.ts:19#TCompiledShadertypenacatamalon
What compileShader gives back: exactly the fields createMaterial takes, so it is spread
straight in, createMaterial({ ...compiled }).
A stage left at the engine's own is missing, the same as not writing it in createMaterial.
uniforms holds every parameter found in the graph, ready to be changed while the game runs.
Properties
shaderSfragmentoptionalstringThe colour hook in WGSL, missing when the graph has no color.
vertexoptionalstringThe vertex hook in WGSL, missing when the graph has no position.
fragmentGlsloptionalstringThe same two hooks in GLSL, always, never on request.
That is what makes a composed shader work on both backends by construction rather than when
somebody remembers to ask. The values are typed, so the second language is a second walk
over the same graph and not a translation of the first one's text.
vertexGlsloptionalstring
View source · shader_composer/types/t_shader_graph.ts:34#TComposerBinaryOptypenacatamalon
TComposerBinaryOp: (a: TComposerInput, b: TComposerInput) => TComposerNode
The two ways to call a two-operand node: both operands give a value, one gives a step for
composerPipe, with the value coming down the pipe as the first operand.
View source · shader_composer/math.ts:66#TComposerInputtypenacatamalon
TComposerInput: TComposerNode | number
What an operand of a composer function may be: another value, or a plain number, which becomes a
constant. So composerAdd(composerX(composerUv()), 0.5) needs no composerFloat(0.5).
View source · shader_composer/types/t_composer_node.ts:102#TComposerNodetypenacatamalon
One value in a composed shader: what kind of value it is, and how to build it from the values it
depends on.
It is plain data, never a closure. kind picks how it is written out, params carries its
literal operands and deps the values it is made from. That is what lets a graph be written to
JSON and read back, the same rule every other piece of state in the engine follows.
Never built by hand: the composer* functions fill these fields consistently and check their
operands as they go.
Properties
kindstringHow it is written out: literal, input, uniform, texture, construct, swizzle, binop or call.
typeTUniformTypeWhat it evaluates to. Every operation checks its operands against this.
depsTComposerNode[]The values it is made from, in argument order.
paramsoptionalnumber | string[]Literal operands: a number, an operator, a swizzle mask or the name of the function called.
inputoptionalTInputKindFor a leaf, which value of the running shader it reads.
uniformoptional{ name, value }For a parameter, the name the shader reads it by and the value it starts at.
helpersoptionalTHelperDef[]Functions this node needs written at the top of the shader.
View source · shader_composer/types/t_composer_node.ts:63#TComposerSteptypenacatamalon
TComposerStep: (value: TComposerNode) => TComposerNode
One stage of composerPipe: it takes the value flowing through and returns the next.
Every one-operand function already is one, and the two-operand ones become one when given a
single operand (composerMul(2)), so they chain without wrapping.
View source · shader_composer/types/t_composer_node.ts:114A note on the canvas: a titled rectangle behind the nodes, for grouping part of a graph and
saying what it is for.
It has an array of its own rather than being a kind of node, because it is not one: no wires, no
value, no place in the graph. As a node, the compiler, the type check and the previews would each
need an exception for the one entry that is not part of the shader.
View source · shader_composer/types/t_shader_graph_doc.ts:87#TGraphEdgeDoctypenacatamalon
A wire: output out of node from feeds input in of node to.
By name rather than by position, so adding an input to a kind of node cannot quietly rewire
every file that uses it.
Properties
fromstringoutstringtostringinstring
View source · shader_composer/types/t_shader_graph_doc.ts:54#TGraphNodeDoctypenacatamalon
One node in a saved graph: which kind of node it is, where it sits on the canvas, and its
literals.
It does not describe itself. Its inputs, outputs and code all come from the catalogue, looked
up by type, so a file stays small and a node learns something new when the catalogue changes
rather than when every file is rewritten.
pos belongs to the editor and is in the file on purpose, like a box's place in a scene: how a
graph is laid out is part of what it says to whoever reads it.
Properties
idstringtypestringWhich entry of the catalogue this is.
pos[number, number]Where it sits on the canvas, [x, y].
paramsoptionalRecord<string, TParamValue>Its literals. One left out takes the catalogue's value.
View source · shader_composer/types/t_shader_graph_doc.ts:28#TGraphTargettypenacatamalon
TGraphTarget: Exclude<TMaterialShader, 'post'>
The families a graph file can be for: the two that draw things, deliberately not every family a
material has.
'post' is missing because no node writes a screen-wide effect, so a graph claiming it would
compile to nothing. Spelling it as its own type makes that gap a compile error in the one place
that could open it, and the reader refuses the same value, so the two cannot disagree.
View source · shader_composer/types/t_shader_graph_doc.ts:73#THelperDeftypenacatamalon
A function a node needs written once at the top of the shader (the noise functions, for
instance), kept only once however many nodes ask for it.
Both languages ride on the node rather than living in a table per language looked up by name.
A helper exists because a node needs it, and keeping the two apart would let a graph ask for
a helper one language never defined: a failure that shows up as a shader that does not compile
in somebody's browser, rather than as a missing entry while writing it.
Properties
namestringwgslstringglslstring
View source · shader_composer/types/t_composer_node.ts:42#TInputKindtypenacatamalon
TInputKind: 'uv' | 'time' | 'resolution' | 'surface' | 'worldNormal' | 'worldPos' | 'viewDir' | 'light' | 'emissive' | 'vertexPosition' | 'vertexNormal' | 'vertexColor'
A value a leaf reads from the running shader: a function argument (uv, pos), one of the
values the engine writes for every material (time), or what the model's colour hook is told
about the place it is colouring (worldNormal, light).
Each one is only there in some stages, and the compiler refuses a leaf read where it does not
exist (light in a vertex graph, say) instead of emitting code the card then rejects.
View source · shader_composer/types/t_composer_node.ts:15#TParamValuetypenacatamalon
TParamValue: number | number[] | string
A literal a node keeps in its own body instead of receiving through a wire: a swizzle mask, a
number of octaves, a colour. Only what JSON keeps intact and an inspector can show a control for.
View source · shader_composer/types/t_shader_graph_doc.ts:11#TShaderGraphtypenacatamalon
What compileShader is handed: the family the shader is for, and up to two results.
color is what the colour hook returns and position is where the vertex hook moves a corner
to (models only). Leave one out and that stage keeps the engine's own.
The family is kept in the type, so what comes out is known to be a sprite's or a model's.
Properties
shaderScoloroptionalTComposerNodepositionoptionalTComposerNode
View source · shader_composer/types/t_shader_graph.ts:17#TShaderGraphDoctypenacatamalon
A .shader file: a shader drawn as nodes on a canvas.
It sits next to a hand-written .wgsl and next to a graph composed in code, and all three end
up as the same thing, so a material cannot tell which one it was given. The file holds no shader
source in any language, only nodes and wires as plain JSON.
target means what @shader means at the top of a .wgsl: it picks the hooks, so it is not a
preference but part of what gets compiled.
Properties
formatnumberkind'shadergraph'
View source · shader_composer/types/t_shader_graph_doc.ts:121