#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;
он не рисует ничего, кроме цвета фона
Это потому, что ваши шейдеры не могут компилироваться или связываться. Вы должны запросить журналы сведений о шейдере и программе и фактически прочитать их.