OpenGL:UV 值未在片段着色器中进行插值

red*_*tom 0 opengl glsl texture-mapping texture2d

我一直在尝试将一些旧的 OpenGL 代码转换为使用着色器,但在让片段着色器在立方体上绘制纹理时遇到了问题。然而,我看到的只是一个灰色的立方体。我已经调试了我的 .obj 加载器代码,并且我知道 UV 正在正确加载,并且我知道纹理正在从磁盘加载并正确放置在 GPU 上。经过大量测试后,我发现我的 UV 值没有在每个三角形的面上进行插值。也就是说,看起来每个片段的 uv 值都为 0.0,0.0(这是我缓冲区中的第一个 uv 值)知道为什么吗?

这是我的片段着色器:

#version 430 core

in vec3 color;
in vec2 uv;
uniform sampler2D tex;
out vec3 frag_color;

void main()
{
    //frag_color = color;
    frag_color = texture(tex,uv).rgb;
}
Run Code Online (Sandbox Code Playgroud)

还有我的顶点着色器:

#version 430 core

layout(location = 0) in vec3 pos;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 uv;
uniform mat4 mvMatrix;
uniform mat4 mvpMatrix;
attribute vec3 lightPos;
out vec3 color;
out vec2 uv_out;

void main()
{
uv_out = uv;

vec3 modelViewVertex = vec3(mvMatrix * vec4(pos,1.0));
vec3 modelViewNormal = vec3(mvMatrix * vec4(normal,0.0));
vec3 modelViewLightPos = vec3(mvMatrix * vec4(lightPos,1.0));

vec3 lightVector = normalize(lightPos - pos);
float diffuse = clamp(dot(normal,lightVector),0,1);

gl_Position = mvpMatrix * vec4(pos,1.0);
color = vec3(diffuse,0.0,0.0);

}
Run Code Online (Sandbox Code Playgroud)

这是我设置缓冲区的地方:

glGenVertexArrays(1, &vertexBufferObjectID);
glBindVertexArray(vertexBufferObjectID);
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(vec3), &vertices[0], GL_STATIC_DRAW);
glGenBuffers(1, &normalBuffer);
glBindBuffer(GL_ARRAY_BUFFER, normalBuffer);
glBufferData(GL_ARRAY_BUFFER, normals.size()*sizeof(vec3), &normals[0], GL_STATIC_DRAW);
glGenBuffers(1, &UVBuffer);
glBindBuffer(GL_ARRAY_BUFFER, UVBuffer);
glBufferData(GL_ARRAY_BUFFER, uvs.size()*sizeof(vec2), &uvs[0], GL_STATIC_DRAW);
Run Code Online (Sandbox Code Playgroud)

最后,这是我的渲染循环:

glUseProgram(shaderProgram);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(textureID, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, normalBuffer);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, UVBuffer);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);

mvpMatrix = projectionMatrix * viewMatrix * modelMatrix;
glUniformMatrix4fv(mvpMatrixID, 1, GL_FALSE, &mvpMatrix[0][0]);
mvMatrix = viewMatrix * modelMatrix;
glUniformMatrix4fv(mvMatrixID, 1, GL_FALSE, &mvMatrix[0][0]); 
glVertexAttrib3fv(lightposID, &lightpos[0]);
glDrawArrays(GL_TRIANGLES, 0, vertices.size());

glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
Run Code Online (Sandbox Code Playgroud)

同样,根据我所阅读的内容,一切看起来都是正确的。看起来有什么不对吗?

dat*_*olf 5

您必须处理uv从顶点到片段着色器的变化。in在顶点着色器和片段着色器中不能有同名的属性。相反,您必须in在顶点着色器中有一些属性,然后将其传递out给与in片段着色器中的对应对象具有相同名称的变量。

在您的情况下,您的顶点着色器已经有一个out不同的uv_out. 因此,片段着色器也需要命名uv_out,即在片段着色器中

in vec2 uv_out
Run Code Online (Sandbox Code Playgroud)

当然,这个名字uv_out有点误导。