Skip to content

(data …)

Defines embedded data for buffer initialization. Supports compile-time shape generators, inline float arrays, WASM (WebAssembly) generated data, and external image files.

; Shape generator (compile-time mesh generation)
(data :name cubeVerts (cube :format [position4 color4 uv2]))
; Inline float array
(data :name weights :float32 [1.0 2.0 3.0])
; WASM-generated data
(data :name curve (wasm-data :file "gen.wasm" :func make :returns "array<f32,360>"))
; External image file
(data :name logoFile :file "path/to/file.png" :mime "image/png")
Key Type Required Default Description
:name symbol Yes - Unique data name
generator sub-form positional form No* - (cube …), (plane …), … or (wasm-data …)
:float32 array No* - Inline float array data
:file string No* - Image file path, relative to the source document
:mime string No application/octet-stream MIME type stored with the :file bytes

*One byte source, three spellings. A (data …) carries at most one positional generator sub-form; a second one is a positional_too_many error rather than a silently ignored form. If more than one spelling is present the generator wins, then :file, then :float32; a (data …) with none of them is an empty entry of zero bytes.

Generate vertex data at compile time instead of writing arrays manually. A shape is a positional sub-form inside (data …). Shape generators produce triangle lists with the specified vertex attributes.

Available shapes: cube, plane, sphere, torus, truncated-cone, cylinder, teapot, dragon. Each accepts a :format list, plus generator-specific parameters:

Key Type Default Applies to
:segments number 24 sphere (longitude)
:rings number 12 sphere (latitude)
:radius number 1.0 sphere, torus (major radius), cylinder
:thickness number 0.24 torus (minor radius)
:radial-subdivisions number 24 torus, truncated-cone, cylinder
:body-subdivisions number 12 torus
:vertical-subdivisions number 1 truncated-cone, cylinder
:bottom-radius number 1.0 truncated-cone (a cylinder takes :radius for both ends)
:top-radius number 0.0 truncated-cone
:height number 1.0 truncated-cone, cylinder
:top-cap / :bottom-cap boolean true truncated-cone, cylinder
:faceted boolean false flat normals, one per triangle

A subdivision count outside its generatable range is a compile error naming the key and the range: no generated mesh may exceed 65536 indices.

Generates a cube centred at the origin, vertices at ±1. Produces 36 vertices (6 faces × 2 triangles × 3 vertices), deindexed.

(data :name cubeVertices (cube :format [position4 color4 uv2]))

Generates a single 1×1 quad on the XY plane, facing +Z. Produces 6 vertices (2 triangles), deindexed.

(data :name planeVertices (plane :format [position3 uv2]))

Generates a UV sphere. Extra parameters (:segments, :rings) tune the tessellation:

(data :name sphereVertices (sphere :format [position3 normal3] :segments 24 :rings 12))

The teapot and dragon generators produce an indexed mesh: vertex data plus an index companion. Source a vertex buffer from the shape and an index buffer with :index-of:

(data :name teapotMesh (teapot :format [position3 normal3]))
(buffer :name vertexBuffer :usage [vertex] :data teapotMesh)
(buffer :name indexBuffer :index-of teapotMesh :usage [index])

The :format array specifies which attributes to generate for each vertex:

Specifier Type Size Description
position3 vec3f 12 bytes XYZ position
position4 vec4f 16 bytes XYZW position (w=1)
normal3 vec3f 12 bytes Surface normal
color3 vec3f 12 bytes RGB vertex colour
color4 vec4f 16 bytes RGBA vertex colour
uv2 vec2f 8 bytes Texture coordinates

Vertex stride is the sum of all attribute sizes. For [position4 color4 uv2]:

  • position4: 16 bytes
  • color4: 16 bytes
  • uv2: 8 bytes
  • Total stride: 40 bytes

Type: array of numbers

Inline float values, written directly:

(data :name vertices :float32 [
0.0 0.5 1.0 0.0 0.0
-0.5 -0.5 0.0 1.0 0.0
0.5 -0.5 0.0 0.0 1.0
])

:float32 takes a literal list only; there is no repeat-or-fill generator. For computed values, use a (wasm-data …) generator (below) to produce the bytes at compile time, or a compute init pass (see (init …)) to fill the buffer on the GPU.

A (wasm-data …) sub-form calls a WASM function once at buffer-create time; its returned bytes fill the buffer.

(data :name curve (wasm-data :file "gen.wasm" :func makeCurve :returns "array<f32,360>"))
Key Type Required Description
:file string Yes WASM file path, relative to the source document
:func symbol Yes Exported function to call
:returns string Yes Return type, turned into a byte count (array<f32,360> is 1440, mat4x4 is 64, vec4 is 16, f32 is 4)

Modules are deduplicated by path, and are read at compile time, so an unreadable :file is an error that names the path.

Type: string

Path to an image file, relative to the source document. It is embedded in the PNGB payload (the compiled bytecode) at compile time as [mime_len][mime][bytes], and decoded at runtime by an (image-bitmap …):

