ProcGeo

TypeScript / JavaScript API Reference for the WASM binding.

Quick Start

Import the WASM module, initialize it, then start building geometry. All SOP functions accept a params object with camelCase keys.

import init, * as pg from 'procgeo-wasm';
await init();

let geo = pg.createBox({ size: [2, 2, 2] });
geo = pg.subdivide(geo, { depth: 2, mode: "catmullClark" });
geo = pg.computeNormals(geo);
return geo;
All parameter keys use camelCase in the WASM/browser binding (e.g. radiusBottom, endAngle, targetPercent). The registry functions (executeSop, etc.) accept snake_case param keys because they pass through to the Rust SOP registry directly.

Geometry Class

The Geometry class is the central data structure. It holds points, vertices, primitives, typed attributes, and groups. Most SOP functions accept and return Geometry instances.

new Geometry() constructor

new pg.Geometry()Geometry
Create an empty geometry with no points or primitives.
const geo = new pg.Geometry();

addPoint method

geo.addPoint(x: number, y: number, z: number)number
Add a point at the given position. Returns the new point index.
const ptIdx = geo.addPoint(1.0, 2.0, 3.0);

setPointPos method

geo.setPointPos(index: number, x: number, y: number, z: number)void
Set the position of an existing point by index.
geo.setPointPos(0, 5.0, 0.0, 0.0);

addFace method

geo.addFace(pointIndices: number[])number
Add a polygon face from an array of point indices. Returns the new primitive index.
const p0 = geo.addPoint(0, 0, 0);
const p1 = geo.addPoint(1, 0, 0);
const p2 = geo.addPoint(1, 1, 0);
const primIdx = geo.addFace([p0, p1, p2]);

addPolyline method

geo.addPolyline(pointIndices: number[])number
Add an open polyline from an array of point indices. Returns the new primitive index.
const lineIdx = geo.addPolyline([p0, p1, p2]);

numPoints getter

geo.numPointsnumber
The total number of points in the geometry (readonly).

numPrims getter

geo.numPrimsnumber
The total number of primitives in the geometry (readonly).

numVertices getter

geo.numVerticesnumber
The total number of vertices in the geometry (readonly).

pointPos method

geo.pointPos(index: number)[x, y, z]
Get the position of a point as a 3-element array.
const [x, y, z] = geo.pointPos(0);

boundingBox method

geo.boundingBox(){ min: [x,y,z], max: [x,y,z] }
Compute the axis-aligned bounding box of all points.
const bbox = geo.boundingBox();
console.log(bbox.min, bbox.max);

getPositions method

geo.getPositions()Float32Array
Get all point positions as a flat interleaved array (x,y,z,x,y,z,...). Suitable for GPU upload.
const positions = geo.getPositions();
// positions.length === geo.numPoints * 3

getTriangleIndices method

geo.getTriangleIndices()Uint32Array
Triangulate all polygon faces and return the index buffer. Suitable for GPU upload.
const indices = geo.getTriangleIndices();

getNormals method

geo.getNormals()Float32Array | undefined
Get vertex normals as a flat array, or undefined if no normal attribute exists.
const normals = geo.getNormals();
if (normals) {
  bufferGeometry.setAttribute('normal', new THREE.BufferAttribute(normals, 3));
}

getColors method

geo.getColors()Float32Array | undefined
Get vertex colors (Cd) as a flat array, or undefined if no color attribute exists.
const colors = geo.getColors();
if (colors) {
  bufferGeometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));
}

attribNames method

geo.attribNames(attribClass: string)string[]
List attribute names for a given class ("point", "vertex", "primitive", "detail").
const pointAttribs = geo.attribNames("point");
// e.g. ["N", "Cd", "uv"]

attribType method

geo.attribType(attribClass: string, name: string)string
Get the type of an attribute (e.g. "Float", "Int", "Vector3", "String").

attribSize method

geo.attribSize(attribClass: string, name: string)number
Get the component count of an attribute (e.g. 3 for Vector3, 1 for Float).

attribData method

