【OpenGL经验谈01】Vertex 规范最佳实践

目录

  • 一、概述
  • 二、缓冲区对象的大小
  • 三、格式化VBO数据
    • 3.1 最小化顶点状态变化
    • 3.2 属性大小
    • 3.3 交织
    • 3.4 流属性
  • 四、顶点、法线、特坐标
  • 五、动态VBO
  • 六、顶点布局规范

一、概述

在使用GLSL中,越是深入使用,越觉得难以把控,而且常常是黑屏无Debug状态。究其原因,buffer需要优化,程序需要优化,本文从buffer的角度提出问题和解决方案。

二、缓冲区对象的大小

在为缓冲区对象分配存储时,可以使用任何大小。但是,有一些规则需要牢记。

创建大量微小缓冲区(大小约为千字节)可能会导致驱动程序问题。某些驱动程序只能从图形内存进行如此多的分配,而不管这些分配的大小如何。请注意,“很多”可能意味着数千。因此,将较小的对象放在一个大缓冲区中是个好主意。

缓冲区大小存在两个相互竞争的问题。

较大的缓冲区意味着将多个对象放在一个缓冲区中。这允许您渲染更多对象,而无需更改缓冲区对象状态。从而提高性能。
较大的缓冲区意味着将多个对象放在一个缓冲区中。但是,映射缓冲区意味着不能使用整个缓冲区(除非永久映射它)。因此,如果一个对象中有多个对象,并且需要映射一个对象的数据,则在修改该对象时,其他对象将无法使用。

三、格式化VBO数据

VBO 在使用它们的方式上非常灵活。例如,有多种方法可以在 VBO 中表示顶点属性数据:

(VVVV) (NNNN) (CCCC)
使用它们的一种选择是,对于每个批处理(绘制调用),为每个顶点属性分配一个单独的 VBO。这当然是可能的。如果将顶点、法线和颜色作为顶点属性,则从图形上看,这是:(VVVVV) (NNNN) (CCCC)
(VVVVNNNNCCCC)
另一种方法是将顶点属性块批量存储在同一个块中,一个接一个地存储在同一个块中,并将它们全部填充到同一个 VBO 中。通过 glVertexAttribPointer 调用指定顶点属性时,需要将字节偏移量传递到 VBO 中,以传递给 ptr 参数。从图示上看,这是:(VVVVNNNNCCCC)。
(VNCVNCVNCVNC)
另一种方法是在批处理中交错每个顶点的顶点属性,然后按顺序存储每个交错的顶点块,再次将所有顶点属性组合到单个缓冲区中。和以前一样,您需要将字节偏移量传递到 VBO 中,以 glVertexAttribPointer ptr 参数,但您还需要使用 stride 参数来确保每个顶点属性数组仅访问该属性数组的触及元素。从图形上看,此选项为:(VNCVNCVNCVNC)
现在这只是一个批次。也没有什么可以阻止您将多个批次的顶点属性数据存储在单个 VBO 或一组 VBO 中。

最佳布局取决于特定的 GPU 和驱动程序(以及 OpenGL 实现),但有些东西通常是好主意。

3.1 最小化顶点状态变化

渲染多个不同的网格时,请尝试组织数据,以便尽可能多的网格驻留在具有相同顶点格式的同一缓冲区对象中。简而言之,您希望尽量减少 glVertexAttribPointer(或 glVertexAttribFormat,如果可用)调用的数量。

glDrawArrays 和其他数组样式的呈现可以很容易地用于选择此缓冲区的子区域进行呈现。

索引渲染有点棘手。您必须根据缓冲区中在每个网格之前出现的其他顶点的数量来偏置每个网格的索引数据。您可以通过在上传索引数据之前递增索引数据来手动执行此操作,也可以使用 BaseVertex 呈现调用,例如 glDrawElementsBaseVertex。基本顶点是应用于每个索引的偏移量。这个绘制函数的好处是,顶点少于 65536 个的网格可以按顺序存储在同一个顶点缓冲区中,因为索引(作为 GLushort 存储,没有任何变化)可用于索引位置大于 65536 的顶点。

3.2 属性大小

可以使属性数据越小越好(尽管有一定的对齐限制)。利用使用有符号/无符号规范化短短字符和字节以及其他专用格式的功能。以下是针对特定类型数据的一些建议:

