在 WebGL 中插入两个 VBO

Interpolate two VBOs in WebGL

我有两个顶点缓冲区,每个缓冲区在每个元素中存储一系列 XYZ 坐标。如何将两个缓冲区传递给着色器以在每个缓冲区的坐标之间执行线性插值?

例如:

buffer1 = [3, 5, 7, 4, 2, 3 ...etc]
buffer2 = [7, 11, 3, 10, 0, 5 ...etc]

要显示给 canvas 的结果顶点缓冲区应该是:

bufferInterp = [5, 8, 5, 7, 1, 4 ...etc]

我可以按如下方式使用单个顶点缓冲区:

vertexPositionBuffer = vertexPositionBuffer1;
vertexIndexBuffer = vertexIndexBuffer;
gl.bindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer[frameCount]);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, vertexPositionBuffer[0].itemSize, gl.FLOAT, false, 0, 0);

注意这两个对象共享同一个索引缓冲区。

我的顶点着色器定义如下:

var vertexShaderSrc = "attribute vec3 aVertexPosition;\n"
          + "attribute vec2 aTextureCoord;\n"
          + "uniform mat4 uMVMatrix;\n"
          + "uniform mat4 uPMatrix;\n"
          + "varying highp vec2 vTextureCoord;\n"
          + "void main(void) {\n"
          + "gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n"
          + "vTextureCoord = aTextureCoord;\n"
          + "}";

var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSrc);
gl.compileShader(vertexShader);

shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);

gl.useProgram(shaderProgram);

shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);

绑定两个缓冲区,并执行如下操作:

attribute vec3 a_b1;
attribute vec3 a_b2;

void main() {
    float k = ...;                          // interpolation factor
    vec3 pos = a_b1*(1-k) + a_b2*k;
    gl_Position = uMVPMatrix * vec4(pos, 1.0);
}

编辑:

要绑定多个缓冲区,请参阅 "Learning webGL" 上的 lesson。 该教程使用颜色和位置缓冲区,但您可以将任何缓冲区用于您命名它们的任何目的。按照类似的代码,绑定两个以上的缓冲区也是可能的。

在调度绘图调用之前,您应该使用多个 gl.bindBuffer() 并根据 gl.vertexAttribPointer() 函数。以下代码并非您的应用程序所需的确切代码,它只是一个示例。

gl.bindBuffer(gl.ARRAY_BUFFER, buffer1);
gl.vertexAttribPointer(shaderProgram.buffer1Att, buffer1.itemSize, gl.FLOAT, false, 0, 0);

gl.bindBuffer(gl.ARRAY_BUFFER, buffer2);
gl.vertexAttribPointer(shaderProgram.buffer2Att, buffer2.itemSize, gl.FLOAT, false, 0, 0);

gl.drawArrays(gl.TRIANGLES, 0, numItems);