BufferLayout
The bufferLayout type provides information about how the application is planning to map the attributes in its pipelines to the memory in GPU buffers.
BufferLayout
affects buffers bound with RenderPipeline.setAttributes({[bufferName]: Buffer})
or
Model.setAttributes({[bufferName]: Buffer})
. The names of buffer bind points are determined by the bufferLayout
mapping supplied to createRenderPipeline()
or new Model()
.
This buffer name then becomes valid in RenderPipeline.setAttributes()
and Model.setAttributes()
.
Usage
The simplest use case is to provide a non-default vertex type:
bufferLayout: [
{name: 'instancePositions', format: 'float32x3'}
...
// RGBA colors can be efficiently encoded in 4 8bit bytes, instead of 4 32bit floats
{name: 'instanceColors', format: 'uint8normx4'},
],
This is short hand for specifying an attribute with the same name as the buffer
bufferLayout: [
{name: 'instancePositions', attributes: [{attribute: 'instancePositions', format: 'float32x3'}]},
{name: 'instanceColors', attributes: [{attribute: 'instanceColors', format: 'uint8normx4'}]},
]
A more advanced use case is interleaving: two attributes access the same buffer sin an interleaved way.
Note that this introduces a buffer name that is different from attribute names. This buffer name can be specified in setAttributes({[bufferName]: Buffer})
method on the RenderPipeline
and Model
classes.
bufferLayout: [
{
name: 'particles', stepMode: 'instance', byteStride: 24, attributes: [
// Note that strides are automatically calculated assuming a packed buffer.
{attribute: 'instancePositions', format: 'float32x3', byteOffset: 0},
{attribute: 'instanceVelocities', format: 'float32x3', byteOffset: 12}
]
}
],
In the above case case a new buffer name particles
is defined and setAttributes({particles: Buffer})
calls will recognize that name and bind the provided buffer to all the interleaved attributes.
BufferLayout
Fields
Each BufferLayout
describes how the memory content of one buffer is mapped to one or more shader attributes, via the following fields:
name: string
defines the name of this buffer for use insetAttributes()
methods. THe application is free to select this name.stepMode: 'vertex' | 'instance'
Whether attributes in this buffer will be treated as instanced.byteStride?: number
the stride between elements in the buffer (default assumes a packed buffer)attributes?: BufferAttributeLayout[]
- A list of attributes that will be bound to this buffer.format?: VertexFormat
- Shorthand that allows specification of a single attribute with the same name as the buffer.
Remarks:
Attributes whose name includes the string instance
will default to stepMode: 'instance'
and all other attributes will default to stepMode: 'vertex'
.
One of attributes
and format
must be supplied, but not both.
The format
field is equivalent to specifying {name: _bufferName_, attributes: [{attribute: _layout_.name, format: _layout_.format, byteOffset: 0}]
BufferAttributeLayout
Fields
The attributes field must contain an array of BufferAttributeLayout
objects.
attribute: string
the name of the attribute.format: VertexFormat
the format of (the subset of) the buffer's memory being mapped to this attribute.byteOffset?: number
the offset into the buffer (defaults to0
). This should be a sum of any global offset into the buffer plus any small offset into thebyteStride
for interleaved attributes.
Unfortunately, interleaving attributes into the same buffer does not help avoid the limit on the number of attributes that can be used in a shader (16 on many systems).