2D 纹理坐标
在大多数情况下,它们可以以标准化GL_SHORT或GL_UNSIGNED_SHORT存储,而不会降低质量。
法线
法线的精度通常并不那么重要。由于归一化向量始终在 [-1, 1] 范围内,因此最好使用某种归一化整数格式。法线的三个分量可以通过 GL_INT_2_10_10_10_REV 类型存储在单个 32 位整数中。您可以忽略最后一个 2 位组件,也可以找到一些有用的东西来插入其中。
颜色
除非它们需要是 HDR 颜色,否则它们可以以归一化GL_UNSIGNED_BYTE存储,因此单个颜色可以打包成 4 个字节。如果您需要更高的颜色精度,可以使用GL_UNSIGNED_INT_2_10_10_10_REV,其中 2 位用于 alpha。如果您绝对需要 HDR 颜色,您可以使用GL_R11F_G11F_B10F,前提是浮动精度有效。如果没有,您可以雇用GL_HALF_FLOAT而不是GL_FLOAT费用。
位置
这些很难比GL_FLOAT更有效地打包,但这取决于您的数据以及您愿意做多少工作。您可以使用GL_HALF_FLOAT,但请记住相对于 32 位浮点数的范围和精度限制。
一个经过时间考验的替代方案是使用标准化的 GLshorts。为此,您需要重新排列模型空间数据,以便将所有位置都打包在原点周围的 [-1, 1] 框中。您可以通过在所有位置中查找 XYZ 中的最小值/最大值来做到这一点。然后,从所有顶点位置减去最小值/最大值框的中心点;然后将所有位置缩放为最小/最大框的宽度/高度/深度的一半。您需要保持中心点和比例因子。
在构建模型到视图矩阵(或模型到任何矩阵)时,需要在变换堆栈的顶部应用中心点偏移和缩放(因此,在最后,就在绘制之前)。请注意,此偏移和缩放不应应用于法线,因为它们具有单独的模型空间。
有一些事情你应该注意。任何属性数据的对齐方式应不少于 4 个字节。因此,如果您有 GLushorts 的 vec3,则不能将第 4 个组件用于新属性(例如 GLbytes 的 vec2)。如果你想把一些东西打包进去,而不是有无用的填充,你需要把它变成 GLushorts 的 vec4。

3.3 交织

交错属性在多大程度上有助于渲染性能尚不清楚。需要分析数据。由于对齐需要,交错的顶点数据可能比未交错的顶点数据占用更多的空间。

3.4 流属性

流式处理属性(每帧或非常频繁地更改的属性)需要使用缓冲区对象流式处理技术。这些通常不能很好地与静态属性配合使用,并且许多流式处理技术需要丢弃整个缓冲区对象。因此,将流式处理属性与未流式处理属性放在同一缓冲区中实际上毫无意义。

四、顶点、法线、特坐标

是否应该为每个 VBO 创建单独的 VBO?你会失去性能吗?
如果对象是静态的,则将它们全部合并到尽可能少的 VBO 中,以获得最佳性能。有关布局注意事项的更多详细信息,请参阅上一节。

如果只有一些顶点属性是动态的,即经常变化,则将它们放在单独的 VBO 中可以更轻松、更快速地进行更新。

例如,如果在 CPU 上模拟水,则每个顶点的位置可能会一直变化,但其颜色保持不变。

示例:每批多个顶点属性 VBO

// Binding the vertex
glBindBuffer(GL_ARRAY_BUFFER, vertexVBOID);
glVertexPointer(3, GL_FLOAT, sizeof(float)*3, NULL); // Vertex start position address// Bind normal and texcoord
glBindBuffer(GL_ARRAY_BUFFER, otherVBOID);
glNormalPointer(GL_FLOAT, sizeof(float)*6, NULL); // Normal start position address
glTexCoordPointer(2, GL_FLOAT, sizeof(float)*6, sizeof(float*3)); // Texcoord start position address

五、动态VBO

主条目:缓冲区对象流式处理
如果 VBO 的内容是动态的,您应该调用 glBufferData 还是 glBufferSubData(或 glMapBuffer)?
如果要更新一小部分,请使用 glBufferSubData。如果要更新整个 VBO,请使用 glBufferData(据报道,此信息来自 nVidia 文档)。但是,在更新整个缓冲区时,另一种被认为效果良好的方法是使用 NULL 指针调用 glBufferData,然后使用新内容调用 glBufferSubData。指向 glBufferData 的 NULL 指针让驱动程序知道你不关心前面的内容,因此可以自由替换完全不同的缓冲区,这有助于驱动程序管道更有效地上传。

