翘首以盼的抗锯齿

news2024/9/20 12:26:10

Antialiasing

实际的图形学中是怎么实现反走样的呢?

我们不希望实际产出的图形有锯齿效果,那怎么办呢?

06fdde0120ff4b10b8382294479640bc.png

从采样的理论开始谈起吧 

Simpling theory

照片也是一种采样,把景象打散成像素放到屏幕上的过程:

9952d87c436040e4ac2145087fd29437.png

还可以在不同的时间(视频):

272da95e35814a6c97b3e1f3bf009cfc.png

 动画是定义在帧数上的

一个专业术语:Artifacts(瑕疵)

采样会产生很多问题,一个是锯齿:

b50e8204e72241589ddf39bd76711e93.png

还有问题比如说摩尔纹:

dc1451b6590e4724ae9dc31f87a8d43c.png

它怎么产生的呢?

 比如说把左边的奇数行奇数列都去掉变成小图,显示成和大图一样大,就能看到摩尔纹了(拿手机拍电脑显示器)

还有一种有意思的叫车轮效应,也是采样中出现的问题,比如人肉眼的采样速度跟不上高速旋转的物体:

6b3c2dc4fdd54addaa0c21deb03de848.png

我们如何反走样呢?

在采样之前做一个模糊(滤波),做一个模糊再采样就可以反走样:

 2b257c213daf49a287aa0bdef6a6e06a.png

d6d6b0f41c144d05adb178c102df534c.png

注意顺序是不能颠倒的,要先模糊再采样,如果先采样再模糊就变成了Blurred Aliasing:

9cd27af2f07e497696799203b1013178.png 那为什么采样的速度跟不上信号变换的速度就会走样?

Antialiasing in practice

Frequency Domain

先来看看频率吧:

f9c0fb9ce108460cb893a0a58b975e2c.png

调整前面的系数会得到不同的余弦波(频率不同) 

介绍正余弦波:

d3920e2a7baf465596ee1c2fcff63bda.png

为了介绍傅里叶级数展开(任何周期函数可以将其写成正余弦函数的线性组合)

还有个东西叫傅里叶变换:

c99a0ff7c92a414c8ed2b777bca86891.png

傅里叶变换:把函数变成不同频率的段并且显示出来:

64b12b35bb8d49e09c9f9bcfd6df205a.png 采样还原出的函数在不同频率下有出入,走样本质是信号变化的太快导致采样跟不上

 时域相乘,频域卷积,必须要到达两倍才不会走样

b0a8b08442f54108a4acebe365c71520.png

上面的结果就是采样两种频率完全不同的信号但是采样结果完全一样!

 这就是走样。

Filtering

把某个特定的频率给抹掉,说出对应信号如何变化

傅里叶变换就是从时域变到频域:

27c5158195f94a93ba1afc3a4fb6dcf0.png

 中心把其定义成低频的区域,周围全都是高频的区域,在不同频率的信息多少通过亮度表示

信息多集中在低频段

水平和竖直方向有道,我们在分析信号的时候我们会认为它是周期性重复的信号,那么对于不周期性重复的信号怎么办呢?

比如上图哪里重复了,并不重复对吧,我们通过右边界在重复左边界的内容,在边界会产生剧烈的变化从而产生极其高的高频,头顶位置和衣服下边缘位置的图像变化剧烈,导致高频区域为白色

滤波是去掉一些频率的内容,把低频信号抹掉,高频信号有意义:图像内容的边界

687f916495fc4d32a48906e67ab82b10.png

这种滤波叫高通滤波 (通过滤波器使只有高频的滤波可通过)

为什么高频信息就对应边界呢?

是不是变化很剧烈的才叫边界?

那就是高频信息呀,我们如果过滤掉高频只留下低频呢?

a416f17a78e34218a99add2139b4cddb.png

会发现边界模糊勒 

还可以做另外的实验:去掉高频。去掉低频,留下中庸之道,就可以提取到一些不是很明显的边界特征(中通滤波):

5bc40c182eed4e97bc4f64ee136d0255.png

卷积(Convolution)和滤波有关系,本质是一种点乘:

4fd0d143595e4a59935ee9e013badac8.png

这是要做一个卷积操作(加权平均):

7e46c9f66c2e48ea8a2408679e65e135.png

卷积定理: 时域卷积等于频域相乘,在时域上的乘积相当于在频域上的卷积:

29bd8929930c46a7b94e535ed931c9dc.png

1d14176bfb8242308d5cb929ddcbfa41.png

 卷积操作进行均值模糊,时域的卷积等于频域的乘积

滤波器本身是一个3×3的盒子,再×eq?%5Cfrac%7B1%7D%7B9%7D是为了不让图像整体的颜色值发生变化:

9b8904cab66a459cb8e8d9a423023f8b.png

 上面的例子显示出的结果是这个盒子是一个低通滤波器

bba02e0dc5b3421994d157bc40680891.png

时域上的一个小格子转换成频域,如果盒子在时域上变大了,那在频域上该如何变化呢?

盒子在时域上变大,反而在频域上变小:

9702e794d2634d618f186698dd1c44c3.png

 用越大的box做卷积会越来越模糊,如果用一个超级小的box就相当于根本没有做滤波,也就是说所有东西都被留了下来

采样是什么?是在重复频域上的内容(×另外一个函数):

d81836510fa24e6eb20e99457a07a78d.png

根据卷积定理,时域上的乘积对应到频域上为卷积,时域卷积等于频域乘积

采样就是在重复原始信号的频谱

1、左侧一列的中间是一个周期冲激序列,它在t=nT上纵坐标为无穷大,且频域(右中)仍是一个冲激序列,若用其与原信号相乘进行采样,采样的过程就不是让左边上中两图简单相乘就行了,它需要再进行一个过程将其转化为离散时间序列

2、实际采样时一个常用的办法是用一个在t=nT上纵坐标为1的采样序列乘信号源,这样可以直接得到采样信号

3、右上和右中卷积得到右下是可证的

为什么会产生走样就很显然了:采样的不同间隔会引起频谱以另外一个不同的间隔移动:

9bd0dc2fbb574112a7505f961fe3dcdc.png

 采样不够快,冲击函数频率低,卷积结果频率低(原始信号和复制粘贴的信号重合在一起了:发生走样,频谱搬移发生混合)

提升分辨率走样就会好很多(进行多的采样)

Reduce Alising

怎么改善走样呢?

052ab591386845a6a3458c8b175432f1.png

1.提高分辨率

2.先去模糊再去采样(模糊:低通滤波):

d1efd7ed0bb74310ae4a4a6b2beb6cb4.png

e4f54afed9644ba3a245dc940106d311.png 那么在实际的操作中,我们采用什么样的滤波器来进行卷积操作呢?

用一定大小的低通滤波器对其进行卷积:

07b7215b996146199b75bf29815c1954.png

 对像素覆盖的面积求平均:

27b2b40d0f3a44dd9a40a9bdc27b4d24.png

MSAA 

对更多采样点进行反走样(对反走样的近似,不能严格意义上解决反走样的问题),对大覆盖的点的近似:

18dc03b1cd43479095ffe36b7e87f78b.png

cc12082c4a31447eadeb2c30359a6d9d.png 

028ba31ba6304e08b10fb8a03bbccfca.png 

d09aa9ffb07049a89b0ae46935f0276f.png 

通过更多的样本进行反走样的第一步:模糊

 676864ff15fc47598a13ce2f1ee2020b.png

 MSAA是采样时提升了计算精度:

df2c91dd8fc449c68941c55ae88b1cd8.png

05a5a744f48c49f1a8a180ae2618a084.png 

通过增大计算量抗锯齿,还有其他抗锯齿的方法:FXAA(Fast Approximate AA:替换成没有锯齿的边界)、TAA(Temporal AA:找上一帧的信息)

Tips:Super resolution,超分辨率,把小图放大看到的全是锯齿,怎样把采样不够的图变得没有锯齿呢?可以通过深度学习的方法:DLSS(猜测)

Visibility/occlusion

