Skip to content

Commit

Permalink
Revert "update from gitbook"
Browse files Browse the repository at this point in the history
This reverts commit c5dd3d3.
  • Loading branch information
LJHG committed Dec 28, 2024
1 parent c5dd3d3 commit 82e0fc1
Show file tree
Hide file tree
Showing 172 changed files with 18,884 additions and 0 deletions.
11 changes: 11 additions & 0 deletions CG/GAMES101/README.md
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是物理模拟相关的,暂时先不更了~
149 changes: 149 additions & 0 deletions CG/GAMES101/assignment1.md
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%;" />

86 changes: 86 additions & 0 deletions CG/GAMES101/assignment2.md
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;
}
```

Loading

0 comments on commit 82e0fc1

Please sign in to comment.