基于图片的抗锯齿方法(一)

目前为止,MSAA仍是抗锯齿效果的黄金标准。然而MSAA需要硬件支持,并且要在RT中存放子像素信息,这大大增加了内存和带宽开销。在使用HDR管线或者G Buffer时此问题显得更加严重。

由于这些限制,基于后处理的抗锯齿方案逐渐成为主流。这类方案并不需要改变渲染管线,而是在图片中寻找被人眼识别为锯齿的像素,再对应模糊处理。morphological antialiasing(MLAA)即是其中之一。

MLAA的思路很简单,考虑锯齿图中的一个微元,它常常是下图中B的样子。而如果分辨率无限加大,可以用一条蓝线来标定实际的几何边界,如图A。如果我们能知道蓝线的实际形状,就可以根据直线斜率计算蓝线下面积与整个像素块面积之比a,然后用如下公式轻松实现抗锯齿效果(如图C):

Cnew = a*Cold + (1-a)Copp    (其中Cold是处理前的颜色,Copp 是锯齿边(edgel)另一侧的对应像素。)

蓝线的斜率等于竖直跨度/水平跨度,对于水平锯齿边,竖直跨度永远为2个像素,要解决的问题只有3个:

1)待处理像素在锯齿边上的位置

2)锯齿边的水平跨度(或竖直跨度)

3)锯齿边界的形状,如下图。

这三个问题可以一起解决:

从待处理像素开始,沿锯齿边分别朝两侧搜索,寻找截边(crossing edge)

锯齿边的跨度以及像素所处的位置可以由左右搜索距离dleft和dright确定。

锯齿边界的形状则由两侧截边的情况而定。

左图黄圈内即是截边需要考虑的像素。中图列举了所有可能的9种情况,其中情况6并不需要做抗锯齿处理。

右图为AreaTex范例,每一块记录了一种情况下对应像素抗锯齿所需的混合权重。

然而,搜索过程和锯齿边界的判断需要大量采样,拿到采样结果后进行重新矢量化时还有大量的分支判断问题(如上图右侧的9种情况)。Jimenez通过巧妙利用硬件免费的bilinear filter来大量减少采样数;再引入一张预计算的AreaTex,使用像素位置、锯齿边跨度和边界情况作为索引,直接取出最终抗锯齿所需的混合权重。

至此MLAA的问题都得到解决,性能也足以流畅的运行。

让我们再重新梳理一下MLAA的算法框架。它基本分为如下三步进行:

1. 寻找位于锯齿边缘的像素,并标记出来。

2. 重新矢量化。

3. 混合对应像素。

一、边缘检测

边缘检测可以基于Depth,亮度,颜色或者其中几种混合判断。

算法需要检测水平和竖直两条边。 每个像素有4个相邻像素,理论上应该做4次边缘检测。但由于像素之间公用边,所以只要针对左侧和上侧的相邻像素进行检测。

这部的处理结果是用像素标记出的锯齿边

二、重新矢量化

这一步的处理单元并不是像素,而是锯齿边。设定一个最长搜索距离,从当前位置起分别针对水平和竖直方向的锯齿边进行重新矢量化。重新矢量化的过程大量利用双线性采样,并最后采样AreaTex得出混合权重。

三、混合对应像素

这步根据混合权重来执行最终的抗锯齿过程,同样也可以使用手动设定采样位置配合免费的双线性采样来优化效率。

由于这一步的处理单元是像素,而不是锯齿边,所以并不方便将它与第二步合并。

图2中,红色表示像素左侧存在锯齿边,绿色表示像素上侧存在锯齿边,黄色表示二者都有。

图3中,RG表示水平锯齿边上下两侧像素的混合权重;BA通道存储了竖直锯齿边左右两侧像素的混合权重。

参考资料:

GPU Pro 2         Practical Morphological Antialiasing

Siggraph2011  Filtering Approaches for Real-Time Anti-Aliasing

时间: 2024-12-25 01:25:19

基于图片的抗锯齿方法(一)的相关文章

android 图片缩放抗锯齿

之前用的时候只设置了antialias属性,其实要设置两个flag才行 1 paint.setFlags(Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG); 2 //或者 3 canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG)); android 图片缩放抗锯齿

android 抗锯齿方法[转]

在Android中,目前,我知道有两种出现锯齿的情况. ① 当我们用Canvas绘制位图的时候,如果对位图进行了选择,则位图会出现锯齿. ② 在用View的RotateAnimation做动画时候,如果View当中包含有大量的图形,也会出现锯齿.我们分别以这两种情况加以考虑. ◆ 用Canvas绘制位的的情况.在用Canvas绘制位图时,一般地,我们使用drawBitmap函数家族,在这些函数中,都有一个Paint参数,要 做到防止锯齿,我们就要使用到这个参数.如下:首先在你的构造函数中,需要创

