Filtering Approaches for Real-Time Anti-Aliasing(2011 SIGGRAPH)

在2011的SIGGRAPH上,NVIDA提出了FXAA3.1,本文主要介绍FXAA实现思路,提供部分简单实现的代码。

1.What is FXAA 3.11

  • Fast approXimate Anti-Aliasing

    • Two algorithms

      • FXAA 3.11 Console (360 and PS3)
      • FXAA 3.11 Quality (PC)
  • Fixed set of constraints
    • One shader pass, only color input, only color output
    • Run on all APIs (GL, DX9, through DX11, etc)
    • Certainly better can be done under other constraints!

FXAA全称“Fast Approximate Anti-Aliasing”,翻译成中文就是“快速近似抗锯齿”。

FXAA3.11在之前FXAA1,2的基础上做了一些改进。

  • FXAA1:最早最基础的版本,也是在PC游戏中使用最广泛的,已用于《孤岛危机2》、《无主之地》。
  • FXAA2:针对Xbox 360游戏机专门设计。
  • FXAA3:Quality质量版本面向PC,Console主机版本则面向Xbox 360、PS3。

FXAA是一种单程像素着色器,和MLAA一样运行于目标游戏渲染管线的后期处理阶段,但不像后者那样使用DirectCompute,而只是单纯的后期处理着色器,不依赖于任何GPU计算API。正因为如此,FXAA技术对显卡没有特殊要求,完全兼容NVIDIA、AMD的不同显卡(MLAA仅支持A卡)和DX9、DX10、DX11。

2.How FXAA Working

  • Early exit for pixels

取4个方向以及中间像素,对5个位置的值做滤波操作,对于范围之外进行分段线性变换。对于差异较大的像素,进行AA。

maxLuma = max(nw,ne,sw,se)
contrast = max(nw,ne,sw,se,m) - min(nw,ne,sw,se,m)
if(contrast >= max(minThreshold, maxLuma * threshold))

  • extra taps
dir.x = -((NW+NE)-(SW+SE))
dir.y = ((NW+SW)-(NE+SE))
dir.xy = normalize(dir.xy) * scale

使用2x2的区域,计算像素边界,做向量运算。得到dir之后归一化长度。

  • Optional extra 2 taps

    缩放dir.xy,扩展到8个像素
minDir = min(|dir.x|, |dir.y|) * sharpness

  • Compare 4-tap filter luma to neighborhood luma

    比较4个方向的luma和相邻luma的值,
// Use the min and max luma range of the original 4 samples
* {NW, NE, SW, SE}
// If 4-tap filter luma exceeds this range,
* Assume invalid and use just the first 2 taps

  • 效果展示

3.简单实现

我自己再Direct11的环境下,参考FXAA思路,实现了简单版本的FXAA,相比自带d3d实现的4xMSAA,效果较为不明显,仅供交流学习。

//--------------------------------------------------------------------------------------
// File: FXAA.fx
//-------------------------------------------------------------------------------------- SamplerState samLinear : register(s0);
Texture2D txFxaa : register(t0); struct PS_INPUT
{
float4 Pos : SV_POSITION;
float4 PosProj : POSITION;
float3 Norm : NORMAL; float4 Diffuse : COLOR0;
float2 Tex : TEXCOORD;
float3 Tangent : TANGENT;
}; float4 FxaaPS(PS_INPUT input) : SV_Target
{
float4 texColor = txFxaa.Sample(samLinear, input.Tex); // FXAA 3x3取9个像素
float3 luma = float3(0.299, 0.587, 0.114);
//luma = float3(0.33, 0.33, 0.33);
float lumaTL = dot(luma, txFxaa.Sample(samLinear, input.Tex.xy + float2(-1.0, -1.0)).xyz);
float lumaTR = dot(luma, txFxaa.Sample(samLinear, input.Tex.xy + float2(1.0, -1.0)).xyz);
float lumaBL = dot(luma, txFxaa.Sample(samLinear, input.Tex.xy + float2(-1.0, 1.0)).xyz);
float lumaBR = dot(luma, txFxaa.Sample(samLinear, input.Tex.xy + float2(1.0, 1.0)).xyz);
float lumaM = dot(luma, txFxaa.Sample(samLinear, input.Tex.xy).xyz); float2 dir;
dir.x = -((lumaTL + lumaTR) - (lumaBL + lumaBR));
dir.y = (lumaTL + lumaBL) - (lumaTR + lumaBR); float FXAA_SPAN_MAX = 8.0; float direReduce = 1.0 / 128.0;
float inverseDir = 1.0 / (min(abs(dir.x), abs(dir.y)) + direReduce); dir = min(float2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),
max(float2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), dir*inverseDir)); float3 res1 = (1.0 / 2.0) * (
txFxaa.Sample(samLinear, input.Tex.xy + (dir * float2(1.0 / 3.0 - 0.5, 1.0 / 3.0 - 0.5))).xyz +
txFxaa.Sample(samLinear, input.Tex.xy + (dir * float2(2.0 / 3.0 - 0.5, 2.0 / 3.0 - 0.5))).xyz); float3 res2 = res1 * (1.0 / 2.0) + (1.0 / 4.0) * (
txFxaa.Sample(samLinear, input.Tex.xy + (dir * float2(0.0 / 3.0 - 0.5, 0.0 / 3.0 - 0.5))).xyz +
txFxaa.Sample(samLinear, input.Tex.xy + (dir * float2(3.0 / 3.0 - 0.5, 3.0 / 3.0 - 0.5))).xyz); float lumaRes = dot(luma, res2); float lumaMin = min(lumaM, min(min(lumaTL, lumaTR), min(lumaBL, lumaBR)));
float lumaMax = max(lumaM, max(max(lumaTL, lumaTR), max(lumaBL, lumaBR))); if (lumaRes <lumaMin || lumaRes > lumaMax)
texColor = float4(res2, 1.0);
else
texColor = float4(res1, 1.0); return texColor;
}
  • 效果对比(左为无FXAA)

