GAMES101-现代计算机图形学学习笔记(作业02)

Assignment 02

    • GAMES101-现代计算机图形学学习笔记(作业02)
  • 作业
    • 作业描述
    • 需要补充的函数
    • 思路
    • 结果

原课程视频链接以及官网
b站视频链接: link.
课程官网链接: link.

作业

作业描述

在上次作业中,虽然我们在屏幕上画出一个线框三角形,但这看起来并不是 那么的有趣。所以这一次我们继续推进一步——在屏幕上画出一个实心三角形, 换言之,栅格化一个三角形。上一次作业中,在视口变化之后,我们调用了函数 rasterize_wireframe(const Triangle& t)。但这一次,你需要自己填写并调用函数 rasterize_triangle(const Triangle& t)。

提高篇:用 super-sampling 处理 Anti-aliasing : 你可能会注意到,当我们放大图像时,图像边缘会有锯齿感。我们可以用 super-sampling 来解决这个问题,即对每个像素进行 2 * 2 采样,并比较前后的结果 (这里 并不需要考虑像素与像素间的样本复用)。需要注意的点有,对于像素内的每一个样本都需要维护它自己的深度值,即每一个像素都需要维护一个 sample list。最后,如果你实现正确的话,你得到的三角形不应该有不正常的黑边。

需要补充的函数

rasterize_triangle(): 执行三角形栅格化算法
static bool insideTriangle(): 测试点是否在三角形内。你可以修改此函 数的定义,这意味着,你可以按照自己的方式更新返回类型或函数参数。

思路

①三角形栅格算法

作业要求已经给出了*rasterize_triangle()*函数的工作流程:

  1. 创建三角形的 2 维 bounding box。
  2. 遍历此 bounding box 内的所有像素(使用其整数索引)。然后,使用像素中心的屏幕空间坐标来检查中心点是否在三角形内。
  3. 如果在内部,则将其位置处的插值深度值 (interpolated depth value) 与深度 缓冲区 (depth buffer) 中的相应值进行比较。
  4. 如果当前点更靠近相机,请设置像素颜色并更新深度缓冲区 (depth buffer)。

老师这里要求实现的是Barycentric Algorithm(三角形栅格化),下面几个点可能需要注意一下:
①寻找三角形的bounding box:根据三角形的三个坐标,找出最大x,最小x,最大y,最小y坐标即可,注意最小x,y坐标需要取比原数小,最大x,y坐标需要取比原数大
②点是否在三角形内:只需要连接点和三角形个点,形成一系列向量,然后判断它们的叉乘结果的z值是否统一即可
③MSAA 4X 深度:把一个点看成一个格子,判断里面4个小点是否落在三角形内,然后找到其中插值的最小z值,和帧缓冲中的z值进行比较替换即可。
③MSAA 4X 颜色
判断有4个小点中有几个小点落入三角形,然后按比例对颜色进行采样即可。

光栅化函数:

