ShaderLayout
A ShaderLayout describes the static interface of a shader pipeline:
- vertex attributes
- bindings such as uniform buffers, storage buffers, textures, and samplers
luma.gl uses ShaderLayout to match named JavaScript resources to the numeric
binding locations used by GPU shaders.
Usage
const shaderLayout = {
attributes: [{name: 'positions', location: 0, type: 'vec3<f32>'}],
bindings: [
{name: 'frameUniforms', type: 'uniform', group: 0, location: 0},
{name: 'lightingUniforms', type: 'uniform', group: 2, location: 0},
{name: 'materialUniforms', type: 'uniform', group: 3, location: 0}
]
};
const pipeline = device.createRenderPipeline({
vs,
fs,
shaderLayout
});
Types
ShaderLayout
type ShaderLayout = {
attributes: AttributeDeclaration[];
bindings: BindingDeclaration[];
uniforms?: any[];
varyings?: VaryingBinding[];
};
ComputeShaderLayout
type ComputeShaderLayout = {
bindings: BindingDeclaration[];
};
Attributes
type AttributeDeclaration = {
name: string;
location: number;
type: AttributeShaderType;
stepMode?: 'vertex' | 'instance';
};
Example:
const shaderLayout = {
attributes: [
{name: 'positions', location: 0, type: 'vec3<f32>'},
{name: 'instanceOffsets', location: 1, type: 'vec2<f32>', stepMode: 'instance'}
],
bindings: []
};
Bindings
Bindings are declared as BindingDeclaration variants such as:
UniformBufferBindingLayoutStorageBufferBindingLayoutTextureBindingLayoutSamplerBindingLayoutStorageTextureBindingLayout
All binding declarations include these core fields:
{
name: string;
group: number;
location: number;
type: ...;
}
group
group is the logical bind-group index for the binding.
Example:
bindings: [
{name: 'frameUniforms', type: 'uniform', group: 0, location: 0},
{name: 'lightingUniforms', type: 'uniform', group: 2, location: 0},
{name: 'materialUniforms', type: 'uniform', group: 3, location: 0},
{name: 'baseColorTexture', type: 'texture', group: 3, location: 1},
{name: 'baseColorSampler', type: 'sampler', group: 3, location: 2}
]
Important details:
locationis the binding index within its group.- Groups can be sparse.
- On WebGL,
groupis still meaningful to luma.gl even though WebGL itself has no native bind-group concept.
Example binding declaration variants
Uniform buffer:
{
name: 'frameUniforms',
type: 'uniform',
group: 0,
location: 0
}
Texture:
{
name: 'baseColorTexture',
type: 'texture',
group: 3,
location: 1,
viewDimension: '2d',
sampleType: 'float'
}
Sampler:
{
name: 'baseColorSampler',
type: 'sampler',
group: 3,
location: 2,
samplerType: 'filtering'
}
WebGPU vs WebGL
WebGPU
WebGPU can use the group and location metadata directly as native bind-group
and binding indices.
WebGL
WebGL reflection does not expose bind-group indices. luma.gl can still preserve logical grouping on WebGL, but it relies on explicit shader-layout metadata or other luma-authored binding metadata rather than GLSL reflection alone.