GLSL 从顶点着色器传递纹理坐标

发布于 2024-12-09 22:27:03 字数 1433 浏览 0 评论 0原文

我想要完成的任务:在场景顶部绘制场景的深度图(以便距离较近的物体更暗,距离更远的物体更亮)

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

所以我创建了我的 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 方面:我真的可以用...

What I'm trying to accomplish: Drawing the depth map of my scene on top of my scene (so that objects closer are darker, and further away are lighter)

Problem: I don't seem to understand how to pass the right texture coordinates from my vertex shader to my fragment shader.

So I created my FBO, and the texture that the depth map gets drawn to... not that I'm entirely sure what I was doing, but whatever, it works. I tested drawing the texture using the fixed functionality pipeline, and it looks just like it's supposed to (the depth map that is).

But trying to use it in my shaders just isn't working...

Here's the part from my render method that binds the texture:

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

So... I think that's sort of right? Maybe? No clue why texture 7, that was just something that was in a tutorial I was checking...

And here's the important stuff from my vertex shader:

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, fragment shader:

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

Now the problem is that the coordinate that the fragment shader receives for the texture is always (0,0), or the bottom-left corner. I tried changing it to ShadowCoord = gl_MultiTexCoord7, because I figured maybe it had something to do with me putting the texture in slot number 7... but alas, the problem persisted. When the color of (0, 0) changes, so does the color of the entire scene, rather than being a change in color for only the appropriate pixel/fragment.

And that's what I'm hoping to get some insight on... how to pass the correct coordinates (I'd like for the corners of the texture to be the same coordinates as the corners of my screen). And yes, this is a beginners question... but I have been looking in the Orange Book, and the problem with it is that it's great on the GLSL side of things, but the OpenGL side of things is severely lacking in the examples that I could really use...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冰之心 2024-12-16 22:27:03

输入变量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

它会在第一遍中写入纹理。这样,您就可以完全节省第一次深度写入过程和第二次过程中的纹理访问。

The input variable gl_MultiTexCoord0 (or 7) is the builtin per-vertex texture coordinate for the 0th (or 7th) texture coordinate, set by gl(Multi)TexCoord (when using immediate mode) or by glTexCoordPointer (when using arrays/VBOs).

But as your depth buffer is already in screen space, what you want is not a usual texture laid onto the object, but just the value in the texture for a specific pixel/fragment. So the vertex shader isn't involved in any way. Instead you just use the current fragment's screen space position as texture coordinate, that can be read in the fragment shader using gl_FragCoord. But keep in mind that this coordinate is in [0,w]x[0,h] and textures are accessed by normalized texture coordinates in [0,1]. So you have to divide the fragment's coordinate by the screen size:

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

But you actually don't need two passes for this effect anyway, as you can just use the fragment's depth directly, without writing it into a texture. Instead of

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

you can just use

gl_FragCoord.z

which is nothing else than the fragment's depth value, that would have been written into the texture in the first pass. This way you completely spare the first depth-writing pass and the texture access in the second pass.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文