//Screen space rasterization
void rst::rasterizer::rasterize_triangle(const Triangle& t) {auto v = t.toVector4();// bounding boxfloat min_x = std::min(v[0][0], std::min(v[1][0], v[2][0]));float max_x = std::max(v[0][0], std::max(v[1][0], v[2][0]));float min_y = std::min(v[0][1], std::min(v[1][1], v[2][1]));float max_y = std::max(v[0][1], std::max(v[1][1], v[2][1]));min_x = (int)std::floor(min_x);max_x = (int)std::ceil(max_x);min_y = (int)std::floor(min_y);max_y = (int)std::ceil(max_y);bool MSAA = false;//MSAA 4Xif (MSAA) {// 格子里的细分四个小点坐标std::vector<Eigen::Vector2f> pos{{0.25,0.25},{0.75,0.25},{0.25,0.75},{0.75,0.75},};for (int x = min_x; x <= max_x; x++) {for (int y = min_y; y <= max_y; y++) {// 记录最小深度float minDepth = FLT_MAX;// 四个小点中落入三角形中的点的个数int count = 0;// 对四个小点坐标进行判断 for (int i = 0; i < 4; i++) {// 小点是否在三角形内if (insideTriangle((float)x + pos[i][0], (float)y + pos[i][1], t.v)) {// 如果在,对深度z进行插值auto tup = computeBarycentric2D((float)x + pos[i][0], (float)y + pos[i][1], t.v);float alpha;float beta;float gamma;std::tie(alpha, beta, gamma) = tup;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;minDepth = std::min(minDepth, z_interpolated);count++;}}if (count != 0) {if (depth_buf[get_index(x, y)] > minDepth) {Vector3f color = t.getColor() * count / 4.0;Vector3f point(3);point << (float)x, (float)y, minDepth;// 替换深度depth_buf[get_index(x, y)] = minDepth;// 修改颜色set_pixel(point, color);}}}}}else {for (int x = min_x; x <= max_x; x++) {for (int y = min_y; y <= max_y; y++) {if (insideTriangle((float)x + 0.5, (float)y + 0.5, t.v)) {auto tup = computeBarycentric2D((float)x + 0.5, (float)y + 0.5, t.v);float alpha;float beta;float gamma;std::tie(alpha, beta, gamma) = tup;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(x, y)] > z_interpolated) {Vector3f color = t.getColor();Vector3f point(3);point << (float)x, (float)y, z_interpolated;depth_buf[get_index(x, y)] = z_interpolated;set_pixel(point, color);}}}}}
}

判断点是否位于三角形内函数

static bool insideTriangle(double x, double 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::Vector2f p;p << x, y;Eigen::Vector2f AB = _v[1].head(2) - _v[0].head(2);Eigen::Vector2f BC = _v[2].head(2) - _v[1].head(2);Eigen::Vector2f CA = _v[0].head(2) - _v[2].head(2);Eigen::Vector2f AP = p - _v[0].head(2);Eigen::Vector2f BP = p - _v[1].head(2);Eigen::Vector2f CP = p - _v[2].head(2);// 判断每个z坐标是否统一return AB[0] * AP[1] - AB[1] * AP[0] > 0 && BC[0] * BP[1] - BC[1] * BP[0] > 0&& CA[0] * CP[1] - CA[1] * CP[0] > 0;
}

结果

以下是结果:

以下依次是没有做MSAA 4X的结果和做了MSAA 4X的结果:

这个光栅化算法其实是比较慢的,一个是自己实现的问题,第二个是从bounding box来看,会扫描很多多余的像素。这里贴几个链接,里面提到了其他的光栅化算法,以后有机会可以改成其他光栅化的算法来实现:
链接: http://www.sunshine2k.de/coding/java/TriangleRasterization/TriangleRasterization.html#algo1.
https://www.thecrazyprogrammer.com/2017/01/bresenhams-line-drawing-algorithm-c-c.html.
https://blog.csdn.net/cppyin/article/details/6232453.

