系列博客总目录:https://segmentfault.com/a/1190000040716735


VertexBuffer 的创立

VertexBuffer 的本体就是一个 GPUBuffer,次要就是指定其 usage,以及在创立 ShaderModule 时配置好 VertexAttribute。

顶点属性,所谓的 VertexAttribute,在 VertexBuffer 中的排列是顶点程序优先。比方在某个 VertexBuffer 中,一个顶点领有 f32 二维坐标属性、f32 RGBA色彩属性,那么它大略长这样:

依次排列↓ 顶点1(24 bytes)         坐标x 坐标y         R重量 G重量 B重量 A重量↓ 顶点2(24 bytes)     坐标x 坐标y          R重量 G重量 B重量 A重量↓ ...

上代码:

const vbodata = new Float32Array([  // 坐标 xy      // 色彩 RGBA  -0.5, 0.0,     1.0, 0.0, 0.0, 1.0, // ← 顶点 1  0.0, 0.5,      0.0, 1.0, 0.0, 1.0, // ← 顶点 2  0.5, 0.0,      0.0, 0.0, 1.0, 1.0  // ← 顶点 3])const vbo = device.createBuffer({  size: vbodata.byteLength,  usage: GPUBufferUsage.VERTEX,  mappedAtCreation: true // 创立时立即映射,让 CPU 端能读写数据})// 实例化一个新的 Float32Array,并获取 GPUBuffer 的映射范畴,传入下面的数据,这样 ArrayBuffer 就有值了new Float32Array(vbo.getMappedRange()).set(vbodata)vbo.unmap() // 肯定要解除映射,GPU 能力读写// ...const vsShaderModule = device.createShaderModule({  code: vsSource,  entryPoint: 'main',  buffers: [    {      shaderLocation: 0,      offset: 0,      format: 'float32x2'    }, {      shaderLocation: 1,      offset: 2 * vbodata.BYTES_PER_ELEMENT,      format: 'float32x4'    }  ]})

WGSL 端承受输出

与 GLSL 略有不同,当新语法学习即可。

WGSL 中当初能够应用构造体作为入口点函数的输入输出,当然也能够只用插槽,见代码中的正文。

/* 顶点着色器阶段 */struct PositionColorInput {  [[location(0)]] in_position_2d: vec2<f32>;  [[location(1)]] in_color_rgba: vec4<f32>;};struct PositionColorOutput {  [[builtin(position)]] coords_output: vec4<f32>;  [[location(0)]] color_output: vec4<f32>;};/*     main 的输出参数除了构造体,还能够是简略的多个参数,例如        fn main(      [[location(0)]] in_position_2d: vec2<f32>,       [[location(1)]] in_color_rgba: vec4<f32>) -> PositionColorOutput {       /* ... */     } 然而 WGSL 函数规定输入只能是单值 本例要向下一个阶段(片元着色器阶段)输入 vbo 中的 colorAttribute,只能应用构造体 */[[stage(vertex)]]fn main(input: PositionColorInput)     -> PositionColorOutput {  var output: PositionColorOutput;  output.color_output = input.in_color_rgba;  output.coords_output = vec4<f32>(input.in_position_2d, 0.0, 1.0);  return output;}

VertexBuffer 的数据传入

向 VBO 传递数据,须要用到勾销映射的 GPUBuffer 和 TypedArray 数组,其次要接口是 渲染通道编码器的 setVertexBuffer() 办法。

参考代码:

// ...passEncoder.setVertexBuffer(0, vbo)// ...