(注:此文以个人知识框架为基础拓开,为方便后期回顾,在保留原课程内容框架的基础上,个别概念的介绍可能过于简单,感兴趣读者可到 GAMES 平台深入学习)

目录

Rasterization

Different raster displays(略)

Rasterizing a triangle

Antialiasing(反走样)

Sampling theory

Antialiasing in practice

Occlusions and Visibility(深度缓冲)

Visibility / occlusion - Z-buffering

作业2

题目简单介绍

核心代码

1.判断像素点是否在三角形内:

2.对场景内的三角形做 z-buffer 深度缓冲

3.MSAA处理:

效果图


Rasterization

Different raster displays(略)

Rasterizing a triangle

(三角形生万物~~)

判断点在三角形内:

做叉积,结果同正或同负,表示点在三条边同侧,即点在三角形内。

注:cross(P0Q,P0p1) -> left;cross(P1Q,P1P2) -> left; cross(P2Q,P2P0) -> right

Antialiasing(反走样)

Sampling theory

  1. (黑话)artifacts:一切不准确,看起来不太对的结果
  2. 采样的存在的问题:

Jaggies(锯齿)

Moiré Patterns(摩尔纹):去掉图片的奇数行和奇数列后按照图片原尺寸显示。

wagonWagon Wheel Illusion(转轮错觉):人眼在时间上采样跟不上转速,而产生的转轮反向旋转的错觉。

3.傅里叶变换,过程不赘述,这里主要是为了给处理 aliasing 的两种方案提供理论基础:

        (1)提高采样率(采样的本质是对频域上频谱的重复搬移,时域上采样越稀疏,对应频域上频谱上的搬移越密集,频谱混叠的部分越多,于是产生的 aliasing 越明显)

  • (2)反走样:先做模糊(对信号做低通滤波,拿掉高频信号),再采样。换句话说,既然你频谱混叠会产生 aliasing 那我就把混丢部分(高频信号)给你拿掉: 

Antialiasing in practice

  • MSAA(Multi-Sample Anti-Aliasing)/ Supersampling:在一个像素内用更多采样点进行超采样。

  • 业内反走样里程碑:

(1)FXAA (Fast Approximate AA);快速近似抗锯齿:在图像层面对锯齿做后期处理。

(2)TAA (Temporal AA):一种基于时间的优化,当前帧复用上一帧像素的值(在 RTRT 也有相关应用)。

Occlusions and Visibility(深度缓冲)

Visibility / occlusion - Z-buffering

  • 概念:以由远到近的顺序对场景中的物体的 Z 值 做深度缓冲,同像素,近物覆盖远物。
  • 开销:需要一个额外的 buffer,颜色值存 framebuffer;深度值存 depth buffer(z-buffer)。
  • other:z-buffer 无法处理透明物体
  • Algorithm:complex:O(n)

作业2

作业2原链接

题目简单介绍

基于作业1空间转换的基础上,光栅化多个三角形,并对三角形内的像素进行深度插值处理,并对结果 antialiasing.

核心代码

1.判断像素点是否在三角形内:

/// <summary>
/// 判断像素点是否在三角形内
/// </summary>
/// <param name="x">像素点 x</param>
/// <param name="y">像素点 y</param>
/// <param name="_v">三角形三个顶点</param>
/// <returns></returns>
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]// 利用向量叉积的结果,判断像素点在三边同侧,即表示点在在三角形内Eigen::Vector3f x1 = _v[0];Eigen::Vector3f x2 = _v[1];Eigen::Vector3f x3 = _v[2];// 三角形三边对应向量Eigen::Vector3f x1x2;Eigen::Vector3f x2x3;Eigen::Vector3f x3x1;x1x2 = { x2.x() - x1.x(), x2.y() - x1.y(), 0 };x2x3 = { x3.x() - x2.x(), x3.y() - x2.y(), 0 };x3x1 = { x1.x() - x3.x(), x1.y() - x3.y(), 0 };// 像素点与三角形三顶点相连对应向量Eigen::Vector3f x1p;Eigen::Vector3f x2p;Eigen::Vector3f x3p;x1p ={ x - x1.x(), y - x1.y(), 0};x2p = { x - x2.x(), y - x2.y(), 0 };x3p = { x - x3.x(), y - x3.y(), 0 };// 向量叉乘,取z轴判断正负float crs1 = x1x2.cross(x1p).z();float crs2 = x2x3.cross(x2p).z();float crs3 = x3x1.cross(x3p).z();return (crs1 > 0 && crs2 > 0 && crs3 > 0) || (crs1 < 0 && crs2 < 0 && crs3 < 0);
}