(data :name imageFile :file "textures/diffuse.png" :mime "image/png")
(data :name cubeVertices (cube :format [position4 color4 uv2]))
(buffer :name vertexBuffer
:usage [vertex]
:data cubeVertices)
(render-pipeline :name cubeRenderer :layout auto
(vertex :module shader :entry vs
(vertex-buffer :array-stride 40
(attribute :shader-location 0 :offset 0 :format float32x4)
(attribute :shader-location 1 :offset 16 :format float32x4)
(attribute :shader-location 2 :offset 32 :format float32x2)))
(fragment :module shader :entry fs
(target :format preferred-canvas-format)))
(data :name triangleVerts :float32 [
0.0 0.5 1 0 0
-0.5 -0.5 0 1 0
0.5 -0.5 0 0 1
])
(buffer :name vertexBuffer
:usage [vertex]
:data triangleVerts)
(data :name textureData :file "assets/logo.png" :mime "image/png")
(image-bitmap :name logo :data textureData)

A buffer with :data takes its size from the data, so no byte count is written beside it:

(data :name vertexData (cube :format [position4 color4 uv2]))
(buffer :name verts ; sized by the data it is filled from
:usage [vertex]
:data vertexData)

Size calculation:

  • Shape generators: vertex_count × stride (e.g. a cube with position4+color4+uv2 = 36 × 40 = 1440 bytes)
  • Inline :float32 arrays: element_count × 4 bytes
  • (wasm-data …): the byte count its :returns type spells

A numeric :size beside :data is legal and over-allocates on purpose; a :size smaller than the data is a compile error. A (data …) name is not accepted in :size itself, which takes a number, an expression, or a (define …) constant.

Rule Error
A name is declared once, across every form kind duplicate_cross_ref_target, or duplicate name 'x': already declared as a (data …) at line N
At most one generator sub-form positional_too_many
The sub-form head is one of the nine generators not_head_member
:format entries are position3, position4, normal3, color3, color4 or uv2 not_member
A generator’s subdivision counts are in range (sphere …) :segments 0 is outside the generatable range 3..4096
:file must be readable at compile time cannot read 'assets/logo.png': FileNotFound (located on the (data …) form; the path is resolved against the document’s directory)

The rows with a code are schema checks; the rows with a message are compiler checks, and they report the line the form is written on.

Every key and value on this page traced to the WebGPU name it stands for, with a link to the definition. How the tracing is made, and what keeps it from rotting, is the subject of Where the Words Come From.

(data …) is PNGine’s own. WebGPU has no data form: bytes arrive through writeBuffer() or a mapped buffer, and where they come from is the page’s business. Here they come from the document (a float list), a file, or a shape generator, and the compiler bakes them into the payload.

Key WebGPU Note
:name PNGine’s own the name a (buffer …) or (image-bitmap …) refers to
:float32 PNGine’s own literal floats, packed little-endian
:file PNGine’s own a file embedded at compile time
:mime PNGine’s own the type of an embedded image file

(cube …) is PNGine’s own. A compile-time shape generator; it produces the vertex bytes a (buffer …) takes as :data.

Key WebGPU Note
:format PNGine’s own the vertex layout to generate: position4, normal3, uv2, …

(plane …) is PNGine’s own. A compile-time shape generator; it produces the vertex bytes a (buffer …) takes as :data.

Key WebGPU Note
:format PNGine’s own the vertex layout to generate: position4, normal3, uv2, …

(sphere …) is PNGine’s own. A compile-time shape generator; it produces the vertex bytes a (buffer …) takes as :data.

Key WebGPU Note
:format PNGine’s own the vertex layout to generate: position4, normal3, uv2, …

(torus …) is PNGine’s own. A compile-time shape generator; it produces the vertex bytes a (buffer …) takes as :data.

Key WebGPU Note
:format PNGine’s own the vertex layout to generate: position4, normal3, uv2, …

(truncated-cone …) is PNGine’s own. A compile-time shape generator; it produces the vertex bytes a (buffer …) takes as :data.

Key WebGPU Note
:format PNGine’s own the vertex layout to generate: position4, normal3, uv2, …

(cylinder …) is PNGine’s own. A compile-time shape generator; it produces the vertex bytes a (buffer …) takes as :data.

Key WebGPU Note
:format PNGine’s own the vertex layout to generate: position4, normal3, uv2, …

(teapot …) is PNGine’s own. A compile-time shape generator; it produces the vertex bytes a (buffer …) takes as :data.

Key WebGPU Note
:format PNGine’s own the vertex layout to generate: position4, normal3, uv2, …

(dragon …) is PNGine’s own. A compile-time shape generator; it produces the vertex bytes a (buffer …) takes as :data.

Key WebGPU Note
:format PNGine’s own the vertex layout to generate: position4, normal3, uv2, …

(wasm-data …) is PNGine’s own. A WASM module run at load time to produce the bytes.

Key WebGPU Note
:file PNGine’s own the module
:func PNGine’s own the export to call
:returns PNGine’s own the shape of what it returns

Checked against the WebGPU specification at revision b8c0fa9; the links go to the current draft.