opengl - 如何将 VBO 中的单个值传递给每个顶点?
问题描述
我有一个 VBO,其中包含一个接一个存储的多个 3d 模型,目的是通过多次调用 glDrawElements 等函数有条件地绘制模型。每个模型都意味着有一个固定的位置。在每次调用 glDrawElements 之前,我可以将模型的位置作为制服传递,但是因为有很多模型这样做是非常昂贵的。
我想将每个模型(而不是每个顶点)的每个模型位置存储在 VBO 内存中一次,并在绘制该模型时从着色器中的每个顶点访问它。
我希望有一个顶点属性指针,其偏移量指向模型位置,步幅为 0,这样它就不会增加每个顶点的内存,但不幸的是,步幅为 0 会使指针向前移动,就好像它很紧打包。
有什么办法可以完成我想要的吗?另外,我很好奇为什么 OpenGL 不允许步长为 0。它会很方便。
解决方案
可以将步幅设置为 0。您只需使用顶点属性绑定 API。设置的步幅可以为 0,并且具有预期的含义(因为无法从可用参数glBindVertexBuffer
中确定紧凑的步幅应该是什么)。
但是,如果您这样做是为了提高性能,那么这并不是特别有用。要在 VBO 中切换到不同的值,您必须发出glBindVertexBuffer
调用,这将与glProgramUniform
调用一样昂贵。事实上,根据 NVIDIA 的AZDO 演示文稿,更改制服比顶点缓冲区绑定更便宜。
如果您想节省统一更新的成本,那么您将不得不使用其他东西。您最好的选择是将您的每个网格“制服”放入 SSBO(或 UBO,如果您没有那么多模型),然后一次绘制所有网格(因此它们必须来自相同的顶点缓冲区具有相同的顶点格式)使用单个glMultiDraw*
命令。然后您必须使用 GL 4.6/ARB_shader_draw_parameters 功能从您的着色器访问gl_DrawID
,以选择从 SSBO 数组中提取哪个“统一”值。
这允许您使用单个绘制命令绘制所有这些对象。
推荐阅读
- apache - SVN 无法打开密码文件
- python - 如何在openpyxl中将列宽设置为bestFit
- javascript - 如何在每个完整的三个单词后插入换行符?
- tensorflow - 从 TFRecord 解析字段名称和类型
- java - 获取任意数量元素的所有组合
- r - 如何避免错误:$ 运算符对于使用 R 中的 precintcon 包的原子向量无效?
- rust - 如何从 Pin 中获取 Pin<&mut T>
>> - react-native - 检查 BottomNavigation - React Native 的渲染方法
- python - Pandas 中的 SQL 查询连接
- reactjs - React 中的 public 文件夹基本上应该包含什么