有没有办法创建多个着色器(顶点,片段,甚至几何和曲面细分),这些着色器可以在它们的作用中复合?
例如:我在OpenGL的更高版本中看到了 和 out 关键字的多种用法,并将使用这些来说明我的题。
是否有一种给定着色器的方法(没有关系,但让我们说片段着色器),例如
in inVar;
out outVar;
void man(){
var varOne = inVar;
var varTwo = varOne;
var varThr = varTwo;
outVar = varThr;
}
将其转换为片段着色器
in inVar;
out varOne;
void main(){
varOne = inVar;
}
跟随片段着色器
in varOne;
out varTwo;
void main(){
varTwo = varOne;
}
跟随片段着色器
in varTwo(
out varThr;
void main(){
varThr = varTwo
}
最后是片段着色器
in varThr;
out outVar;
void main(){
outVar = varThr;
}
和 out 是正确的"概念"描述这种行为还是我应该寻找其他关键词?
答案 0 :(得分:4)
生成着色器。这就是所有3D引擎和游戏引擎所做的事情。
换句话说,他们使用代码操作文本,并在运行时或构建时生成源代码。
有时候他们会使用GLSL的预处理器。实施例
if (datediff(mm,@maxdw01,@maxas48)=1)
begin
select 1 as MonthFlag
end else
select 0 as MonthFlag
End
然后在运行时预先添加一个字符串来定义#ifdef USE_TEXTURE
uniform sampler2D u_tex;
varying vec2 v_texcoord;
#else
uniform vec4 u_color;
#endif
void main() {
#ifdef USE_TEXTURE
gl_FragColor = texture2D(u_tex, v_texcoord);
#else
gl_FragColor = u_color;
#endif
}
。
的JavaScript
USE_TEXTURE
大多数引擎虽然通过使用大量的小块GLSL并将它们与各种字符串替换相结合来进行更多的字符串操作。
答案 1 :(得分:3)
在OpenGL中,您可以将多个相同类型的着色器附加到程序对象。在OpenGL ES中,不支持此功能。
这是来自OpenGL 4.5规范,“7.3程序对象”一节,第88页(重点补充):
相同类型的多个着色器对象可以附加到单个程序对象,并且单个着色器对象可以附加到多个程序对象。
与OpenGL ES 3.2规范相比,第7章“7.3程序对象”一节(重点补充):
相同类型的多个着色器对象可能不会附加到单个程序对象。但是,单个着色器对象可以附加到多个程序对象。
但是,即使在OpenGL中,使用相同类型的多个着色器也不起作用,您可以在问题中概述它。只有一个着色器可以有main()
。其他着色器通常只包含函数。因此,将相同类型的多个着色器链接到管道中的想法将无法以此形式工作。
有时使用的方式是有一个(或多个)着色器包含一组泛型函数,只需要编译一次,然后可以用于多个着色器程序。这与一般编程中的函数库相当。您可以使用非官方术语,“库着色器”来调用它。
然后每个着色器程序都有一个包含main()
的每种类型的着色器,该着色器包含该程序的特定逻辑和控制流,同时从“库着色器”调用泛型函数。
按照问题中的大纲,您可以通过在每个着色器中定义一个函数来实现类似的功能。例如,第一个片段着色器可以包含以下代码:
void shaderOne(in vec4 varIn, out vec4 varOut) {
varOut = varIn;
}
第二个着色器:
void shaderTwo(in vec4 varIn, out vec4 varOut) {
varOut = varIn;
}
第三个着色器:
void shaderThr(in vec4 varIn, out vec4 varOut) {
varOut = varIn;
}
然后你需要一个带有main()
的着色器,你可以在其中链接其他着色器:
in vec4 varOne;
out vec4 outVar;
void main() {
vec4 varTwo, varThr;
shaderOne(varOne, varTwo);
shaderTwo(varTwo, varThr);
shaderThr(varThr, outVar);
}