为什么我不能在GLSL中使用多个“in”变量?
考虑我的着色器程序。
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 && 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,而且即使当我尝试在in下面添加我自己的变量时uv,它也会发生。我试图通过vertex_pos在顶点着色器中创建一个新out 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)因为在删除它而不是顶点着色器中的分配时,问题不会持续存在。我在这里做错了什么?日志中仍然没有报告错误。
回答
所有以 开头的标识符gl_都是为 GLSL 规范保留的。你不能重新发明它们。您可以重新声明其中的一些,但前提是它们在着色器阶段已经以某种形式存在。
至于:
直到我
gl_VertexID在片段着色器中添加了 in int
gl_VertexID是一个内置变量,用于定义特定输入顶点来自哪个顶点索引。由于片段着色器处理片段,而不是顶点,因此该变量在 FS 中不可用(片段由图元生成,可以从多个顶点构建。因此您不知道从哪个顶点获取索引)。如果您想将某种标识符传递给 FS,您将不得不让您的 VS 提供该数据。