当前位置: 首页 > news >正文

OpenGL:Uniform Block

在使用着色器的时候,会出现一个问题,很多着色器会共享相同的 uniform 数据,比如projection, view 矩阵,这无形中对于性能是一种浪费。在OpenGL中,提供了一种方式,Uniform Block 可以解决这个问题。

Uniform Block Object

Uniform Block 也是一种 buffer ,和 VBO, EBO 一样,将数据绑定到上面去,然后就可以使用,所以可以将它称之为 UBO

共享数据存储在一个与特定 binding point 关联的 UBO 缓冲对象 之后,在需要使用该共享数据的着色器中,只需要声明一个与该 binding point 关联的 uniform block 。这样,所有链接到同一个 binding point 的不同着色器程序都可以自动访问该 UBO 中的共享数据 。之后只需要更新 UBO 缓冲区本身一次(例如在投影或视图矩阵变化时),所有关联的着色器就都能获取到新数据,**无需再使用 glUniform* 函数对_每个_着色器程序单独设置这些 uniform 值。因此 传输操作的次数显著减少,特别是当很多着色器共享相同数据时。”

GLuint ubo;
glGenBuffers(1, &ubo);
glBindBuffer(GL_UNIFORM_BUFFER, ubo);
// 这里不填充数据,只是为了在GPU设置一片区域用于存储 uniform block的数据
glBufferData(GL_UNIFORM_BUFFER, sizeof(uniform block), nullptr, GL_STATIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);

Uniform Block Layout

uniform block 的使用中,理解其内存布局是实现 CPU 端与 GPU 端数据正确匹配的关键问题。OpenGL 提供了几种布局规范,其中 std140 是最常用的标准:

layout (std140) uniform Matrices {mat4 projection;mat4 view;
};

对于 std140 的数据布局规则,每种数据类型都有它自己的 base alignment,在 block 中的数据还有一个相对于block 开始位置的偏移,这个偏移量的计算需要用到每种数据类型的 base alignment。下面是每种数据类型的布局规则。每4个字节用一个 N 表示。

类型布局规则
标量,比如int和bool每个标量的基准对齐量为N。
向量2N或者4N。这意味着vec3的基准对齐量为4N。
标量或向量的数组每个元素的基准对齐量与vec4的相同。
矩阵储存为列向量的数组,每个向量的基准对齐量与vec4的相同。
结构体等于所有元素根据规则计算后的大小,但会填充到vec4大小的倍数。

计算的一个例子:

layout (std140) uniform ExampleBlock {// 基准对齐量       // 对齐偏移量float value;     // 4               // 0 vec3 vector;     // 16              // 16  (必须是16的倍数,所以 4->16)mat4 matrix;     // 16              // 32  (列 0)// 16              // 48  (列 1)// 16              // 64  (列 2)// 16              // 80  (列 3)float values[3]; // 16              // 96  (values[0])// 16              // 112 (values[1])// 16              // 128 (values[2])bool boolean;    // 4               // 144int integer;     // 4               // 148
}; 

如何使用

  1. 创建 UBO,分配GPU空间
glGenBuffers(1, &uboMatrices);
glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices);
glBufferData(GL_UNIFORM_BUFFER, 2 * sizeof(glm::mat4), nullptr, GL_STATIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
  1. 绑定 UBO 到指定的绑定点
// 将 uboMatrices 绑定到0号绑定点
glBindBufferBase(GL_UNIFORM_BUFFER, 1, uboMatrices);
// 也可以用下面的函数进行绑定,
glBindBufferRange(GL_UNIFORM_BUFFER, 1, uboMatrices, 0, 2 * sizeof(glm::mat4));
  • void glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size):指定位置 index,绑定 buffertarget上,数据从 offset 开始,大小为 size
  1. 将着色器中需要使用到的共享 uniform 数据也绑定到和 UBO 相同的绑定点。
// 可以先获取到原来的绑定点
GLuint bindingIndex = glGetUniformBlockIndex(shader.ID, "Matrices");
// 然后当前的绑定点换到 UBO 所绑定的绑定点上(上一步是绑定到1位置,所以这里也是写0位置)
glUniformBlockBinding(shader.ID, bingdingIndex, 1);

在OpenGL4.2开始,可以GLSL中直接指定绑定点:

layout (std140, binding=1) uniform Matrices {mat4 projection;mat4 view;
};

在使用Sampler的时候也是一样可以这样绑定的

layout (binding = 0) uniform sampler2D samp;
  1. 将数据传入到 UBO
glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4), glm::value_ptr(pMat));
glBufferSubData(GL_UNIFORM_BUFFER, sizeof(glm::mat4), sizeof(glm::mat4), glm::value_ptr(vMat));
glBindBuffer(GL_UNIFORM_BUFFER, 0);
http://www.dtcms.com/a/614622.html

相关文章:

  • 网站建设方案怎么做WordPress防红
  • 数据分析笔记07:Python编程语言介绍
  • 网站建设 佛山市wordpress 文字背景颜色
  • 一文讲清 this 所有知识点
  • 【以太网交换机】交换机通关指南!自学习算法 + 交换模式 + 核心对比
  • 电子商务网站搭建方案房屋在线设计网站
  • 双目相机标定时左右目图片角点识别顺序错误问题的解决办法(c++)
  • JavaSE知识分享——异常(二)
  • Java语言编译器 | 解析与优化策略的研究
  • 舟山网站开发做兼职的网站都有哪些工作内容
  • 重建内在秩序:从神经科学理解情绪的逻辑
  • 网站排名软件利搜做网站背景图的科技图片
  • ASC学习笔记0019:返回给定游戏属性的当前值,如果未找到该属性则返回零。
  • Pytnon入门学习(一)
  • 学习笔记9
  • 自己做的相册网站php做网站开源项目
  • 宁波本地网站排行网架生产企业
  • 百度网站域名做网站为什么差价很大
  • 青岛网站建设公司有哪些设计logo素材
  • C语言编译软件 | 提升编程效率与开发体验
  • 深圳市建设行业门户网站做网站准备什么问题
  • 基于Android智能旅游管家系统
  • 数据智能开发之六 AI原生架构
  • 如何建一个购物网站wordpress国外主题下载
  • 第37节:移动端优化与触控交互
  • 网站地图什么意思wordpress 政企
  • mig烧录卡资源 Mig-Switch游戏合集 烧录卡 1.75T
  • com网站注册域名wordpress 下载的主题插件在俺儿
  • 主控STM32F407ZET6控制板PLC工控板FX3U,FX5U,控制IO卡 STM32F4...
  • 资阳网站优化互联网网站 数据库