为何要在GLSL中使用UBO
来源:互联网 发布:js保存cookie到本地 编辑:程序博客网 时间:2024/05/01 21:17
关于UBO的介绍和使用详情,请看http://www.zwqxin.com/archives/shaderglsl/communication-between-opengl-glsl-2.html
除了OpenGL手册,应该没有比这个更详细的了。
最近在一个GLSL项目中,需要循环绘制多块buffer,而每次循环都要给buffer传入大量的uniform,导致shader的渲染效率极低。
比如之前的代码是类似这个样子:
- m_pProgramBlock->sendUniform3fv(A);
- m_pProgramBlock->sendUniform3fv(B);
- m_pProgramBlock->sendUniform3fv(C);
- m_pProgramBlock->sendUniform3fv(D);
- glDrawElements(…);
m_pProgramBlock->sendUniform3fv(A);m_pProgramBlock->sendUniform3fv(B);m_pProgramBlock->sendUniform3fv(C);m_pProgramBlock->sendUniform3fv(D);glDrawElements(...);
相应的,在shader中uniform有如下定义:
- #version 330
- uniform vec3 A;
- uniform vec3 B;
- uniform vec3 C;
- uniform vec3 D;
#version 330uniform vec3 A;uniform vec3 B;uniform vec3 C;uniform vec3 D;
结果在性能测试中发现,每执行一次sendUniform的操作耗费的时间居然大于执行一次glDrawElements的时间!
GLSL提供了UBO技术能很好的解决这个问题。通过把uniform绑定到显卡的缓冲区,可以极大提升修改Uniform数据的速度。此外他的最大优势在于能在Shader之间共享Uniform。UBO的详细说明请参阅http://www.opengl.org/wiki/Uniform_Buffer_Object
修改后的opengl代码是类似这个样子:
- glBindBuffer(GL_UNIFORM_BUFFER, m_uboHandle);
- glBufferSubData(GL_UNIFORM_BUFFER, 0, 16, (char*)(&A);
- glBufferSubData(GL_UNIFORM_BUFFER, 16, 16, (char*)(&B);
- glBufferSubData(GL_UNIFORM_BUFFER, 32, 16, (char*)(&B);
- glBufferSubData(GL_UNIFORM_BUFFER, 48, 16, (char*)(&B);
- glDrawElements(…);
glBindBuffer(GL_UNIFORM_BUFFER, m_uboHandle);glBufferSubData(GL_UNIFORM_BUFFER, 0, 16, (char*)(&A);glBufferSubData(GL_UNIFORM_BUFFER, 16, 16, (char*)(&B);glBufferSubData(GL_UNIFORM_BUFFER, 32, 16, (char*)(&B);glBufferSubData(GL_UNIFORM_BUFFER, 48, 16, (char*)(&B);glDrawElements(...);
相应的,在shader中uniform有如下定义:
- #version 330
- layout(std140) uniform BlobSettings{
- vec3 A;
- vec3 B;
- vec3 C;
- vec3 D;
- }Blob;
#version 330layout(std140) uniform BlobSettings{ vec3 A; vec3 B; vec3 C; vec3 D; }Blob;
那么到底性能差异有多大呢?使用VS2012的性能测试,可以得到如下数据:
sendUniform占用了9.4%的渲染时间,而一条glBufferSubData只占用了0.1%!
使用glBufferSubData的效率比使用sendUniform高将近2个数量级!
然而使用UBO也要付出代价。因为每个显卡不同,UBO里每个uniform所占用字节数都未必相同,即使你指定了layout(std140)。
- 为何要在GLSL中使用UBO
- 为何要在GLSL中使用UBO
- GLSL 在OpenGL中使用GLSL
- GLSL 在OpenGL中使用GLSL
- 在OpenGL中使用GLSL
- 在 Unity3d 中使用 GLSL
- 【GLSL教程】(二)在OpenGL中使用GLSL
- 【GLSL教程】(二)在OpenGL中使用GLSL
- 【GLSL教程】(二)在OpenGL中使用GLSL
- 【GLSL教程】(二)在OpenGL中使用GLSL
- 【GLSL教程】(二)在OpenGL中使用GLSL
- 【GLSL教程】(二)在OpenGL中使用GLSL
- 【GLSL教程】(二)在OpenGL中使用GLSL
- 【GLSL教程】(二)在OpenGL中使用GLSL
- 【GLSL教程】(二)在OpenGL中使用GLSL
- 【GLSL教程】(二)在OpenGL中使用GLSL
- 【GLSL教程】(二)在OpenGL中使用GLSL
- 【GLSL教程】(二)在OpenGL中使用GLSL
- Android Studio快速注释
- (带哨兵)直接插入排序
- Android studio (单元测试)
- json数据结构拼装的一个例子
- 交通流
- 为何要在GLSL中使用UBO
- NIO学习整理
- Codeforces Round #408 (Div. 2)-D. Police Stations
- Java泛型
- Django+Vue.js 初学入手的一些坑,已填坑
- oracle11g adg从库开启闪回
- ln: target ‘libcublas’ is not a directory
- Error:Jack is required to support java 8 language features.
- 使用popwindow制作弹出框与获得焦点弹出软键盘