所以这是我已经有一段时间的设计问题了。我有这个矢量着色器(称为“矢量着色器”),它非常好用:
#version 330 core
layout (location = 0) in vec4 values;
layout (location = 1) in vec4 rect;
layout (location = 2) in int depth;
layout (location = 3) in float radians;
layout (location = 4) in float effect;
layout (std140) uniform Matrices
{
mat4 projection;
mat4 view;
};
out vec2 texCoord;
void main()
{
vec2 transformed = vec2(values.xy * rect.zw*.5); //scale
transformed = vec2(cos(radians)*transformed.x - sin(radians)*transformed.y,sin(radians)*transformed.x + cos(radians)*transformed.y); //rotate
transformed += rect.xy + rect.zw*.5; //move
gl_Position = projection*view*vec4(transformed,depth,1);
texCoord = vec2(values.z,values.a);
}
这个着色器经常将数据传递给这个片段着色器(称之为“片段着色器”):
#version 330 core
out vec4 fragColor;
in vec2 texCoord;
uniform sampler2D sprite;
void main()
{
vec4 text = texture(sprite,texCoord);
fragColor = text;
}
我的顶点着色器和片段着色器一起帮助我渲染精灵,太酷了! 现在我有另一个片段着色器(称为“Paint Shader”),它有一个额外的 vec4 输入,称为“tint”:
#version 330 core
//renders a sprite in a specific color
out vec4 fragColor;
in vec2 texCoord;
in vec4 tint;
uniform sampler2D sprite;
void main()
{
vec4 text = texture(sprite,texCoord);
if (text.w ==0)
{
fragColor = vec4(0);
}
else
{
fragColor = tint;
}
}
我想将 Paint Shader 与 Vector Shader 一起使用,但据我所知(如果错误请更正),我对片段着色器的所有输入要么是制服,要么是来自顶点着色器的输出。我可能需要使用许多不同的值多次调用 Paint Shader,这似乎与统一的想法不符。但如果我想使用顶点着色器,我必须创建一个全新的顶点着色器,它使用与以前相同的代码,唯一的区别是它现在输出 Paint Shader 将使用的 vec4,如下所示:
#version 330 core
layout (location = 0) in vec4 values;
layout (location = 1) in vec4 rect;
layout (location = 2) in int depth;
layout (location = 3) in float radians;
layout (location = 4) in float effect;
layout (location = 5) in vec4 tint_;
layout (std140) uniform Matrices
{
mat4 projection;
mat4 view;
};
out vec2 texCoord;
out vec4 tint;
void main()
{
vec2 transformed = vec2(values.xy * rect.zw*.5); //scale
transformed = vec2(cos(radians)*transformed.x - sin(radians)*transformed.y,sin(radians)*transformed.x + cos(radians)*transformed.y); //rotate
transformed += rect.xy + rect.zw*.5; //move
gl_Position = projection*view*vec4(transformed,depth,1);
texCoord = vec2(values.z,values.a);
tint = tint_;
}
现在我有两个顶点着色器,它们可以有效地执行相同的操作,但由于片段着色器,它们有 3 行不同。如果我决定改变我的顶点着色器的工作方式,我现在必须改变它们,而不仅仅是一个。
有没有办法在不创建第二个顶点着色器的情况下做到这一点?对于这种情况,最佳做法是什么?我可以将顶点着色器的第二次迭代与原始片段着色器一起使用,但忽略“色调”输出吗?
为了避免重写代码,请使用预处理器。
例如在你的着色器代码中使用类似这样的东西
#ifdef THIS_CONSTANT
//some code
#elif THAT_CONSTANT
//some other code
#endif
然后,当您创建着色器时,您只需将两个(或更多)源字符串传递给
glShaderSource
const char *constants =
"#version 330 core\n"
"#define THIS_CONSTANT\n"
"//or #define THAT_CONSTANT\n";
const char *vs_or_fs_src = "your main code";
//pass this to glShaderSource
const char *shader_src[] = {
constants,
vs_or_fs_src
};
简单、轻松的方法是使用位掩码,让着色器管理器根据掩码中设置的位动态创建特定的着色器程序(如果不存在)。
是的,您最终会得到多个着色器程序,但只有一个源文件(对于每种着色器类型)。