繁体   English   中英

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

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

经过一番搜索,据说分离的 VAO 共享完全相同的着色器属性布局,将它们合并为一个 VAO 并将所有这些数据放入一个 VBO,这样我就可以只用一次绘制调用来绘制这些对象。

这完全有道理,但是统一变量呢? 说我想画树和球。 它们具有不同的顶点数,具有不同的变换,但共享完全相同的着色器程序。

直到现在,我的程序就像

// 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

并将这些顶点连接到一个 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(...)

对不起,举个例子,但重点是,有没有办法在绘制一个 VAO 时给出不同的统一变量? 或者,我的方法完全错误吗?

批处理的目的是通过最小化绘制调用之间的状态变化来提高性能(批处理将它们减少到 0,因为绘制调用之间没有任何内容)。 然而,性能提升是有程度的,并不是所有的状态变化都是平等的。

状态更改成本范围内,更改程序制服是成本最低的状态更改。 这并不是说它没有意义,而是您应该考虑与从中获得的结果相比,您真正想要花费多少努力。 特别是如果您没有尽快推动硬件。

VAO 更改(即非缓冲区更改)属于更昂贵的状态更改,因此通过消除它们您可以获得很多。

顾名思义,在一次绘制调用中,不能uniform变量从一个着色器实例更改为另一个着色器实例。 甚至是多次绘制调用。 但这并不意味着没有什么可以做的。

多绘图功能允许您在单个函数调用中发出多个绘图调用。 这些单独的绘制可以从顶点和索引缓冲区的不同部分获取它们的顶点数据。 您需要的是一种与您的顶点着色器进行通信的方法,它参与了哪个绘制调用,以便它可以索引某种数组以提取该绘制调用的每个对象数据。

半新硬件 可以访问gl_DrawID ,它是正在执行的特定绘图调用的多绘图命令的索引。 ARB_shader_draw_parameters 扩展得到了相当广泛的实现 您可以使用该索引从 UBO 或 SSBO 获取每个对象的数据。

暂无
暂无

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

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