【问题标题】:GLSL texture coordinate to absolute pixel? [duplicate]GLSL纹理坐标到绝对像素? [复制]
【发布时间】:2012-04-06 22:47:26
【问题描述】:

我的问题是关于纹理坐标如何精确映射到纹理中的纹素(不考虑过滤)。

例如,(0,0) 是指左上角像素的左上角还是指左上角像素的中心?

如果使用近似过滤,在纹理坐标 (0.5,0.5) 处获取什么像素?

(1.0,1.0) 是指右下角像素的右下角还是右下角像素的左上角? (我记得几年前这在一些 ATI 和 NVIDIA 卡之间有所不同。现在标准化了吗?)

如果使用 texelFetch() 而不是 textureLod(),那么访问像素的正确方法是什么?

是吗

ivec2 size = textureSize(sampler,0);
ivec2 iCoords = ivec2(int(uv.x*size.x),int(uv.y*size.y));
vec4 col = texelFetch(sampler,iCoords);

或许是

ivec2 iCoords = ivec2(int(uv.x*size.x+0.5f),int(uv.y*size.y+0.5f));

正确吗?

甚至

ivec2 iCoords = ivec2(int(uv.x*(size.x+1)),int(uv.y*(size.y+1)));

?

也许有人可以澄清映射究竟是如何工作的?

【问题讨论】:

标签: opengl glsl texture-mapping uv-mapping


【解决方案1】:

如果您的问题只是出于好奇:AFAIK 该问题没有标准答案,因为您的纹理坐标不必以 1.0 结尾。此外,显卡将以不同的方式处理这些值(例如,今天的一些显卡支持 64 位 FP-Ops)。我认为您应该始终尝试以安全的方式编写代码,如果适用,可能使用 0.999 而不是 1.0。

否则,如果您正在寻找一种从渲染纹理中读回像素的方法,您可以按照the website of dominik göddeke on gpgpu 中的说明定义您的视口。如果将视口设置为纹理的大小,则可以简单地在原始坐标处抓取像素。我真的很推荐这个网站,它对我帮助很大。

更新:使用 GL_REPEAT 时,纹理坐标在纹理中的第一个和最后一个像素之间进行插值。所以 4 texel 纹理中第一个像素的中心在 0.125,因为每个像素的宽度为 0.25 或 1/4。

这更直观地解释了它:

如您所见,[0,0] 处的纹素是 [0.125,0] 和 [0.875,0] 的线性混合,在本例中等于 [1,1]。

DelphiGL Wiki (english translation) 上的所有内容都得到了很好的解释

对于起初的困惑,我深表歉意。

【讨论】:

  • 那么,如果它引用像素的中心,那么例如(-0.0001,-0.0001)仍然会引用topLeftPixel? (假设texturewrapping被激活并且纹理很小)
  • mmmh - 但如果这是真的,你会在角落顶点上创建一个具有 uv 坐标 (0,0) 到 (1,1) 的四边形并对其进行纹理处理,那么你只会看到一半纹理的边界纹素......
  • 这取决于GL_TEXTURE_WRAP_S/T 参数。如果您启用了 GL_REPEATGL_LINEAR,那么 (-0.0001,-0.0001) 将被 (texsize_x, texsize_y) 最小插值。如果您启用了GL_NEAREST,它仍将返回 (0,0) 处的纹理颜色
  • 好的 - 所以 - 如果我创建一个 3x3 纹理并用它创建一个四边形纹理并将插值设置为 GL_Linear,那么我将始终在中间看到一个完整的纹素并将其包围在被切成两半的纹素?
  • 你说得对,我会在几秒钟内更正我的答案。
猜你喜欢
  • 1970-01-01
  • 2013-04-03
  • 1970-01-01
  • 1970-01-01
  • 2012-03-05
  • 1970-01-01
  • 1970-01-01
  • 2015-09-30
  • 1970-01-01
相关资源
最近更新 更多