在 GLSL 着色器中访问 VBO/VAO 数据

Posted

技术标签:

【中文标题】在 GLSL 着色器中访问 VBO/VAO 数据【英文标题】:Acessing VBO/VAO Data in GLSL Shader 【发布时间】:2015-10-08 22:14:56 【问题描述】:

vertex shader 中,如何使shader 中的函数在将其顶点数据缓冲到VBO 后访问特定的属性数组值?

cmp() 下方的shader 函数中应该将统一变量与vertex i 进行比较。

#version 150 core

in vec2 vertices;
in vec3 color;
out vec3 Color;

uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;

uniform vec2 cmp_vertex; // Vertex to compare
out int isEqual;         // Output variable for cmp()

// Comparator 
vec2 cmp()
  int i = 3; 
  return (cmp_vertex == vertices[i]); 


void main() 
    Color = color;
    gl_Position = projection * view * model * vec4(vertices, 0.0, 1.0);
    isEqual = cmp();

另外,可以修改cmp() 使其并行进行比较吗?

【问题讨论】:

【参考方案1】:

根据您的着色器代码中的命名以及您问题的措辞,您似乎误解了顶点着色器的概念。

每个顶点调用一次顶点着色器。因此,当您的顶点着色器代码执行时,它总是在单个顶点上运行。这意味着您的 in 变量的名称具有误导性:

in vec2 vertices;

此变量为您提供着色器正在处理的唯一一个顶点的位置。因此,如果您使用单数形式的名称可能会更清楚:

in vec2 vertex;

一旦您意识到您正在对单个顶点进行操作,其余的就变得容易了。对比:

bool cmp() 
    return (cmp_vertex == vertex); 

顶点着色器通常已经被并行调用,这意味着许多实例可以同时执行,每个实例都在自己的顶点上。所以在单个着色器实例中不需要并行。

你可能会遇到更多的问题来实现你所追求的。但我希望这至少能让你克服最初的障碍。

比如下面的out变量就有问题:

out int isEqual;

out 顶点着色器的变量在片段着色器中有匹配的in 变量。默认情况下,顶点着色器写入的值是跨三角形线性插值的,片段着色器获取插值后的值。这对于 int 类型的变量不支持。它们仅支持平面插值:

flat out int isEqual;

但这可能不会给你你想要的,因为你在片段着色器中看到的值在整个三角形中总是相同的。

【讨论】:

好的,但我仍然不确定当我的绘图调用使用 VBO 中的顶点数组时会发生什么。 GLfloat 顶点[] = -1.0f, 1.0f, ..., 1.0f, 1.0f, ..., 1.0f, -1.0f, ..., -1.0f, -1.0f, ..., . . . . . . ;我知道如何指定顶点数组属性,但是顶点属性如何处理每个顶点? 澄清一下,在我的绘图调用中:drawArrays(GL_TRIANGLES, n * 3, GL_UNSIGNED_INT, 0); vertex如何对应n * 3个顶点的数组?

以上是关于在 GLSL 着色器中访问 VBO/VAO 数据的主要内容,如果未能解决你的问题,请参考以下文章

从 GLSL 着色器中获取常量

为啥我的着色器中的 GLSL 纹理坐标不是线性的?

如果未绑定,统一值是不是保留在 GLSL 着色器中?

满足条件时是不是可以在 GLSL 着色器中回调 C/C++ 函数/代码? [关闭]

GLSL 像素化着色器中的边框伪影

一次调用可以在 glsl 计算着色器中进行乒乓传播吗?