首先需要谈的问题就是关于可见性,很直观的一种想法是先画远处的物体,再画近处的物体(把远处的物体遮挡住),由远到近做光栅化:(Painter's Algorithm)画家算法:

555ac0251ef74c2ab944998019f9a944.png

但是想要定义深度并不简单,需要光栅化排序:

da204d864e344033ac52f835b911a1b7.png

上面这种复杂的情况在深度上存在互相遮挡的关系,也就没办法用亲爱的画家算法,为了解决这个问题,在图形学中引入了一个概念:Z-Buffering

Z-Buffering

深度缓冲84144df9616640509bd52144d7ada7e6.png

 对三角形的覆盖关系不好判断,但是可以面向像素排序,记录像素离我们比较近的距离

最后得到的结果是要渲染出一幅画面:

cd2f42a7ce4f4a2b909567eabae90c14.png

这两幅图永远都是同时生成的,那算法在一开始的时候该如何进行呢?

看像素的具体情况,更新最浅深度:

ac623824a9b94441a2f66c1d5443adb1.png

深度缓存工作实例:

cec161338af1479eababbeafbf69b4a7.png 

涂新颜色、更新最小深度值 

深度缓存算法有一个好处:与顺序无关,不会有两个浮点数的值完全一样(出现深度完全一样的情况),深度缓存算法被广泛的应用于图形学

f68362e6eebb49b7bddfc6f794100c21.png

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1794840.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

统信UOS SSH服务升级(ubuntu20)内网

服务器配置 系统信息 SSH版本 目标版本 openssh-server_8.2p1-4_arm64.deb 因为不通互联网,所以所有deb包需要手动下载(可以连接互联网的可以自动忽略手动下载deb步骤,直接apt-get install xxx 即可) 升级步骤 !!!deb下载方式…

开源低代码平台技术为数字化转型赋能!

实现数字化转型升级是很多企业未来的发展趋势,也是企业获得更多发展商机的途径。如何进行数字化转型?如何实现流程化办公?这些都是摆在客户面前的实际问题,借助于开源低代码平台技术的优势特点,可以轻松助力企业降低开…

SpringFramework总结

一.SpringFramework介绍 (一)Spring 广义上的 Spring 泛指以 Spring Framework 为基础的 Spring 技术栈。 Spring 已经不再是一个单纯的应用框架,而是逐渐发展成为一个由多个不同子项目(模块)组成的成熟技术,例如 Spring Frame…

LeetCode790多米诺和托米诺平铺

题目描述 有两种形状的瓷砖:一种是 2 x 1 的多米诺形,另一种是形如 “L” 的托米诺形。两种形状都可以旋转。给定整数 n ,返回可以平铺 2 x n 的面板的方法的数量。返回对 109 7 取模 的值。平铺指的是每个正方形都必须有瓷砖覆盖。两个平铺…

iPhone的5G设置怎么更改吗?设置好这些能够优化电池的使用寿命

随着5G技术的普及,iPhone用户现在可以享受到更快的网络速度,但这同时也带来了一个问题:如何在使用5G和保持电池寿命之间找到平衡?苹果公司通过引入“5G Auto”设置,为用户提供了一个智能的解决方案,但用户也…

动态库加载【Linux】

从此往后,建立映射,我们执行的任何代码,都是在我们的进程地址空间中进行执行 例如:将动态库映射到共享区,进程在CPU调度时,是在进程的进程地址空间处运行 程序在编译好之后,在加载到内存之前&a…

设计循环队列---力扣622

1、题目 1.1基础设置与讲解 循环队列,即固定长度的队列,可以想象成一个环形队列 就类似于这种队列,队尾指针后会有一个空位,用于控制判断队列为空还是为满; typedef int MyDataType;typedef struct {MyDataType fron…

美团发布2024年一季度财报:营收733亿元,同比增长25%

6月6日,美团(股票代码:3690.HK)发布2024年第一季度业绩报告。受益于经济持续回暖和消费复苏,公司各项业务继续取得稳健增长,营收733亿元(人民币,下同),同比增长25%。 财报显示,一季度,美团继续…

vue-cl-service不同环境运行/build配置

概述 在项目开发过程中,同一个项目在开发、测试、灰度、生产可能需要不同的配置信息,所以如果能根据环境的不同来设置参数很重要。 vue项目的vue-cl-service插件也支持不同环境的不同参数配置和打包。 实现 新建不同环境配置文件 vue项目中的配置文件以…

Spring 的自动装配方式你都答的出来吗?

引言:Sprin g框架作为 Java 企业级应用开发的主流选择,其自动装配功能大大简化了开发人员的工作。自动装配能够帮助开发者减少手动配置的繁琐过程,提高了代码的可维护性和灵活性。在本文中,我们将深入探讨 Spring 的自动装配方式&…

六、Docker Swarm、Docker Stack和Portainer的使用

六、Docker swarm和Docker stack的使用 系列文章目录1.Docker swarm1.简介2.docker swarm常用命令3.docker node常用命令4.docker service常用命令5.实战案例6.参考文章 2.Docker stack1.简介3.Docker stack常用命令4.实战案例5.常见问题及调错方式1.查看报错信息并尝试解决&am…

Shell脚本文本处理三剑客(grep、awk、sed)和正则表达式

一、正则表达式 1.正则表达式基础 正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串,将匹配的子串替换或者从某个串中取出符号某个条件的子串等&…

【Mybatis】INSERT INTO 遇到NULL怎么处理?

目录标题 背景-使用Mybatis手写批量插入Insert方法测试核心代码,author字段为null,插入条件怎么写? MybatisPlus解决方案自动填充字段 Mybatis解决方案if标签处理 问题:如果不在工程里面设置默认值?如何直接使用数据库…

c语言速成系列指针上篇

那么这一篇文章带大家学习一下c语言的指针的概念、使用、以及一些注意事项。 指针的概念 指针也就是内存地址,指针变量是用来存放内存地址的变量。就像其他变量或常量一样,您必须在使用指针存储其他变量地址之前,对其进行声明。 大白话讲解…

【Python报错】已解决ValueError: cannot reindex from a duplicate axis

成功解决“ValueError: cannot reindex from a duplicate axis”错误的全面指南 在数据处理和分析的过程中,尤其是在使用Pandas这样的强大工具时,我们有时会遇到一些错误信息。其中,“ValueError: cannot reindex from a duplicate axis”错误…

RabbitMQ启动报错:Error during startup: {error, {schema_integrity_check_failed,

报错信息如下: Error during startup: {error,{schema_integrity_check_failed,[{table_attributes_mismatch,rabbit_user,[username,password_hash,tags,hashing_algorithm,limits],[username,password_hash,tags,hashing_algorithm]},{table_attributes_mismatch…

【LeetCode】二叉树oj专题

如有不懂的地方,可查阅往期相关文章! 个人主页:小八哥向前冲~ 所属专栏:数据结构【c语言】 目录 单值二叉树 对称二叉树 计算二叉树的深度 二叉树的前序遍历 相同二叉树 另一棵树的子树 二叉树的构建和遍历 翻转二叉树 判…

使用python优雅的将PDF转为Word

使用python优雅的将PDF转为Word 先装这个优雅的库 pip install pdf2docx然后运行下面优雅的代码,将pdf路径和docx路径修改 from pdf2docx import Converter # path pdf_file C:\\Users\\phl\\Desktop\\软件工程期末\\软件工程模拟试题5.pdf docx_file C:\\User…

UML交互图-序列图

概述 序列图又称为时序图、活动序列图,它是一种详细表示对象之间及对象与参与者实例之间交互的图,它由一组协作的对象(或参与者实例)及它们之间可发送的消息组成,它强调消息之间的时间顺序。 序列图主要用于按照交互发生的一系列顺序,显示对…

查看Linux端口占用和开启端口命令

查看端口的使用的情况 lsof 命令 比如查看80端口的使用的情况 lsof -i tcp:80列出所有的端口 netstat -ntlp查看端口的状态 /etc/init.d/iptables status开启端口以开启端口80为例。 1 用命令开启端口 iptables -I INPUT -p tcp --dport 80 -j accpet --写入要开放的端口/…