我读过很多关于统一 if 语句的文章,这些语句处理分支以改变大型着色器“超级着色器”的行为。我开始使用 uber 着色器 (opengl lwjgl),但后来我意识到,与没有统一 if 语句的单独着色器相比,在片段着色器中添加由统一的 if 语句集进行简单计算的简单操作将我的 fps 降低了 5。我没有对 fps 限制设置任何上限,只是尽可能快地刷新。我即将添加法线贴图和视差贴图,我可以看到两条路线:
Uber 顶点着色器:
#version 400 core
layout(location = 0) in vec3 position;
layout(location = 1) in vec2 textureCoords;
layout(location = 2)in vec3 normal;
**UNIFORM float RenderFlag;**
void main(void){
if(RenderFlag ==0){
//Calculate outVariables for normal mapping to the fragment shader
}
if(RenderFlag ==1){
//Calcuate outVariables for parallax mapping to the fragment shader
}
gl_Position = MVPmatrix *vec4(position,1);
}
Uber 片段着色器:
layout(location = 0) in vec3 position;
layout(location = 1) in vec2 textureCoords;
layout(location = 2)in vec3 normal;
**UNIFORM float RenderFlag;**
**UNIFORM float reflectionFlag;** // if set either of the 2 render modes
will have some reflection of the skybox added to it, like reflective
surface.
void main(void){
if(RenderFlag ==0){
//display normal mapping
if(reflectionFlag){
vec4 reflectColor = texture(cube_texture, ReflectDirR) ;
//add reflection color to final color and output
}
}
if(RenderFlag ==1){
//display parrallax mapping
if(reflectionFlag){
vec4 reflectColor = texture(cube_texture, ReflectDirR) ;
//add reflection color to final color and output
}
}
gl_Position = MVPmatrix *vec4(position,1);
}
这样做的好处(对我来说)是流程简单,但使整个程序更加复杂,而且我面临着丑陋的嵌套 if 语句。另外,如果我想完全避免 if 语句,我将需要 4 个单独的着色器,一个用于处理每个可能的分支(正常无反射:正常有反射:Parrallax 无反射:Parrallax 有反射),仅用于一个功能,反射。
1:GLSL是否执行两个分支和后续分支并计算两个函数然后输出正确的函数?
2:我应该删除 if 语句,而不是使用统一的反射标志,以支持计算反射颜色,无论如何,如果它是一个相对较小的操作,则将其添加到最终颜色,例如
finalColor = finalColor + reflectionColor * X
where X = a uniform variable, if none X == 0, if Reflection X==some amount.