Ser*_*gey 8 architecture opengl glsl
我有几个具有统一变量的着色器,它们在所有着色器中具有相同的名称.一次更新所有着色器中具有相同名称的制服的最佳方法是什么?我考虑以下方法:
1)只为每个程序存储该统一的位置,并在程序被指定为"已使用"程序(glUseProgram)之后立即更新它.
缺点:每次glUseProgram调用后都会更新所有"共享"统一变量.此外,如果在当前帧期间不是第一次使用程序,则所有glUniform*呼叫都将是冗余的.或者,应该有一组标志,用于判断程序是否第一次使用.应该每帧重置"未使用"标志.
2)使用统一缓冲区和shared(或甚至std140)布局.在这种方法中,我们可以立即设置一个统一,然后更改着色器程序而不更新缓冲区.但是,如果有一堆简单的着色器,其中唯一的共享变量是变换矩阵呢?是否可以为这么少的内存使用统一缓冲区?在一些论坛讨论中,我读到了这一点
glBindBuffer(GL_UNIFORM_BUFFER,buf);
glBufferSubData(/*just 16 floats*/);
glBindBuffer(GL_UNIFORM_BUFFER,0);
Run Code Online (Sandbox Code Playgroud)
比glUniform*打电话慢得多.在这里我们可以注意到,第一种和第二种方法之间的选择取决于以下条件:
有没有妥协的设计模式,无论这三个问题的答案如何,都会有良好的表现?
3)使用ubershader.这里提到第二段:GLSL多个着色程序VS制服开关.我有两个问题:
什么有更好的性能:一个glUseProgram呼叫或几个统一的开关,这将改变ubershader的功能?
该问题的作者提到了
每帧必须多次更换制服
作为ubershader的缺点之一.但为什么不好呢?性能不好吗?如果是这样,是否可以将转换矩阵和其他一些小尺寸的东西作为统一变量传递并更新每帧?
总结以上所有的主要问题:您是否可以建议在几个不同的着色器程序中更新同名统一变量的任何其他技术或设计模式?
UPD:答案被接受了,但是如果你可以建议一个非常重要的高级设计技术(用C++或语言独立),请将其留在这里.
在一些论坛讨论中,我读过[...]比glUniform*call慢得多.
那么如果是(假设有证据表明它甚至是当然的话)呢?每帧仅执行一次,而glUniform每个修改的程序调用一次.
std140对于任何共享数据,我都会使用统一块(默认情况下始终使用).更新它们有固定的成本,而更新其他成本则有可变成本.
| 归档时间: |
|
| 查看次数: |
4462 次 |
| 最近记录: |