@builtin
装饰器 这些是GPU硬件自动提供的内置值:
js@builtin(position) position: vec4f // 顶点在屏幕空间的位置
@builtin(vertex_index) vertexIndex: u32 // 当前顶点的索引号
@builtin(instance_index) instanceIndex: u32 // 实例索引
@location
装饰器 用于在着色器阶段之间传递自定义数据:
js@location(0) texcoord: vec2f, // 纹理坐标
@location(1) color: vec3f, // 颜色
@location(2) normal: vec3f, // 法向量
js// 获取适配器和设备
const adapter = await navigator.gpu?.requestAdapter();
const device = await adapter?.requestDevice();
jsconst canvas = document.querySelector('canvas');
const context = canvas.getContext('webgpu');
context.configure({
device,
format: presentationFormat, // 像素格式
});
jsconst pipeline = device.createRenderPipeline({
label: 'hardcoded textured quad pipeline',
layout: 'auto', // 自动推断绑定组布局
vertex: {
module, // 顶点着色器模块
},
fragment: {
module, // 片段着色器模块
targets: [{ format: presentationFormat }],
},
});
用于将资源绑定到着色器:
绑定组布局:
js┌─────────────────────────────────────┐
│ @group(0) @binding(0) ourSampler │ ← 采样器
│ @group(0) @binding(1) ourTexture │ ← 纹理
└─────────────────────────────────────┘
|
JavaScript中对应:
┌─────────────────────────────────────┐
│ binding: 0 → sampler │
│ binding: 1 → texture.createView() │
└─────────────────────────────────────┘
jsconst texture = device.createTexture({
size: [kTextureWidth, kTextureHeight],
format: 'rgba8unorm', // 每个通道8位,归一化到[0,1]
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST,
});
jsfunction render() {
// 1. 获取当前帧缓冲
renderPassDescriptor.colorAttachments[0].view =
context.getCurrentTexture().createView();
// 2. 创建命令编码器
const encoder = device.createCommandEncoder();
// 3. 开始渲染通道
const pass = encoder.beginRenderPass(renderPassDescriptor);
// 4. 设置管线和资源
pass.setPipeline(pipeline);
pass.setBindGroup(0, bindGroup);
// 5. 绘制
pass.draw(6); // 绘制6个顶点(2个三角形)
// 6. 结束并提交
pass.end();
device.queue.submit([encoder.finish()]);
}
jsWebGPU 标准化设备坐标 (NDC)
Y
↑
(-1,1) | (1,1)
----+----→ X
(-1,-1) | (1,-1)
|
纹理坐标 (0 到 1)
Y
↑
(0,1) | (1,1)
----+----→ X
(0,0) | (1,0)
|
本文作者:幽灵
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 幽灵AI 许可协议。转载请注明出处!