geo.attribData(attribClass: string, name: string)Float32Array
Get the raw numeric data of an attribute as a flat Float32Array.
const uvs = geo.attribData("vertex", "uv");
bufferGeometry.setAttribute('uv', new THREE.BufferAttribute(uvs, 2));

attribDataString method

geo.attribDataString(attribClass: string, name: string)string[]
Get the values of a string attribute as an array of strings.

primPointIndices method

geo.primPointIndices(primIndex: number)number[]
Get the point indices for a specific primitive.
const pts = geo.primPointIndices(0);
// e.g. [0, 1, 2, 3] for a quad

primVertexCount method

geo.primVertexCount(primIndex: number)number
Get the number of vertices in a specific primitive.

vertexPoint method

geo.vertexPoint(vertexIndex: number)number
Get the point index that a vertex references.

toObj method

geo.toObj()string
Serialize the geometry to Wavefront OBJ format.
const objString = geo.toObj();
download("model.obj", objString);

toGlb method

geo.toGlb()Uint8Array
Serialize the geometry to binary glTF (GLB) format.
const glbBytes = geo.toGlb();
const blob = new Blob([glbBytes], { type: "model/gltf-binary" });

CopImage Class

The CopImage class represents a 2D image produced by COP (Compositing Operator) functions. Pixel data is stored as RGBA float32 values in the range 0–1.

width getter

image.widthnumber
The width of the image in pixels (readonly).

height getter

image.heightnumber
The height of the image in pixels (readonly).

getPixels method

await image.getPixels()Float32Array
Get all pixel data as RGBA float32 values. This is an async method. The returned array has length width * height * 4.
const pixels = await image.getPixels();
// pixels.length === image.width * image.height * 4
// Each pixel: [r, g, b, a] in 0..1 range

SOPs — Creation

Creation SOPs generate new geometry from parameters alone. They take no geometry input.

createBox creation

pg.createBox(params?)Geometry
Create an axis-aligned box centered at a given position.
ParamTypeDefaultDescription
size[w, h, d][1, 1, 1]Width, height, and depth of the box
center[x, y, z][0, 0, 0]Center position
let geo = pg.createBox({ size: [2, 1, 3], center: [0, 0.5, 0] });

createGrid creation

pg.createGrid(params?)Geometry
Create a planar polygon grid.
ParamTypeDefaultDescription
rowsnumber2Number of rows
colsnumber2Number of columns
sizeXnumber1Size along the X axis
sizeYnumber1Size along the Y axis
orientationstring"xz"Plane orientation: xz | xy | yz
let grid = pg.createGrid({ rows: 10, cols: 10, sizeX: 5, sizeY: 5 });

createSphere creation

pg.createSphere(params?)Geometry
Create a UV sphere.
ParamTypeDefaultDescription
radiusnumber0.5Sphere radius
rowsnumber12Number of latitude rows
colsnumber24Number of longitude columns
center[x, y, z][0, 0, 0]Center position
let sphere = pg.createSphere({ radius: 2, rows: 24, cols: 48 });

createTube creation

pg.createTube(params?)Geometry
Create a tube (cylinder or cone when radii differ).
ParamTypeDefaultDescription
radiusBottomnumber0.5Bottom radius
radiusTopnumber0.5Top radius (set to 0 for a cone)
heightnumber1Height of the tube
rowsnumber1Number of height divisions
colsnumber12Number of radial divisions
capsbooleantrueGenerate end caps
let cone = pg.createTube({ radiusBottom: 1, radiusTop: 0, height: 2 });

createTorus creation

pg.createTorus(params?)Geometry
Create a torus (donut shape).
ParamTypeDefaultDescription
radiusOuternumber1.0Distance from center to tube center
radiusInnernumber0.3Tube cross-section radius
rowsnumber12Tube cross-section divisions
colsnumber24Radial divisions around the ring
center[x, y, z][0, 0, 0]Center position
let torus = pg.createTorus({ radiusOuter: 2, radiusInner: 0.5, rows: 24, cols: 48 });

createCircle creation

