Skip to content

3D charts

3D styling and palettes ​

scenes/3d-styling-and-palettes
plot.showMesh(plot.uploadMesh(extractIsosurface(field(40, 10, radial), 6)), [0.25, 0.45, 0.75]);
const { positions, scalars } = shell(60_000, 5);
// Unset, the palette spans the scalars. Written, it spans what the page
// says, and everything outside takes the colour of the nearer end.
const points = range === "narrow" ? { positions, scalars, range: [0.98, 1.02] } : { positions, scalars };
plot.showPoints(plot.uploadPoints(points));
plot.frameScene();

Calls

6 in the code above, in the order it makes them

plot.showMesh(handle: MeshHandle, colour: Colour | Hex): void

Draw the surface handle names.

plot.uploadMesh(mesh: Mesh): MeshHandle

Upload a surface and return a handle naming it.

extractIsosurface(field: Field, isovalue: number): Surface

The surface through isovalue in a scalar field, as triangles.

Nothing is uploaded and nothing is drawn. The drawn path -- Plot.uploadField and Plot.showIsosurface -- triangulates in a compute shader every frame and keeps nothing, which is what makes a dragged isovalue cost a frame rather than an upload, and also why it cannot answer a question about the surface itself. This is the path for those: an area, an intersection, a file to export.

An isovalue the field never reaches gives a surface of no triangles rather than an error, so a slider swept past the end of the range makes the surface disappear rather than fail.

plot.showPoints(handle: PointsHandle): void

Draw the point cloud handle names.

plot.uploadPoints(points: PointSet): PointsHandle

Upload a point cloud and return a handle naming it.

plot.frameScene(): void

Point the camera at the middle of everything uploaded, far enough back to see it.

Call after uploading. A scene measured in grid cells or in millimetres is nowhere near where a camera starts, and without this the first thing a caller sees is an empty canvas.