Filtering Approaches for Real-Time Anti-Aliasing(2011 SIGGRAPH)的更多相关文章

  1. Lighting Techinology of the Last Of Us (2013 SIGGRAPH)

    Lighting Techinology of the Last Of Us(2013 SIGGRAPH) or "Old Lightmaps - New Tricks" 原作:M ...

  2. MIT-6.006算法导论(2011秋)

    L01 Algorithmic Thinking,Peak Finding 算法定义:高效处理大量数据的程序 在学本课之前最好先学习6.042,本课进阶为6.046 本门课的8个主要章节:算法思想.排 ...

  3. 资料下载:生活方向盘PPT以及活动录音(2011.02)

    本文已挪至 http://www.zhoujingen.cn/blog/676.html 免费PDF和活动录音下载: http://down.51cto.com/data/216824 敏捷个人生活方 ...

  4. 基于Windows7下snort+apache+php 7 + acid(或者base) + adodb + jpgraph的入侵检测系统的搭建(图文详解)(博主推荐)

    为什么,要写这篇论文? 是因为,目前科研的我,正值研三,致力于网络安全.大数据.机器学习.人工智能.区域链研究领域! 论文方向的需要,同时不局限于真实物理环境机器实验室的攻防环境.也不局限于真实物理机 ...

  5. Statistical physics approaches to the complex Earth system(相关系统建模理念方法的摘要)

    本文翻译自"Statistical physics approaches to the complex Earth system",其虽然是针对复杂地球系统的统计物理方法的综述,但 ...

  6. 实时降噪(Real-time Denoising):Spatio-Temporal Filtering

    目录 空间滤波(Spatial Filtering) 基于距离的高斯滤波 双边滤波(Bilateral filtering) 联合双边滤波(Joint Bilateral filtering)[201 ...

  7. 剖析虚幻渲染体系(12)- 移动端专题Part 3(渲染优化)

    目录 12.6 移动端渲染优化 12.6.1 渲染管线优化 12.6.1.1 使用新特性 12.6.1.2 管线优化 12.6.1.3 带宽优化 12.6.2 资源优化 12.6.2.1 纹理优化 1 ...

  8. 分析oracle的执行计划(explain plan)并对对sql进行优化实践

    基于oracle的应用系统很多性能问题,是由应用系统sql性能低劣引起的,所以,sql的性能优化很重要,分析与优化sql的性能我们一般通过查看该sql的执行计划,本文就如何看懂执行计划,以及如何通过分 ...

  9. PROC 文件系统调节参数介绍(netstat -us)

    转自:http://www.cnblogs.com/super-king/p/3296333.html /proc/net/* snmp文件 Ip: ip项 Forwarding        : 是 ...

随机推荐

  1. Kubernetes---Pod笔记

    ⒈pod的理解     将多个容器镜像融合在一起,共享网络命名空间及容器卷 ⒉pod的分类 自助式podv          不是被控制器管理的pod,它一旦死亡不会被人给拉起来. 控制器管理的pod ...

  2. spring-redis使用

    导包 注入调用           opsForValue()     opsForList() redisTemplate   配置 ,为了   对key采用string序列化方式          ...

  3. (十四)mybatis 和 spring 整合

    目录 整合思想 整合步骤 整合之后原始 dao 开发 整合之后 Mapper 代理开发 总结 整合思想 让 spring 管理 sqlSessionFactory ,使用 单例模式 创建该对象 : 根 ...

  4. Redis 和 Memcached 各有什么优缺点,主要的应用场景是什么样的?

    1.显示最新的项目列表 2.删除与过滤 3.排行榜相关 4.按照用户投票和时间排序 5.处理过期项目 6.计数 7.特定时间内的特定项目 8.实时分析正在发生的情况,用于数据统计与防止垃圾邮件等 9. ...

  5. python学习-5 python基础-2 条件语句(if的简单用法2---elif)

    1.if的基本语句 if条件: 内部代码块 else: ........ print(‘.......’) 2.if语句支持嵌套 if条件: 内部代码块 if条件: 内部代码块 else: ..... ...

  6. 牛客 26C 手铐 (缩环, 树形dp)

    先缩环建树, 对于树上个环$x,y$, 假设$x,y$路径上有$cnt$个环(不包括$x,y$), 贡献就为$2^{cnt}$. 这题卡常挺严重的, 刚开始用并查集合并竟然T了. #include & ...

  7. 关于typora换行的问题

    neo4j> profile MATCH (liskov:Scientist { name:'Liskov' })-[:KNOWS]->(wing:Scientist)-[:RESEARC ...

  8. python 画图像训练结果的loss图

    得到每个epoch的loss和predict精度后,就可以愉快地画图直观地看出训练结果和收敛性了. # coding:utf-8 import matplotlib.pyplot as plt dat ...

  9. 我是如何将一个加载90s的接口优化到不足2s的

    一.提出问题 由于公司是做医疗级智能可穿戴设备的,所以数据(二进制数据)的存储方面有点特殊,数据没有存储于数据库里面,而是存储于磁盘上.可能有同学质疑,mysql的Blob类型也可以存储二进制数据啊, ...

  10. 基于【 springBoot +springCloud+vue 项目】二 || 后端框架详解

     前言 在上一篇中,我们搭建了一个-API服务提供接口模块,目的为了提供了消费方进行调用.为什么不直接在service层直接提供调用接口,而是重新创建一个接口层模块?首先我们需要对Feign有所了解. ...