纹理采样坐标渲染雪碧

假设我们有一个纹理(在这种情况下是8×8像素)我们想用作精灵表。 其中一个子图像(sprite)是纹理内的4×3的子区域,就像在这个图像中一样:

在这里输入图像说明

(显示四angular的标准化纹理坐标)

现在,基本上有两种方法将纹理坐标分配给4像素x 3像素大小的四边形,以便它有效地成为我们正在寻找的精灵; 首先也是最直接的是在分区域的angular落采样纹理:

在这里输入图像说明

// Texture coordinates GLfloat sMin = (xIndex0 ) / imageWidth; GLfloat sMax = (xIndex0 + subregionWidth ) / imageWidth; GLfloat tMin = (yIndex0 ) / imageHeight; GLfloat tMax = (yIndex0 + subregionHeight) / imageHeight; 

虽然当第一次实施这种方法,约。 2010年,我意识到这些精灵看起来有点“扭曲”了。 经过一番search之后,我在cocos2d论坛上发现了一篇文章,解释渲染精灵时用于采样纹理的“正确方法”是:

在这里输入图像说明

 // Texture coordinates GLfloat sMin = (xIndex0 + 0.5) / imageWidth; GLfloat sMax = (xIndex0 + subregionWidth - 0.5) / imageWidth; GLfloat tMin = (yIndex0 + 0.5) / imageHeight; GLfloat tMax = (yIndex0 + subregionHeight - 0.5) / imageHeight; 

…修复我的代码后,我很高兴了一段时间。 但是在某个地方,我相信这是围绕着iOS 5的介绍,我开始觉得我的精灵看起来不太好。 经过一些testing后,我切换回“蓝色”的方法(第二图像),现在他们看起来不错,但并不总是

我会疯了吗,还是iOS 5与GL ES纹理贴图相关的东西发生了变化? 也许我在做别的事情呢? (例如,顶点位置坐标稍微偏离了?错误的纹理设置参数?)但是我的代码库没有改变,所以也许我从一开始就做错了什么?

我的意思是,至less在我的代码中, 感觉好像“红色”方法是正确的,但是现在“蓝色”方法可以得到更好的结果。

现在,我的游戏看起来不错,但是我觉得迟早会有一些错误,

任何想法/经验/意见?

附录

为了渲染上面的精灵,我会在正交投影中绘制一个4×3的四边形测量,每个顶点都被赋予前面提到的代码中隐含的纹理坐标,如下所示:

 // Top-Left Vertex { sMin, tMin }; // Bottom-Left Vertex { sMin, tMax }; // Top-Right Vertex { sMax, tMin }; // Bottom-right Vertex { sMax, tMax }; 

原始四元组由(-0.5,-0.5)至(+0.5,+0.5)创build; 即它是屏幕中心的单位正方形,然后缩放到子区域的大小(在这种情况下是4×3),其中心位于整数(x,y)坐标处。 我闻到这也有一些事情要做,特别是当宽度,高度或两者都不是?

附录2

我也发现这篇文章,但我仍然试图把它放在一起(这是凌晨4点在这里) http://www.mindcontrol.org/~hplus/graphics/opengl-pixel-perfect.html

这张照片稍微比眼睛稍微多一些,纹理坐标不是纹理取样的唯一因素。 在你的情况下,我相信蓝色可能是想要的。

你最终想要的是在每个texel中心进行采样。 您不希望在两个纹理元素之间的边界上采样,因为要么将它们与线性采样相结合,要么随机select一个或另一个最接近的 ,这取决于浮点计算的方式。

话虽如此,你可能会认为你不想在(0,0),(1,1)和其他angular落有texcoords,因为那些在纹理边界上。 但是需要注意的是,opengl会在片段的中心对纹理进行采样。

对于一个超级简单的例子,考虑一个2×2像素的显示器,一个2×2像素的纹理。

如果从(0,0)到(2,2)绘制一个四边形,则这将覆盖4个像素。 如果你用这个四边形纹理贴图,它需要从纹理中取4个样本。

如果你的纹理坐标从0到1,那么opengl将插入这个和从每个像素的中心采样,左下angular的texcoord从左下angular的左下angular开始。 这将最终生成(0.25,0.25),(0.75,0.75),(0.25,0.75)和(0.75,0.25)的texcoord对。 哪个把样品放在每个texel的中间,这正是你想要的。

如果像红色示例中那样将texcoords偏移半个像素,则会错误地进行插值,并且最终会对texels中心的纹理进行采样。

所以长话短说,你要确保你的像素与你的纹理元素正确alignment(不要在非整数像素位置绘制精灵),并且不要以任意数量缩放精灵。

如果蓝色方块给你带来不好的结果,你可以给一个例子图片,或者描述你如何绘制它?

图片说1000字:

IMG