文章目录

  • 1 光栅化 Rasterization
    • 1.1 视口变换 viewport (正则立方体 to 屏幕)
    • 1.2 像素化
      • 1.2.1 三角形构成图像
      • 1.2.2 三角形离散化
        • 1.2.2.1 叉乘判断点是否在三角形内
        • 1.2.2.2 三角形像素化使用包围盒
        • 1.2.3 效果
  • 2 反走样 Antialiasing
    • 2.1 提前滤波 Pre-Filter
    • 2.2 滤波原理
      • 2.2.1 频域与傅里叶变换
      • 2.2.2 滤波
      • 2.2.3 卷积 Convolution
      • 2.2.4 低通滤波盒子
      • 2.2.4 采样等于重复频率内容***
    • 2.3 低通滤波采样
      • 2.3.1 超采样 MSAA Multisample anti-aliasing
  • 3 作业 光栅化三角形
  • 4 总结

1 光栅化 Rasterization

  1. raster 来自 德语 ,意思是屏幕,动词化后变rasterize再名词化 Rasterization,意为光栅化.
  2. 像素Pixelpicture element,可理解为屏幕最小单位,为正方形,颜色为RGB.

1.1 视口变换 viewport (正则立方体 to 屏幕)

像素指标从(0,0)(宽-1,高-1),每个像素中心坐标是(x+0.5,y+.5)

MVP变换的正则立方体(先不管z轴,只看xy)[-1,1]²投到屏幕(0×宽,0×高),

需要一个视口变换矩阵 viewport

到达让正方形左下角点屏幕原点,右上角点屏幕右上角顶点的效果.

1.2 像素化

1.2.1 三角形构成图像

经过视口变换,图像已经在屏幕上了.
现在研究怎么用屏幕表现图像,也就是屏幕上每个像素值是多少. 我们认为图像基本单元是三角形,有了通过像素组成单个三角形,我们可以通过三角形集合得到各种图像. (PS. 早期的电视也是用CRT通过打电子到屏幕来显示画面)

  • 用三角形是因为
  1. 三角形是最基础多边形
  2. 三角形三点在一平面
  3. 方便判断点在三角形内外
  4. 方便重心插值

1.2.2 三角形离散化

所以换句话说,就是怎么在屏幕画三角形,即 Rasterizing Triangles into Pixels.

  • 采样近似,用inside函数判断像素点是否在三角形内
  • 伪代码

1.2.2.1 叉乘判断点是否在三角形内

1.2.2.2 三角形像素化使用包围盒

只遍历AABB盒子,避免计算量过大

1.2.3 效果

大概像个三角形,但是有锯齿 Jaggies!!!

  • 真实例子: 手机屏幕

    总结: MVP变换后viewport变换,所以是MVPV变换,然后光栅化,但会出现锯齿!!

2 反走样 Antialiasing

采样 (sampling) 会产生 瑕疵 artifact,如

  • 锯齿 Jaggies 空间
  • 摩尔纹 Moire欠采样
  • 风扇倒转 Wagon wheel effect时间
  • 本质: 信号变化过快(高频),采样速度跟不上(低频).

2.1 提前滤波 Pre-Filter

  • 滤波---采样
  • 效果

    可以看见在滤波模糊处理后再采样,图像的锯齿少了很多.那么具体该怎么滤波呢?原理是什么?

2.2 滤波原理

2.2.1 频域与傅里叶变换

根据傅里叶变换,周期函数,比如方波可以分解为频率不同余弦函数,如下图

  • 空域到频域
    F(ω)=∫−∞∞f(x)e−2πiωxdxF(\omega)=\int_{-\infty}^{\infty} f(x) e^{-2 \pi i \omega x} d x F(ω)=∫−∞∞​f(x)e−2πiωxdx
  • 频域到空域
    f(x)=∫−∞∞F(ω)e2πiωxdω欧拉公式eix=cos⁡x+isin⁡x\begin{gathered} f(x)=\int_{-\infty}^{\infty} F(\omega) e^{2 \pi i \omega x} d \omega \\ \text { 欧拉公式} e^{i x}=\cos x+i \sin x \end{gathered} f(x)=∫−∞∞​F(ω)e2πiωxdω 欧拉公式eix=cosx+isinx​

    将这些频率不同的余弦函数画在一起,我们发现用一个固定频率 (图中竖线)采样,对频率越高的余弦函数,采样后拟合的折线原函数差别越大,这是采样产生artifacts的原因.

2.2.2 滤波

滤波就是去掉特定频率函数,那么这个特定频率什么呢?

  • 例子
    右图左边人物图频谱图,中心频率最低.
  • 高通滤波 High-pass filter
    去掉中间低频,我们发现人物图只有边缘轮廓,所以高频代表边界,边界(颜色发生突变的地方)
  • 低通滤波 Low-pass filter
    去掉外部高频,我们发现人物图模糊
  • 上面的高(低)通滤波具体是通过卷积实现的.

