• 版块
  • 最新
  • 标签
皮肤
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • 默认(不使用皮肤)
  • 不使用皮肤
折叠

Orillusion

3

在线

550

用户

171

主题

456

帖子

WebGPU 中消失的 VAO

已定时 已固定 已锁定 已移动 中文社区
vaovbowebgpuwebglopengl
1 帖子 1 发布者 154 浏览
    • 从旧到新
    • 从新到旧
    • 最多赞同
回复
  • 在新帖中回复
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • 寻风觅迹寻 离线
    寻风觅迹寻 离线
    寻风觅迹
    写于 最后由 编辑
    #1

    1 VAO 是 OpenGL 技术中提出来的

    参考:

    https://www.khronos.org/opengl/wiki/Tutorial2:_VAOs,VBOs,Vertex_and_Fragment_Shaders(C/_SDL)

    其中有一段文字记录了 VAO 是什么:

    A Vertex Array Object (VAO) is an object which contains one or more Vertex Buffer Objects and is designed to store the information for a complete rendered object. In our example this is a diamond consisting of four vertices as well as a color for each vertex.

    VAO 记录的是多个(一组) VBO 的 gl.bindBuffer 和 gl.vertexAttribPointer (WebGL API)的状态,省去切换另一组 VBO 时再次设置绑定关系和读取规则的成本。

    里面也描述了 VBO 是什么:一个 VBO 可以是 position,也可以是 uv,甚至可以是 indices;当然,在 WebGL 中,你可以用 1 个 VBO 来存储 position + uv + normal,但是不能和 indices 混用(和 type 有关)。

    2 WebGPU 天生就能先保存状态

    WebGPU 不需要 VAO 了,源于 WebGPU 的机制,并不是过程式,所以不需要借助 VAO 保存绑定一组 VBO 并读取它的状态。

    2.1 WebGL 与 WebGPU 相关 API 对比

    当 device.createShaderModule 时,就有 buffers 属性描述着色器需要什么类型的数据,类似 gl.vertexAttribPointer 的作用;

    而 gl.bindBuffer 的操作则由 renderPass.setVertexBuffer 完成;

    关于数据的传递,gl.bufferData 的任务就由 device.createBuffer 时通过映射、解映射的机制将 TypedArray 传递进 GPUBuffer 来替代

    2.2 谁替代了 VAO?

    那么谁能在渲染时告诉着色器,我有多组 VBO 要切换呢?

    准确的说,VBO 这个概念已经被 GPUBuffer + GPUShaderModule 替代了,由后者两个对象共同分担,GPUBuffer 专注于 cpu~gpu 的数据传递,GPUShaderModule 不仅仅是着色器代码本身,还承担着 GPUBuffer[type=vertex] 的数据如何读取的职能(替代了 gl.vertexAttribPointer 的职能)。

    VAO 的职能则转至 GPURenderPipeline 完成,其 GPURenderPipelineDescriptor.GPUVertexState.buffers 属性是 GPUVertexBufferLayout[] 类型的,这每一个 GPUVertexBufferLayout 对象就类似于 VAO 的职能。

    2.3 代码举例

    下列只有一个 GPUVertexBufferLayout:

    const renderPipeline = device.createRenderPipeline({
      /* ... */
      vertex: {
        module: device.createShaderModule({
          code: ` /* wgsl vertex shader code */ `,
        }),
        entryPoint: 'vertex_main',
        buffers: [
          {
            arrayStride: 4 * 5, // 一个顶点数据占 20 bytes
            attributes: [
              {
                // for Position VertexAttribute
                shaderLocation: 0,
                offset: 0,
                format: "float32x3" // 其中顶点的坐标属性占 12 字节,三个 float32 数字
              },
              {
                // for UV0 VertexAttribute
                shaderLocation: 1,
                offset: 3 * 4,
                format: "float32x2" // 顶点的纹理坐标占 8 字节,两个 float32 数字
              }
            ]
          }
        ]
      }
    })
    

    下面有两个 GPUVertexBufferLayout:

    const renderPipeline = device.createRenderPipeline({
      vertex: {
        module: spriteShaderModule,
        entryPoint: 'vert_main',
        buffers: [
          {
            arrayStride: 4 * 4,
            stepMode: 'instance',
            attributes: [
              {
                // instance position
                shaderLocation: 0,
                offset: 0,
                format: 'float32x2',
              },
              {
                // instance velocity
                shaderLocation: 1,
                offset: 2 * 4,
                format: 'float32x2',
              },
            ],
          },
          {
            arrayStride: 2 * 4,
            stepMode: 'vertex',
            attributes: [
              {
                // vertex positions
                shaderLocation: 2,
                offset: 0,
                format: 'float32x2',
              },
            ],
          },
        ],
      },
      /* ... */
    });
    

    通过 renderPassEncoder.setVertexBuffer 就能切换 VBO 了:

    renderPassEncoder.setVertexBuffer(0, bf0);
    renderPassEncoder.setVertexBuffer(1, bf1);
    
    1 条回复 最后回复
    0

Copyright © 2023 Orillusion | Contact US

  • 登录

  • 没有帐号? 注册

  • 登录或注册以进行搜索。
  • 第一个帖子
    最后一个帖子
0
  • 版块
  • 最新
  • 标签
  • 登录

  • 没有帐号? 注册

  • 登录或注册以进行搜索。