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

2024-02-14

我读过很多关于统一 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.

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

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

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenGL GLSL 统一分支与多个着色器 的相关文章

  • OpenGL 和加载/读取 AoSoA(混合 SoA)格式的数据

    假设我有以下 AoSoA 格式的简化结构来表示顶点或点 struct VertexData float px 4 position x float py 4 position y 也就是说 每个实例VertexData存储4个顶点 我见过的
  • gluPerspective 与 gluOrtho2D

    我查看了 MSDN 上关于这两个函数的文档 但是 我不太明白这两个功能之间的区别 一个是用于设置 3D 相机视图 另一个是用于设置 2D 相机视图 如果能得到解答就太好了 预先感谢您的评论 正交投影基本上是没有透视的 3D 投影 本质上 这
  • 使用 glDrawElements 时在 OpenGL 核心配置文件中选取三角形

    我正在使用 glDrawElements 绘制三角形网格 并且希望能够使用鼠标单击来拾取 选择三角形 三角形的网格可以很大 在固定功能 OpenGL 中 可以使用 GL SELECT http content gpwiki org inde
  • 不理解 gluOrtho2D 函数

    我不能做什么gluOrtho2D 函数是做什么的 是否将原点固定在 OpenGL 窗口上的某个特定点或其他位置 这是因为gluOrtho2D 1 1 1 1 将原点固定在窗口的中间 如果它在某个时刻没有修复原点 那么有什么方法可以修复原点
  • 如何将点光源转换为卵形/椭圆形?

    我希望通过具有不同 x 和 y 值的 vec2 半径将当前的圆形光变成椭圆形 有没有办法根据我当前在片段着色器中的代码来做到这一点 uniform struct Light vec4 colour vec3 position vec2 ra
  • 使用未声明的标识符“gl_InstanceID”

    大家好 我一直在IOS平台上尝试在OpenGLES2 0中进行实例化绘制 我的渲染代码 glEnableVertexAttribArray glVertexAttribPointer glDrawElementsInstancedEXT G
  • OpenGL 中连续暂停

    void keyPress unsigned char key int x int y int i switch key case f i 3 while i x pos 3 sleep 100 glutPostRedisplay 上面是在
  • WebKit 是否使用 OpenGL 来渲染 CSS 过渡?

    WebKit 是使用 OpenGL 来渲染 CSS 过渡 还是使用软件渲染 WebKit 只是一个前端 这取决于后端和硬件支持 谷歌浏览器使用skia http code google com p skia 作为后端 它可以使用软件或硬件
  • 使用draw()而不是eventloop时的pyglet

    我正在尝试用 pyglet 画一个圆 但当我使用 draw 函数而不是 app run 循环时 它是不可见的 有什么建议我可以做什么吗 谢谢 from math import from pyglet gl import window pyg
  • OpenGL 与 Eclipse CDT + MinGW + GLEW + GLFW:未定义的参考

    Edit 与此同时 我已经弄清楚了这一点 并在下面写了详细的答案 我刚刚尝试在 Win7 上从 Express 版本的 MSVC 10 切换到 Eclipse CDT 在配置时遇到了以下简单 OpenGL 代码的问题 在 Visual St
  • GLSL 中的二阶函数?

    我正在寻找一种方法来使用一个函数作为 GLSL 中另一个函数的参数 在常规 C 中 可以通过传递函数指针作为函数参数来模拟它 似乎其他语言 如 HLSL 现在提供了处理高级构造 如高阶函数 的方法 或者可以使用以下命令来模拟它们巧妙利用 H
  • 当 OpenGL 中同时绑定 1D 和 2D 纹理时,正确的行为是什么?

    假设你有这样的东西 glBindTexture GL TEXTURE 2D my2dTex glBindTexture GL TEXTURE 1D my1dTex glBegin 正确的 OpenGL 行为是什么 要绘制一维纹理 二维纹理还
  • 无法在 WSL2 上运行 OpenGL

    我尝试在 WSL2 上运行 OpenGL 代码 但在尝试运行可执行文件时出现以下错误 GLFW error 65543 GLX Failed to create context GLXBadFBConfig Unable to create
  • 将四元数旋转转换为旋转矩阵?

    基本上 给定一个四元数 qx qy qz qw 我如何将其转换为OpenGL旋转矩阵 我也对哪个矩阵行是 向上 向右 向前 等感兴趣 我有一个四元数的相机旋转 我需要在向量中 以下代码基于四元数 qw qx qy qz 其中顺序基于 Boo
  • OpenGL缓冲区更新[重复]

    这个问题在这里已经有答案了 目前我正在编写一个模拟水的程序 以下是我所做的步骤 创建水面 平面 创建VAO 创建顶点缓冲区对象 在其中存储法线和顶点 将指针绑定到此 VBO 创建索引缓冲区对象 然后我使用 glDrawElements 渲染
  • Glew+GLFW Win32 无依赖项 Visual Studio

    是否可以在不将文件复制到 C 的情况下构建并链接 Glew 和 GLFW 我找不到任何说明如何在不将 DLL 复制到 C 上的 Visual Studio 目录的情况下使用这些库的文档 我只想包含项目目录中所需的所有 dll 和 lib 文
  • 使用 GLSL 直接在着色器中从位置计算平移矩阵

    我正在开发 C OpengL 程序以及 GLSL 顶点和片段着色器 我正在创建同一对象的多个实例 我只需要改变实例之间的对象位置 这是我所做的 我正在使用一个统一变量 它是一个变换矩阵数组 每个矩阵代表一个对象实例 MVP 也是一个变换矩阵
  • gldrawarrays 不绘制任何东西

    我正在尝试用 VBO 绘制一个三角形 我在窗口上没有看到任何像素 我也没有看到任何 GL ERROR 这是我尝试运行的代码 include
  • 使用 pyclutter 进行编程

    我是混乱 和 pyclutter 的新手 我一直在尝试使用 pyclutter 到目前为止我还没有找到任何好的教程 我的意思是没有真正正确解释的内容 我看到了几个示例程序 但是当我尝试使用 pyclutter 时 我没有得到任何好的结果 这
  • OpenGL:如何检查用户是否支持glGenBuffers()?

    我检查了文档 它说 OpenGL 版本必须至少为 1 5 才能制作glGenBuffers 工作 用户使用的是1 5版本但是函数调用会导致崩溃 这是文档中的错误 还是用户的驱动程序问题 我正在用这个glGenBuffers 对于VBO 我如

