当前位置:  开发笔记 > 编程语言 > 正文

将数据传递给像素着色器时如何避免int-> float转换?

如何解决《将数据传递给像素着色器时如何避免int->float转换?》经验,为你挑选了1个好方法。

我有一个像素着色器:

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++代码中进行哪些更改?



1> Reto Koradi..:

这个问题有几个方面.

值得优化吗?

我同意@ Nick的评论.你很有可能试图优化那些对性能不重要的东西.例如,如果此代码每帧仅执行一次,则此代码的执行时间绝对无关紧要.如果这是执行许多每帧的时间,事情可能看起来有点不同.使用分析器可以告诉您在此代码中花费了多少时间.

你正在优化正确的事情吗?

确保glGetUniformLocation()在链接着色器后仅进行一次调用,而不是每次设置制服.否则,该调用很可能比其余代码昂贵得多.如果您已经这样做,那么从代码中就不完全清楚了.

你能使用更有效的OpenGL调用吗?

不是真的,如果你需要在着色器中将值作为浮点数.制服没有自动格式转换,因此您不能简单地使用来自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;

您不能指望编译器为您执行此转换,因为更改操作可能会影响操作的精度/舍入.一些编译器具有标志以实现这些类型的优化.请参阅例如优化浮点除法和转换操​​作.

推荐阅读
可爱的天使keven_464
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有