如何将模型矩阵包含到 VBO 中? [英] How to include model matrix to a VBO?

查看:34
本文介绍了如何将模型矩阵包含到 VBO 中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想发送一个缓冲区列表(到 GPU/顶点着色器),其中包含有关顶点位置、世界位置、颜色、比例和旋转的信息.

如果我的每个 3D 对象在矩阵中都有与变换相关的信息,我如何通过 VBO(s)将这个矩阵数组(除了其他顶点数据)传递给 GPU?

已更新请原谅任何错别字:

//绑定 &设置顶点.gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);gl.vertexAtribPointer(a_Position, 3, gl.FLOAT, false, stride, 0);//绑定 &设置顶点法线.gl.bindBuffer(gl.ARRAY_BUFFER,, vertexNormalsBuffer);gl.vertexAttribPointer(a_Normal, 3, gl.FLOAT, false, stride, 0);//因为我不能通过 VBO 传入模型矩阵,我试图传入我的世界坐标.gl.bindBuffer(gl.ARRAY_BUFFER, worldPositionBuffer);//不知道为什么我需要这样做,但我读过的大多数教程都说要这样做.gl.bindBuffer(gl.ARRAY_BUFFER, null);//绑定 &绘制索引缓冲区.gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer);gl.drawElements(gl.TRIANGLES, vertexIndexCount, gl.UNSIGNED_SHORT, 0);

请注意,这些缓冲区(vertexBuffervertexNormalsBufferworldPostiionBuffervertexIndexBuffer)是所有我的场景中的各个 3D 对象(我通过属性/制服逐个渲染 - 这是一种更简单、更容易掌握的幼稚方法,但对于 1000 个对象来说却非常慢).

解决方案

对于渲染帧时需要频繁更改的任何值,将它们作为 属性传递到着色器中会更有效

code> 而不是 uniform.这还有一个优点,您可以选择将值存储在 VBO 中.请注意,在 VBO 中存储属性不是必需,它们也可以用 glVertexAttrib[1234]f()glVertexAttrib[1234]fv().

这适用于转换矩阵,就像传递给着色器的任何其他值一样.如果它经常更改,您可能应该将其设为一个属性.在这种情况下唯一的小问题是我们正在处理一个矩阵,并且属性必须是向量.但这很容易克服.通常作为 mat4 传入的内容可以用 vec4 类型的 3 个值表示,其中这 3 个向量是矩阵的列向量.表示完全通用的 4x4 矩阵当然是 4 个向量,但变换矩阵中的第 4 列不用于任何常见的变换类型(投影矩阵除外).

如果您希望在 VBO 中进行转换,您可以再设置 3 个属性,就像您已经为您的位置和颜色所做的那样.你存储在 VBO 中的属性值就是对应变换矩阵的列向量.

然后在顶点着色器中,通过计算变换属性向量与输入位置的点积来应用变换.代码可能如下所示:

 属性 vec4 InPosition;属性 vec4 XTransform;属性 vec4 YTransform;属性 vec4 ZTransform;主要的() {vec3 眼睛位置 = vec3(点(XTransform,InPosition),点(YTransform,InPosition),点(ZTransform,InPosition));...}

在完整的 OpenGL 中还有其他方法可以解决这个问题,比如使用统一缓冲区对象.但是对于 WebGL 和 OpenGL ES 2.0,我认为这是最好的解决方案.

I want to send a buffer list (to the GPU/vertex shader) which contains information about vertex position, world position, color, scale, and rotation.

If each of my 3D objects have transformation related information in a matrix, how can i pass this array of matrices (in addition to the other vertex data) to the GPU via the VBO(s) ?

Updated Please excuse any typos:

// bind & set vertices.
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.vertexAtribPointer(a_Position, 3, gl.FLOAT, false, stride, 0);

// bind & set vertex normals.
gl.bindBuffer(gl.ARRAY_BUFFER,, vertexNormalsBuffer);
gl.vertexAttribPointer(a_Normal, 3, gl.FLOAT, false, stride, 0);

// becaue i cant pass in a model matrix via VBO, im tryng to pass in my world coordinates.
gl.bindBuffer(gl.ARRAY_BUFFER, worldPositionBuffer);

// not sure why i need to do this, but most tutorials i've read says to do this.
gl.bindBuffer(gl.ARRAY_BUFFER, null);

// bind & draw index buffer.
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer);
gl.drawElements(gl.TRIANGLES, vertexIndexCount, gl.UNSIGNED_SHORT, 0);

Note that these buffers (vertexBuffer, vertexNormalsBuffer, worldPostiionBuffer, vertexIndexBuffer) are a concatenation of all the respective 3D objects in my scene (which i was rendering one-by-one via attributes/uniforms - a naive approach which is much simpler and easier to grasp, yet horribly slow for 1000's objects).

解决方案

For any values that you need to change frequently while rendering a frame, it can be more efficient to pass them into the shader as an attribute instead of a uniform. This also has the advantage that you can store the values in a VBO if you choose. Note that it's not required to store attributes in VBOs, they can also be specified with glVertexAttrib[1234]f() or glVertexAttrib[1234]fv().

This applies to the transformation matrix like any other value passed into the shader. If it changes very frequently, you should probably make it an attribute. The only slight wrinkle in this case is that we're dealing with a matrix, and attributes have to be vectors. But that's easy to overcome. What is normally passed in as a mat4 can be represented by 3 values of type vec4, where these 3 vectors are the column vectors of the matrix. It would of course be 4 vectors to represent a fully generic 4x4 matrix, but the 4th column in a transformation matrix is not used for any common transformation types (except for projection matrices).

If you want the transformations to be in the VBO, you set up 3 more attributes, the same way you already did for your positions and colors. The values of the attributes you store in the VBO are the column vectors of the corresponding transformation matrix.

Then in the vertex shader, you apply the transformation by calculating the dot product of the transformation attribute vectors with your input position. The code could look like this:

attribute vec4 InPosition;
attribute vec4 XTransform;
attribute vec4 YTransform;
attribute vec4 ZTransform;
main() {
    vec3 eyePosition = vec3(
        dot(XTransform, InPosition),
        dot(YTransform, InPosition),
        dot(ZTransform, InPosition));
    ...
}

There are other approaches to solve this problem in full OpenGL, like using Uniform Buffer Objects. But for WebGL and OpenGL ES 2.0, I think this is the best solution.

这篇关于如何将模型矩阵包含到 VBO 中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