OpenGL ES 纹理坐标略有偏差
我试图通过指定我想要的坐标来在 OpenGL 中绘制纹理的子区域。但发生的情况是,根据图像的大小,选择纹理坐标的原点似乎有轻微的偏移。偏移量似乎小于像素的大小&输出是相邻像素的模糊组合。
这是我所描述的一个想法。在本例中,我想要选择 6x5 绿色/白色区域,但 OpenGL 渲染的内容包括顶部和底部的轻微粉红色调。左像素。
输出的样子:
我可以通过在将纹理坐标传递给 glTexCoordPointer 之前添加偏移量来修复它,但问题是我无法计算偏移量是多少,而且不同纹理的偏移量似乎不同。
伪代码:
float uFactor = regionWidth / textureWidth; // For the example: 0.6f
float vFactor = regionHeight / textureHeight; // For the example: 0.5f
data[0].t[0] = 0.0f * uFactor;
data[0].t[1] = 0.0f * vFactor;
data[1].t[0] = 1.0f * uFactor;
data[1].t[1] = 0.0f * vFactor;
data[2].t[0] = 0.0f * uFactor;
data[2].t[1] = 1.0f * vFactor;
data[3].t[0] = 1.0f * uFactor;
data[3].t[1] = 1.0f * vFactor;
glPushMatrix();
// translate/scale/bind operations
glTexCoordPointer(2, GL_FLOAT, 0, data[0].t);
I'm trying to draw a subregion of a texture in OpenGL by specifying the coordinates I want. What's happening though is that, depending on the size of the image, it seems there's a slight offset in the origin of where it selects the texture coordinates. The offset amount seems to be less than the size of a pixel & the output is is blurred combination of neighboring pixels.
Here's an idea of what I'm describing. In this case I'd want to select the 6x5 green/white region but what OpenGL is rendering includes a slight pink tint to the top & left pixels.
What the output would look like:
I can fix it by adding an offset to the texture coordinates before passing them to glTexCoordPointer but the problem is that I have no way to calculate what the offset is and it seems different for different textures.
Pseudocode:
float uFactor = regionWidth / textureWidth; // For the example: 0.6f
float vFactor = regionHeight / textureHeight; // For the example: 0.5f
data[0].t[0] = 0.0f * uFactor;
data[0].t[1] = 0.0f * vFactor;
data[1].t[0] = 1.0f * uFactor;
data[1].t[1] = 0.0f * vFactor;
data[2].t[0] = 0.0f * uFactor;
data[2].t[1] = 1.0f * vFactor;
data[3].t[0] = 1.0f * uFactor;
data[3].t[1] = 1.0f * vFactor;
glPushMatrix();
// translate/scale/bind operations
glTexCoordPointer(2, GL_FLOAT, 0, data[0].t);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
请记住,OpenGL 在纹理像素中心采样纹理。因此,当使用线性过滤(例如
GL_LINEAR
或GL_LINEAR_MIPMAP_LINEAR
)时,只有在纹素中心采样时才会返回精确的纹素颜色。因此,当您只想使用纹理的子区域时,您需要将纹理坐标缩进半个纹素(或0.5/width
和0.5/height
)。否则,过滤会将纹理的边界与预期区域之外的相邻纹理像素混合。这会导致你的边框略带粉红色。如果您用完整个纹理,此效果可以通过 GL_CLAMP_TO_EDGE 环绕模式进行补偿,但是当使用子区域时,GL 不知道其边缘在哪里,并且过滤不应穿过它。因此,当您获得
[s1,s2]x[t1,t2]
(0 <= s,t <= 1
) 范围内的纹理子区域时,真正有效的 texCoord 间隔应为[s1+x,s2-x]x[t1+y,t2-y]
,其中x
为0.5/width
且y
为 0.5/height
([0,1]x[0,1]
对应的整个纹理的宽度和高度) 。因此尝试
Keep in mind, that OpenGL samples textures at the texel centers. So when using linear filtering (like
GL_LINEAR
orGL_LINEAR_MIPMAP_LINEAR
) the exact texel color is only returned if sampled at the texel center. Thus, when you only want to use a sub-region of a texture, you need to indent your texture coordinates by half a texel (or0.5/width
and0.5/height
). Otherwise the filtering will blend the border of the texture with neigbouting texels outside of your intended region. This causes your slightly pinkish border. If you use up the whole texture this effect is compensated by theGL_CLAMP_TO_EDGE
wrapping mode, but when using a subregion, GL does not know where it's edge is and that filtering should not cross it.So when you got a subregion of the texture in the range
[s1,s2]x[t1,t2]
(0 <= s,t <= 1
), the real valid texCoord interval should be[s1+x,s2-x]x[t1+y,t2-y]
withx
being0.5/width
andy
being 0.5/height
(the width and height of the whole texture corresponding to[0,1]x[0,1]
).Therefore try
这可能与环绕有关。创建源图像时尝试此操作:
Propably this has to do with the wrap around. Try this when you create the source image: