Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
OpenGL GLSL均匀分支与多着色器_Opengl_Glsl - Fatal编程技术网

OpenGL GLSL均匀分支与多着色器

OpenGL GLSL均匀分支与多着色器,opengl,glsl,Opengl,Glsl,我已经阅读了许多关于uniform if语句的文章,这些语句处理分支以更改大型着色器“uber着色器”的行为。我开始使用uber着色器(opengl lwjgl),但后来我意识到,在片段着色器中添加由统一设置的if语句的简单操作可以进行简单计算,与没有统一if语句的单独着色器相比,我的fps减少了5。我没有设置任何上限,我的fps限制,它只是刷新尽可能快。我将添加法线贴图和parrallax贴图,我可以看到两条路线: Uber顶点着色器: #version 400 core layout(lo

我已经阅读了许多关于uniform if语句的文章,这些语句处理分支以更改大型着色器“uber着色器”的行为。我开始使用uber着色器(opengl lwjgl),但后来我意识到,在片段着色器中添加由统一设置的if语句的简单操作可以进行简单计算,与没有统一if语句的单独着色器相比,我的fps减少了5。我没有设置任何上限,我的fps限制,它只是刷新尽可能快。我将添加法线贴图和parrallax贴图,我可以看到两条路线:

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个独立的着色器,一个用于处理每个可能的分支(正常w/o反射:正常带反射:Parrallax w/o反射:Parrallax带反射),只用于一个功能,反射

1:GLSL是否同时执行两个分支和后续分支,并计算两个函数,然后输出正确的函数

2:如果反射是一个相对较小的操作,那么我是否应该删除if语句,以便不加考虑地计算反射颜色,并将其添加到最终颜色中,而不是使用统一的反射标志

finalColor = finalColor + reflectionColor * X 
where X = a uniform variable, if none X == 0, if Reflection X==some amount.

一开始,让我指出GL4添加了一些子程序,它们是您所讨论的两个方面的组合。但是,除非您使用单个基本着色器的大量置换,并且在一帧期间多次交换(如果您在正向渲染引擎中使用了一些动态材质系统,则可能会这样),否则子例程实际上并不是性能的胜利。我在自己的工作中投入了一些时间和精力,在一个特定的硬件/驱动程序组合上我得到了有价值的改进,而在大多数其他硬件/驱动程序组合上没有明显的变化(好或坏)

为什么我要提出子程序?主要是因为你在讨论什么是微观优化,而子程序是一个很好的例子,说明了为什么在开发结束前花费大量时间思考这个问题是不值得的。如果您正努力满足某些性能指标,并且您已经将所有高级优化策略从列表中划掉,那么您可以担心这些问题

也就是说,要回答GLSL如何执行着色器几乎是不可能的。它只是一种高级语言;自GLSL创建以来,底层硬件体系结构已经改变了好几次。最新一代的硬件具有实际的分支谓词和一些GLSL 1.10类硬件从未拥有过的相当复杂的线程引擎,其中一些实际上是通过计算着色器直接公开的


您可以运行这些数字,看看哪种策略在您的硬件上最有效,但我认为您会发现这是一个古老的微观优化难题,您甚至可能无法获得足够的性能差异来猜测采用哪种方法。请记住,“Uber着色器”之所以具有吸引力,有多种原因(并非所有的性能都与此相关),其中最重要的一个原因是,要批处理的绘图命令可能越来越少,也越来越不复杂。如果在性能上没有明显的差别,请考虑设计更简单、更容易实现和维护的。

你如何将你的制服加载到着色器程序中?如果不使用缓冲区对象,则可能看不到性能优势-glUniform非常昂贵,多次调用它可能是导致性能下降的原因。也就是说,(微小的)性能提升几乎绝对不值得编写“uber着色器”的额外复杂性,IMHO.是的,我正在使用vbos,所有制服仅在绘制不同批次的对象时更新。经过一些测试后,我决定使用多个着色器,对我来说,如果着色器中发生分支(嵌套),则性能下降越大,同时在链接时添加#include prepoccessor指令,我所有的着色器都可以共享照明计算等,而不需要在着色器之间使用冗余和相同的代码。我非常喜欢使用注入
#define
s来创建着色器置换。相关问题。Thnx Andrew,我自己也尝试过子程序,我尝试过多个着色器、统一标志和子程序。基本上,我将整个渲染模式包装在一个子例程中,就好像它是自己的着色器一样,它大大降低了我的帧速率,我基本上将其视为一个统一的标志,但将其替换为一个子例程,输出是正确的,但我可能没有正确地实现它们。这也是一本好书