pg.createCircle(params?)Geometry
Create a circle (closed polyline in the XZ plane).
ParamTypeDefaultDescription
radiusnumber1.0Circle radius
divisionsnumber12Number of segments
center[x, y, z][0, 0, 0]Center position
let circle = pg.createCircle({ radius: 3, divisions: 32 });

createLine creation

pg.createLine(params?)Geometry
Create a straight line (polyline) between two points.
ParamTypeDefaultDescription
origin[x, y, z][0, 0, 0]Start position
direction[x, y, z][0, 1, 0]Direction vector
lengthnumber1.0Length of the line
pointsnumber2Number of points along the line
let line = pg.createLine({ origin: [0, 0, 0], direction: [1, 0, 0], length: 5, points: 10 });

createMetaball creation

pg.createMetaball(params?)Geometry
Generate an implicit-surface mesh from a set of metaballs using marching cubes.
ParamTypeDefaultDescription
balls[{center, radius, weight}]Array of metaball definitions
thresholdnumber1.0Isosurface threshold
kernelstring"wyvill"Kernel function: wyvill | blinn | hart
resolutionnumber32Marching cubes grid resolution
paddingnumber0.2Extra padding around bounding box
let meta = pg.createMetaball({
  balls: [
    { center: [0, 0, 0], radius: 1, weight: 1 },
    { center: [1.2, 0, 0], radius: 0.8, weight: 1 }
  ],
  resolution: 64,
  kernel: "wyvill"
});

SOPs — Transform

Transform SOPs modify geometry positions, topology, or connectivity.

transform transform

pg.transform(geo, params?)Geometry
Apply translate, rotate, and scale transformations to geometry.
ParamTypeDefaultDescription
translate[x, y, z][0, 0, 0]Translation offset
rotate[x, y, z][0, 0, 0]Rotation in degrees (Euler XYZ)
scale[x, y, z][1, 1, 1]Scale factor per axis
pivot[x, y, z][0, 0, 0]Pivot point for rotation and scale
geo = pg.transform(geo, { translate: [0, 1, 0], rotate: [0, 45, 0], scale: [2, 2, 2] });

subdivide transform

pg.subdivide(geo, params?)Geometry
Subdivide polygon faces to increase mesh resolution.
ParamTypeDefaultDescription
depthnumber1Number of subdivision levels
modestring"linear"Subdivision mode: linear | catmullClark
geo = pg.subdivide(geo, { depth: 2, mode: "catmullClark" });

smooth transform

pg.smooth(geo, params?)Geometry
Laplacian smoothing of point positions.
ParamTypeDefaultDescription
iterationsnumber1Number of smoothing passes
strengthnumber0.5Blend factor per iteration (0–1)
geo = pg.smooth(geo, { iterations: 5, strength: 0.8 });

revolve transform

pg.revolve(geo, params?)Geometry
Revolve a profile curve around an axis to create a surface of revolution.
ParamTypeDefaultDescription
origin[x, y, z]Axis origin point
axis[x, y, z][0, 1, 0]Axis direction
divisionsnumber24Number of radial steps
startAnglenumber0Start angle in degrees
endAnglenumber360End angle in degrees
endCapsbooleanfalseCap open ends
let profile = pg.createLine({ origin: [1, 0, 0], direction: [0, 1, 0], points: 10 });
let vase = pg.revolve(profile, { divisions: 32, endAngle: 360 });

resample transform

pg.resample(geo, params?)Geometry
Resample polylines to a uniform segment length.
ParamTypeDefaultDescription
lengthnumber0.1Target segment length
maxSegmentsnumber1000Maximum number of segments
geo = pg.resample(geo, { length: 0.05 });

SOPs — Topology

Topology SOPs modify mesh connectivity, create new primitives, or combine geometries.

polyExtrude topology

pg.polyExtrude(geo, params?)Geometry
Extrude polygon faces along their normals.
ParamTypeDefaultDescription
distancenumber0.5Extrusion distance
insetnumber0.0Inset amount before extruding
outputFrontbooleantrueOutput the extruded front face
outputSidebooleantrueOutput the side faces
geo = pg.polyExtrude(geo, { distance: 0.5, inset: 0.1 });