您可以做的另一件事是双缓冲 VBO。这意味着您制作了 2 个 VBO。在第 N 帧上,更新 VBO 2 并使用 VBO 1 进行渲染。在第 N+1 帧上,更新 VBO 1 并从 VBO 2 进行渲染。这也大大提升了 nVidia 和 ATI/AMD 的性能。

六、顶点布局规范

很多新代码都是这样编写的

glBindBuffer(GL_ARRAY_BUFFER, vboID);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(TVertex_VNTWI), info->posOffset);
glTexCoordPointer(2, GL_FLOAT, sizeof(TVertex_VNTWI), info->texOffset);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glNormalPointer(GL_FLOAT, sizeof(TVertex_VNTWI), info->nmlOffset);
glEnableClientState(GL_NORMAL_ARRAY);
// --------------------
int weightPosition = glGetAttribLocation(programID, "blendWeights");
glVertexAttribPointer(weightPosition, 4, GL_FLOAT, GL_FALSE, sizeof(TVertex_VNTWI), info->weightOffset);
glEnableVertexAttribArray(weightPosition);
// --------------------
int indexPosition = glGetAttribLocation(programID, "blendIndices");
glVertexAttribPointer(indexPosition, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(TVertex_VNTWI), info->indexOffset);
glEnableVertexAttribArray(indexPosition);
// --------------------
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iboID);
glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, 0);

在着色器中,将使用 gl_Vertex、gl_Normal 和 gl_MultiTexCoord0。最好对顶点、法线和特质坐标也使用通用顶点属性,因为这是指定顶点布局的现代方式。您已经将它用于 blendWeights 和 blendIndices。

核心上下文中,您必须使用自己的顶点属性来调用 glVertexAttribPointer。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/744672.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

flink重温笔记(十六): flinkSQL 顶层 API ——实时数据流结合外部系统

Flink学习笔记 前言:今天是学习 flink 的第 16 天啦!学习了 flinkSQL 与企业级常用外部系统结合,主要是解决大数据领域数据计算后,写入到文件,kafka,还是mysql等 sink 的问题,即数据计算完后保存…

华为机试题-士兵的任务 2

题目 士兵在迷宫中执行任务,迷宫中危机重重,他需要在在最短的时间内到达指定的位置。你可以告诉土兵他最少需要多长时间吗? 输入一个 n m 的迷宫中,迷宫中 0 为路,1 为墙,2 为起点,3 为终点,4 为陷阱,6 为炸弹。士兵只能向上下左右四个方向移动,如果路径上为墙,不能移动。已知…

商业模式的深度解析:以四个特点构筑成功之路

商业模式,是企业将产品、服务、信息流、资金流等要素组合在一起,形成独特价值主张,并通过特定的渠道和方式传递给目标市场,从而获取利润的一种系统性设计。一个成功的商业模式,往往具备四个显著特点:重点突…

企业微信如何接入第三方应用?

1.登录企业微信管理后台:https://work.weixin.qq.com/wework_admin​​​​​ 2.点击创建应用; ​​​​​​​ 3. 此时可以看到已经创建好的应用,并且生成应用的唯一id(agentId) 4. 第三方应用申请域名 (举例&…

智慧楼宇物联网建设实施方案(2)

建设方案 楼宇综合管理平台 智慧楼宇物联网应用综合管理系统是对整个物联网系统的集中监控和展示。其主要功能是对各应用子系统的关键监测数据进行数据格式解析并呈现。进而使管理者能够从整体上对整个物联网系统运行状态有个直观的了解。其不同于各专业子系统的管理软件,重…

flstudio教程如何设置成中文 flstudio基础教程 flstudio免费

Fl studio编曲软件总共有英文和中文两种语言供用户选择,对于我们来说,更习惯于使用中文版本的flstudio编曲软件,包括我自己也比较习惯于使用中文版本的flstudio,同时也能提高工作效率。Flstudio编曲软件默认语言是英文&#xff0c…

vue:功能【xlsx】动态行内合并

场景:纯前端导出excel数据,涉及到列合并、行合并。 注)当前数据表头固定,行内数据不固定。以第一列WM为判断条件,相同名字的那几行数据合并单元格。合并的那几行数据,后面的列按需求进行合并。 注&#x…

