如何在 OpenGL 中标准化纹理 space 的图像坐标?
How to normalize image coordinates for texture space in OpenGL?
假设我有一张尺寸为 320x240 的图片。现在,从具有整数图像坐标 ux, uy
的 sampler2D
中采样,我必须对 [0, size] 范围内的纹理坐标进行归一化(大小可以是宽度或高度) .
现在,我想知道我是否应该像这样正常化
texture(image, vec2(ux/320.0, uy/240.0))
或者像这样
texture(image, vec2(ux/319.0, uy/239.0))
因为 ux = 0 ... 319 和 uy = 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
假设我有一张尺寸为 320x240 的图片。现在,从具有整数图像坐标 ux, uy
的 sampler2D
中采样,我必须对 [0, size] 范围内的纹理坐标进行归一化(大小可以是宽度或高度) .
现在,我想知道我是否应该像这样正常化
texture(image, vec2(ux/320.0, uy/240.0))
或者像这样
texture(image, vec2(ux/319.0, uy/239.0))
因为 ux = 0 ... 319 和 uy = 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