Super Sampling Anti-Aliasing
SSAA算是在众多抗锯齿算法中比较昂贵的一种了,年代也比较久远,但是方法比较简单,
主要概括为两步
1.    查找边缘
2.    模糊边缘
这是一种post processing的处理方法,
接下来我们就看看怎么实现

查找边缘

查找边缘的原因也是因为减少消耗,这样就可以只在边缘处进行超级采样,不必为全图进行采样了。
之前的文章详细说过三种查找边缘的方法Roberts,Sobel,Canny ,其中sobel最优,所以我们就是用sobel查找边缘
这里简单讲解一下,查找边缘的不同在于过滤器的不同,但都是水平垂直采样
Sobel算子的两个过滤器分别算出横向与纵向的灰度
 
GX为水平过滤器,GY为垂直过滤器,垂直过滤器就是水平过滤器旋转90度。
过滤器为3x3的矩阵,将与图像作平面卷积。
如果不存在边则两个点颜色很接近,过滤器返回一个较小的值,否则就可判断出边缘的存在。
找出边缘之后就可以模糊边缘了

模糊边缘

模糊边缘就是要进行超级采样了,采取周围的像素点再进行混色

大家经常看到比如说SSAAx2,SSAAx4,x8….后面的数目就是采样点的个数。

之前翻译了一篇wiki上的超级采样

模糊边缘的方式(采样方式)有很多种,比较流行的几种有
网格采样,随机采样,poisson disc采样,Jitter算法采样,旋转网格采样
 

部分方法的采样范围,我设定为他们边缘的灰度了,也就是边缘检测中的G,因为G越大边缘越深,出现锯齿越明显,就要加大采样范围。

我们试试网格,随机,与旋转采样

网格采样比较简单,但是因为太规则了,模糊的效果可能不够好,
显获取周围的点,然后进行混色

		float4 c0 = tex2D(_MainTex, i.uv_MainTex + fixed2(0.5, 1) / _Size);
float4 c1 = tex2D(_MainTex, i.uv_MainTex + fixed2(-0.5, 1) / _Size);
float4 c2 = tex2D(_MainTex, i.uv_MainTex + fixed2(0.5, -1) / _Size);
float4 c3 = tex2D(_MainTex, i.uv_MainTex + fixed2(-0.5, -1) / _Size);

然后就是随机,个人认为随机的效果不太好,因为像是边缘被噪波了一样,有像素点扩散的痕迹

				float2 randUV = 0;
randUV = rand(float2(n.x, n.y));
float4 c0 = tex2D(_MainTex, i.uv_MainTex + float2(randUV.x / 2, randUV.y) / _Size);
randUV = rand(float2(-n.x, n.y));
float4 c1 = tex2D(_MainTex, i.uv_MainTex + float2(randUV.x / 2, randUV.y) / _Size);
randUV = rand(float2(n.x, -n.y));
float4 c2 = tex2D(_MainTex, i.uv_MainTex + float2(randUV.x / 2, randUV.y) / _Size);
randUV = rand(float2(-n.x, -n.y));
float4 c3 = tex2D(_MainTex, i.uv_MainTex + float2(randUV.x / 2, randUV.y) / _Size);

然后就是旋转网格采样,最佳的旋转角度是arctan (1/2) (大约 26.6°),这里偷个懒,也省去了旋转计算的消耗,大概个位置进行采样,效果还算好。

		<span style="font-size:14px;">		float4 c0 = tex2D(_MainTex, i.uv_MainTex + fixed2(0.2 / 2, 0.8) / _Size);
float4 c1 = tex2D(_MainTex, i.uv_MainTex + fixed2(0.8 / 2, -0.2) / _Size);
float4 c2 = tex2D(_MainTex, i.uv_MainTex + fixed2(-0.2 / 2, -0.8) / _Size);
float4 c3 = tex2D(_MainTex, i.uv_MainTex + fixed2(-0.8 / 2, 0.2) / _Size);</span>

结果比较

性能

性能方面SSAA比其他AA弱了一些,主要因为方法是这样暴力的采样

SSAA采样方式间的损耗都差不多

都是SSAAx4

无抗锯齿

网格采样

随机采样

旋转采样

在unity中image effect的SSAA消耗与本文差不多

又看了一下其他的unity的抗锯齿方法,发现FXAA消耗是最少的在2.8ms左右

全部代码已共享至GitHub

   ----- by wolf96

