欢迎光临
我们一直在努力

WebGPU 纹理格式与采样器配置细节

WebGPU 纹理格式与采样器配置细节

封面信息图

从 WebGL 迈入 WebGPU,最显著的思维转变在于:隐式的全局状态机被彻底废除,取而代之的是显式的资源创建与不可变的管线对象(Pipeline Objects)。

在 WebGL 中,纹理绑定往往依赖 gl.bindTexture 与 gl.texParameteri 的运行时状态切换,极易出现状态遗漏或驱动层性能抖动。而在 WebGPU 中,纹理(GPUTexture)、纹理视图(GPUTextureView)与采样器(GPUSampler)被解耦为三个完全独立的显存与计算实体。

搞清楚纹理格式与采样器的底层配置细节,是写出高性能 WebGPU 渲染与通用计算(GPGPU)着色器的基石。


纹理格式(GPUTextureFormat)选型图谱

WebGPU 提供了极其严谨的纹理格式定义,常见的格式主要分为以下几类:

  • 标准色彩格式:
    • rgba8unorm / bgra8unorm:最常用的 8 位无符号归一化整数格式,每个通道映射到 $[0.0, 1.0]$,显存占用 4 字节/像素。bgra8unorm 通常作为 Canvas 上下文(navigator.gpu.getPreferredCanvasFormat())的推荐格式以匹配操作系统原生显示。
    • rgba8unorm-srgb:带 sRGB 非线性伽马校正的色彩格式,适合色彩准确度要求极高的 UI 与材质贴图。
  • 高动态范围与浮点格式:
    • rgba16float / rgba32float:用于 HDR 渲染、后期辉光(Bloom)或 GPGPU 粒子物理位置计算。注意:并非所有移动端 GPU 都支持对 32 位浮点纹理进行线性滤波采样(Filtering)。
  • 深度与模板格式:
    • depth24plus / depth24plus-stencil8 / depth32float:用于 Z-Buffer 遮挡剔除与阴影映射。

  • 显式使用意图:GPUTextureUsage 的严格约束

    在 WebGPU 中,必须在创建纹理时通过位掩码(Bitmask)提前声明该纹理的所有使用场景,以便底层图形驱动进行显存分配与管线优化:

    export async function createStandardTexture(
    device: GPUDevice,
    imageBitmap: ImageBitmap
    ): Promise<{ texture: GPUTexture; view: GPUTextureView }> {
    const texture = device.createTexture({
    size: [imageBitmap.width, imageBitmap.height, 1],
    format: 'rgba8unorm',
    // 显式声明:该纹理将被作为着色器采样资源,且允许从 CPU 写入数据
    usage:
    GPUTextureUsage.TEXTURE_BINDING |
    GPUTextureUsage.COPY_DST |
    GPUTextureUsage.RENDER_ATTACHMENT,
    });

    // 使用 writeTexture 将位图数据上传至 GPU 显存
    device.queue.copyExternalImageToTexture(
    { source: imageBitmap },
    { texture: texture },
    [imageBitmap.width, imageBitmap.height]
    );

    const view = texture.createView();
    return { texture, view };
    }


    采样器(GPUSampler)的核心配置与抗锯齿

    采样器负责在着色器执行 textureSample() 时,定义如何根据 UV 坐标在离散的纹理像素点之间进行插值。

    1. 过滤模式(Filtering)与 Mipmap
    • magFilter(放大过滤):当一个纹理像素覆盖多个屏幕像素时生效(近景)。
    • minFilter(缩小过滤):当多个纹理像素缩在一个屏幕像素内时生效(远景)。
    • mipmapFilter:在不同层级的 Mipmap 贴图之间进行插值。设置为 linear 即开启三线性过滤(Trilinear Filtering),能极大消除摩尔纹与走样。
    2. 各向异性过滤(Anisotropic Filtering)

    当以大斜角观察地表或墙面时,普通的各向同性过滤会导致远景严重模糊。通过配置 maxAnisotropy: 16,采样器会在沿视线倾斜方向进行椭圆多重采样,恢复清晰的细节:

    export function createHighQualitySampler(device: GPUDevice): GPUSampler {
    return device.createSampler({
    addressModeU: 'repeat', // U 轴平铺
    addressModeV: 'repeat', // V 轴平铺
    addressModeW: 'clamp-to-edge',
    magFilter: 'linear', // 双线性放大
    minFilter: 'linear', // 双线性缩小
    mipmapFilter: 'linear', // 开启三线性 Mipmap 混合
    maxAnisotropy: 16, // 开启最高 16x 各向异性过滤
    });
    }

    export function createShadowComparisonSampler(device: GPUDevice): GPUSampler {
    return device.createSampler({
    compare: 'less', // 开启硬件深度比较采样
    magFilter: 'linear',
    minFilter: 'linear',
    });
    }


    WGSL 着色器中的纹理与采样器绑定

    在 WGSL 着色器代码中,采样器与纹理作为独立的 Bind Group 条目注入:

    // WGSL 片元着色器示例
    @group(0) @binding(0) var mySampler: sampler;
    @group(0) @binding(1) var myTexture: texture_2d<f32>;

    struct VertexOutput {
    @builtin(position) position: vec4<f32>,
    @location(0) uv: vec2<f32>,
    };

    @fragment
    fn fs_main(input: VertexOutput) -> @location(0) vec4<f32> {
    // 使用采样器对纹理进行双线性/各向异性采样
    let color: vec4<f32> = textureSample(myTexture, mySampler, input.uv);
    return color;
    }

    在阴影计算中,如果使用了比较采样器(sampler_comparison),WGSL 提供了 textureSampleCompare 函数:

    @group(0) @binding(2) var shadowSampler: sampler_comparison;
    @group(0) @binding(3) var shadowMap: texture_depth_2d;

    fn calculateShadow(shadowCoords: vec3<f32>) -> f32 {
    // 硬件直接完成深度对比并返回 [0.0, 1.0] 的阴影遮挡因子
    return textureSampleCompare(shadowMap, shadowSampler, shadowCoords.xy, shadowCoords.z);
    }

    从粗糙的全局状态控制转向精密的管线与采样器配置,WebGPU 赋予了前端开发者直面现代 GPU 硬件微架构的能力。

    赞(0)
    未经允许不得转载:171主机测评 » WebGPU 纹理格式与采样器配置细节
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址