-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This reverts commit c5dd3d3.
- Loading branch information
Showing
172 changed files
with
18,884 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
这里会整理GAMES101的各个assignments的代码以及相关的知识 | ||
|
||
* [Assignment1](assignment1.md) | ||
* [Assignment2](assignment2.md) | ||
* [Assignment3](assignment3.md) | ||
* [Assignment4](assignment4.md) | ||
* [Assignment5](assignment5.md) | ||
* [Assignment6](assignment6.md) | ||
* [Assignment7](assignment7.md) | ||
|
||
games101的assignment更新到此为止,assignment8是物理模拟相关的,暂时先不更了~ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
--- | ||
title: GAMES101-assignment1-画三角形 | ||
date: 2021-10-24 | ||
tags: [GAMES101] | ||
--- | ||
# Assignment1 | ||
|
||
## 运行结果 | ||
|
||
关于三角形颠倒的解决方法,请见 [结果出现上下颠倒,怎么办?只加一个负号即可 – 计算机图形学与混合现实研讨会 (games-cn.org)](http://games-cn.org/forums/topic/结果出现上下颠倒,怎么办?只加一个负号即可/) | ||
|
||
<img src="https://raw.githubusercontent.com/ljhgpp/whatisthis/main/static/image-20211024134106868.png" alt="image-20211024134106868" style="zoom: 50%;" /> | ||
|
||
## 实现细节 | ||
|
||
详细代码请见:[详细代码](https://github.com/LJHG/GAMES101-assignments) | ||
|
||
实现了main.cpp中的**get_model_matrix**, **get_rotation**, **get_projection_matrix**函数。 | ||
|
||
其中每一个的实现基本都能在下面的相关知识找到对应,无非就是把矩阵用代码写出来了而已。 | ||
|
||
这里记录一个需要注意的点,就是在**get_projection_matrix**函数中,在设置**n**和**f**(近平面和远平面)时,需要加一个负号: | ||
|
||
```cpp | ||
float n = -zNear; | ||
float f = -zFar; | ||
``` | ||
|
||
|
||
|
||
|
||
# 相关知识 | ||
|
||
|
||
|
||
## 关于三维的变换 | ||
|
||
### 一般的旋转变换 | ||
|
||
[旋转变换(一)旋转矩阵_Frank的专栏-CSDN博客_旋转变换矩阵](https://blog.csdn.net/csxiaoshui/article/details/65446125) | ||
|
||
### 绕任意轴的旋转变换 | ||
|
||
<img src="https://raw.githubusercontent.com/ljhgpp/whatisthis/main/static/image-20211017163952680.png" alt="image-20211017163952680" style="zoom: 33%;" /> | ||
|
||
## MVP | ||
|
||
### M: Model transformation | ||
|
||
模型变化,**应该**就是指模型的变化。包括平移、旋转、放缩等等操作。 | ||
|
||
在本次的作业中指的就是绕z轴旋转,这对应一个变换矩阵。 | ||
|
||
|
||
|
||
### V: View transformation | ||
|
||
视图变换,指的就是从相机出发观测物体,那么就需要将相机移动到原点,并且面朝-z方向,向上方向为y轴正方向。 | ||
|
||
将相机移动后,我们需要也对物体做一个移动,来保持相对位置不变。所以最后的结果就是,我们直接假定相机在原点,面朝-z方向,向上方向为y轴正方向,然后**只对物体做这个变换**就行了。 | ||
|
||
<img src="https://raw.githubusercontent.com/ljhgpp/whatisthis/main/static/image-20211017141934274.png" alt="image-20211017141934274" style="zoom:50%;" /> | ||
|
||
该变换分为两步: | ||
|
||
这里我们把视图变换的矩阵令为 $$M_{view}$$ ,平移矩阵令为 $$T_{view}$$ ,旋转矩阵令为 $$R_{view}$$ | ||
|
||
1. 将相机移动到原点 | ||
|
||
平移矩阵为 $$T_{view}$$ | ||
|
||
<img src="https://raw.githubusercontent.com/ljhgpp/whatisthis/main/static/image-20211017135851689.png" alt="image-20211017135851689" style="zoom:50%;" /> | ||
|
||
2. 将相机旋转到面朝-z方向,且上方为y正方向。 | ||
|
||
直接对$$R_{view}$$ 进行求解比较困难,所以我们转而去求它的逆变换,即将处于原点,面向-z,上朝y的相机旋转到当前的相机位置,用$$R_{view}^{-1}$$表示,那么有: | ||
|
||
<img src="https://raw.githubusercontent.com/ljhgpp/whatisthis/main/static/image-20211017142628026.png" alt="image-20211017142628026" style="zoom: 67%;" /> | ||
|
||
因为旋转矩阵是一个正交矩阵,所以矩阵的逆等于矩阵的转置,因此我们可以求得$$R_{view}$$: | ||
|
||
<img src="https://raw.githubusercontent.com/ljhgpp/whatisthis/main/static/image-20211017142711735.png" alt="image-20211017142711735" style="zoom:67%;" /> | ||
|
||
因为模型变换和视图变化都是在物体上进行变化,所以一般我们把他们一起叫做**模型视图变换**。 | ||
|
||
|
||
|
||
### P:Perspective projection | ||
|
||
#### 正交投影(Orthographic projection) | ||
|
||
正交投影就是在空间中确定一个立方体 (用来表示相机的可视区域),对应六个面在不同坐标轴下的距离为right, left, top, bottom, near, far,要做的事情就是把这个立方体移动到原点,并且缩放到 (-1, 1)。 | ||
|
||
<img src="https://raw.githubusercontent.com/ljhgpp/whatisthis/main/static/image-20211017144539084.png" alt="image-20211017144539084" style="zoom:50%;" /> | ||
|
||
对应的矩阵$$M_{ortho}$$ 为: | ||
|
||
<img src="https://raw.githubusercontent.com/ljhgpp/whatisthis/main/static/image-20211017144634725.png" alt="image-20211017144634725" style="zoom:67%;" /> | ||
|
||
#### 透视投影(Perspective projection) | ||
|
||
##### 矩阵推导 | ||
|
||
透视投影就是将正交投影里面的一个立方体变成了一个forstum,我们要做的就是先将这个forstum "挤" 成一个立方体,然后后续操作就和正交投影一样了。 | ||
|
||
<img src="https://raw.githubusercontent.com/ljhgpp/whatisthis/main/static/image-20211017144945299.png" style="zoom:50%;" /> | ||
|
||
其中,透视投影变换矩阵为 $$M_{persp}$$ ,我们只需要去求透视投影向正交投影的变换矩阵 $$M_{persp->ortho}$$ 即可 | ||
|
||
<img src="https://raw.githubusercontent.com/ljhgpp/whatisthis/main/static/image-20211017145049085.png" alt="image-20211017145049085" style="zoom:50%;" /> | ||
|
||
$$M_{persp->ortho}$$ 的求法比较发杂,下面贴一些图: | ||
|
||
* 对于当$$M_{persp->ortho}$$ 作用到(x,y,z,1)后,对于frostum里的每一个点,可以得到: | ||
|
||
<img src="https://raw.githubusercontent.com/ljhgpp/whatisthis/main/static/image-20211017145920777.png" alt="image-20211017145920777" style="zoom:50%;" /> | ||
|
||
* 根据这个,我们已经可以得出矩阵中的大部分元素 | ||
|
||
<img src="https://raw.githubusercontent.com/ljhgpp/whatisthis/main/static/image-20211017145933930.png" alt="image-20211017145933930" style="zoom:50%;" /> | ||
|
||
* 再根据下面标红的两个发现(近平面的点不会变,远平面的z不会变)列出公式,求解最后剩余的? | ||
|
||
<img src="https://raw.githubusercontent.com/ljhgpp/whatisthis/main/static/image-20211017145948598.png" alt="image-20211017145948598" style="zoom:50%;" /> | ||
|
||
<img src="https://raw.githubusercontent.com/ljhgpp/whatisthis/main/static/image-20211017150723015.png" alt="image-20211017150723015" style="zoom: 50%;" /> | ||
|
||
<img src="https://raw.githubusercontent.com/ljhgpp/whatisthis/main/static/image-20211017150746852.png" alt="image-20211017150746852" style="zoom:50%;" /> | ||
|
||
<img src="https://raw.githubusercontent.com/ljhgpp/whatisthis/main/static/image-20211017150800394.png" alt="image-20211017150800394" style="zoom:50%;" /> | ||
|
||
于是就求解得到$$M_{persp->ortho}$$ 了。 | ||
|
||
|
||
|
||
##### fov与aspect ratio | ||
|
||
fov是(field of view),即竖直方向的可视角度 | ||
|
||
aspect ratio是width/height | ||
|
||
只需要使用fov和aspect ratio就可以用来表示一个透视投影(n和f是给定的,所以我们再把fov和aspect ratio转换为l, r, b, t即可) | ||
|
||
|
||
|
||
<img src="https://raw.githubusercontent.com/ljhgpp/whatisthis/main/static/image-20211017155422637.png" alt="image-20211017155422637" style="zoom:50%;" /> | ||
|
||
<img src="https://raw.githubusercontent.com/ljhgpp/whatisthis/main/static/image-20211017155555652.png" alt="image-20211017155555652" style="zoom: 50%;" /> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
--- | ||
title: GAMES101-assignment2-ZBuffuer | ||
date: 2021-11-11 | ||
tags: [GAMES101] | ||
--- | ||
# Assignment2 | ||
|
||
## 运行结果 | ||
|
||
<img src="https://raw.githubusercontent.com/ljhgpp/whatisthis/main/static/image-20220101175340666.png" alt="image-20220101175340666" style="zoom:50%;" /> | ||
|
||
|
||
|
||
|
||
|
||
## 实现细节 | ||
|
||
[详细代码](https://github.com/LJHG/GAMES101-assignments) | ||
我认为这次的assignment的重点有三个: | ||
|
||
1. 三角形内的判断 | ||
2. 三角形边界的确定 | ||
3. 深度buffer | ||
|
||
|
||
|
||
### 1. 三角形内的判断 | ||
|
||
判断一个点是否在三角形内是通过叉乘来判断的,假设一个点为**P**,我们与三角形的三个顶点相连,并分别令为**PA**,**PB**,**PC**,那么需要计算**PAPB**, **PBPC**, **PCPA**的叉乘,只要三个结果同号,那么该点就在三角形内。这里需要注意一下叉乘的顺序,倘若把**PCPA**写为**PAPC**,结果就会大不相同。 | ||
|
||
```cpp | ||
static bool insideTriangle(int x, int y, const Vector3f* _v) | ||
{ | ||
//TODO : Implement this function to check if the point (x, y) is inside the triangle | ||
|
||
//suppose the coordinate of p is (x,y) | ||
|
||
x = x + 0.5f; | ||
y = y + 0.5f; | ||
std::pair<float,float> pa = std::make_pair(_v[0][0]-x, _v[0][1]-y); | ||
std::pair<float,float> pb = std::make_pair(_v[1][0]-x, _v[1][1]-y); | ||
std::pair<float,float> pc = std::make_pair(_v[2][0]-x, _v[2][1]-y); | ||
|
||
float papb = cross_product(pa,pb); | ||
float pbpc = cross_product(pb,pc); | ||
float pcpa = cross_product(pc,pa); | ||
|
||
if( (papb > 0 && pbpc > 0 && pcpa >0) || (papb < 0 && pbpc < 0 && pcpa < 0) ) | ||
return true; | ||
return false; | ||
} | ||
``` | ||
### 2. 三角形边界的确定 | ||
<img src="https://raw.githubusercontent.com/ljhgpp/whatisthis/main/static/image-20211025231838941.png" alt="image-20211025231838941" style="zoom: 67%;" /> | ||
通过对三角形的边界进行确认,可以加速光栅化的过程,具体代码如下: | ||
```cpp | ||
//确定bounding box的坐标 | ||
int left = std::min(v[0][0],std::min(v[1][0],v[2][0])); | ||
int bottom = std::min(v[0][1],std::min(v[1][1],v[2][1])); | ||
int right = std::max(v[0][0],std::max(v[1][0],v[2][0])) + 1 ; //向上取整 | ||
int top = std::max(v[0][1],std::max(v[1][1],v[2][1])) + 1; | ||
``` | ||
|
||
|
||
|
||
### 3. 深度buffer | ||
|
||
代码中维护了一个**depth_buf**,如果当前要绘制的像素离摄像机近,那么才绘制,否则不绘制。具体的相关代码也很简单: | ||
|
||
```cpp | ||
int index = get_index(x,y); | ||
if(z_interpolated < depth_buf[index] ){ // if near | ||
Eigen::Vector3f point; | ||
point << x,y,z_interpolated; | ||
Eigen::Vector3f color; | ||
set_pixel(point,t.getColor()); | ||
depth_buf[index] = z_interpolated; | ||
} | ||
``` | ||
|
Oops, something went wrong.