GAMES101-现代计算机图形学学习笔记(作业02)相关推荐

  1. Games101计算机图形学学习笔记:线性代数-向量

    目录 一.标量与向量 1.标量 2.向量 1.向量的方向 2.向量的长度 3.向量的计算 1.向量加法 2.向量的减法 3.向量的乘法 1.点乘 1.在图形学中我们经常使用点乘来计算两个向量的夹角,比 ...

  2. 计算机图形学学习笔记——Whitted-Style Ray Tracing(GAMES101作业5讲解)

    计算机图形学学习笔记--Whitted-Style Ray Tracing GAMES101作业5讲解 遍历所有的像素生成光线 光线与平面求交 遍历所有的像素生成光线 关于作业五中如何遍历所有的像素, ...

  3. GAMES101课程学习笔记—Lec 02:Linear Algebra 线性代数回顾

    GAMES101课程学习笔记-Lec 02:Linear Algebra 线性代数回顾 0 图形学的依赖学科 1 向量 1.1 点乘 1.2 叉乘 2 矩阵 本节课知识比较基础,大学课程里应该都学过, ...

  4. GAMES101-现代计算机图形学学习笔记(作业07)

    GAMES101-现代计算机图形学学习笔记(作业07) Assignment 07 GAMES101-现代计算机图形学学习笔记(作业07) 作业 作业描述 思路 结果 原课程视频链接以及官网 b站视频 ...

  5. GAMES101-现代计算机图形学学习笔记(作业01)

    GAMES101-现代计算机图形学学习笔记(作业01) Assignment 01 GAMES101-现代计算机图形学学习笔记(作业01) 作业 作业描述 需要补充的函数 思路 结果 原课程视频链接以 ...

  6. GAMES101-现代计算机图形学学习笔记(作业03)

    GAMES101-现代计算机图形学学习笔记(作业03) Assignment 03 GAMES101-现代计算机图形学学习笔记(作业03) 作业 作业描述 思路 原课程视频链接以及官网 b站视频链接: ...

  7. 计算机图形学 学习笔记(五):多边形裁剪(Suther land-Hodgeman),文字裁剪

    接上文 计算机图形学 学习笔记(四):直线裁剪算法:Cohen-Suther land,中点分割法,Liang-Barsky 光栅图形学算法 3.4 多边形裁剪 之前上一篇文章中,我们介绍了直线段的裁 ...

  8. 计算机图形学 学习笔记(七):二维图形变换:平移,比例,旋转,坐标变换等

    接上文 计算机图形学 学习笔记(六):消隐算法:Z-buffer,区间扫描线,Warnock,光栅图形学小结 在图形学中,有两大基本工具:向量分析,图形变换.本文将重点讲解向量和二维图形的变换. 5. ...

  9. Liunx学习笔记 - 07 - 02 正则表达式与文件格式化处理

    Liunx学习笔记 - 07 - 02 正则表达式与文件格式化处理 1 前言:啥是正则表达式 简单来讲,正则表达式是处理字符串的方法,它是以行为单位来进行字符串的处理行为,正则表达式通过一些特殊符号的 ...

最新文章

  1. 编写Makefile中遇到的各种奇葩问题汇总
  2. linux存储--dup和dup2函数解析(十八)
  3. Requires: libstdc++.so.6(GLIBCXX_3.4.15)
  4. Nginx模块开发入门
  5. SQL注入攻击再度肆虐殃及大量网站
  6. 开源oracle client,oracle client安装与配置
  7. 构建时预渲染:网页首帧优化实践
  8. 米斯特白帽培训讲义(v2)漏洞篇 文件上传
  9. ecshop ipdel.php,去除Ecshop后台调用api.ecshop.com官网后门代码
  10. java字符串怎么拼接字符串_Java中String使用+ 拼接字符串的原理是什么?
  11. 线程安全的atomic wrapper classes例子
  12. watch解放你的双手
  13. 基于springboot+vue的旅游信息(旅游线路)网站(前后端分离)
  14. 计算机主板 g41,g41主板bios设置方法
  15. android 六边形简书,水波浪贝塞尔效果(六边形)
  16. 西安交通大学计算机学院贾宇轩,CCF西安交通大学学生分会成立
  17. virtualhackinglabs靶机 NATURAL 10.12.1.77
  18. 【热搜】想卷深度学习必会的10题【最全AI面经】
  19. Unity Shader之燃烧消散效果
  20. linux复制操作 cp: -r not specified; omitting directory XXX 错误

热门文章

  1. 微信群助手机器人如何使用?哪家群助手好用?
  2. 不平等博弈_不平等与全球性大流行:完美的风暴?
  3. 从技术宝库到云上机遇:华为云开天aPaaS的“修路记”
  4. 使用豆瓣安装python包(以numpy为例)
  5. 人工智能两大技术驱动力
  6. 为什么是百度先造出了“知识型网红”
  7. jquery按钮和回车键绑定
  8. 2022年废纸价格预测
  9. 教你用U盘安装原版Win7系统详细步骤
  10. 华硕x450vb黑苹果系统拯救与安装