GLSL如何避免多次检查

时间:2013-06-19 17:56:52

标签: opengl if-statement shader

这是我的片段着色器:

#version 120
uniform sampler2D sampler0;
uniform bool isf1;

vec4 f1(vec4 color) {
...
}
vec4 f2(vec4 color) {
...
}

void main()
{
    gl_FragColor = texture2D( sampler2, gl_TexCoord[0].xy);
    gl_FragColor = f1(gl_FragColor);
    if(isf1) gl_FragColor = f2(gl_FragColor); //How to avoid it?
}

纹理分辨率1920x1080,所以“如果”调用2073600次,这是非常低效的。如何让'if'只为所有纹素发射一次?

5 个答案:

答案 0 :(得分:2)

只需使用isf1 truefalse渲染呈现的内容之间切换纹理即可。切换纹理 痛苦。

这绝对是过早优化的结果。

答案 1 :(得分:1)

正如其他人所说,避免着色器中if的唯一方法是使用不同版本的程序。

您在评论中提到实际上可能需要调用六个函数(也许您可以将这些信息添加到您的问题中)。您可以将if替换为#ifdef并自动生成(64?)版本的程序(通过在代码前添加相应的#define)。

这样做的缺点是,如果要绘制具有不同条件的许多不同对象,则必须在绘制之间切换着色器程序,这可能比着色器中的分支更昂贵。

有一点需要注意的是,如果相邻的片段采用相同的路径,则分支不会太昂贵(在最近的gpus上)。在您的情况下,所有片段都采用相同的路径,因此分支的价格尽可能便宜。

答案 2 :(得分:0)

编译两个程序,一个isf1true,另一个为false

使用适当的程序设置isf1制服。

答案 3 :(得分:0)

您正在根据传入的一些外部变量执行某些代码,即布尔值f1。您应该使用子程序。在渲染之前,基于isf1在OpenGL程序中设置子例程,然后渲染“f1”的所有内容。重复非f1的事情。这将在着色器之外选择适当的功能,而不是在每个片段上浪费时钟周期。

答案 4 :(得分:0)

也许这有点晚了,但我建议您查看Lighthouse3d heresubroutine教程。

此外,对于更多基本分支,您还可以使用clampmix对其进行优化。 This tutorial给出了一个很好的例子。