polyBevel topology

pg.polyBevel(geo, params?)Geometry
Bevel polygon edges to create chamfers or rounded edges.
ParamTypeDefaultDescription
offsetnumber0.1Bevel offset distance
divisionsnumber1Number of bevel subdivisions
geo = pg.polyBevel(geo, { offset: 0.05, divisions: 3 });

polyWire topology

pg.polyWire(geo, params?)Geometry
Convert edges or polylines into tubes (wireframe mesh).
ParamTypeDefaultDescription
radiusnumber0.02Wire tube radius
divisionsnumber4Radial divisions of the tube
let wireframe = pg.polyWire(geo, { radius: 0.05, divisions: 6 });

polyFill topology

pg.polyFill(geo, params?)Geometry
Fill open holes in geometry with polygons.
ParamTypeDefaultDescription
modestring"fan"Fill mode: single | fan
smoothbooleanfalseSmooth the filled surface
geo = pg.polyFill(geo, { mode: "fan" });

polyReduce topology

pg.polyReduce(geo, params?)Geometry
Reduce polygon count while preserving shape.
ParamTypeDefaultDescription
targetPercentnumber50.0Target polygon count as percentage of original
preserveBoundariesbooleantruePreserve boundary edges
geo = pg.polyReduce(geo, { targetPercent: 25 });

clip topology

pg.clip(geo, params?)Geometry
Clip geometry with an infinite plane.
ParamTypeDefaultDescription
origin[x, y, z][0, 0, 0]A point on the clipping plane
normal[x, y, z][0, 1, 0]Plane normal direction
keepAbovebooleantrueKeep the geometry above the plane
geo = pg.clip(geo, { origin: [0, 0.5, 0], normal: [0, 1, 0] });

fuse topology

pg.fuse(geo, params?)Geometry
Merge points that are within a given distance threshold.
ParamTypeDefaultDescription
distancenumber0.001Maximum distance to merge points
geo = pg.fuse(geo, { distance: 0.01 });

reverse topology

pg.reverse(geo)Geometry
Reverse the winding order of all polygon faces (flip normals).
geo = pg.reverse(geo);

scatter topology

pg.scatter(geo, params?)Geometry
Scatter random points on the surface of a mesh.
ParamTypeDefaultDescription
countnumber100Number of points to scatter
seednumber0Random seed
let points = pg.scatter(geo, { count: 500, seed: 42 });

copyToPoints topology

pg.copyToPoints(source, target)Geometry
Copy source geometry onto every point of the target geometry.
let box = pg.createBox({ size: [0.1, 0.1, 0.1] });
let pts = pg.scatter(pg.createGrid(), { count: 50 });
let instanced = pg.copyToPoints(box, pts);

merge topology

pg.merge(a, b)Geometry
Merge two geometries into one. Chain calls to merge more than two.
let box = pg.createBox();
let sphere = pg.createSphere();
let merged = pg.merge(box, sphere);

// Merge three:
let third = pg.createTorus();
merged = pg.merge(pg.merge(box, sphere), third);

voronoiFracture topology

pg.voronoiFracture(geo, points, params?)Geometry
Fracture geometry into Voronoi cells using a set of seed points.
ParamTypeDefaultDescription
cutPlaneOffsetnumber0.0Offset for cut planes
createInsideFacesbooleantrueGenerate interior faces at cut boundaries
let box = pg.createBox({ size: [2, 2, 2] });
let seeds = pg.scatter(box, { count: 20 });
let fractured = pg.voronoiFracture(box, seeds, { createInsideFaces: true });

SOPs — Utility

Utility SOPs compute derived data, set attributes, or filter elements.

computeNormals utility

pg.computeNormals(geo)Geometry
Compute smooth vertex normals from face topology. Creates or overwrites the N attribute.
geo = pg.computeNormals(geo);

color utility

pg.color(geo, params?)Geometry
Set a uniform color on all points. Creates or overwrites the Cd attribute.
ParamTypeDefaultDescription
color[r, g, b][1, 1, 1]RGB color in 0–1 range
geo = pg.color(geo, { color: [0.2, 0.6, 1.0] });

