Почему я не могу использовать несколько переменных «в» в GLSL?

#c #opengl #glsl #shader

Вопрос:

Рассмотрим мою программу шейдеров.

 const char* vert_shader_script =

"#version 330 coren                                    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 amp;amp; tex_color.g == 0.0 amp;amp; 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 , но даже когда я пытаюсь добавить свою собственную in переменную ниже uv , это происходит. Я пытаюсь перейти vertex_pos от вершинного шейдера к шейдеру фрагментов, создав новый out pos в шейдере вершин, создайте in pos его в шейдере фрагментов, затем измените его в шейдере вершин, прежде чем он будет отправлен в шейдер фрагментов. Но проблема возникает сразу же после добавления другой in переменной внутри шейдера фрагментов.

Могу ли я использовать только один за раз? Происходит ли здесь что-то еще, например, отсутствует функция gl в моем коде на C ? Единственное, что я использую до и после рендеринга на данный момент, — это:

     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);
 

Even without them except the first one, the problem still occurs.

EDIT: There are no error/warning messages in the logs of both vertex and fragment shaders.


UPDATE:
I’ve relocated the gl_VertexID from the fragment shader to the vertex shader and solved any possible problems I may get int the future. However, I’ve noticed when my current issue actually occurs, but do not know why.

Рассмотрим обновленные шейдеры как таковые:

 // 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) , потому что после удаления этого вместо назначения в шейдере вершин проблема не сохраняется. Что я здесь делаю не так? В журналах по-прежнему не сообщается об ошибках.

Комментарии:

1. При компиляции и связывании вы можете не только проверить, было ли это успешно или нет, но и получать сообщения об ошибках, в которых более подробно рассказывается о причинах сбоя. Вы должны проверить эти сообщения и включить их в вопрос.

2. @t.niese Я обновил свой вопрос. Спасибо!

3. Вам не нужно «перезагружать» gl_VertexID переменную. Эта встроенная переменная существует без необходимости ее явного определения. Вы просто используете его 🙂

4. @datenwolf Отлично, спасибо! Но почему эта проблема сохраняется? Установка vert_id на мое собственное значение, например 1, по-прежнему вызывает проблему. Надеялся, что перераспределение вызвало проблему, но нет!

Ответ №1:

Все идентификаторы, начинающиеся с gl_ , зарезервированы для спецификации GLSL. Вы не можете изобретать их заново. Вы можете повторно объявить некоторые из них, но только в том случае, если они уже существуют в той или иной форме на этой стадии шейдера.

На уит:

пока я не добавлю in int gl_VertexID в шейдер фрагментов

gl_VertexID является встроенной переменной, которая определяет, из какого индекса вершины происходит конкретная входная вершина. Поскольку шейдеры фрагментов обрабатывают фрагменты, а не вершины, эта переменная недоступна в FS (фрагмент создается примитивами, которые могут быть построены из нескольких вершин. Так что вы не будете знать, из какой вершины получить индекс). Если вы хотите передать какой-либо идентификатор в FS, вам придется заставить ваш VS предоставить эти данные.

Комментарии:

1. В этом есть большой смысл, спасибо! Я обновил свой вопрос по этой проблеме.

Ответ №2:

Для интегральных типов отсутствует поддержка интерполяции. Поэтому, если вы хотите перенаправить целочисленные значения в шейдер фрагментов, вы должны использовать квалификатор flat интерполяции:

против:

 flat out int vert_id;
 

ФС:

 flat in int vert_id;
 

он не рисует ничего, кроме цвета фона

Это потому, что ваши шейдеры не могут компилироваться или связываться. Вы должны запросить журналы сведений о шейдере и программе и фактически прочитать их.