Attribute Wrangle
Run an expression on any input, once per point, pixel, or voxel. The expression runs on the GPU.
What it does
Runs a short expression across every element of the input: points, image pixels, volume voxels, distance-field samples or mesh vertices. The input type sets what is available to read and write. A point cloud gives @P (position), @Cd (colour), @N (normal) and @pscale; an image gives @Cd for pixel colour and @P.xy for pixel position; a volume gives @density; a distance field gives @dist. The expression compiles to run on the GPU across every element at once.
With Output Field on, the same expression evaluates as an analytic field instead of being baked to a fixed set of points.
When to use it
A custom operation with no dedicated node: displacement, colour remapping, conditional recolouring, procedural noise.
Turning an image into a 3D point cloud, driving
@P.zfrom pixel colour.A value sampled at any position rather than a fixed bake: turn on Output Field.
Blending or comparing two inputs, read as
@Cd1for images or sampled directly for fields.A value that keeps updating every simulation step, such as following foam or live particle colour: set Evaluate to Per Step.
| Parameter | Type | Default |
|---|---|---|
input | Any | — |
code | String | "@P.z = luminance(@Cd) * 10.0" |
output_field | Boolean | false |
input2 | Any | — |
evaluate | String | "Per Cook" |
output_scatter | Boolean | false |
scatter_width | Number | 256 |
scatter_height | Number | 256 |
scatter_channels | Number | 1 |
input3 | Any | — |
input4 | Any | — |
strength | Number | 1 |
Gotchas
With Output Field on, the field kind follows what is written: a single number gives a Scalar field, a 3-value write gives a Vector field, a 4-value write (with alpha) gives a Colour field. Writing to the distinctly-named @sdf attribute instead produces a Distance Field. An expression that is not field-compatible, for example one reading @Cd with nothing wired into the second input, falls back to the normal point-cloud output.
Reading a live simulation attribute, such as the density carried by a running fluid or cloth sim, defers evaluation to every step regardless of the Evaluate setting. Evaluate matters only for expressions that do not already depend on live sim state.
Write param("name", 1.0) anywhere in the expression and it becomes a numbered, editable pin on the node. Dragging it updates the value live, with no recompile delay.
Worked example
Add an Attribute Wrangle and wire an image into Input.
In the expression, write
@P.z = luminance(@Cd) * 100;to push each pixel into 3D depth based on its brightness.Turn on Output Field and instead write
@density = luminance(sample_input(0, @P));for a Scalar field version of the same idea, sampled at any position rather than baked to fixed points.Add
param("strength", 100.0)in place of the literal100and drag the new Strength pin to tune the effect without touching the code.
See also
Lua · p5.js · Shader · Attributes