blast utility

pg.blast(geo, params)Geometry
Delete primitives or points belonging to a named group.
ParamTypeDefaultDescription
groupNamestringName of the group to blast
entitystring"primitives"Entity type: primitives | points
negatebooleanfalseIf true, keep the group and delete everything else
geo = pg.blast(geo, { groupName: "top_faces", negate: true });

deleteSop utility

pg.deleteSop(geo, params)Geometry
Delete a range of points or primitives by index.
ParamTypeDefaultDescription
entitystringEntity type: points | primitives
rangeStartnumberStart of the range (inclusive)
rangeEndnumberEnd of the range (exclusive)
geo = pg.deleteSop(geo, { entity: "primitives", rangeStart: 0, rangeEnd: 5 });

sort utility

pg.sort(geo, params?)Geometry
Randomly reorder primitives using a seed.
ParamTypeDefaultDescription
seednumber0Random seed for shuffling
geo = pg.sort(geo, { seed: 42 });

connectivity utility

pg.connectivity(geo, params?)Geometry
Assign a class attribute to each connected component.
ParamTypeDefaultDescription
attribNamestring"class"Name of the output attribute
geo = pg.connectivity(geo);
// Each primitive now has a "class" attribute

enumerateAttrib utility

pg.enumerateAttrib(geo, params?)Geometry
Add a sequential integer attribute to each element.
ParamTypeDefaultDescription
namestring"id"Attribute name
startnumber0Starting value
geo = pg.enumerateAttrib(geo, { name: "id", start: 0 });

measure utility

pg.measure(geo, params?)Geometry
Compute face areas and store as a primitive attribute.
ParamTypeDefaultDescription
attribNamestring"area"Name of the output attribute
geo = pg.measure(geo, { attribName: "area" });

SOPs — Attributes

Attribute SOPs create, modify, transfer, and query typed attributes on geometry elements.

attribCreate attributes

pg.attribCreate(geo, params)Geometry
Create a new attribute with a constant initial value.
ParamTypeDefaultDescription
namestringAttribute name
classstring"point"Attribute class: point | vertex | primitive | detail
attribTypestring"Float"Data type: Float | Int | Vector3 | String
valueFloatnumberDefault value for Float type
valueIntnumberDefault value for Int type
valueVector3[x, y, z]Default value for Vector3 type
valueStringstringDefault value for String type
geo = pg.attribCreate(geo, { name: "density", attribType: "Float", valueFloat: 1.0 });
geo = pg.attribCreate(geo, {
  name: "up", class: "point", attribType: "Vector3", valueVector3: [0, 1, 0]
});

attribDelete attributes

pg.attribDelete(geo, params)Geometry
Remove an attribute from geometry.
ParamTypeDefaultDescription
namestringAttribute name to delete
classstring"point"Attribute class
geo = pg.attribDelete(geo, { name: "temp_data", class: "point" });

attribRename attributes

pg.attribRename(geo, params)Geometry
Rename an existing attribute.
ParamTypeDefaultDescription
fromNamestringCurrent attribute name
toNamestringNew attribute name
classstring"point"Attribute class
geo = pg.attribRename(geo, { fromName: "Cd", toName: "base_color" });

attribPromote attributes

pg.attribPromote(geo, params)Geometry
Promote an attribute from one class to another (e.g. point to primitive).
ParamTypeDefaultDescription
namestringAttribute name
fromClassstringSource class
toClassstringDestination class
methodstring"average"Promotion method (for numeric types)
deleteOriginalbooleantrueDelete the original attribute after promotion
geo = pg.attribPromote(geo, {
  name: "Cd", fromClass: "point", toClass: "vertex", method: "average"
});

attribNoise attributes

pg.attribNoise(geo, params?)Geometry
Generate noise values based on point positions and store as an attribute.
ParamTypeDefaultDescription
attribNamestring"noise"Output attribute name
noiseTypestring"simplex"Noise type: simplex | perlin | worley
elementSizenumber1.0Scale of noise features
amplitudenumber1.0Output amplitude
fractalstring"none"Fractal mode
octavesnumber4Number of fractal octaves
operationstring"set"How to apply: set | add | multiply
geo = pg.attribNoise(geo, {
  attribName: "height",
  noiseType: "simplex",
  elementSize: 2.0,
  amplitude: 0.5
});

