4

我要完成的工作:在场景顶部绘制场景的深度图(以便靠近的物体更暗,更远的物体更亮)

问题:我似乎不明白如何将正确的纹理坐标从我的顶点着色器传递到我的片段着色器。

所以我创建了我的 FBO,以及深度贴图被绘制到的纹理……并不是说我完全确定我在做什么,但无论如何,它可以工作。我测试了使用固定功能管道绘制纹理,它看起来就像它应该的那样(即深度图)。

但是尝试在我的着色器中使用它是行不通的......

这是我的渲染方法中绑定纹理的部分:

glActiveTexture(GL_TEXTURE7);
glBindTexture(GL_TEXTURE_2D, depthTextureId);
glUniform1i(depthMapUniform, 7);
glUseProgram(shaderProgram);
look();  //updates my viewing matrix
box.render();   //renders box VBO

所以...我认为这是对的?也许?不知道为什么纹理 7,这只是我正在检查的教程中的内容......

这是我的顶点着色器中的重要内容:

out vec4 ShadowCoord;

void main() {
    gl_Position = PMatrix * (VMatrix * MMatrix) * gl_Vertex;  //projection, view and model matrices
    ShadowCoord = gl_MultiTexCoord0;    //something I kept seeing in examples, was hoping it would work.
}

Aaand,片段着色器:

in vec4 ShadowCoord;
in vec3 Color;  //passed from vertex shader, didn't include the code for it though. Just the vertex color.

out vec4 FragColor;

void main(
    FragColor = vec4(texture2D(ShadowMap,shadowCoord.st).x * vec3(Color), 1.0);

现在的问题是,片段着色器接收到的纹理坐标始终是 (0,0),即左下角。我尝试将其更改为 ShadowCoord = gl_MultiTexCoord7,因为我认为这可能与我将纹理放在插槽号 7 中有关...但是,唉,问题仍然存在。当 (0, 0) 的颜色发生变化时,整个场景的颜色也会发生变化,而不是仅针对适当的像素/片段发生颜色变化。

这就是我希望获得的一些见解......如何传递正确的坐标(我希望纹理的角落与我的屏幕角落的坐标相同)。是的,这是一个初学者的问题......但我一直在看橙皮书,问题在于它在 GLSL 方面很棒,但是在示例中严重缺乏 OpenGL 方面我真的可以用...

4

1 回答 1

6

输入变量gl_MultiTexCoord0(或 7)是第 0 个(或第 7 个)纹理坐标的内置逐顶点纹理坐标,由gl(Multi)TexCoord(使用立即模式时)或glTexCoordPointer(使用数组/VBO 时)设置。

但是由于您的深度缓冲区已经在屏幕空间中,您想要的不是放置在对象上的通常纹理,而只是纹理中特定像素/片段的值。所以顶点着色器不以任何方式参与。相反,您只需使用当前片段的屏幕空间位置作为纹理坐标,可以在片段着色器中使用gl_FragCoord. 但请记住,此坐标位于 [0,w]x[0,h] 中,并且通过 [0,1] 中的归一化纹理坐标访问纹理。所以你必须将片段的坐标除以屏幕大小:

uniform vec2 screenSize;
...
... texture2D(ShadowMap, gl_FragCoord.st/screenSize) ...

但是你实际上并不需要两个通道来实现这个效果,因为你可以直接使用片段的深度,而不用将它写入纹理。代替

texture2D(ShadowMap, gl_FragCoord.st/screenSize).x

你可以使用

gl_FragCoord.z

这就是片段的深度值,它会在第一遍中写入纹理。这样,您就可以完全省去第一个深度写入通道和第二个通道中的纹理访问。

于 2011-10-16T02:33:25.257 回答