vue2 elementui 封装一个动态表单复杂组件

封装一个动态表单组件在 Vue 2 和 Element UI 中需要考虑到表单字段的动态添加、删除以及验证等复杂功能。下面是一个简单的例子,展示如何创建一个可以动态添加和删除字段的表单组件。 首先,你需要安装并引入 Element UI: bash 复制 npm in…

CV论文--2024.3.13

1、Sora Generates Videos with Stunning Geometrical Consistency 中文标题:Sora 生成具有惊人几何一致性的视频。 简介:最近发布的 Sora 模型展示了在视频生成领域的出色表现,引发了人们对其模拟真实世界现象能力的激烈讨论。尽管该模型越来越受欢迎&…

如何保证Redis和数据库数据一致性

缓存可以提升性能,减轻数据库压力,在获取这部分好处的同时,它却带来了一些新的问题,缓存和数据库之间的数据一致性问题。 想必大家在工作中只要用了咱们缓存势必就会遇到过此类问题 首先我们来看看一致性: 强一致性…

前端实现生成图片并批量下载,下载成果物是zip包

简介 项目上有个需求,需要根据表单填写一些信息,来生成定制的二维码图片,并且支持批量下载二维码图片。 之前的实现方式是直接后端生成二维码图片,点击下载时后端直接返回一个zip包即可。但是项目经理说后端实现方式每次改个东西…

python基础——列表【创建,下标索引,常见操作方法】

📝前言: 这篇文章主要讲解一下python中常见的数据容器之一——列表 本文主要讲解列表的创建以及我们常用的列表操作方法 🎬个人简介:努力学习ing 📋个人专栏:C语言入门基础以及python入门基础 &#x1f380…

泰迪智能科技3月线上培训计划

有学习意向可到 泰迪智能科技官网 咨询了解

Visual Basic6.0零基础教学(3)—焦点概念和深入学习属性

焦点概念和深入学习属性 文章目录 焦点概念和深入学习属性前言一、什么是焦点(Focus)?焦点的特点 二、窗体属性一、窗体的结构二、窗体的属性三、事件四、方法 一.控件属性一. 标签 Label二.文本框 TextBox2.常用事件 三.命令按钮事件 总结 前言 今天我们来继续学习VB中的属性…

Java全系工程源码加密,防止反编译

一、前言 在大约2015年左右,由于公司产品序列逐渐增加,涉及到N多项目部署交付,为了有效防止产品被滥用,私自部署,当时技术中心决定开发一套统一的授权认证管理系统,对公司所有产品序列进行 License 控制。…

【DevSecOps】10种静态应用程序安全测试SAST工具对比

【DevSecOps】10种静态应用程序安全测试SAST工具对比 目录 【DevSecOps】10种静态应用程序安全测试SAST工具对比关于静态应用程序安全测试(SAST)工具的一切知识(常见问题解答)什么是静态应用程序安全测试(SAST)工具?静态应用程序安全测试(SAST)工具是如何工作的?静态…

蓝桥杯历年真题省赛java b组 2016年 第七届 抽签

一、题目 抽签 X星球要派出一个5人组成的观察团前往W星。 其中: A国最多可以派出4人。 B国最多可以派出2人。 C国最多可以派出2人。 .... 那么最终派往W星的观察团会有多少种国别的不同组合呢? 下面的程序解决了这个问题。 数组a[] 中既是每个国家可…

区块链技术的革命性影响

1. 区块链技术的基本原理: 区块链是一种去中心化的分布式数据库技术,通过不断增长的记录(块)构成一个链式结构。每个区块包含了交易数据的加密信息以及上一个区块的哈希值,从而形成了不可篡改的交易记录。这种去中心化…

Kotlin:为什么创建类不能被继承

一、为什么创建类不能被继承 class或data class 默认情况下,Kotlin 类是最终(final)的:它们不能被继承。 示例:data class PsersonBean 反编译data class PsersonBean 生成 public final class PsersonBean 示例&…

材料科学类3区SCI,仅13天超快上线见刊,国人友好!!

录用案例 JCR3区材料类SCI (3.31截稿) 【期刊简介】IF:3.0-4.0,JCR3区,中科院4区; 【检索情况】SCI在检; 【征稿领域】低温环境下新型生物降解材料的开发相关或结合研究均可; 【案例分享】重要时间节点…