attribRandomize attributes

pg.attribRandomize(geo, params?)Geometry
Assign random values to an attribute.
ParamTypeDefaultDescription
attribNamestring"rand"Output attribute name
classstring"point"Attribute class
attribTypestring"Float"Data type
distributionstring"uniform"Distribution type
seednumber0Random seed
minValuenumber0.0Minimum value
maxValuenumber1.0Maximum value
globalScalenumber1.0Global scale factor
geo = pg.attribRandomize(geo, {
  attribName: "pscale", seed: 42, minValue: 0.5, maxValue: 2.0
});

attribTransfer attributes

pg.attribTransfer(dest, source, params)Geometry
Transfer an attribute from source geometry to destination geometry using proximity.
ParamTypeDefaultDescription
attribNamestringName of the attribute to transfer
classstringAttribute class
attribTypestringAttribute data type
maxSamplesnumber1Max nearest points to sample
distanceThresholdnumber1.0Max transfer distance
geo = pg.attribTransfer(destGeo, sourceGeo, {
  attribName: "Cd", class: "point", attribType: "Vector3"
});

attribCopy attributes

pg.attribCopy(dest, source?, params)Geometry
Copy an attribute within the same geometry or from another geometry.
ParamTypeDefaultDescription
attribNamestringSource attribute name
classstringAttribute class
newNamestringName for the copied attribute
geo = pg.attribCopy(geo, null, {
  attribName: "Cd", class: "point", newName: "Cd_backup"
});

attribSort attributes

pg.attribSort(geo, params)Geometry
Sort elements by an attribute value.
ParamTypeDefaultDescription
attribNamestringAttribute to sort by
orderstring"Ascending"Sort order: Ascending | Descending
geo = pg.attribSort(geo, { attribName: "area", order: "Descending" });

attribBlur attributes

pg.attribBlur(geo, params)Geometry
Smooth an attribute across neighboring elements using diffusion.
ParamTypeDefaultDescription
attribNamestringAttribute to blur
iterationsnumber1Number of blur passes
stepSizenumber0.5Blend factor per pass
geo = pg.attribBlur(geo, { attribName: "noise", iterations: 5, stepSize: 0.3 });

attribFill attributes

pg.attribFill(geo, params)Geometry
Fill attribute values by diffusing from boundary elements inward.
ParamTypeDefaultDescription
attribNamestringAttribute to fill
boundaryGroupstringGroup defining boundary elements
iterationsnumber10Number of diffusion iterations
stepSizenumber1.0Diffusion step size
geo = pg.attribFill(geo, {
  attribName: "temperature", boundaryGroup: "edges", iterations: 20
});

SOPs — Groups

Group SOPs create and combine element groups using ranges, bounding boxes, or normal directions.

groupCreate groups

pg.groupCreate(geo, params)Geometry
Create a named group of points or primitives based on a selection mode.
ParamTypeDefaultDescription
namestringGroup name
groupTypestring"points"Group type: points | primitives
modestring"range"Selection mode: range | boundingBox | normal
rangeStartnumberStart index (range mode)
rangeEndnumberEnd index (range mode)
bboxMin[x, y, z]Bounding box minimum (boundingBox mode)
bboxMax[x, y, z]Bounding box maximum (boundingBox mode)
normalDirection[x, y, z]Target normal (normal mode)
normalSpreadnumberAngle tolerance in degrees (normal mode)
// Select top-facing primitives
geo = pg.groupCreate(geo, {
  name: "top_faces",
  groupType: "primitives",
  mode: "normal",
  normalDirection: [0, 1, 0],
  normalSpread: 45
});

// Select a range of points
geo = pg.groupCreate(geo, {
  name: "first_ten", groupType: "points", mode: "range", rangeStart: 0, rangeEnd: 10
});

