Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

texture! and sampler!

Declare texture and sampler bindings.

texture!

#![allow(unused)]
fn main() {
texture!(group(N), binding(M), NAME: TextureKind<SampleType>);
}

Generates:

@group(N) @binding(M) var NAME: TextureKind<SampleType>;

Texture Kinds

KindDepth variant
Texture1D
Texture2DTextureDepth2D
Texture2DArrayTextureDepth2DArray
Texture3D
TextureCubeTextureDepthCube
TextureCubeArrayTextureDepthCubeArray
TextureMultisampled2D

The sample type for color textures is typically <f32>. Depth textures need no sample type parameter.

Storage Textures

Storage textures (texture_storage_* in WGSL) are declared with TextureStorage types. They take two type parameters: a texel format marker and an access mode marker:

#![allow(unused)]
fn main() {
texture!(group(0), binding(0), OUTPUT: TextureStorage2D<Rgba8unorm, Write>);
}
KindWGSL
TextureStorage1D<F, A>texture_storage_1d<format, access>
TextureStorage2D<F, A>texture_storage_2d<format, access>
TextureStorage2DArray<F, A>texture_storage_2d_array<format, access>
TextureStorage3D<F, A>texture_storage_3d<format, access>

Texel format markers (unit structs implementing WgslTexelFormat):

MarkerWGSL formatValue type
Rgba8unormrgba8unormVec4f
Rgba8uintrgba8uintVec4u
Rgba16floatrgba16floatVec4f
R32uintr32uintVec4u
R32floatr32floatVec4f
Rg32floatrg32floatVec4f
Rgba32floatrgba32floatVec4f
Bgra8unormbgra8unormVec4f

Access mode markers:

MarkerWGSLDescription
ReadreadRead-only (load with texture_load_storage)
WritewriteWrite-only (store with texture_store)
ReadWriteread_writeBoth (requires texture_formats_tier1)

The enable texture_formats_tier1; directive is auto-hoisted to the start of the assembled WGSL translation unit when storage textures are present — you don't need to add it manually.

sampler!

#![allow(unused)]
fn main() {
sampler!(group(N), binding(M), NAME: Sampler);
sampler!(group(N), binding(M), NAME: SamplerComparison);
}

Generates:

@group(N) @binding(M) var NAME: sampler;
@group(N) @binding(M) var NAME: sampler_comparison;

Two-Level Binding

Both macros produce a hidden __NAME static plus a visible pub const NAME: &'static ... so the binding can be passed by value. You reference NAME directly in functions:

#![allow(unused)]
fn main() {
#[wgsl]
pub mod texturing {
    use wgsl_rs::std::*;

    texture!(group(0), binding(0), ALBEDO: Texture2D<f32>);
    sampler!(group(0), binding(1), LIN: Sampler);

    #[fragment]
    pub fn fs_main(
        #[location(0)] uv: Vec2f,
    ) -> Vec4f {
        texture_sample(ALBEDO, LIN, uv)
    }
}
}

Passing to Functions

Texture and sampler bindings are passed by value (no &) — the visible NAME is already a reference:

#![allow(unused)]
fn main() {
pub fn sample_albedo(uv: Vec2f, tex: Texture2D<f32>, smp: Sampler) -> Vec4f {
    texture_sample(tex, smp, uv)
}
}

Notes

  • SamplerComparison is used with textureSampleCompare and textureSampleCompareLevel for shadow maps.
  • Pair each texture with its sampler; binding numbers must not collide within a group.