2.对场景内的三角形做 z-buffer 深度缓冲

/// <summary>
/// Screen space rasterization
/// </summary>
/// <param name="t">the triangle need to rasterize</param>
void rst::rasterizer::rasterize_triangle(const Triangle& t) {auto v = t.toVector4();// compute the bounding boxint max_x = MAX(v[0].x(), MAX(v[1].x(), v[2].x()));int max_y = MAX(v[0].y(), MAX(v[1].y(), v[2].y()));int min_x = MIN(v[0].x(), MIN(v[1].x(), v[2].x()));int min_y = MIN(v[0].y(), MIN(v[1].y(), v[2].y()));for (int x1 = min_x; x1 <= max_x; x1++) {for (int y1 = min_y; y1 <= max_y; y1++) {if (insideTriangle(x1 + 0.5, y1 + 0.5,t.v)) {// 计算点在三角形内的中心坐标,关于下面的插值算法可参考:https://zhuanlan.zhihu.com/p/140926917auto [alpha, beta, gamma] = computeBarycentric2D(x1, y1, 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 (depth_buf[get_index(x1, y1)] > z_interpolated) {depth_buf[get_index(x1, y1)] = z_interpolated;// 更新 z-buffer 深度值set_pixel({ (float)x1,(float)y1,1 }, t.getColor()); // 更新 frame-buffer 颜色值}}}}
}

3.MSAA处理:

/// <summary>
/// Screen space rasterization(super sampling)
/// </summary>
/// <param name="t">the triangle need to rasterize</param>
void rst::rasterizer::super_rasterize_triangle(const Triangle& t) {auto v = t.toVector4();// compute the bounding boxint max_x = MAX(v[0].x(), MAX(v[1].x(), v[2].x()));int max_y = MAX(v[0].y(), MAX(v[1].y(), v[2].y()));int min_x = MIN(v[0].x(), MIN(v[1].x(), v[2].x()));int min_y = MIN(v[0].y(), MIN(v[1].y(), v[2].y()));for (int x1 = min_x; x1 <= max_x; x1++) {for (int y1 = min_y; y1 <= max_y; y1++) {int inner = 0;// 一个像素16个点进行超采样for (int sx = 0; sx < 4; sx++) {for (int sy = 0; sy < 4; sy++) {if (insideTriangle(x1 + 0.125 + 0.25 * sx, y1 + 0.125 + 0.25 * sy, t.v)) {inner++;}}}if (inner > 0) {//计算三角形重心坐标auto [alpha, beta, gamma] = computeBarycentric2D(x1, y1, 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 (depth_buf[get_index(x1, y1)] > z_interpolated) {depth_buf[get_index(x1, y1)] = z_interpolated;// 更新 z-buffer 深度值set_pixel({ (float)x1,(float)y1,1 }, t.getColor() * (inner / 16.f));// 更新 frame-buffer 颜色值}}}}
}

效果图

1.正常光栅化

2.MSAA 处理后的效果对比:

GAMES-101-个人总结归纳-Rasterization相关推荐

  1. Games 101(forth_part)

    Games 101 学习笔记 – Geometry Applications of Textures In modern GPUs , texture = memory + range query ( ...

  2. 【GAMES 101】作业3的实现和思考

    文章目录 作业要求 代码实现 rasterize_triangle phong_fragment_shader texture_fragment_shader bump_fragment_shader ...

  3. 计算机图形学新篇章——Games 101环境搭建

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.如何搭建games 101学习环境 1.visual code 配置 2.MinGW安装 3.Cmake安装 4. ...

  4. [Games 101] Lecture 06 Rasterization 2 (Antialiasing and Z-Buffering)

    Rasterization 2 (Antialiasing and Z-Buffering) Sampling theory Sampling Artifacts in Computer Graphi ...

  5. 菜鸟的GAMES图形学笔记 Lecture 6:Rasterization 2 (Antialiasing and Z-Buffering)

    资料来自 链接: GAMES:101 M李丽 Heinrich 阮一峰的网络日志 麻花团子 松下J27 阿姆斯特朗 维基百科 Sampling Artifacts(Errors/Mistakes/In ...

  6. [Games 101] Lecture 13-16 Ray Tracing

    Ray Tracing Why Ray Tracing 光栅化不能得到很好的全局光照效果 软阴影 光线弹射超过一次(间接光照) 光栅化是一个快速的近似,但是质量较低 光线追踪是准确的,但是较慢 Ras ...

  7. Games 101 shading part 03 纹理

    shading part 03 纹理映射: 重心坐标 重心坐标的计算: 使用重心坐标插值 重心坐标的缺陷 纹理的应用(Applying Textures) 纹理太小时 解决方法 - 双线性插值(Bil ...

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

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

  9. 【GAMES101 作业4】贝塞尔曲线+反走样

    一.样例函数naive_bezier解读 函数名为"简单贝塞尔曲线". 传入的参数有2,其中: const std::vector<cv::Point2f> & ...

最新文章

  1. usb PHY linux驱动
  2. XML配置文件中的Spring配置文件
  3. 前端学习(926):淘宝flexiblejs源码分析之核心原理
  4. Spring cloud Gateway(二) 一个Http请求的流程解析
  5. 老年人学摄影,装备该如何选择?
  6. Aspose for Maven 使用
  7. 风力摆控制系统,stm32f1程序,通过pid控制算法实现了风力摆摆定长直线,变长直线,一定角度摆动,定点停滞
  8. Android 4.1 Netd详细分析(一)概述与应用实例
  9. 【图形学】计算网格中两点连成的直线所经过的格子
  10. FPI厂商SoleraNetworks被Blue Coat收购
  11. 微信如何群删好友 微信群删好友的方法教程
  12. O2O之下,腾讯觊夺移动支付大数据,手Q支付出战支付宝
  13. 打开Windows系统某设置的方法有哪些?
  14. SteamVR Unity工具包(VRTK)之概览和控制器事件
  15. 机顶盒开发助手Tvbox
  16. 微软官方网站下载 Visual Studio 2019 各版本
  17. Kotlin-面向对象
  18. 如何将md文件转换为html
  19. 浅谈HTTP Adaptive Streaming技术及其前景
  20. 论文翻译:Speech Super Resolution Generative Adversarial Network

热门文章

  1. Mac M1芯片处理器能用的Bridge 2020/2019 for mac 解决M1版MAC安装BR无法安装问题 完美支持M1芯片处理器
  2. 谷歌AdMob广告接入(插屏广告)
  3. JS正则表达式实现简单的表单验证(账号,密码,手机号)
  4. 别让这些考场突发情况毁了你一整年的心血!!
  5. 第一篇,从0开始安装Ubuntu
  6. 【PTA】读入一个正整数 n,计算其各位数字之和,用汉语拼音写出和的每一位数字。c。
  7. 弘辽科技:不拼低价,95后小伙3个月从0冲上150万
  8. 星空云协同开发入门(一)
  9. ChatGPT 火爆“出圈”,谷歌员工慌了!CEO 回应:我们也有,担心声誉才没上
  10. php 文字水印换行,thinkPHP5图片加文字水印实现换行的方法