groupCombine groups

pg.groupCombine(geo, params)Geometry
Combine two groups using a boolean operation.
ParamTypeDefaultDescription
nameAstringFirst group name
nameBstringSecond group name
resultstringOutput group name
operationstring"union"Boolean operation: union | intersect | subtract
geo = pg.groupCombine(geo, {
  nameA: "top_faces", nameB: "large_faces", result: "selected", operation: "intersect"
});

COPs — Generators

COP generator functions create images from scratch. All return a CopImage.

You must call await pg.initCopGpu() once before using any COP function. This initializes the WebGPU backend.

copConstant generator

pg.copConstant(params?)CopImage
Create a solid-color image.
ParamTypeDefaultDescription
color[r, g, b, a][0, 0, 0, 1]RGBA fill color (0–1)
widthnumber256Image width in pixels
heightnumber256Image height in pixels
await pg.initCopGpu();
let img = pg.copConstant({ color: [1, 0, 0, 1], width: 512, height: 512 });

copCheckerboard generator

pg.copCheckerboard(params?)CopImage
Generate a checkerboard pattern.
ParamTypeDefaultDescription
colorA[r, g, b, a]First checker color
colorB[r, g, b, a]Second checker color
frequency[x, y][8, 8]Number of checks per axis
widthnumber256Image width
heightnumber256Image height
let checker = pg.copCheckerboard({
  colorA: [1, 1, 1, 1], colorB: [0, 0, 0, 1], frequency: [16, 16]
});

copNoise generator

pg.copNoise(params?)CopImage
Generate a 2D noise texture.
ParamTypeDefaultDescription
noiseTypestring"perlin"Noise type: perlin | simplex | worley
frequencynumber4.0Base frequency
octavesnumber4Number of octaves
lacunaritynumber2.0Frequency multiplier per octave
gainnumber0.5Amplitude multiplier per octave
amplitudenumber1.0Overall amplitude
offset[x, y]Noise space offset
seednumberRandom seed
widthnumber256Image width
heightnumber256Image height
let noise = pg.copNoise({
  noiseType: "simplex", frequency: 8, octaves: 6, width: 512, height: 512
});

copRamp generator

pg.copRamp(params?)CopImage
Generate a gradient ramp image.
ParamTypeDefaultDescription
rampTypestring"linear"Ramp shape: linear | radial | box | diagonal
stops[{position, color}]Array of color stops with position (0–1) and RGBA color
widthnumber256Image width
heightnumber256Image height
let ramp = pg.copRamp({
  rampType: "radial",
  stops: [
    { position: 0.0, color: [1, 1, 1, 1] },
    { position: 1.0, color: [0, 0, 0, 1] }
  ]
});

copLoadImage generator

pg.copLoadImage(params)CopImage
Load an image from a URL or path.
ParamTypeDefaultDescription
pathstringURL or file path to load
let img = pg.copLoadImage({ path: "/textures/diffuse.png" });

COPs — Filters

COP filter functions process an existing image and return a new CopImage.

copBlur filter

pg.copBlur(image, params?)CopImage
Blur an image with a Gaussian or box kernel.
ParamTypeDefaultDescription
blurTypestring"gaussian"Blur kernel: gaussian | box
radiusXnumber4.0Horizontal blur radius
radiusYnumber4.0Vertical blur radius
let blurred = pg.copBlur(img, { blurType: "gaussian", radiusX: 8, radiusY: 8 });

copFlip filter

pg.copFlip(image, params?)CopImage
Flip an image horizontally and/or vertically.
ParamTypeDefaultDescription
horizontalbooleanfalseFlip horizontally
verticalbooleantrueFlip vertically
let flipped = pg.copFlip(img, { horizontal: true, vertical: false });

copMirror filter

pg.copMirror(image, params?)CopImage
Mirror an image along an axis.
ParamTypeDefaultDescription
axisstring"x"Mirror axis: x | y
offsetnumber0.5Mirror line position (0–1)
let mirrored = pg.copMirror(img, { axis: "x", offset: 0.5 });

copChannelSwap filter

