顶点着色器的输入如何工作?

gor*_*oro 4 c++ opengl sdl glsl

总之,我有以下顶点缓冲区:

GLfloat _vertices[] = {
    -1.0f, -1.0f,
    1.0f, -1.0f,
    -1.0f, 1.0f,
    1.0f, -1.0f,
    1.0f, 1.0f,
    -1.0f, 1.0f };
Run Code Online (Sandbox Code Playgroud)

然后我设置顶点并调用绘制,如下所示:

glViewport(0, 0, w, h);
glEnableVertexAttribArray(0);
glDisable(GL_BLEND);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, _vertices);
glDrawArrays(GL_TRIANGLES, 0, 6);
Run Code Online (Sandbox Code Playgroud)

我的顶点着色器如下:

glViewport(0, 0, w, h);
glEnableVertexAttribArray(0);
glDisable(GL_BLEND);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, _vertices);
glDrawArrays(GL_TRIANGLES, 0, 6);
Run Code Online (Sandbox Code Playgroud)

片段是:

#version 320 es
layout(location = 0) in vec2 vertPos;

out vec2 fragPos;
out float theLength;
void main()
{
    fragPos = vertPos;
    theLength = length(fragPos);
    gl_Position = vec4(vertPos.xy, 1.0, 1.0);
}
Run Code Online (Sandbox Code Playgroud)

通过像上面这样的片段,我得到了以下图像: 我没想到会这样

如果我将行更改fragColor = vec4(d, 0.0, 0.0, 1.0);fragColor = vec4(theLength, 0.0, 0.0, 1.0);

还行吧。

为什么我会得到不同的结果?我本来期待有一个红色方块。我在 SDL 中使用 glsl 着色器。也许 SDL 正在后台实现几何着色器?

谢谢。

BDL*_*BDL 7

使用 时fragColor = vec4(theLength, 0.0, 0.0, 1.0);,仅计算每个顶点的长度,然后对顶点的长度结果进行插值。

由于所有顶点都具有相同的长度(可能是 sqrt(2)),因此这些值之间的所有插值都会产生相同的结果。

在原始版本中,单独计算每个像素(片段)的长度。这导致朝向中心的值更小。

重要的区别在于哪些值被插值。在第一个版本中,它是位置(顶点之间不同)。第一个像素行的示例:fragPos.x 从 -1 到 1 进行插值(所有值都在其间)。fragPos.y 为常数 -1。然后计算距离时,每个片段都会得到不同的值。

在第二个版本中,长度没有变化。


Ale*_*nov 6

默认情况下,行为如下(省略深度缓冲区、模板缓冲区以及此处不相关的其他内容的工作):

  1. 对于每个顶点,顶点着色器都会评估out变量
  2. 对于每个面(三角形),out其 3 个顶点的变量根据重心坐标进行插值,该插值对于属于三角形的每个片段(像素)是独立的
  3. 片段着色器针对每个这样的片段执行,将插值接收到in参数中

在 的情况下fragPos,每个顶点都是不同的,因此自然会得到具有不同向量的插值,并且这些向量的长度与距中心的距离成正比,因为您的四边形在 -1 到 1 的范围内

在 的情况下length,对于每个顶点,长度计算为sqrt(2),因此对于每个片段来说,这些顶点的插值是恒定的

在此输入图像描述