通常,在着色器中分支不是一个好主意。但是现在我有了一个着色器,其条件对于整个绘制调用而言是恒定的。因此,对于一个绘制调用而言,执行的分支始终是相同的。

这种分支是否比没有多个着色器且没有这些分支并在它们之间切换的方法还要昂贵? >

评论

为什么此片段着色器中的此条件为何如此慢的可能重复项?

正如答案在我的问题上所解释的那样,片段被分组为“扭曲”或“波阵面”,并且如果该组中的所有片段都使用同一分支,则仅执行该分支。

但是与片段不同的着色器又如何呢?

我相信顶点会以相同的方式组装成扭曲或波阵面。

我怀疑这不是重复项,但需要对其进行编辑以明确要求什么,然后才能确定。一些示例代码或对所比较的两个选项的解释会很有帮助。

#1 楼

在现代硬件上,如果组中的所有调用都遵循相同的路径,则未计算未使用的路径。

使用伪代码:

if(cond){
   res = ...
}else{
   res = ...
}


成为

if(anyInvocationARB(cond)){
    res1 = ...
}
if(anyInvocationARB(!cond)){
    res2 = ...
}
res = cond?res1:res2;


如果着色器的任何调用将为anyInvocationARB(来自opengl扩展名ARB_shader_group_vote),则cond为真。

如果cond仅来自制服,则驱动程序可以在开始渲染之前优化和评估条件,然后将if替换为正确的分支。 OpenGL具有称为统一子例程的功能,该功能使它显式。

评论


$ \ begingroup $
这是事实,但这并不是您需要考虑的唯一性能。 GPU仍在静态地为每个着色器调度资源,因此这可能仍然像在执行两个分支一样资源,这可能会损害占用率。
$ \ endgroup $
– John Calsbeek
15年8月21日在6:16