2.2.3 卷积 Convolution

  • 图像理论的卷积是如下:

  • 时域的卷积=频域的乘积,反之亦然.
    (时域) 小女孩图片 卷积 (低通)滤波器 = (傅里叶变换后频域) 两者相乘 再逆变换 ,得到对图像的模糊处理

2.2.4 低通滤波盒子

  • 注意上面用了一个低通滤波器模糊图像
  • 对应的时域图(左)频域图(右)

    如果要得到更模糊的图像,我们需要时域图盒子变大(大于3×3的盒子,一个点代表更多信息),即频域图变小 (留下更低频的函数,代表边界的函数更少).

    更极端的理解,如果盒子比屏幕大,等于各处颜色一样,完全模糊.如果盒子是1×1,等于没有模糊.

2.2.4 采样等于重复频率内容***

经过傅里叶变换的函数X经过冲击函数P采样,即搬运复制.

密dense采样(频率高,对应一个三角形的像素密度大) 和 稀疏sparse采样(频率低,对应一个三角形的像素密度小)

总结:为了避免走样alias,需要

  • 增加采样率(如增加屏幕分辨率),成本太高
  • 反走样(模糊再采样)

2.3 低通滤波采样





一个关键问题,怎么根据覆盖率得到上图四种像素值?

2.3.1 超采样 MSAA Multisample anti-aliasing

  • 如果一个像素Pixel有的部分覆盖率三角形,有的没有覆盖三角形.我们需要将一个像素分成N×N个点(并没有增加分辨率),来算覆盖率
  • 计算覆盖率
  • 结果
  • 对应的模糊后的三角形
  • 其他反走样方案
    MSAA会增加计算量~~~No free lunch!

3 作业 光栅化三角形

  • 首先在main.cpp复制作业1的Viewing观测变换矩阵
    float t = - tan((eye_fov / 360.0) * acos(-1)) * zNear;//t is negative?//float t =  tan((eye_fov / 360.0) * acos(-1)) * zNear;float r = t / aspect_ratio;Eigen::Matrix4f perspective;perspective << zNear, 0, 0, 0,0, zNear, 0, 0,0, 0, zNear + zFar, -zNear * zFar,0, 0, 1, 0;Eigen::Matrix4f translate;translate <<1,0,0,0,//-(r + l) / 20,1,0,0,//-(t + b) / 20,0,1,-(zNear + zFar)/2,0,0,0,1;Eigen::Matrix4f scale;scale << 1/r,0,0,0,//2 / (r - l)0,1/t,0,0,//2 / (t - b)0,0,2/(zNear-zFar),0,0,0,0,1;projection = scale * translate * perspective * projection;
  • 然后在rasterizer.cpp实现判断点是否在三角形内,找AABB轴向边界盒子,比较深度(Z-buffer算法)并更新颜色三个功能
  • 判断点是否在三角形内
