【问题标题】:Manually calculate gl_FragCoord手动计算 gl_FragCoord
【发布时间】:2014-07-17 00:21:49
【问题描述】:

我正在尝试使用 OpenGL 和 GLSL 着色器实现点的最近邻搜索。 NN 计算工作正常,并将结果绘制到大小为 1024x1024 的纹理中(使用当前屏幕大小的视口)。 结果只包含一个 vec4 保存邻居的位置。

现在重要的部分是: 持有 vec4 的纹素正好位于点投影到的位置(我正在寻找邻居的点)。所以理论上,为了访问任意点的邻居,我将其世界位置投影到屏幕坐标并使用这些坐标来访问纹理(例如,使用texelFetch)。

如果我在顶点着色器中进行点投影并使用 gl_FragCoord 访问片段程序中的纹理,则此方法有效。但是现在我遇到了一种新情况,即这些点仅在片段着色器中可用(通过纹理/缓冲区访问),因此我必须手动计算屏幕位置。

我尝试了以下方法自行计算 gl_FragCoord,但它不起作用(仅限空白结果):

vec4 pointPos = ... //texture lookup
vec4 transformedPos = matProjectionOrtho * pointPos;
transformedPos.xy /= transformedPos.w;
transformedPos.xy = transformedPos.xy * 0.5f + 0.5f;
transformedPos.xy = vec2(transformedPos.x * textureWidth, 
                         transformedPos.y * textureHeight);

投影矩阵matProjectionOrtho 对于所有渲染通道都是相同的,只是一个正交投影。 textureWidthtextureHeight 是保存相邻数据的纹理大小(通常为 1024x1024)。

屏幕/纹理位置的计算是否正确?

【问题讨论】:

  • 您的问题的表述方式有点问题,但是...如果您要投影一个世界位置,那么除了您的之外,您还应该乘以一个视图矩阵投影矩阵。
  • @AndonM.Coleman 投影应该是独立于视图的,这就是为什么不使用视图矩阵的原因。 PS:我的母语不是英语,很抱歉措辞不好。还在练习:-)
  • 投影不可能独立于视图。您需要一个方向来决定将什么投影到您的图像平面上。世界空间坐标没有说方向。如果您说您的坐标在视图空间中,那对我来说会更有意义。
  • 有一个很好的视觉表示我的意思here。教科书 GL 将 view-space eye-space 称为 view-space eye-space,但它们是同一事物的两个词……有时您可能还会看到它称为 camera-space。

标签: c++ opengl graphics glsl


【解决方案1】:

屏幕/纹理位置的计算是否正确?

你的视口是什么?假设视口具有与您的纹理相同的大小(您已经说过)并且非常不包含偏移量(例如,它的原点是 0, 0)。

这里唯一真正不确定的是,要使用texelFetch (...),您需要整数坐标,transformedPos 是一个浮点向量。 GLSL 没有定义从vecNivecN 的隐式转换,因此您不能直接使用刚刚计算的坐标——您必须自己构造一个ivec

大意:

ivec2 texel_coords = ivec2 (transformedPos.x, transformedPos.y);

幸运的是,因为纹素的中心是 i+0.5 而不是 i+0.0,当您将坐标从浮点数转换为整数时,事实证明它们被截断了在这种情况下无关紧要。也就是说像素坐标511.9明显比511更接近512。如果纹素以整数边界为中心,那么当您尝试找到最近的邻居时,当转换为整数时 511.9 变为 511 的事实会真的搞砸了。 p>

【讨论】:

  • 感谢您的回答!视口位于 (0, 0),但与纹理的大小不同。我必须使用两个不同的视口。 1.) 编写纹理视口大小 == 屏幕大小时。 2.) 在阅读阶段,视口大小要小得多(另一个纹理的大小)。由于纹理大小是固定的(1024x1024),我是否也必须相应地缩放坐标?对于整数问题:我使用texelFetch(...)gl_FragCoord。也可以改用texture2D(...)
  • 如果两者的视口不匹配,它将不匹配 gl_FragCoord。但我想我可能误解了你在问什么。我会睡一觉,早上再看问题。
  • 在绘制纹理时使用屏幕大小的视口让我感到困惑。你想填充整个纹理,对吧?视口应该基于你正在绘制的东西的大小,而不是窗口。想象一下,如果窗口的尺寸为 32x32,而您正在绘制 1024x1024 的纹理...
  • 很抱歉给您带来了困惑。你是绝对正确的:我需要将视口调整为我想要绘制的纹理的大小。无论如何,上面的屏幕坐标计算现在对我有用(没有改变任何东西)。错误位于其他地方,我的错误。再次感谢!
猜你喜欢
  • 1970-01-01
  • 2017-07-17
  • 2018-12-21
  • 2015-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-01
  • 2016-12-26
相关资源
最近更新 更多