Unity3d 超级采样抗锯齿 Super Sampling Anti-Aliasing的更多相关文章

  1. Unity3D学习(七):Unity多重采样抗锯齿设置无效的解决办法

    前言 学习Shader的过程中发现模型锯齿严重,于是去Edit--Project Settings--Quality选项下将反锯齿设置为了8X Multi Sampling.结果没有任何改变,如图: ...

  2. OpenGL ES3使用MSAA(多重采样抗锯齿)的方法

    昨晚花费了我2个多小时的时间终于把OpenGL ES3.0中的MSAA给搞定了.在OpenGL ES2.0中,Khronos官方没有引入标准的MSAA全屏抗锯齿的方法,而Apple则采用了自己的GL_ ...

  3. osg如何设置抗锯齿(反走样,反锯齿)

    首先抗锯齿是什么? 举个最简单的例子 你用windows画图软件画一根直线(准确说这个叫做线段),当水平或者垂直的时候,如下图,这是绝对完美的 但是当线段出现倾斜时,就无法做到完美了此时就会出现锯齿 ...

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

    写在前面 在之前的基础篇中,我们讲到了在绘制点线时如何处理边缘的锯齿,也就是使用smoothstep函数.而模糊参数是一些定值,或者是跟屏幕分辨率相关的数值,例如分辨率宽度的5%等等.但这种方法其实是 ...

  5. Android画图之抗锯齿 paint 和 Canvas 两种方式

    在画图的时候,图片如果旋转或缩放之后,总是会出现那些华丽的锯齿.其实Android自带了解决方式.    方法一:给Paint加上抗锯齿标志.然后将Paint对象作为参数传给canvas的绘制方法. ...

  6. Android画图之抗锯齿

    在画图的时候,图片如果旋转或缩放之后,总是会出现那些华丽的锯齿.其实Android自带了解决方式.    方法一:给Paint加上抗锯齿标志.然后将Paint对象作为参数传给canvas的绘制方法. ...

  7. Unity QualitySettings.antiAliasing 抗锯齿

    QualitySettings.antiAliasing 抗锯齿 Description 描述 Set The AA Filtering option. 设置AA过滤选项. The AntiAliaz ...

  8. 【OptiX】第5个示例 递归反射、抗锯齿

    运行结果如下: [抗锯齿] 可以看到中间那个竖线的右侧从地面上看有款明显的锯齿,而左边就没有.包括球的反射出来的三角形和地面也有明显的锯齿.那么抗锯齿究竟本例中是怎么做的呢? 首先在采样时,当场景需要 ...

  9. 在qt的QOpenGLWidget开启opengl的抗锯齿

    在QOpenGLWidget的构造函数添加下面几句代码即可 QSurfaceFormat surfaceFormat; surfaceFormat.setSamples();//多重采样 setFor ...

随机推荐

  1. Java file文件的写入和读取及下载

    File文件的写入 一.FileWriter 和BufferedWriter 结合写入文件 FileWriter是字符流写入字符到文件.默认情况下,它会使用新的内容代替文件原有的所有内容,但是,当指定 ...

  2. C# 控制台窗口的显示与隐藏

    1. 定义一个Consolse帮助类,如下: /// <summary> /// 控制台帮助类 /// </summary> public static class Conso ...

  3. mysql 链接数据库

    一.MySQL 连接本地数据库,用户名为“root”,密码“root”(注意:“-p”和“root” 之间不能有空格) C:\>mysql -h localhost -u root -proot ...

  4. 输出不大于N的素数的个数

    输出不大于N的素数的个数 Sieve of Eratosthenes 方法  素数的性质: 非素数可以分解为素数乘积. 证明 (1)n = 2 成立,n = 3 成立: (2)若 n = k 时成立, ...

  5. JavaScript拖拽

    <!DOCTYPE html><html><head> <meta charset="utf-8"> <meta http-e ...

  6. winform C#屏幕右下角弹出消息框并自动消失

    ①弹出信息框后慢慢下降消失 在主窗体中新增按钮重命名为btnShowAndDisappearMessages,在click事件中写如下代码: private void btnShowAndDisapp ...

  7. MySQL配置文件路径及‘The total number of locks exceeds the lock table size’问题

    在删除mysql中的数据时,遇到报错: ERROR 1206 (HY000): The total number of locks exceeds the lock table size 查了查,发现 ...

  8. Python【第一篇】基础介绍

    一.本节主要内容 Python介绍 发展史 Python 2 or 3? 安装 Hello World程序 变量 用户输入 模块初识 .pyc文件 数据类型初识 数据运算 表达式if ...else语 ...

  9. TaskMgr C#技术拾遗

    1. DataGridView和ContextMenuStrip的绑定是发生在DataGridView的CellMouseClick事件,在事件中指定右键菜单弹出: 2. DataGridView的列 ...

  10. C#反射(二) 【转】

    如果没有看<C#反射(一)>.建议先看<C#反射(一)>再看这一篇.上一篇文章发表,有人评论我所写的东西比较基础.其实我也知道我也只不过是在写最基础的语法而已,之所以写它是因为 ...