我有一个像素着色器:
varying vec2 f_texcoord; uniform vec4 mycolor_mult; uniform sampler2D mytexture; void main(void) { gl_FragColor = (texture2D(mytexture, f_texcoord) * mycolor_mult); };
和相应的C++代码:
GLint m_attr = glGetUniformLocation(m_program, "mycolor_mult"); // ... unsigned int myColor = ...; // 0xAARRGGBB format float a = (myColor >> 24) / 255.f; float r = ((myColor >> 16) & 0xFF) / 255.f; float g = ((myColor >> 8) & 0xFF) / 255.f; float b = (myColor & 0xFF) / 255.f; glUniform4f(m_attr, r, g, b, a);
我保持精灵的颜色,unsigned int
并且必须将其转换为4个浮点数以将它们传递给着色器.
可以优化吗?我的意思是我可以传递不浮点数,但是无符号字符作为着色器的组件并避免"除以255"操作吗?我应该在着色器和C++代码中进行哪些更改?
这个问题有几个方面.
我同意@ Nick的评论.你很有可能试图优化那些对性能不重要的东西.例如,如果此代码每帧仅执行一次,则此代码的执行时间绝对无关紧要.如果这是执行许多每帧的时间,事情可能看起来有点不同.使用分析器可以告诉您在此代码中花费了多少时间.
确保glGetUniformLocation()
在链接着色器后仅进行一次调用,而不是每次设置制服.否则,该调用很可能比其余代码昂贵得多.如果您已经这样做,那么从代码中就不完全清楚了.
不是真的,如果你需要在着色器中将值作为浮点数.制服没有自动格式转换,因此您不能简单地使用来自glUniform*()
家庭的其他电话.从规格:
对于所有其他统一类型,使用的Uniform*命令必须与着色器中声明的制服的大小和类型相匹配.没有进行类型转换.
如果您真的想进行微优化,可以通过乘法替换除法.在大多数CPU上,划分比乘法更昂贵.然后代码如下所示:
const float COLOR_SCALE = 1.0f / 255.f; float a = (myColor >> 24) * COLOR_SCALE; float r = ((myColor >> 16) & 0xFF) * COLOR_SCALE; float g = ((myColor >> 8) & 0xFF) * COLOR_SCALE; float b = (myColor & 0xFF) * COLOR_SCALE;
您不能指望编译器为您执行此转换,因为更改操作可能会影响操作的精度/舍入.一些编译器具有标志以实现这些类型的优化.请参阅例如优化浮点除法和转换操作.