我想要完成的任务:在我的场景顶部绘制场景的深度贴图(以便更近的物体更暗,更远的物体更亮)
问题:我似乎不明白如何将正确的纹理坐标从我的顶点着色器传递到我的片段着色器。
所以我创建了我的FBO,以及深度贴图所绘制的纹理......并不是说我完全确定我在做什么,但无论如何,它都有效。我测试了使用固定功能管道绘制纹理,它看起来就像它应该的那样(深度贴图)。
但是试图在我的着色器中使用它只是不起作用......
这是我的render方法中绑定纹理的部分:
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方面的事情在这些例子中严重缺乏我真的可以用......
答案 0 :(得分:4)
输入变量gl_MultiTexCoord0
(或7)是第0(或第7)个纹理坐标的内置每顶点纹理坐标,由gl(Multi)TexCoord
设置(使用立即模式时)或{{ 1}}(当使用数组/ VBO时)。
但是当您的深度缓冲区已经在屏幕空间中时,您想要的不是放置在对象上的常用纹理,而只是特定像素/片段的纹理中的值。所以顶点着色器不以任何方式参与。相反,您只需使用当前片段的屏幕空间位置作为纹理坐标,可以使用glTexCoordPointer
在片段着色器中读取。但请记住,此坐标位于[0,w] x [0,h]中,纹理可通过[0,1]中的标准化纹理坐标访问。因此,您必须将片段的坐标除以屏幕大小:
gl_FragCoord
但是你实际上不需要两次传递此效果,因为你可以直接使用片段的深度,而无需将其写入纹理。而不是
uniform vec2 screenSize;
...
... texture2D(ShadowMap, gl_FragCoord.st/screenSize) ...
你可以使用
texture2D(ShadowMap, gl_FragCoord.st/screenSize).x
这是片段的深度值,它可以在第一遍中写入纹理。通过这种方式,您可以在第二遍中完全省去第一个深度写入过程和纹理访问。