gpt4 book ai didi

OpenGL GLSL 统一分支与多个着色器

转载 作者:行者123 更新时间:2023-12-04 20:38:41 24 4
gpt4 key购买 nike

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

优步顶点着色器:

#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);



}

优步片段着色器:
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 个单独的着色器,一个来处理每个可能的分支(无反射的正常:带反射的正常:无反射的视差:带反射的视差)仅用于一个功能,反射。

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

2:我应该删除 if 语句而不是反射的统一标志,以支持计算反射颜色,并将其添加到最终颜色中,如果它是一个相对较小的操作,例如
finalColor = finalColor + reflectionColor * X 
where X = a uniform variable, if none X == 0, if Reflection X==some amount.

最佳答案

马上,让我指出 GL4 已经添加了子例程,它们是您讨论过的两件事的组合。但是,除非您使用单个基本着色器的大量排列,这些排列在一帧期间多次换出(就像您在前向渲染引擎中有一些动态 Material 系统一样),子例程确实不是性能上的胜利.我在自己的工作中为此投入了一些时间和精力,我在一个特定的硬件/驱动程序组合上获得了有值(value)的改进,而在大多数其他硬件/驱动程序组合上没有明显的变化(好或坏)。

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

也就是说,几乎不可能回答 GLSL 如何执行您的着色器。它只是一种高级语言;自从创建 GLSL 以来,底层硬件架构已经发生了多次变化。最新一代的硬件具有实际的分支预测和一些非常复杂的线程引擎,这是 GLSL 1.10 类硬件从未有过的,其中一些现在实际上是通过计算着色器直接公开的。

您可以运行数字以查看哪种策略最适合您的硬件,但我认为您会发现这是旧的微优化困境,您甚至可能无法获得足够的性能差异来猜测采用哪种方法。请记住,“Uber 着色器”具有多种吸引力(并非所有与性能相关),最重要的是,您可能需要批处理的绘制命令越来越少,也越来越不复杂。如果性能没有明显差异,请考虑采用更简单、更易于实现/维护的设计。

关于OpenGL GLSL 统一分支与多个着色器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30581719/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com