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

时间:2014-01-17 22:35:40

标签: 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;
}

我的顶点着色器:

#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);

}

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

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);

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

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);

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

1 个答案:

答案 0 :(得分:4)

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

在您的情况下,您的顶点着色器已经有out变化uv_out。因此,片段着色器变化也需要命名为uv_out,即在片段着色器中

in vec2 uv_out

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