pg.copChannelSwap(image, params)CopImage
Remap color channels.
ParamTypeDefaultDescription
rstringSource for red: r | g | b | a | one | zero
gstringSource for green
bstringSource for blue
astringSource for alpha
// Convert to grayscale by using red channel for all
let gray = pg.copChannelSwap(img, { r: "r", g: "r", b: "r", a: "one" });

copResize filter

pg.copResize(image, params)CopImage
Resize an image to new dimensions.
ParamTypeDefaultDescription
widthnumberTarget width
heightnumberTarget height
filterstring"nearest"Resize filter: nearest | bilinear
let small = pg.copResize(img, { width: 128, height: 128, filter: "bilinear" });

copRotate filter

pg.copRotate(image, params?)CopImage
Rotate an image around a center point.
ParamTypeDefaultDescription
anglenumber0Rotation angle in degrees
center[x, y][0.5, 0.5]Rotation center (normalized)
filterstringSampling filter
let rotated = pg.copRotate(img, { angle: 45 });

copSwirl filter

pg.copSwirl(image, params?)CopImage
Apply a swirl distortion to an image.
ParamTypeDefaultDescription
center[x, y][0.5, 0.5]Swirl center (normalized)
anglenumber90Maximum rotation angle in degrees
radiusnumber0.5Effect radius (normalized)
let swirled = pg.copSwirl(img, { angle: 180, radius: 0.4 });

COPs — Composite

Composite COPs combine two images together.

copComposite composite

pg.copComposite(a, b, params?)CopImage
Composite two images using a blend operation.
ParamTypeDefaultDescription
operationstring"over"Blend mode: over | add | multiply | screen | subtract | difference | min | max
mixnumber1.0Mix factor (0 = only A, 1 = full blend)
let layerA = pg.copNoise({ frequency: 4 });
let layerB = pg.copCheckerboard({ frequency: [8, 8] });
let result = pg.copComposite(layerA, layerB, { operation: "multiply", mix: 0.5 });

I/O & Registry

The registry functions provide a dynamic, name-based interface to all SOPs and COPs. Useful for building UIs, scripting systems, or executing operators by name at runtime.

executeSop registry

pg.executeSop(name, geo, params?)Geometry
Execute any registered SOP by name. Params use snake_case keys.
let geo = pg.createBox();
geo = pg.executeSop("subdivide", geo, { depth: 2, mode: "catmull_clark" });

executeSopCreate registry

pg.executeSopCreate(name, params?)Geometry
Execute a creation SOP by name (no geometry input required).
let geo = pg.executeSopCreate("box", { size: [2, 2, 2] });

listSops registry

pg.listSops()string[]
List all registered SOP names.
const sops = pg.listSops();
// ["box", "grid", "sphere", "tube", "torus", "circle", "line", ...]

executeCopCreate registry

pg.executeCopCreate(name, params?)CopImage
Execute a COP generator by name.
let img = pg.executeCopCreate("noise", { frequency: 8 });

executeCop registry

pg.executeCop(name, image, params?)CopImage
Execute a COP filter by name on an existing image.
let blurred = pg.executeCop("blur", img, { radius_x: 4, radius_y: 4 });

executeCopComposite registry

pg.executeCopComposite(name, a, b, params?)CopImage
Execute a COP composite operation by name.
let result = pg.executeCopComposite("composite", imgA, imgB, { operation: "add" });

listCops registry

pg.listCops()string[]
List all registered COP names.
const cops = pg.listCops();
// ["constant", "checkerboard", "noise", "ramp", "blur", ...]

initCopGpu registry

await pg.initCopGpu()void
Initialize the WebGPU backend for COP operations. Must be awaited before calling any COP function.
await pg.initCopGpu();

toObj i/o

geo.toObj()string
Export geometry to Wavefront OBJ format string.
const objData = geo.toObj();

toGlb i/o

geo.toGlb()Uint8Array
Export geometry to binary glTF (GLB) format.
const glb = geo.toGlb();
const blob = new Blob([glb], { type: "model/gltf-binary" });
const url = URL.createObjectURL(blob);