随机推荐

  • 如何检测隐藏字段篡改?

    在我的网络应用程序的一种形式上 我有一个隐藏字段 出于安全原因 我需要保护它免遭篡改 我正在尝试提出一个解决方案 通过该解决方案 我可以检测隐藏字段的值是否已更改 并做出适当的反应 即使用通用的 出现问题 请重试 错误消息 该解决方案应该足
  • 对成员 'tableView(_:numberOfRowsInSection:)' 的引用不明确 为什么会出现此错误?

    这是我的代码 其中出现错误 错误出现在第 3 行 if let indexpath override func prepare for segue UIStoryboardSegue sender Any if segue identifi
  • 像一维一样循环二维子图

    我正在尝试使用子图绘制许多数据 并且没有遇到麻烦 但我想知道是否有一种方便的方法可以做到这一点 下面是示例代码 import numpy as np import math import matplotlib pyplot as plt q
  • spectj可以向java.lang.String添加方法吗

    我读过aspectj的一些文章 我知道它可以增强类 这很有吸引力 我有一个非常愚蠢的问题 我找不到明确的答案 spectj可以向java lang String添加方法吗 或者类似的问题 如果我无法获取某些类的源代码 我可以通过aspect
  • Kubernetes 集群中的 DisallowedHost Django 部署:无效的 HTTP_HOST 标头

    我在 Azure Kubernetes 集群中为前端服务部署了 Django 并进行了一些基本配置 但请注意 同样的问题也适用于我本地的 Minikube 集群 我从远程容器注册表中获取 Django 前端容器映像并公开port 8010
  • 检测数据何时发生变化

    好吧 故事是这样的 我有很多特定格式的文件 相当大 大约 25GB 需要导入到数据存储中 这些文件不断更新数据 有时是新的 有时是相同的数据 我正在尝试找出一种算法来检测文件中特定行是否发生更改 以便最大限度地减少更新数据库所花费的时间 目
  • PHP date - 获取本地语言的月份名称

    我有这部分功能 它给我英文月份的名称 我如何将它们翻译成我的当地语言 塞尔维亚语 month name date F mktime 0 0 0 i Where i是月份的数字 值 1 12 也可以看看PHP mktime https www
  • 用于旋转相机意图捕获的图像的代码在 Android 中不起作用

    我有一个问题 使用相机意图捕获的图像被旋转 我在为什么使用相机意图捕获的图像在某些 Android 设备上会旋转 https stackoverflow com questions 14066038 why image captured u
  • 当选择标签样式属性设置为 display: none; 时如何从下拉列表中检索值在 python 硒中

    我正在尝试废弃一个网站的下拉类别的所有组合 但是 选项的文本属性仅为空白 尽管在检查时 我可以看到每个选项都存在文本 from selenium import webdriver from selenium webdriver suppor
  • 如何使用 .Mdf 文件部署 C# exe?

    我已经创建了 Windows 应用程序 并且创建了本地数据库并添加了用户名和密码 如果用户名和密码正确 那么我必须打开代码 我已经生成了一个 Setup Msi 但是当我尝试在我的机器中安装时它工作正常 但是当我尝试在其他没有 Net或任何
  • 为什么 SQL Server '=' 比较器不区分大小写?

    我刚刚意识到 SQL Server 比较器在用于文本比较时不区分大小写 我对这个功能有几个疑问 这对于所有数据库都相同还是特定于 SQL Server 我一直在使用lower函数以确保文本比较到目前为止不敏感 遵循同样的做法仍然是一个好主意
  • Slim - 如何发送带有“Content-Type:application/json”标头的响应?

    我有这个简单的 REST api 用 Slim 完成
  • 通过Ajax将画布图像数据(Uint8ClampedArray)发送到Flask Server

    我想通过 AJAX 将 HTML5 上的图像数据发送到 Flask 服务器后端 我从使用中提取相关图像数据context getImageData a b c d 并且理想情况下希望能够在我的 Flask 后端以 numpy 数组的形式访问
  • 如何使 cocos2d 精灵每秒缩放(以获得脉动效果)?

    我想让精灵每秒缩放一次 使其看起来像是鼓起来并脉动 我怎样才能做到这一点 由于之前的帖子包含语法错误 更准确地说 我发布了工作代码 CCSprite sprite create the sprite id scaleUpAction CCE
  • Xcode 4、dylib 和 install_name_tool

    我正在尝试让 dylib 在我的 OSX 项目中工作 我一直在阅读一些示例 特别是这个 Xcode 4 添加 dylib https stackoverflow com questions 6801709 xcode 4 adding dy
  • Python 模块中的类内相关性?

    我正在寻找计算组内相关性 ICC https en wikipedia org wiki Intraclass correlation在Python中 我还没有找到具有此功能的现有模块 有替代名称吗 还是我应该自己起一个 我知道有人问了这个
  • 使用SIMD解包8位到16位:AVX2版本混淆了顺序

    我正在尝试使用 SSE2 来解压带零的文本 并将其扩展到 AVX2 这就是我的意思 假设您有这样的文本 abcd 我正在尝试使用SSE2来解压abcd into a 0b 0c 0d The 0是零 这当然适用于 16 个字符而不是 4 个
  • 将 .npy(numpy 文件)输入到张量流数据管道中

    Tensorflow 似乎缺少 npy 文件的阅读器 如何将数据文件读入新的tensorflow data Dataset pipline 我的数据不适合内存 每个对象都保存在单独的 npy 文件中 每个文件包含 2 个不同的 ndarra
  • cmake 将中间文件放置到某个目录

    我对 cmake 还很陌生 想知道如何使用 cmake 来做到这一点 我想将所有中间文件 如 o 文件 放置在某个目录 例如 build 中 然后一旦构建完成 我想复制我需要的某些文件 例如 exe dll 就像最终产品一样 从构建目录到
  • OpenGL GLSL 统一分支与多个着色器

    我读过很多关于统一 if 语句的文章 这些语句处理分支以改变大型着色器 超级着色器 的行为 我开始使用 uber 着色器 opengl lwjgl 但后来我意识到 与没有统一 if 语句的单独着色器相比 在片段着色器中添加由统一的 if 语