GLSL问题:一个程序中有多个着色器
GLSL Problem: Multiple shaders in one program
我一定是误解了shaders:
我认为,因为你可以附加多个着色器到一个程序,你可以简单地附加多个片段着色器,作为一个例子:一个板条箱纹理渲染与颜色调制和折射。
但显然情况并非如此,因为每个程序只能有一个main函数。
- 我如何才能围绕主要功能限制工作,并允许在同一程序中并相互调用的多个片段着色器的任何动态组合?
您可以预定义一组入口点。假设你有有限数量的效果(漫射、镜面、环境等)。它们最多不会应用一次,所以你只需要创建一个管理着色器,就像这样:
void apply_diffuse();
void apply_specular();
void apply_environment();
void main(){ ...
apply_diffuse();
apply_specular();
apply_environment();
...}
然后,当需要链接着色器程序时,将相应的实现附加为单独的GLSL对象。如果您不想要效果,有些实现可能是假的。这种方法不需要源文本解析,并且几乎没有性能损失。
你不能。这被称为着色器的组合爆炸。要么你使用大量着色器-称为Übershader方法-或者我相信你可以通过扰乱预处理器并动态生成你需要的着色器来实现它。
新版本的GLSL应该支持虚函数,它允许你像在CPU代码中那样模块化地构建虚函数——HLSL5就是这样做的。
问题出在你使用的术语上。
让我做一个类比:
- 可执行文件由链接的对象组成,对象从源代码编译。
- 一个着色器程序是由链接的着色器对象组成的,着色器对象是从源代码编译的。
如你所见,着色器程序是可执行的。它链接多个着色器对象。每个着色器对象都是从一个源编译的。对于通常的可执行文件,只有一个主入口点,它只由一个着色器对象定义。就像用任何编译工具链编译一样。
解决方案是在着色器对象组合和着色器程序数量之间取得良好的平衡。当然,只有一个着色器程序用于渲染是很漂亮的,但这是假装太多了:尝试分解着色器功能,然后分别编译这些功能并根据需要链接。
你一定要看一下OpenGL Registry,我想你可能会在扩展列表中发现一些有趣的东西。
你可以在一个shader中有多个程序,但不能反过来。
要进行多个组合,最简单的方法是将每个主要块存储为带有命名入口点的片段,然后从另一个程序中包含它们,或者在运行时将它们组合到一个程序中,按您需要的顺序调用它们。但是,在处理输入和输出时,这会变得很混乱。
您可以使用多个通道,在每个通道中使用不同的效果和程序。这有一些额外的开销,但可以更容易设置。
- 试图在visual studio上用C++创建一个桌面应用程序
- FFmpeg:制作一个应用程序比直接使用ffmepg更好吗
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- VSCode-有一个红色下划线,但程序构建和运行正确,并且出现配音错误
- 我正在尝试使用 c++ 创建一个货币转换程序,我不知道如何继续
- 试图创建一个多线程程序来查找0-100000000之间的总素数
- 我试图制作一个程序,要求用户输入问题和答案,但程序循环不正确
- 为什么它只打印双链接列表的第一个值,而我的程序却崩溃了
- 如何声明一个可以在整个程序中使用的全局 2d 3d 4d .. 数组(堆版本)变量?
- 我写了一个C++程序来模拟Enigma机器.我没有得到输出
- 为什么这个程序返回最后一个单词而不是最长的单词?
- 如何使用C++读取另一个程序中的源代码输出
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 我的程序有一个保存配置文件的GUI,如何双击此配置文件以直接加载带有配置数据的GUI?
- 我想通过带有C++和Python的插件创建一个可扩展的应用程序
- 3-3. 编写一个程序来计算每个不同单词在其输入中出现的次数
- 为什么有时我输入一个整数,程序将第一个输入的数字打印成十进制数?
- 未定义的操作?程序一个接一个地打印出不同的值
- 如何给这个简单的 c++ 程序一个适当的循环
- 我如何给一个c++程序一个图标