我有一些用GLSL编写的数学函数,我想在同一着色器程序的TES,几何和片段阶段使用它们。所有这些着色器类型都非常有效,现在代码只是在着色器文件中复制粘贴。
我想从着色器文件中提取函数并将它们放入一个单独的文件中,从而产生一个着色器“库”。我至少可以看到两种方法:
是否可以仅编译着色器源一次(有适当的限制),将其链接到着色器程序并在管道的任何阶段使用它?我的意思是这样的:
GLuint shaderLib = glCreateShader(GL_LIBRARY_SHADER);
//...add source and compile....
glAttachShader(shProg, vertexShader);
glAttachShader(shProg, tesShader);
glAttachShader(shProg, geomShader);
glAttachShader(shProg, fragShader);
glAttachShader(shProg, shaderLib);
glLinkProgram(shProg); // Links OK; vertex, TES, geom and frag shader successfully use functions from shaderLib.
当然,库着色器不应包含in
或out
个全局变量,但可以使用uniform
s。此外,函数原型应在每个着色器源中使用之前声明,因为在将多个相同类型的着色器链接到一个程序时可以这样做。
如果上述情况不可能,那么为什么?对于GLSL的C类编译模型,这种“库”着色器看起来非常符合逻辑。
答案 0 :(得分:2)
是否可以仅编译着色器源一次(有适当的限制),将其链接到着色器程序并在管道的任何阶段使用它?
没有。我建议,如果你必须这样做,只需将文本添加到各种着色器。好吧,不要直接添加到实际的字符串中;相反,将其添加到您通过glShaderSource/glCreateShaderProgram
提供的着色器字符串列表中。
如果上述情况不可能,那么为什么?
因为每个着色器阶段都是独立的。
应该注意的是,甚至Vulkan都没有改变这一点。好吧,不是你想要的方式。 允许您在一个SPIR-V模块中进行反向:多个着色器阶段。但它没有(在API级别)允许您有多个模块为单个阶段提供代码。
答案 1 :(得分:0)
结构,功能,模块链接等所有高级构造都大多只是API提供的细节,使您的生活更容易输入。例如,HLSL允许您使用#include,但要在GLSL中执行类似的操作,您需要自己执行该预处理步骤。
当GPU必须执行着色器时,它每帧运行相同的代码数百,数千,甚至数百万次 - 驱动程序将您的着色器转换为自己的HW特定指令集并将其优化为最小可用于保证其指令缓存和着色器引擎的最佳性能的指令数。