Skip to main content
 首页 » 编程设计

optimization之着色器优化 : Is a ternary operator equivalent to branching

2024年10月25日19落叶无声

我正在研究一个顶点着色器,我想在其中有条件地删除一些顶点:

float visible = texture(VisibleTexture, index).x; 
if (visible > threshold) 
    gl_Vertex.z = 9999; // send out of frustum 

我知道当相邻数据之间几乎没有共同点时,分支会降低性能。在这种情况下,每个其他顶点可能会获得不同的“可见”值,这对本地着色器核心集群的性能不利(根据我的理解)。

对于我的问题:三元运算符更好吗(不考虑可读性问题)?
float visible = texture(VisibleTexture, index).x; 
gl_Vertex.z = (visible > threshold) ? 9999 : gl_Vertex.z; 

如果没有,将其转换为计算是否值得?
float visible = texture(VisibleTexture, index).x; 
visible = sign(visible - threshold) * .5 + .5; // 1=visible, 0=invisible 
gl_Vertex.z += 9999 * visible; // original value only for visible 

有没有更好的方法可以在不依赖几何着色器的情况下删除顶点?

在此先感谢您的帮助!

请您参考如下方法:

三元运算符只是 if 语句的语法糖。他们是一样的。

如果您在 if 语句中编写更多内容,则可能可以在此处完成一些优化,但是由于任一分支内部都如此之少,因此实际上没有什么可优化的。

默认情况下通常不使用分支。

在您的情况下,三元运算符(或 if 语句)可能首先评估条件的两侧,然后丢弃条件不满足的分支。

为了使用分支,您需要在着色器代码中设置分支编译器标志,以生成指示 GPU 实际尝试分支的程序集(如果 GPU 支持分支)。在这种情况下,只有当分支预测器表明某个预定义数量的内核将采用其中一个分支时,GPU 才会尝试分支。

您的里程可能因一种编译器和 GPU 而异。