cocos2dx 抗锯齿

这个不是经常用到,但偶尔又需要,记录一下. 缩小抗锯齿:(要求是pot图片,即2的n次方的宽高的图片) CCTexture2D* pTexture = sprite:getTexture(); pTexture->generateMipmap(); ccTexParams texParams = {GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE}; pTexture->setTexParameters

【ShaderToy】基础篇之再谈抗锯齿(antialiasing,AA)

写在前面 在之前的基础篇中,我们讲到了在绘制点线时如何处理边缘的锯齿,也就是使用smoothstep函数.而模糊参数是一些定值,或者是跟屏幕分辨率相关的数值,例如分辨率宽度的5%等等.但这种方法其实是有一种问题的.这需要我们从绘制的图像说起. ShaderToy中绘制的很多图像可以说是一种Procedure Texture,过程纹理,即是计算机生成的纹理.拿之前画的圆和线来说,这些圆和线的绘制过程,是我们计算每个fragment到"期望图像"的距离,然后根据距离来判断使用哪种颜色.如果

UE4在PSVR中的抗锯齿和优化相关知识

UE4目前版本(4.15)在PS平台上并不支持MSAA,在未来的版本会加入.也就是说目前没有办法在PS平台上使用Forward Rendering + MSAA的组合 FXAA效率最高,但效果最差,只做了最后的图像边缘锐化 MSAA的优点是物体边缘和贴图分开处理,边缘会比较清晰.缺点是开销会比TAA稍大(即使有硬件支持),另外会有Specular aliasing.在使用MSAA时,可以在材质中打开normal to roughness,这样会使normal上突出的部分更加粗糙,减少高光闪烁.

Unity3d 超级采样抗锯齿 Super Sampling Anti-Aliasing

Super Sampling Anti-Aliasing SSAA算是在众多抗锯齿算法中比较昂贵的一种了,年代也比较久远,但是方法比较简单, 主要概括为两步 1.    查找边缘 2.    模糊边缘 这是一种post processing的处理方法, 接下来我们就看看怎么实现 查找边缘 查找边缘的原因也是因为减少消耗,这样就可以只在边缘处进行超级采样,不必为全图进行采样了. 之前的文章详细说过三种查找边缘的方法Roberts,Sobel,Canny ,其中sobel最优,所以我们就是用sobe

图片变形的抗锯齿处理方法

本文转载至http://adad184.com/2015/08/31/image-rotate-with-antialiasing/ 周末在微博上看到@周楷雯Kevin说起CALayer抗锯齿的问题 具体做法是: 1 layer.allowsEdgeAntialiasing = true 想起了很久以前也遇到过类似的问题 那时候要做一个类贴纸的应用 理所当然会遇到贴纸缩放和旋转的问题 所以锯齿的问题也是需要解决的 但是那时候是iOS4,5的时代 压根没有上面说的allowsEdgeAntiali

SSE图像算法优化系列二十四: 基于形态学的图像后期抗锯齿算法--MLAA优化研究。

偶尔看到这样的一个算法,觉得还是蛮有意思的,花了将近10天多的时间研究了下相关代码. 以下为百度的结果:MLAA全称Morphological Antialiasing,意为形态抗锯齿是AMD推出的完全基于CPU处理的抗锯齿解决方案.对于游戏厂商使用的MSAA抗锯齿技术不同,Intel最新推出的MLAA将跨越边缘像素的前景和背景色进行混合,用第2种颜色来填充该像素,从而更有效地改进图像边缘的变现效果,这就是MLAA技术. 其实就是这个是由Intel的工程师先于2009年提出的技术,但是由AMD将

(转)Android中实现区域平均算法在图片缩放里的应用(缩放图片抗锯齿)

摘要:Android图片缩放效果较差,尤其是将大尺寸的图片缩放成小尺寸的图片时,即便是加了抗锯齿,锯齿现象也比较严重:而java sdk里的区域平均算法缩放图片,效果就比较完美了,因为jdk不能直接用于安卓项目中(类冲突),也没找到可以使用的替代的library,最终只好自己写,在此分享! 正文: 目前我知道的Android API中的传统的图片抗锯齿优化处理无非就是以下相关的设置: //缩放抗锯齿Bitmap.createScaledBitmap(bitmap, width, height,