如何在 OpenGL 中标准化纹理 space 的图像坐标?

How to normalize image coordinates for texture space in OpenGL?

假设我有一张尺寸为 320x240 的图片。现在,从具有整数图像坐标 ux, uysampler2D 中采样,我必须对 [0, size] 范围内的纹理坐标进行归一化(大小可以是宽度或高度) .

现在,我想知道我是否应该像这样正常化

texture(image, vec2(ux/320.0, uy/240.0))

或者像这样

texture(image, vec2(ux/319.0, uy/239.0))

因为 ux = 0 ... 319uy = 0 ... 239。后一个实际上会覆盖 [0, 1] 的整个范围,对吗?这意味着 0 对应于例如最左边的像素和 1 对应最右边的像素,对吧?

另外我想保持过滤,所以我不想使用texelFetch

谁能说说这件事?谢谢。

不对,第一个其实是正确的:

texture(image, vec2(ux/320.0, uy/240.0))

你的前提 "ux = 0 ... 319 and uy = 0 ... 239" 是不正确的。如果你渲染一个 320x240 的四边形,那么它实际上是 ux = 0 ... 320 和 uy = 0 ... 240.

这是因为像素 纹素是 正方形 在半整数坐标处采样的。因此,例如,假设您在 320x240 四边形上渲染 320x240 纹理。然后左下角的像素 (0,0) 实际上将在屏幕坐标 (.5,.5) 处被采样。您通过除以 (320,240) 对其进行标准化,但随后 OpenGL 会将标准化坐标乘以 (320,240) 以获得实际纹素坐标,因此它将从对应于中心的纹理中采样 (.5,.5)的 (0,0) 像素,returns 它的确切颜色。

将 OpenGL 中的像素视为 正方形 很重要,因此坐标 (0,0) 对应于 左下角 和非归一化的 (w,h) 对应于 右上角 的右上像素(对于大小为 (w,h) 的纹理) .

纹理坐标(和像素坐标)在像素的边缘从 0 变为 1,无论有多少像素。

4 像素宽的纹理

   0          0.5          1    <- texture coordinate
   |           |           |
   V           V           v 
   +-----+-----+-----+-----+
   |     |     |     |     |
   |     |     |     |     |   <- texels
   +-----+-----+-----+-----+

5 像素宽的纹理

   0             0.5             1    <- texture coordinate
   |              |              |
   V              V              v 
   +-----+-----+-----+-----+-----+
   |     |     |     |     |     |
   |     |     |     |     |     |   <- texels
   +-----+-----+-----+-----+-----+

6 像素宽的纹理

   0                0.5                1    <- texture coordinate
   |                 |                 |
   V                 V                 V 
   +-----+-----+-----+-----+-----+-----+
   |     |     |     |     |     |     |
   |     |     |     |     |     |     |   <- texels
   +-----+-----+-----+-----+-----+-----+

1 像素宽的纹理

   0 0.5 1   <- texture coordinate 
   |  |  |
   V  V  V 
   +-----+
   |     |
   |     |   <- texels
   +-----+

如果您对每个纹理坐标使用 u = integerTextureCoordinate / width,您将获得这些坐标

   0    0.25  0.5   0.75       <- u = intU / width;
   |     |     |     |     
   V     V     V     V     
   +-----+-----+-----+-----+
   |     |     |     |     |
   |     |     |     |     |   <- texels
   +-----+-----+-----+-----+

那些坐标直接指向纹素之间。

但是,如果你想处理特定的纹素,你想要的纹理坐标是这样的

     0.125 0.375 0.625 0.875   
      |     |     |     |   
      V     V     V     V  
   +-----+-----+-----+-----+
   |     |     |     |     |
   |     |     |     |     |   <- texels
   +-----+-----+-----+-----+

你从哪里得到

   u = (integerTextureCoord + .5) / width