在 WebGL 中插入两个 VBO

Posted

技术标签:

【中文标题】在 WebGL 中插入两个 VBO【英文标题】:Interpolate two VBOs in WebGL 【发布时间】:2015-04-02 15:27:58 【问题描述】:

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

例如:

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

要显示到画布的结果顶点缓冲区应该是:

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);

【问题讨论】:

【参考方案1】:

绑定两个缓冲区,然后执行以下操作:

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);

编辑:

要绑定多个缓冲区,请参阅“学习 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);

【讨论】:

感谢您的回答。这是我想要实现的,但是如何绑定两个缓冲区? 已编辑答案。从教程代码中应该很明显,绑定缓冲区数量并在着色器中使用它们的确切途径是什么。希望对您有所帮助。 感谢您提供额外信息。你帮了大忙!

以上是关于在 WebGL 中插入两个 VBO的主要内容,如果未能解决你的问题,请参考以下文章

Cesium原理篇:6 Render模块(3: Shader)

渲染一个包含两个 VBO 的 VAO

WebGL 与 WebGPU比对[3]

对两个对象使用相同的 VBO 好吗?

Qtopengl,为啥不能使用不同的vbo绘制两个立方体

当在两个不同的vbo之间进行插值时,网格面向迷失方向