OpenGL中是否存在一种通用方法,允许在以原始尺寸(包括边缘像素)绘制时从地图集中进行像素完美的2D绘制,并在过滤到非原生尺寸时实现高质量缩放?
假设您正在编写某种用于从纹理图集中绘制精灵的系统,以便用户可以指定精灵,以及绘制精灵的大小和位置。此外,他们可能只想绘制精灵的子矩形。
例如,这是一个64x64的棋盘格式:
......单独在其纹理图集中:
注意:我们假设视口设置为将1:1映射到设备像素。
为了清晰起见而编辑:请注意,下面的前两个方法没有给出所需的结果,并且专门用于概述哪些方法不起作用。
1。要以原始大小绘制精灵,只需使用GL_NEAREST
这适用于以原生大小绘制,但是当用户以64x64以外的大小绘制对象时,NEAREST过滤效果不佳。它还会强制纹理像素与像素网格对齐,当在非整数像素位置绘制对象时效果不佳:
2。启用GL_LINEAR
(0.5/atlas_size,0.5/atlas_size)
到(63.5/atlas_size,63.5/atlas_size)
。否则,对于最外面的像素,线性过滤将对图集中精灵的邻居进行采样。
请注意,除了与背景混合的边缘像素外,我们得到像素精确的绘图,因为顶点边界位于像素之间的中间位置。
编辑:还要注意,此行为还取决于是否启用了抗锯齿功能。如果不是,前一种方法实际上确实提供像素完美渲染,但是当精灵从像素对齐移动到子像素位置时不提供良好的转换。在许多情况下,必须使用抗锯齿功能。
第3。在纹理图集中填充精灵
边缘像素问题的两个明显的解决方案涉及在纹理图集中用1px边框填充精灵的边缘。你可以:
这基本上为我们提供了线性缩放的像素精确绘图。但是,如果我们允许用户只绘制精灵的子矩形,则这些方法中的任何一个都会失败,因为子矩形显然没有所需的填充。
我错过了什么吗?这个问题有一般解决方案吗?
答案 0 :(得分:2)
很难确切知道"正确的事情"你正在寻找的是。如果你有一个64x64精灵,并且想要将其缩放到65x65或63x63,那么任何过滤都不会使它看起来很好。当您将抗锯齿投入混合时,请记住多重采样不是超级采样,因此您的纹理不会神奇地变得更柔和的内部。
那就是说,真正非最近的过滤应该在多重采样的情况下开箱即用。我认为你的GL_LINEAR方法是正确的,但我认为你可能有实施问题。
特别是,线性过滤应该在沿着纹素边界时进行过滤。例如,如果您有两个相邻的三角形,就会发生这种情况。事实上,你应该期望沿着精灵边缘进行线性过滤,这种过滤就是正确的事情。
您不应该通过调整纹理坐标(以及顶点)来尝试纠正此问题,因为这会错误地缩放纹理上的纹理坐标。我建议将纹理坐标钳制到着色器中所需的范围加/减0.5 / texture_res。
您会发现这解决了原始缩放时像素完美结果以及高质量放大的问题。缩小看起来没问题,但我建议使用三线(mipmap)过滤以获得最佳效果。