GAMES101:现代计算机图形学入门(Chapter5 光栅化1(三角形遍历))迅猛式学习笔记(附Homework 0)
文章目录
- Homework 0
- 配置Eigen库环境
- Eigen 样例代码
- 作业描述
- CMakeLists.txt
- 透视投影
- 屏幕空间
- 示波管
- 早期显示设备CRT:隔行扫描技术简单介绍
- 现代显示器:
- LCD显示器(液晶显示器Liquid Crystal Display)
- LED显示器(发光二极管Light Emitting diode)
- Electrophoretic显示器(墨水屏)黑白、刷新率低
- 三角形为啥广泛应用?
- 如何将三角形转化为一个一个的像素?
- 简单近似采样
- 点是否在三角形内?
- 点刚好在边上怎么处理?
- 包围盒
课程作业和代码仓库

Homework 0
#include <cmath>
#include <iostream>int main(){float a = 1.0, b = 2.0;std::cout << a << std::endl;std::cout << a / b << std::endl;std::cout << std::sqrt(a) << std::endl;// 反余弦(Arc Cosine)是余弦函数的反函数,通常表示为 acos(x)。// 它的作用是给定一个余弦值,返回一个角度(以弧度为单位),这个角度的余弦值等于给定的数值。// acos(1) 返回 0,因为 cos(0) = 1// acos(0) 返回 π/2(约为 1.5708),因为 cos(π/2) = 0// acos(-1) 返回 π(约为 3.1416),因为 cos(π) = -1std::cout << std::acos(-1) << std::endl;// 角度转换成弧度std::cout << std::sin(30.0 / 180.0 * std::acos(-1)) << std::endl;return 0;
}
配置Eigen库环境
ubuntu@VM-12-15-ubuntu:~/GAMES101/hw0$ sudo apt-get install libeigen3-dev
Eigen 样例代码
#include <eigen3/Eigen/Core>
#include <cmath>
#include <iostream>int main() {// Example of vectorstd::cout << "Example of vector \n";// vector definitionEigen::Vector3f v(1.0f,2.0f,3.0f);Eigen::Vector3f w(1.0f,0.0f,0.0f);// vector outputstd::cout << "Example of output \n";std::cout << v << std::endl;// vector addstd::cout << "Example of add \n";std::cout << v + w << std::endl;// vector scalar multiplystd::cout << "Example of scalar multiply \n";std::cout << v * 3.0f << std::endl;std::cout << 2.0f * v << std::endl;}
上述关于 Vector 的使用样例展示了如何定义一个三维浮点向量并且进行输出、加减、数乘,请自行根据数乘的形式与向量点积的形式探索点积的用法。
#include <eigen3/Eigen/Core>
#include <cmath>
#include <iostream>int main() {// Example of matrixstd::cout << "Example of matrix \n";// matrix definition// 定义了两个 3x3 的矩阵 i 和 j,元素类型为 float。Eigen::Matrix3f i, j;// 使用 << 操作符初始化矩阵 i/*1.0 2.0 3.04.0 5.0 6.07.0 8.0 9.0*/i << 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0;j << 2.0, 3.0, 1.0, 4.0, 6.0, 5.0, 9.0, 7.0, 8.0;// matrix outputstd::cout << "Example of output \n";std::cout << i << std::endl;// matrix add i + j// matrix scalar multiply i * 2.0// matrix multiply i * j// matrix multiply vector i * v}
上述关于 Matrix 的使用样例展示了如何定一个三维浮点矩阵进行输出,请
自行根据注释与 Vector 部分的经验探索矩阵加减、数乘、矩阵乘法、矩阵乘向
量的用法。
作业描述
CMakeLists.txt
cmake_minimum_required (VERSION 2.8.11)
project (Transformation)find_package(Eigen3 REQUIRED)
include_directories(EIGEN3_INCLUDE_DIR)add_executable (Transformation main.cpp)
在进行了上节课的操作之后,所有物体都处在了[-1,1]³的立方体中,接下来就要把他画在屏幕上,这一步就叫做光栅化
在做透视投影时候需要将一个四棱梯挤压成正方体,就需要先定义一个视锥(四棱锥)
那么如何定义视锥呢?
透视投影
怎么定义三维空间的近平面的left、right、bottom、top?
从摄像机看向一个地方,我们把它当作近平面,宽和高是可以定义的,所以宽高比就是可以定义的
- 宽高比 Aspect ratio
- 可视角度 FOV (垂直角度和水平角度可以互相转换)
通过以上两点即可定义一个视锥
模型、视图、投影变换最后都是把数据变换到一个标准立方体,那这个立方体最终是要显示到我们的屏幕上的,那么我们需要定义好屏幕。在图形学中,屏幕就认为是一个装了像素的二维数组。如数组大小1920*1080
像素是最小单位,每个像素由RBG构成
光栅(德语:屏幕的意思)
光栅化就是画在屏幕的意思
像素(picture element的缩写)
暂时理解成一个一个相同颜色的小方块
颜色是红绿蓝的混合
屏幕空间
屏幕坐标系如下图
像素的坐标以左下角为准,如图中蓝色像素坐标为(2,1)
像素的中心为(x+0.5,y+0.5)
如何将[-1,1]³中的东西显示到屏幕上呢?
暂时忽略z
如果只将[-1,1]²中的东西显示到[0,width] x [0,height],那么就很简单了
做个缩放并平移就可以,这个变换就被称为视口变换
立方体的中心点位于坐标轴的原点(0,0) 现在屏幕显示空间的中心点是(width/2,height/2),所以立方体原点点需要移动(width/2 - 0, height/2 - 0)
示波管
早期显示设备CRT:隔行扫描技术简单介绍
以前的显示设备要成像,都是在屏幕上画很多线,画满整个屏幕就形成了一帧画面
隔行扫描就是说
在第一帧只画1、3、5等奇数线
在第二帧只画2、4、6等偶数线
利用人眼的视觉残留特性,这样人们即发现不了画面的异常,还能使机器工作量减半
如今还有某些视频压缩技术采用了这个思想
(但是隔行扫描会造成严重的画面撕裂,特别是对高速运动的画面来说)
现代显示器:
显存(Frame Buffer)
LCD显示器(液晶显示器Liquid Crystal Display)
不通电的时候,液晶不旋转,垂直的方向的光无法从水平的偏振片射出
通电后,液晶旋转,带动光旋转,然后就能通过偏振片,显示出来
LED显示器(发光二极管Light Emitting diode)
Electrophoretic显示器(墨水屏)黑白、刷新率低
三角形为啥广泛应用?
三角形是最基本的多边形,没有比三角形边更少的多边形
其他多边形都可以拆分为三角形
三角形必定在一个平面内
容易定义三角形的里外
三角形的三个点定义好后,三角形内任意一点可以通过线性的插值来计算得到(重心坐标的插值方法)
如:定义好三个点的颜色,三角形内任意一点的颜色可以通过三个点的颜色来进行插值计算得到
如何将三角形转化为一个一个的像素?
简单近似采样
给定一个连续的函数f(x),当x等于1时得到的f(1)就是1的采样
所以采样就是把一个函数离散化的过程
只要有一个定义在屏幕空间的函数,那么我们就能算出来不同像素中心的值是多少
我们要采样的东西就是
给定一个三角形,在像素的中心进行采样,来判断中心是否落在三角形内
逐像素遍历,判断该像素中心是否在三角形内部,输出到屏幕显示
点是否在三角形内?
叉积
点刚好在边上怎么处理?
不做处理(这套课程做法)
或者特殊处理。要么算在三角形内,要么不算
包围盒
但是遍历所有像素开销太大,如下图中白色那一列的像素根本没有碰到三角形,所以只要遍历蓝色区域就可以了
我们知道三角形三个顶点的坐标,有了Xmin,Ymin,Xmax,Ymax就可以得到蓝色的区域
蓝色区域就叫做包围盒(轴向包围盒/BoundingBox/AABB)
下图是看每一行的左右边界,适用于细长的三角形,所占面积不大但是包围盒很大的那种三角形
上图右边为bayer pattern
屏幕叫三基色,打印是三原色
(😄 眼镜一摘,这就是完美的三角形)
采样完成后,因为每个像素都是最小单位,像素内的颜色必须一样,所以我们会得到这样一副图
这看起来和初始的三角形差别很大,有一个个的明显锯齿(Jaggies/Aliasing)
下节课就会学习图形学中的重大技术,反走样aka抗锯齿!
之后我会持续更新,如果喜欢我的文章,请记得一键三连哦,点赞关注收藏,你的每一个赞每一份关注每一次收藏都将是我前进路上的无限动力 !!!↖(▔▽▔)↗感谢支持!