这是签名。
glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
glUniform4fv(GLint location, GLsizei count, const GLfloat *v);
以我的愚见,前者应该更快,因为值可以直接从寄存器传递,而不需要从内存中获取。不过,我想听听很多意见。
最佳答案
虽然 *v
变体主要用于设置数组类型的统一,但 OpenGL 规范明确允许您使用数组变体来设置标量值:使用一数。
让我引用一下 OpenGL 规范(强调我自己添加的):
The commands glUniform{1|2|3|4}{f|i}v can be used to modify a single uniform variable or a uniform variable array. These commands pass a count and a pointer to the values to be loaded into a uniform variable or a uniform variable array. A count of 1 should be used if modifying the value of a single uniform variable, and a count of 1 or greater can be used to modify an entire array or part of an array.
这来自OpenGL 2.1 Spec ,但是对于 OpenGL 4.2 Spec 来说它读起来是一样的。 .
实际上,反过来也是允许的。假设您有一套 vec3 v[2]
类型的制服,并且您使用 glGetUniformLocation()
查询其位置,它可能会返回 6
。这意味着 6
实际上是 v[0]
的位置。
现在回到最初的问题:哪种变体更快?
这很难说。它们可能同样快,或者其中一个可能比另一个更快,这非常依赖于实现。实际上,我希望大多数实现都在另一种之上实现其中一种。
例如考虑以下代码:
void glUniform1f ( GLint location, GLfloat v0 ) {
glUniform1fv(location, 1, &v0);
}
在这种情况下,数组变体会更快。但是,以下变体也是可能的:
void glUniform1fv ( GLint location, GLsizei count, GLfloat * value ) {
int i;
for (i = 0; i < count; i++) {
glUniform1f(location, *value);
value++;
location++;
}
}
在这种情况下,非数组变体会更快。
就我个人而言,我会说(这只是我个人的观点)早期的 OpenGL 实现可能已经使用非数组变体实现了数组变体,因为这是更简单的实现,在整个其余部分几乎没有任何其他修改OpenGL 库。另一方面,它的实现速度也慢得多,因为它涉及现代图形适配器很可能不需要的循环,因此现代实现很可能在数组变体之上实现非数组变体。
阵列变体还有其他优点。考虑以下函数:
struct v3 {
GLfloat x;
GLfloat y;
GLfloat z;
};
void setUniform ( GLint location, struct v3 * vPtr ) {
glUniform3f(location, vPtr->x, vPtr->y, vPtr->z);
}
仅仅为了调用非数组函数而取消引用 vPtr 三次是相当愚蠢的,并且几乎没有比以下实现更快的:
void setUniform ( GLint location, struct v3 * vPtr ) {
glUniform3fv(location, 1, (const GLfloat *)vPtr);
}
此外,所有数组变体始终只有三个参数,而其他变体最多可以有五个参数。当这些参数通过堆栈而不是在寄存器中传递时,需要传递给函数的参数越多,函数调用本身的速度就越慢。对于具有混合调用方案的架构,函数调用具有的参数越多,这些参数在寄存器内传递的可能性就越小。因此,根据普通 CPU 上的纯函数调用开销,对带有少量参数的函数的调用通常比对带有许多参数的函数的调用要快,尽管只有当您执行数千次调用时,这种差异才会产生影响。其次,对于统一值通常不是这种情况。
关于optimization - 考虑到所有类型的优化,glUniform4f/glUniform4fv 更快是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3642468/