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

mzillmmw  于 2023-06-25  发布在  其他
关注(0)|答案(3)|浏览(184)

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

  1. GLfloat _vertices[] = {
  2. -1.0f, -1.0f,
  3. 1.0f, -1.0f,
  4. -1.0f, 1.0f,
  5. 1.0f, -1.0f,
  6. 1.0f, 1.0f,
  7. -1.0f, 1.0f };

然后我设置顶点并调用draw如下:

  1. glViewport(0, 0, w, h);
  2. glEnableVertexAttribArray(0);
  3. glDisable(GL_BLEND);
  4. glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, _vertices);
  5. glDrawArrays(GL_TRIANGLES, 0, 6);

我的顶点着色器为:

  1. #version 320 es
  2. layout(location = 0) in vec2 vertPos;
  3. out vec2 fragPos;
  4. out float theLength;
  5. void main()
  6. {
  7. fragPos = vertPos;
  8. theLength = length(fragPos);
  9. gl_Position = vec4(vertPos.xy, 1.0, 1.0);
  10. }

片段是:

  1. #version 320 es
  2. precision mediump float;
  3. in vec2 fragPos;
  4. in float theLength;
  5. out vec4 fragColor;
  6. void main()
  7. {
  8. vec4 color = vec4(0.0);
  9. float d = length(fragPos);
  10. fragColor = vec4(d, 0.0, 0.0, 1.0);
  11. }

有了上面的片段,我有了下面的图像:

如果我将行fragColor = vec4(d, 0.0, 0.0, 1.0);改为fragColor = vec4(theLength, 0.0, 0.0, 1.0);,我得到:

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

rjzwgtxy

rjzwgtxy1#

默认情况下,行为如下(省略深度缓冲区、模板缓冲区等与此无关的工作):
1.对于每个顶点,顶点着色器计算out变量
1.对于每个面(三角形),其顶点的out变量根据重心坐标进行插值,该插值对于属于三角形的每个片段(像素)是单独的
1.为每个这样的片段执行片段着色器,接收插入到in参数中的值
fragPos的情况下,每个顶点的值都不同,因此自然会得到具有不同向量的插值,并且这些向量的长度与到中心的距离成正比,因为四边形的范围是-1到1
length的情况下,对于每个顶点,长度计算为sqrt(2),因此在这些顶点上的插值对于每个片段都是恒定的

pb3skfrl

pb3skfrl2#

对于fragColor = vec4(theLength, 0.0, 0.0, 1.0);,只计算每个顶点的长度,然后对顶点的长度结果进行插值。
由于所有顶点都具有相同的长度(可能是sqrt(2)),因此这些值之间的所有插值都会产生相同的结果。
在原始版本中,分别为每个像素(片段)计算长度。这导致朝向中心具有较小的值。
重要的区别在于插值的值。在第一个版本中,它是位置(在顶点之间变化)。第一像素行的示例:fragPos.x从-1到1进行插值(所有值都在中间)。fragPos.y为常数-1。当你计算距离时,你会得到每个片段的不同值。
在第二个版本中,长度不变。

uplii1fm

uplii1fm3#

顶点着色器将为三角形的每个顶点-3次调用调用。为每个片段调用片段着色器-为每个像素调用(粗略地)。
每个统一变量可以有一个插值限定符smoothflatnoperspective,描述如何将顶点着色器中的3个值分配到片段着色器的每次调用。
如果限定符是flat,那么对于每个图元都有一个主顶点,从该顶点开始,变量的值用于属于该图元的所有片段。
smooth将为三角形的每个顶点取三个值,并在它们之间插值。尝试将theLength设置为例如.x的顶点坐标,自己看。
它永远不会与你想要的模式,虽然有根本没有足够的信息在顶点着色器。

相关问题