重写我的整个屁股矢量着色器只是为了适应稍微不同的片段着色器

问题描述 投票:0回答:1

所以这是我已经有一段时间的设计问题了。我有这个矢量着色器(称为“矢量着色器”),它非常好用:

#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 行不同。如果我决定改变我的顶点着色器的工作方式,我现在必须改变它们,而不仅仅是一个。

有没有办法在不创建第二个顶点着色器的情况下做到这一点?对于这种情况,最佳做法是什么?我可以将顶点着色器的第二次迭代与原始片段着色器一起使用,但忽略“色调”输出吗?

opengl graphics glsl shader
1个回答
0
投票

为了避免重写代码,请使用预处理器。

例如在你的着色器代码中使用类似这样的东西

#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
};

简单、轻松的方法是使用位掩码,让着色器管理器根据掩码中设置的位动态创建特定的着色器程序(如果不存在)。

是的,您最终会得到多个着色器程序,但只有一个源文件(对于每种着色器类型)。

© www.soinside.com 2019 - 2024. All rights reserved.