static bool insideTriangle(float x, float y, const Vector3f* _v)
{   // TODO : Implement this function to check if the point (x, y) is inside the triangle represented by _v[0], _v[1], _v[2]Vector3f p(x, y, 0);Vector3f ap(p - _v[0]); Vector3f bp(p - _v[1]); Vector3f cp(p - _v[2]); Vector3f ab(_v[1] - _v[0]); Vector3f bc(_v[2] - _v[1]); Vector3f ca(_v[0] - _v[2]);return ap.cross(ab).dot(bp.cross(bc)) > 0 && bp.cross(bc).dot(cp.cross(ca)) > 0;
}
  • 找AABB轴向边界盒子
    int x_min1 = v[0].x() < v[1].x() ? v[0].x() : v[1].x();int x_min = x_min1 < v[2].x() ? x_min1 : v[2].x();int x_max1 = v[0].x() > v[1].x() ? v[0].x() : v[1].x();int x_max = x_max1 > v[2].x() ? x_max1 : v[2].x();int y_min1 = v[0].y() < v[1].y() ? v[0].y() : v[1].y();int y_min = y_min1 < v[2].y() ? y_min1 : v[2].y();int y_max1 = v[0].y() > v[1].y() ? v[0].y() : v[1].y();int y_max = y_max1 > v[2].y() ? y_max1 : v[2].y();
  • 比较深度并更新颜色 (Z-buffer算法)
   for (int x = x_min; x <= x_max; x++){for (int y = y_min; y <= y_max; y++){//imag[x][y] = insideTriangle(x + 0.5, y + 0.5, t.v);if (insideTriangle(x + 0.5, y + 0.5, t.v)){auto[alpha, beta, gamma] = computeBarycentric2D(x, y, t.v);float w_reciprocal = 1.0/(alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());float z_interpolated = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();z_interpolated *= w_reciprocal;if (z_interpolated < depth_buf[get_index(x, y)]){depth_buf[get_index(x, y)] = z_interpolated;Vector3f point((float)x, (float)y, z_interpolated);Vector3f color = t.getColor();set_pixel(point, color);}}}}

输出

./Rasterizer output.png

4 总结

作业1作业2实现了下面所表示的变换:

  1. Model模型变换
  2. Viewing观测变换
  3. Projection(透视perspective平移translate缩放scale)变换和视口(viewport)变换
  4. 光栅化Rasterize三角形(判断点在三角形内外,包围盒,Z-buffer算法,设置像素颜色)

光栅化 Rasterization相关推荐

  1. 计算机图形学三:光栅化-Rasterization

    文章目录 什么是光栅化? 像素和屏幕 直线光栅化(Linear Rasterization) DDA数值微分算法 中点Bresenham算法 三角形光栅化(Triangle Rasterization ...

  2. GAMES101笔记_Lec05~06_光栅化 Rasterization

    1 视口变换-从裁剪空间到屏幕空间 Canonical Cube to Screen 1.1 什么是屏幕 What is a screen? 在图形学中,抽象的认为屏幕是一个二维数组,数组中每一个元素 ...

  3. 计算机图形学【GAMES-101】2、光栅化(反走样、傅里叶变换、卷积)

    快速跳转: 1.矩阵变换原理Transform(旋转.位移.缩放.正交投影.透视投影) 2.光栅化(反走样.傅里叶变换.卷积) 3.着色计算(深度缓存.着色模型.着色频率) 4.纹理映射(重心坐标插值 ...

  4. 渲染 光栅化 光线追踪 着色器 投影视图模型矩阵 未来VR关键技术

    渲染介绍得非常详细易懂(强烈建议观看):https://www.zhihu.com/question/31971846/answer/36727962 https://www.zhihu.com/qu ...

  5. 光栅化(Rasterization)

    什么是光栅化? 简单来说,光栅化就是将几何数据经过一系列变换(可以说是连点描边裁剪)最终转换为像素,从而呈现在屏幕上的过程. 光栅化的过程 读取模型的顶点,3个3个的读,因为要画三角形. 将3个顶点两 ...

  6. 4、计算机图形学——光栅化、抗锯齿、画家算法和深度缓冲算法(Z-buffer)

    一.光栅化(Rasterization) 1.1.概念 光栅raster这个词就是德语中屏幕的意思,光栅化的意思就是将图像绘制在屏幕上进行显示. 1.2.三角形光栅化过程简述 首先,为什么要以三角形的 ...

  7. 谈谈Hybird3D中的光栅化优化

    看到空明流转分享了他的SALVIA 0.5.2优化谈,我也来说说Hybird3D中和光栅化相关的一些优化技术. Hybird3D的设计目标是打造一款准实时的软件高质量渲染器,采用了光栅化和光线跟踪混合 ...

  8. 用C#实现一个简易的软件光栅化渲染器

    这是一个用C#+winform实现的软件光栅化渲染器,今天拿出来与大家分享一下,希望能起到抛砖引玉的作用,给新人一点启发(结构比较简单,注释比较详细^_^),也欢迎司机们拍砖指点和交流~ 目的: 巩固 ...

  9. 图形学基础笔记II:多边形光栅化算法和显卡三角形光栅算法

    为什么三角形就够了 实际对于 3D 来说肯定全是基于三角形的 geometry - OpenGL: Is it more efficient to use GL_QUADS or GL_TRIANGL ...

最新文章

  1. Android runOnUiThread() 方法的使用
  2. python做一个系统-用python做一个系统监控程序
  3. 图像处理与计算机视觉资源汇总——论文+代码+教材+视频等等
  4. QRCode.js -- 用 Javascript 生产二维码
  5. WordPress添加固定位置的百度分享按钮
  6. Eclipse 各种快捷键
  7. js 字符串操作函数有哪些
  8. nuSVC的使用和解读
  9. 一个十年SAP CRM老司机对产品主数据的理解
  10. 我说我精通字符串,面试官竟然问我Java中的String有没有长度限制!?|附视频讲解
  11. 免费SSL申请:(各大服务商资源综合)- 免费获取
  12. sqlquerystress
  13. 【英语学习】【WOTD】farouche 释义/词源/示例
  14. VS 2019 for Mac 第 3 个预览版发布,新编辑器、Xamarin 开发改进
  15. SharePoint2010添加webpart找不到内容编辑器
  16. 红帽安装Oracle步骤
  17. MIT App Inventor使用与入门教程
  18. Java日期练习—计算已出生多少天
  19. 过滤器和拦截器的区别_拦截器和过滤器的区别
  20. c++ linux pthread函数

热门文章

  1. 【1252. 奇数值单元格的数目】
  2. java实现双向RSA + AES加密
  3. python 编写查字典程序,Python_字典实现简单预约系统
  4. [Qt5布局] 控件自动填满所在布局框架
  5. RN-微信钱包页面布局
  6. 帕特森销售法则(转载)
  7. 鼠标屏幕取词原理 (VC++)
  8. SQL2005数据库附加
  9. [D-VI] my_second_fpga(1位加法器 Verilog HDL抽象级别 modelsim-altrea功能仿真 综合器)
  10. 数组push后的返回值,容易忽略