Performance WebGL-何时调用bindBuffer和VertexAttribute指针?

Performance WebGL-何时调用bindBuffer和VertexAttribute指针?,performance,optimization,webgl,vertex-buffer,Performance,Optimization,Webgl,Vertex Buffer,此问题特定于WebGL,假设VAO不可用 我试图通过限制低级状态更改的数量,对3D引擎进行一些小的改进。但事实证明,我对使用bindBuffer和vertexattributepointer的正确方法有点困惑 假设我想画两个对象: 第一个对象使用两个缓冲区A和C以及元素缓冲区E 第二个对象使用具有相同元素缓冲区E的缓冲区B和C 缓冲区A和B使用相同的布局,并且都由位置0引用,而C由位置1引用 最初,ARRAY\u BUFFER\u BINDING指向null,而ELEMENT\u ARRAY

此问题特定于WebGL,假设VAO不可用

我试图通过限制低级状态更改的数量,对3D引擎进行一些小的改进。但事实证明,我对使用
bindBuffer
vertexattributepointer
的正确方法有点困惑

假设我想画两个对象:

  • 第一个对象使用两个缓冲区A和C以及元素缓冲区E
  • 第二个对象使用具有相同元素缓冲区E的缓冲区B和C
缓冲区A和B使用相同的布局,并且都由位置0引用,而C由位置1引用

最初,
ARRAY\u BUFFER\u BINDING
指向null,而
ELEMENT\u ARRAY\u BUFFER\u BINDING
指向E

冗余检查器输出以下内容,其中(A、B、C、E)=(3、6、5、2):

这意味着:

  • bindBuffer(元素数组缓冲区,[BUFFER 2])
    是不必要的
  • VertexAttributePointer(1,2,FLOAT,false,0,0)
    本来可以避免的
  • 由于WebGL可以直接读取
    元素数组缓冲区绑定
    以了解索引的存储位置,1。对我来说有道理

    然而,2。这意味着缓冲区布局存储在VBO内部,这是错误的,因为缓冲区A和B在第15行和第30行上不被视为冗余。(已经渲染了多个帧,因此它们应该保持其状态)

    我想我对
    drawerelements
    如何知道使用什么缓冲区以及在哪里/何时存储缓冲区布局感到困惑


    在本例中,
    bindBuffer
    vertexattributepointer
    的最佳用途是什么?为什么?

    事实上,我想我只需查看

    有两件重要的事情需要知道:

    • 缓冲区布局是按每个位置绑定的,而不是按VBO绑定的
    • VertexAttributePointer
      还将将当前缓冲区分配给给定位置
    在内部,WebGL在每个位置保留6个参数:

    VERTEX_ATTRIB_ARRAY_SIZE_X
    VERTEX_ATTRIB_ARRAY_TYPE_X
    VERTEX_ATTRIB_ARRAY_NORMALIZED_X
    VERTEX_ATTRIB_ARRAY_STRIDE_X
    VERTEX_ATTRIB_ARRAY_POINTER_X
    VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_X
    
    下面是
    VertexAttributePointer
    的作用:

    function vertexAttribPointer(indx, size, type, normalized, stride, offset) {
        this.stateCache["VERTEX_ATTRIB_ARRAY_SIZE_" + indx] = size;
        this.stateCache["VERTEX_ATTRIB_ARRAY_TYPE_" + indx] = type;
        this.stateCache["VERTEX_ATTRIB_ARRAY_NORMALIZED_" + indx] = normalized;
        this.stateCache["VERTEX_ATTRIB_ARRAY_STRIDE_" + indx] = stride;
        this.stateCache["VERTEX_ATTRIB_ARRAY_POINTER_" + indx] = offset;
        this.stateCache["VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_" + indx] = this.stateCache["ARRAY_BUFFER_BINDING"];
    }
    
    最后,WebGL检查员是真的!第15行和第30行的状态更改是必要的,因为顶点属性数组缓冲区绑定0正在更改

    以下是最佳跟踪:

    bindBuffer(ARRAY_BUFFER, A)
    vertexAttribPointer(0, 3, FLOAT, false, 0, 0)
    drawElements(TRIANGLES, 768, UNSIGNED_BYTE, 0)
    bindBuffer(ARRAY_BUFFER, B)
    vertexAttribPointer(0, 3, FLOAT, false, 0, 0)
    drawElements(TRIANGLES, 768, UNSIGNED_BYTE, 0)
    

    bindBuffer(ARRAY\u BUFFER,C)
    不再需要了,因为我们没有对它做任何事情。)

    事实上,我想我只需查看

    有两件重要的事情需要知道:

    • 缓冲区布局是按每个位置绑定的,而不是按VBO绑定的
    • VertexAttributePointer
      还将将当前缓冲区分配给给定位置
    在内部,WebGL在每个位置保留6个参数:

    VERTEX_ATTRIB_ARRAY_SIZE_X
    VERTEX_ATTRIB_ARRAY_TYPE_X
    VERTEX_ATTRIB_ARRAY_NORMALIZED_X
    VERTEX_ATTRIB_ARRAY_STRIDE_X
    VERTEX_ATTRIB_ARRAY_POINTER_X
    VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_X
    
    下面是
    VertexAttributePointer
    的作用:

    function vertexAttribPointer(indx, size, type, normalized, stride, offset) {
        this.stateCache["VERTEX_ATTRIB_ARRAY_SIZE_" + indx] = size;
        this.stateCache["VERTEX_ATTRIB_ARRAY_TYPE_" + indx] = type;
        this.stateCache["VERTEX_ATTRIB_ARRAY_NORMALIZED_" + indx] = normalized;
        this.stateCache["VERTEX_ATTRIB_ARRAY_STRIDE_" + indx] = stride;
        this.stateCache["VERTEX_ATTRIB_ARRAY_POINTER_" + indx] = offset;
        this.stateCache["VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_" + indx] = this.stateCache["ARRAY_BUFFER_BINDING"];
    }
    
    最后,WebGL检查员是真的!第15行和第30行的状态更改是必要的,因为顶点属性数组缓冲区绑定0正在更改

    以下是最佳跟踪:

    bindBuffer(ARRAY_BUFFER, A)
    vertexAttribPointer(0, 3, FLOAT, false, 0, 0)
    drawElements(TRIANGLES, 768, UNSIGNED_BYTE, 0)
    bindBuffer(ARRAY_BUFFER, B)
    vertexAttribPointer(0, 3, FLOAT, false, 0, 0)
    drawElements(TRIANGLES, 768, UNSIGNED_BYTE, 0)
    
    bindBuffer(ARRAY\u BUFFER,C)
    不再需要了,因为我们不再使用它。)