【问题标题】:Why can I not use multiple "in" variables in GLSL?为什么我不能在 GLSL 中使用多个“in”变量?
【发布时间】:2021-09-20 05:52:24
【问题描述】:

考虑一下我的着色器程序。

const char* vert_shader_script =

"#version 330 core\n                                    \n\
                                                        \n\
layout(location = 0) in vec3 vertex_pos;                \n\
layout(location = 1) in vec2 texture_uv;                \n\
                                                        \n\
uniform mat4 M, V, P;                                   \n\
                                                        \n\
out vec2 uv;                                            \n\
                                                        \n\
void main() {                                           \n\
                                                        \n\
    gl_Position = P * V * M * vec4(vertex_pos, 1.0);    \n\
    uv = texture_uv;                                    \n\
}\n";

const char* frag_shader_script =

"#version 330 core                                                                  \n\
                                                                                    \n\
uniform sampler2D texture0;                                                         \n\
uniform vec4 override_color;                                                        \n\
uniform vec2 player_pos;                                                            \n\
                                                                                    \n\
in vec2 uv;                                                                         \n\
in int gl_VertexID; // This causes it!                                                              \n\
                                                                                    \n\
out vec4 out_col;                                                                   \n\
                                                                                    \n\
void main() {                                                                       \n\
                                                                                    \n\
    vec4 tex_color = texture2D(texture0, uv);                                       \n\
    float alpha = 1.0;                                                              \n\
                                                                                    \n\
    if (tex_color.r == 1.0 && tex_color.g == 0.0 && tex_color.b == 1.0)             \n\
        alpha = 0.0;                                                                \n\
    else {                                                                          \n\
                                                                                    \n\
        if (override_color.a > 0.0)                                                 \n\
            tex_color = override_color;                                             \n\
        else {                                                                      \n\
                                                                                    \n\
            tex_color.r = max(tex_color.r - 0.9, 0.1);                              \n\
            tex_color.g = max(tex_color.g - 0.9, 0.1);                              \n\
            tex_color.b = max(tex_color.b - 0.9, 0.1);                              \n\
        }                                                                           \n\
    }                                                                               \n\
                                                                                    \n\
    out_col = vec4(tex_color.r, tex_color.g, tex_color.b, alpha);                   \n\
}\n";

在我在片段着色器中添加in int gl_VertexID 之前一切正常。只绘制背景颜色。不仅在我使用gl_VertexID 时会发生这种情况,而且即使我尝试在uv 下方添加我自己的in 变量时也会发生这种情况。我试图通过在顶点着色器中创建一个新的out pos,将vertex_pos从顶点着色器传递到片段着色器,在片段着色器中创建in pos,然后在它被发送到片段之前在顶点着色器中更改它着色器。但是,在片段着色器中添加另一个 in 变量后,问题立即出现。

我一次只能使用一个吗?这里是否发生了其他事情,例如我的 C++ 代码中缺少 gl 函数?目前我在渲染之前和之后唯一使用的是:

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glDepthFunc(GL_LESS);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_BLEND);

即使没有它们,除了第一个,问题仍然存在。

编辑:顶点和片段着色器的日志中都没有错误/警告消息。


更新: 我已将gl_VertexID 从片段着色器重新定位到顶点着色器,并解决了我将来可能遇到的任何问题。但是,我注意到我当前的问题实际发生的时间,但不知道为什么。

考虑更新后的着色器:

// Vertex Shader
...
in int gl_VertexID;
out int vert_id;

void main() {

    ...
    vert_id = gl_VertexID;
}

// Fragment Shader
...
in int vert_id;

void main() {

    ...
    if (vert_id == 0) {

        // Empty statement for testing purposes.
    }
    else {

        // This statement is empty as well.
    }

    ...
    // Draw normally. Apply regular data to the out_color vector. Nothing else has been changed nor prevents the code from reaching the declaration. But doesn't it really?
}

问题在于 vert_id 变量的赋值。如果我要从顶点着色器的主函数中保留除vert_id = gl_VertexID 之外的所有内容,则不会发生此问题,但只要我给 vert_id 任何值,它就不会绘制除背景颜色之外的任何内容。这可能发生在我检查片段着色器时,主要是if (vert_id == N),因为在删除它而不是顶点着色器中的分配时,问题不会持续存在。我在这里做错了什么?日志中仍然没有报告错误。

【问题讨论】:

  • 在编译和链接时,您不仅可以检查是否成功,还会收到错误消息,详细说明失败的原因。您应该检查这些消息并将它们包含在问题中。
  • @t.niese 我已经更新了我的问题。谢谢!
  • 您不必“重新定位”gl_VertexID 变量。该内置变量无需显式定义即可存在。你只需使用它:-)
  • @datenwolf 完美,谢谢!但为什么问题仍然存在?将 vert_id 设置为我自己的值(如 1)仍然会使问题持续存在。希望重新分配导致问题,但不是!

标签: c++ opengl glsl shader


【解决方案1】:

整数类型不支持插值。因此,如果您想将整数值转发到片段着色器,您必须使用flat 插值限定符:

VS:

flat out int vert_id;

FS:

flat in int vert_id;

除了背景色之外什么都不画

那是因为您的着色器无法编译或链接。您应该查询ShaderProgram info logs,并实际阅读它们。

【讨论】:

    【解决方案2】:

    所有以gl_ 开头的标识符都是为 GLSL 规范保留的。你不能重新发明它们。您可以重新声明其中一些,但前提是它们已经以某种形式存在于该着色器阶段。

    对白:

    直到我在片段着色器中添加 int gl_VertexID

    gl_VertexID 是一个built-in variable,它定义了特定输入顶点来自哪个顶点索引。由于片段着色器处理片段,而不是顶点,因此该变量在 FS 中不可用(片段由基元生成,可以从 多个 顶点构建。所以你不知道要获取哪个顶点索引)。如果您想将某种标识符传递给 FS,则必须让您的 VS 提供该数据。

    【讨论】:

    • 很有道理,谢谢!我已经更新了我的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多