简体   繁体   English

将两个不同的网格放在同一个顶点 VBO 中的 OpenGL 最佳实践

[英]OpenGL best practice for putting two different mesh in the same vertex VBO

After some searching, it is said that the separated VAOs which shares the exact same shader attribute layouts, merging these into one VAO and put all these datas into one VBO so that I can draw this objects with only one draw call.经过一番搜索,据说分离的 VAO 共享完全相同的着色器属性布局,将它们合并为一个 VAO 并将所有这些数据放入一个 VBO,这样我就可以只用一次绘制调用来绘制这些对象。

This perfectly makes sense, but how about uniform variables?这完全有道理,但是统一变量呢? Say that I want to draw tree and ball.说我想画树和球。 these have different count of vertices, have different transform but share exactly the same shader program.它们具有不同的顶点数,具有不同的变换,但共享完全相同的着色器程序。

Until now, My program was like直到现在,我的程序就像

// generate VAOs, called only once

glGenVertexArray(1, &treeVaoId);
// generate VBO and bind tree vertices
// enabled vertex attribute and set it for shader program

glGenVertexArray(1, &ballVaoId);
// repeat for ball


// draw, called each frame

// give the tree's transform to shader as uniform
glDrawArrays(...) // first draw call

// repeat for ball
glDrawArrays(...) // second draw call

And with these vertices to one VAO and VBO, like:并将这些顶点连接到一个 VAO 和 VBO,例如:

glGenVertexArray(1, &treeBallId);
// generate enough size of VBO and bind tree vertices and ball vertices after it.
// enabled vertex attribute and set it for shader program

// to draw, I have to separately give transform to it's uniform to each tree and ball, but how?
glDrawArrays(...)

Sorry for poor example, but the point is, Is there a way for giving different uniform variable while drawing one VAO?对不起,举个例子,但重点是,有没有办法在绘制一个 VAO 时给出不同的统一变量? Or, is my approach totally wrong?或者,我的方法完全错误吗?

The purpose of batching is to improve performance by minimizing state changes between draw calls (batching reduces them to 0, since there is nothing between draw calls). 批处理的目的是通过最小化绘制调用之间的状态变化来提高性能(批处理将它们减少到 0,因为绘制调用之间没有任何内容)。 However, there are degrees of performance improvement, and not all state changes are equal.然而,性能提升是有程度的,并不是所有的状态变化都是平等的。

On the scale of the costs of state changes , changing program uniforms is the least expensive state change.状态更改成本范围内,更改程序制服是成本最低的状态更改。 That's not to say that it's meaningless, but you should consider how much effort you really want to spend compared to the results you get out of it.这并不是说它没有意义,而是您应该考虑与从中获得的结果相比,您真正想要花费多少努力。 Especially if you're not pushing hardware as fast as possible.特别是如果您没有尽快推动硬件。

VAO changes (non-buffer-only changes, that is) are among the more expensive state changes, so you gained a lot by eliminating them. VAO 更改(即非缓冲区更改)属于更昂贵的状态更改,因此通过消除它们您可以获得很多。

As the name suggests, uniform variables cannot be changed from one shader instance to another within a draw call.顾名思义,在一次绘制调用中,不能uniform变量从一个着色器实例更改为另一个着色器实例。 Even a multi-draw call.甚至是多次绘制调用。 But that doesn't mean that there's nothing that can be done.但这并不意味着没有什么可以做的。

Multi-draw functionality allows you to issue multiple draw calls in a single function call. 多绘图功能允许您在单个函数调用中发出多个绘图调用。 These individual draws can get their vertex data from different parts of the vertex and index buffers.这些单独的绘制可以从顶点和索引缓冲区的不同部分获取它们的顶点数据。 What you need is a way to communicate to your vertex shader which draw call it is taking part in, so that it can index an array of some sort to extract that draw call's per-object data.您需要的是一种与您的顶点着色器进行通信的方法,它参与了哪个绘制调用,以便它可以索引某种数组以提取该绘制调用的每个对象数据。

Semi-recent hardware has access to gl_DrawID , which is the index into a multi-draw command of the particular draw call being executed.半新硬件 可以访问gl_DrawID ,它是正在执行的特定绘图调用的多绘图命令的索引。 The ARB_shader_draw_parameters extension is fairly widely implemented . ARB_shader_draw_parameters 扩展得到了相当广泛的实现 You can use that index to fetch per-object data from a UBO or SSBO.您可以使用该索引从 UBO 或 SSBO 获取每个对象的数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM