条件分支语句太多导致 WebGL 效率低下

最近工作上遇到一个问题。
在使用 WebGL 的时候发现没法用位运算,发现有两种解决方案:
1. 在 shader 前面标识 shader 的版本 #version 130
2. 自己写位运算函数
第一种方案因为 CocosCreator 会在自己写的 Shader 前面添加一些纹理坐标之类的代码,所以没法把 #version 130加在 Shader 的最前面。但是 #version 130 又必须写在最前面,所以只能改 Cocos 源码了。觉得稍微麻烦了点,就采用了第二种方案。这时候就开始入坑了。
最开始我写的 Shader 是这样:

bool and(float a, float b) {
    for(float i = 32.0; i >= 0.0; i--) {
        float n = pow(2.0,i);
        if(b == i && a >= n) return true;
        if(a >= n) a -= n;
    }
    return false;
}

功能是实现了,但发现效率非常低下,导致游戏帧率一下子从 60 FPS 降到了 30FPS。
然后就开始寻找解决方案的漫漫长路,想找到问题的症结所在。
最后发现无论怎么改写这个函数,都依然效率低下。
然后我感觉我的 Shader 程序 if 别多。可能是编译之后 if 语句突破了某个阈值,导致运行效率特别低。
于是开始着手改写位运算 and ,改成了这样:

bool and(float a, float b) {
    float n = pow(2.0,b);
    if(a >= n && mod(floor(a/n),2.0) == 1.0) return true;
    return false;
}

果然效率一下子提高了非常多, fps 立马回到 60 帧。
为什么说上面的函数比下面的函数 if 多很多呢,因为我知道 shader 如果用 for 循环在编辑阶段就必须确定最大循环次数,感觉像是编译时把 for 展开了一样。

到此为止,问题解决。不过目前还不是非常确定是不是条件分支语句太多导致效率低下,但感觉很像是这样。

猜你喜欢

转载自blog.csdn.net/jiexiaopei_2004/article/details/81563174
今日推荐