Resources
Accessing uniforms, textures, buffers, samplers, and storage images through the resources namespace.
Pressure-test the syntax
Take the concept from this page into the playground and deliberately break a pass, binding, or type signature to see how the compiler responds.
Try a Live EditShader-visible resources are declared in the pipeline with resources {} and accessed through resources.* from stages that opt into them.
float4 albedo = sample(resources.albedoTexture, resources.albedoSampler, input.uv);
mat4 viewProj = resources.projectionMatrix * resources.viewMatrix;
Particle p = resources.particles[input.instance_id];
Where Resources Come From
Resources are declared in a pipeline-level resources {} block:
resources {
viewMatrix: mat4
projectionMatrix: mat4
time: float
albedoTexture: texture2D
albedoSampler: sampler
particles: buffer<Particle>
}
Each pass selects the resources it uses:
pass "Main" {
use resources { viewMatrix, projectionMatrix, time, albedoTexture, albedoSampler }
fragment {
float4 albedo = sample(resources.albedoTexture, resources.albedoSampler, input.uv);
output.color = albedo;
}
}
The compiler resolves usage from source, assigns bindings automatically, and emits reflection for the host. The resource block is the public declaration surface for shader-visible host data.
Common resource types include:
- scalar, vector, and matrix values such as
float,float3, andmat4 - custom structs, including structs defined in imported modules
- textures such as
texture2D,texture3D,textureCube, andtexture2DArray sampler- buffers such as
buffer<Particle>andcbuffer<CameraData> - storage images where supported
The exact resource type controls how it can be used from BWSL.
Struct Resource Types
Resources can use local struct types:
struct CameraData {
mat4 viewProj;
float3 cameraPosition;
};
resources {
camera: CameraData
}
They can also use structs defined in imported modules. Module-defined resource payloads use Module.Type spelling in the resources {} block:
module RenderTypes {
struct FrameData {
float4[4] transforms;
};
}
pipeline ModuleResourcePayload {
import RenderTypes
attributes {
position: float3
}
resources {
frame: RenderTypes.FrameData
}
pass "Main" {
use attributes { position }
use resources { frame }
vertex {
float4 transform = resources.frame.transforms[0];
float2 p = attributes.position.xy * transform.zw + transform.xy;
output.position = float4(p, attributes.position.z, 1.0);
}
fragment {
output.color = float4(1.0);
}
}
}
After declaration, access fields and arrays through resources.<name> like any other resource.
Selecting Resources Per Pass
use resources is pass-scoped. A resource must be selected before that pass can access resources.<name>.
pass "Shadow" {
use resources { lightViewProj }
vertex {
output.position = resources.lightViewProj * float4(attributes.position, 1.0);
}
fragment = null
}
Resources can also be optional. Optional resources create implicit variant facts that can be used for specialization:
pass "Main" {
use resources { albedoTexture?, albedoSampler? }
fragment {
if (variants.has_resource_albedoTexture && variants.has_resource_albedoSampler) {
output.color = sample(resources.albedoTexture, resources.albedoSampler, input.uv);
} else {
output.color = float4(1.0);
}
}
}
Uniforms and Buffers
Uniforms and buffers are read with normal member or index access:
float time = resources.time;
mat4 vp = resources.projectionMatrix * resources.viewMatrix;
Particle particle = resources.particles[input.instance_id];
Sampled Textures
Sampled textures can be accessed through reflected texture bindings:
float4 texel = sample(resources.albedoTexture, resources.albedoSampler, input.uv);
Storage Images
Storage images are used with load and store style intrinsics:
float4 texel = load(resources.inputImage, int2(4, 8), 0);
store(resources.outputImage, int2(4, 8), texel);
Stage Validation
Resource access is validated against how the resource is actually used in the pipeline.
That means:
- invalid stage/resource access is rejected during compilation
- unsupported backend bindings can be surfaced through reflection before runtime
Typical Patterns
Graphics:
vertex {
output.position = resources.mvp * float4(attributes.position, 1.0);
}
fragment {
float4 albedo = sample(resources.albedoTexture, resources.albedoSampler, input.uv);
output.color = albedo;
}
Compute:
compute "Main" [16, 16, 1] {
uint2 gid = input.global_id.xy;
float4 value = load(resources.inputImage, int2(gid), 0);
store(resources.outputImage, int2(gid), value);
}