Runs your own WGSL compute shader on the GPU to generate data — vertex positions, particle state, a simulation step — that the rest of the scene reads.
Declarative element:
<sk-compute-node>
Global: available as sk.ComputeNode inside a scene <script>.
The compute node is the concrete member of the AbstractComputeNodecompute-and-custom-WGSL family: it runs its own compute dispatch on the GPU
timeline — its own command buffer, possibly multi-step (steps-per-frame) and
stateful / self-re-arming (continuous) — decoupled from any consumer.
Consumers read its TYPED outputs by key (output.0 …) via a
compute-node="#id" reference on a compute-buffer-* source.
The element owns the binding ABI (group 0): the record-typed output
storage array, the 32-byte params uniform
(time/progress/output_size/output_count/output_stride), and the
packed named-uniform block (<sk-wgsl-uniform> children, read via the
generated skUniform_<name>() accessors). The author supplies ONLY the
@compute @workgroup_size(…) fn main kernel — declaring bindings in
author WGSL is a validation error.
Outputs are slices of one shared buffer, padded so each slice starts on a
256-byte boundary (minStorageBufferOffsetAlignment); records for output
i live at [i * output_stride, i * output_stride + output_size).
A kernel writes its OWN slice through output (invocation-owned, so
race-free), but reads any SIBLING slice through previous — a per-step
snapshot of output the scaffold also binds at group 0. Cross-slice reads
through output race the sibling invocation's own write and are undefined
per the WGSL spec; previous holds the committed previous-step state, so a
neighbour-reading continuous sim (e.g. n-body) evolves deterministically
regardless of GPU invocation order.
constructor(config?: { wgsl?: string; src?: string; outputKind?: ComputeNodeOutputKind; outputCount?: number; outputSize?: number; stepsPerFrame?: number; continuous?: boolean; id?: string; x?: number; y?: number; z?: number; h?: number; p?: number; b?: number; quaternion?: Quaternion; sx?: number; sy?: number; sz?: number; s?: number; class?: string; style?: string })
Inherited from: SceneNode, SkenraAnimatable
— see those pages for inherited members.
| Property | Type | Default | Description | Declared by |
|---|---|---|---|---|
wgsl |
string |
"" |
Inline WGSL kernel. Ignored while src is set. |
ComputeNode |
src |
string |
— | External WGSL source URL (the src attribute), or null if none. |
ComputeNode |
outputKind |
ComputeNodeOutputKind |
"spline-polyline" |
The typed output contract (fixes record layout and handle type). | ComputeNode |
outputCount |
number |
1 |
Number of typed outputs (keys output.0 … output.N-1). |
ComputeNode |
outputSize |
number |
1 |
Records per output (e.g. vertices per polyline). | ComputeNode |
stepsPerFrame |
number |
1 |
Compute dispatches per frame (sub-steps). | ComputeNode |
continuous |
boolean |
false |
Whether the node re-arms itself every frame (continuous simulation) | ComputeNode |
idconfig-only |
string |
— | Unique identifier for the node, reflected to the host id attribute. |
SceneNodeConfig |
x |
number |
0 |
Gets the X position component. | SceneNode |
y |
number |
0 |
Gets the Y position component. | SceneNode |
z |
number |
0 |
Gets the Z position component. | SceneNode |
h |
number |
0 |
Gets the heading (Y-axis) rotation in radians. | SceneNode |
p |
number |
0 |
Gets the pitch (X-axis) rotation in radians. | SceneNode |
b |
number |
0 |
Gets the bank (Z-axis) rotation in radians. | SceneNode |
quaternion |
Quaternion |
— | Gets the rotation as a quaternion. | SceneNode |
sx |
number |
1 |
Gets the X-axis scale factor. | SceneNode |
sy |
number |
1 |
Gets the Y-axis scale factor. | SceneNode |
sz |
number |
1 |
Gets the Z-axis scale factor. | SceneNode |
sconfig-only |
number |
— | Uniform scale factor for all axes (overrides sx, sy, sz if provided) | SceneNodeConfig |
classconfig-only |
string |
— | Standard HTML class applied to the node host at construction |
SceneNodeConfig |
styleconfig-only |
string |
— | Standard inline style applied to the node host at construction |
SceneNodeConfig |
| Property | Type | Default | Description | Declared by |
|---|---|---|---|---|
outputStrideread-only |
number |
— | Records per output slice after 256-byte-alignment padding — the | ComputeNode |
hasEffectiveWGSLread-only |
boolean |
— | Whether usable effective WGSL is available. false while a src is |
ComputeNode |
hRad |
number |
0 |
Gets the heading (Y-axis) rotation in radians. | SceneNode |
pRad |
number |
0 |
Gets the pitch (X-axis) rotation in radians. | SceneNode |
bRad |
number |
0 |
Gets the bank (Z-axis) rotation in radians. | SceneNode |
hDeg |
number |
0 |
Gets the heading (Y-axis) rotation in degrees. | SceneNode |
pDeg |
number |
0 |
Gets the pitch (X-axis) rotation in degrees. | SceneNode |
bDeg |
number |
0 |
Gets the bank (Z-axis) rotation in degrees. | SceneNode |
xBasebase value |
number |
— | Gets the base (non-animated) value of X position. | SceneNode |
yBasebase value |
number |
— | Gets the base (non-animated) value of Y position. | SceneNode |
zBasebase value |
number |
— | Gets the base (non-animated) value of Z position. | SceneNode |
hBasebase value |
number |
0 |
Gets the base (non-animated) value of heading (Y-axis rotation). | SceneNode |
pBasebase value |
number |
0 |
Gets the base (non-animated) value of pitch (X-axis rotation). | SceneNode |
bBasebase value |
number |
0 |
Gets the base (non-animated) value of bank (Z-axis rotation). | SceneNode |
quaternionBasebase value |
Quaternion |
— | Gets the base (non-animated) quaternion rotation. | SceneNode |
sxBasebase value |
number |
— | Gets the base (non-animated) value of X-axis scale. | SceneNode |
syBasebase value |
number |
— | Gets the base (non-animated) value of Y-axis scale. | SceneNode |
szBasebase value |
number |
— | Gets the base (non-animated) value of Z-axis scale. | SceneNode |
draggable |
boolean |
false |
Gets whether this node can be dragged. | SceneNode |
parentread-only |
SceneNode | null |
— | The parent node in the scene graph, or null at the root. |
SceneNode |
sceneread-only |
any |
— | Gets the Scene this node belongs to, if any. | SceneNode |
posread-only |
Point3D |
— | Gets the world-space position of this node. | SceneNode |
matrixread-only |
Float32Array<ArrayBufferLike> |
— | Gets the computed 4x4 transformation matrix. | SceneNode |
animationsread-only |
SkenraAnimation[] |
— | Public getter for the animations affecting this target. | SkenraAnimatable |
| Method | Description | Declared by |
|---|---|---|
addUniform(name: string, value: number): WGSLUniform |
Imperative twin of authoring a <sk-wgsl-uniform> child. |
ComputeNode |
addF32ArrayUniform(name: string, values: readonly number[]): WGSLF32ArrayUniform |
Imperative twin of authoring a <sk-wgsl-f32-array-uniform> child. |
ComputeNode |
addVec2Uniform(name: string, x: number, y: number): WGSLVec2Uniform |
Imperative twin of authoring a <sk-wgsl-vec2-uniform> child. |
ComputeNode |
addVec3Uniform(name: string, x: number, y: number, z: number): WGSLVec3Uniform |
Imperative twin of authoring a <sk-wgsl-vec3-uniform> child. |
ComputeNode |
addVec4Uniform(name: string, x: number, y: number, z: number, w: number): WGSLVec4Uniform |
Imperative twin of authoring a <sk-wgsl-vec4-uniform> child. |
ComputeNode |
addColorUniform(name: string, color: ColorInput): WGSLColorUniform |
Imperative twin of authoring a <sk-wgsl-color-uniform> child. |
ComputeNode |
addMaterialPaint(material: Material, paintTarget: PaintTarget, options?: any): Paint |
Applies a material to this node for a specific paint target. | SceneNode |
getPaints(): ReadonlyMap<PaintTarget, Paint> |
— | SceneNode |
getOwnPaints(): readonly Paint[] |
Gets only the paints directly applied to this node (not inherited). | SceneNode |
removePaint(paint: Paint): void |
Removes a paint from this node. | SceneNode |
getWorldPosition(): number[] |
Returns this node’s origin in world space. | SceneNode |
getWorldMatrix(): Float32Array<ArrayBufferLike> |
Returns this node’s world transform — its local transform composed with all ancestor transforms. | SceneNode |
setViewportPosition(camera: AbstractCamera, x: number, y: number, z: number = 0.5): boolean |
Sets the node's local translation so that it appears at the specified viewport position. | SceneNode |
getViewportPosition(camera?: AbstractCamera): [number, number, number] | null |
Returns the node's current world position projected to viewport CSS pixel coordinates. | SceneNode |
setNDCPosition(camera: AbstractCamera, ndcX: number, ndcY: number, ndcZ: number = 0.5): boolean |
Sets the node's local translation so that it appears at the specified NDC position in the viewport. | SceneNode |
getBoundsInSpace(targetSpaceMatrix: Float32Array): { minX: number; maxX: number; minY: number; maxY: number; minZ: number; maxZ: number; } | null |
Computes the axis-aligned bounding box (AABB) of this node and its descendants | SceneNode |
animate(firstArg: TypedKeyframe<this>[] | TypedPropertyIndexedKeyframes<this> | Record<string, any> | globalThis.Keyframe[] | globalThis.PropertyIndexedKeyframes | null, secondArg?: number | KeyframeAnimationOptions | globalThis.KeyframeAnimationOptions): SkenraAnimation & Animation |
Creates a new SkenraAnimation for this target per Web Animations API. | SkenraAnimatable |
removeAnimation(animation: SkenraAnimation): boolean |
Removes a specific animation from this object. | SkenraAnimatable |
constrain(type: K, config: ConstraintConfigMap[K]): ConstraintReturnMap[K] |
Creates a constraint on this Animatable using a fluent API. | SkenraAnimatable |
const sim = new ComputeNode({
id: 'sim',
outputSize: 256,
wgsl: `
@compute @workgroup_size(64)
fn main(@builtin(global_invocation_id) gid: vec3u) {
let i = gid.x;
if (i >= params.output_size) { return; }
let t = f32(i) / f32(params.output_size - 1u) * 6.283185;
output[i] = SplineVertex(sin(5.0 * t), cos(3.0 * t), cos(t), 1.0);
}
`,
});
scene.appendChild(sim);