【问题标题】:OpenGL ES Texture Coordinates Slightly OffOpenGL ES 纹理坐标略微关闭
【发布时间】:2011-05-16 21:02:26
【问题描述】:

我试图通过指定我想要的坐标在 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);

【问题讨论】:

标签: c++ opengl-es textures


【解决方案1】:

请记住,OpenGL 在纹素中心对纹理进行采样。因此,当使用线性过滤(如GL_LINEARGL_LINEAR_MIPMAP_LINEAR)时,只有在纹素中心采样时才会返回准确的纹素颜色。因此,当您只想使用纹理的子区域时,您需要将纹理坐标缩进半个纹素(或0.5/width0.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] 其中 x0.5/widthy being 0.5/height ( [0,1]x[0,1]对应的整个纹理的宽高。

所以试试

data[0].t[0] = 0.0f * uFactor + 0.5/textureWidth;
data[0].t[1] = 0.0f * vFactor + 0.5/textureHeight;
data[1].t[0] = 1.0f * uFactor - 0.5/textureWidth;
data[1].t[1] = 0.0f * vFactor + 0.5/textureHeight;
data[2].t[0] = 0.0f * uFactor + 0.5/textureWidth;
data[2].t[1] = 1.0f * vFactor - 0.5/textureHeight;
data[3].t[0] = 1.0f * uFactor - 0.5/textureWidth;
data[3].t[1] = 1.0f * vFactor - 0.5/textureHeight;

【讨论】:

  • 这非常接近,如果我将 0.5f 添加到所有坐标,它会修复一些但会弄乱其他坐标。如果我像你提到的那样加/减,我不会得到任何边缘伪影,但图像中仍有一些像素数据出血
  • 这些是使用上述两种颜色形状的测试渲染。不使用偏移量:bit.ly/ioKuV7。将一半添加到所有坐标:bit.ly/mklitW。在您的示例中添加/减去一半:bit.ly/m8O5dd
  • 您也可以尝试将顶点坐标与像素中心对齐,这意味着将它们调整半个像素(当然是在视图坐标中)。否则它们有点偏离纹理坐标,这意味着你得到了一个带有 cxd 纹理的 axb rect。如果你想要像素精确的纹理,你需要 a==c 和 b==d。因此,也从 texCoords 对位置进行相同的调整。然后大小匹配。
  • Christian,我将更多地使用这些值,但我认为您是对的,最终的解决方案将需要更多的调整。无论如何,我们已经足够接近了,艺术团队很满意,所以我会接受你的回答。再次感谢!
【解决方案2】:

这可能与环绕有关。在创建源图像时试试这个:

glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP )
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP )

【讨论】:

  • 这样做可以改善结果,但整体图像仍然关闭。似乎这可以夹紧顶部和左侧,但由于它不会改变 (1,1) 顶点,它所抓取的纹理仍然涉及一些像素颜色的合并。
猜你喜欢
  • 2012-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-26
  • 1970-01-01
  • 2011-05-19
  • 1970-01-01
  • 2015-04-23
相关资源
最近更新 更多