当前位置: 代码迷 >> 综合 >> 【GAMES101】透视投影
  详细解决方案

【GAMES101】透视投影

热度:29   发布时间:2023-12-29 07:26:50.0

原文链接:【GAMES101】透视投影

GAMES101作业1中编程实现一个三角形旋转投影的任务,期间配置环境、找Bug费了好几天的功夫。本期,推送一些注意的地方。

1 3D Perspective Projection

How to do perspective projection

  • First “squish” the frustum into a cuboid n→n,f→fn \rightarrow n, f \rightarrow fnn,ff (Mpersp→orthoM_{persp\rightarrow ortho}Mpersportho?)

  • Do orthographic projection (MorthoM_{ortho}Mortho?, already known!)

就是将Frustum拉成一个长方体,然后再利用正交投影进行变换。

注意:在右手系中,相机正对?z-z?z方向。这是一个坑,在编程时,应该n=?zNearn = -zNearn=?zNear

△OAC?△OBD\triangle OAC \sim \triangle OBDOAC?OBD,有
{y′=nzyx′=nzx。\left\{ \begin{aligned} y' = \frac{n}{z}y\\ x' = \frac{n}{z}x \end{aligned}\right.。 ??????y=zn?yx=zn?x?
在齐次坐标系中,,有
(xyz1)?(nzxnzyunknown1)?×z(nxnystill unknownz)\left ( \begin{matrix} x \\ y \\ z \\ 1 \end{matrix} \right ) \Longrightarrow \left ( \begin{matrix} \frac{n}{z}x \\ \frac{n}{z}y \\ \text{unknown} \\ 1 \end{matrix} \right ) \Longrightarrow^{\times z} \left ( \begin{matrix} nx \\ ny \\ \text{still unknown} \\ z \end{matrix} \right ) ?????xyz1????????????zn?xzn?yunknown1???????×z?????nxnystill unknownz??????
因此
KaTeX parse error: No such environment: equation* at position 8: \begin{?e?q?u?a?t?i?o?n?*?}?M_{persp\righta…
Mpersp→orthoM_{persp\rightarrow ortho}Mpersportho?如下
Mpersp→ortho=(n0000n00????0010)M_{persp\rightarrow ortho} = \left ( \begin{matrix} n & 0 & 0 & 0 \\ 0 & n & 0 & 0 \\ ? & ? & ? & ? \\ 0 & 0 & 1 & 0 \end{matrix}\right ) Mpersportho?=?????n00?0n0?001?000??????

Observation: the third row is responsible for z’z’z

  • Any point on the near plane will not change
  • Any point’s zzz on the far plane will not change
  • Near plane

Mpersp→ortho(xyn1)=(xyn1)M_{persp\rightarrow ortho} \left ( \begin{matrix}x \\ y \\ n \\ 1\end{matrix}\right ) = \left ( \begin{matrix}x \\ y \\ n \\ 1\end{matrix}\right ) Mpersportho??????xyn1??????=?????xyn1??????

所以Mpersp→orthoM_{persp\rightarrow ortho}Mpersportho?第三行为(0,0,A,B)(0, 0, A, B)(0,0,A,B)

  • Far plane

Mpersp→ortho(00f1)=(00f1)M_{persp\rightarrow ortho}\left ( \begin{matrix}0 \\ 0 \\ f \\ 1\end{matrix}\right ) = \left ( \begin{matrix}0 \\ 0 \\ f \\ 1\end{matrix}\right ) Mpersportho??????00f1??????=?????00f1??????

综上
{An2+B=nAf2+B=f。\left\{ \begin{aligned}A n^2 + B = n\\A f^2 + B = f\end{aligned}\right.。 { An2+B=nAf2+B=f?
解得
{A=n+fB=?n×f。\left\{ \begin{aligned}A &= n + f\\ B &= - n \times f\end{aligned}\right.。 { AB?=n+f=?n×f?

2 Orthographic Projection

In general

  • We want to map a cuboid [l,r]×[b,t]×[f,n][l, r] \times [b, t] \times [f, n][l,r]×[b,t]×[f,n] to the canonical cube [?1,1]3[-1,1]^3[?1,1]3.

Slightly different orders (to the “simple way”)

需要两部操作:

  • Center cuboid by translating
  • Scale into “canonical” cube

因此
Mortho=(2r?l00002t?b00002n?f)00001)(000?r+l2000?t+b2000?n+f20001)M_{ortho} = \left ( \begin{matrix} \frac{2}{r - l} & 0 & 0 & 0 \\ 0 & \frac{2}{t - b} & 0 & 0 \\ 0 & 0 & \frac{2}{n - f}) & 0\\ 0 & 0 & 0 & 1\end{matrix}\right ) \left ( \begin{matrix} 0 & 0 & 0 & -\frac{r + l}{2} \\ 0 & 0 & 0 & -\frac{t + b}{2} \\ 0 & 0 & 0 & -\frac{n + f}{2} \\ 0 & 0 & 0 & 1\end{matrix}\right ) Mortho?=?????r?l2?000?0t?b2?00?00n?f2?)0?0001???????????0000?0000?0000??2r+l??2t+b??2n+f?1??????

3. Filed of View

Filed of View如下

How to convert from fovYfovYfovY and aspect to l,r,b,tl, r, b, tl,r,b,t?

易得
{t=tan?(fovY2)∣n∣,b=?tr=aspect×t,l=?r。\left\{ \begin{aligned}t &= \tan(\frac{fovY}{2}) | n |, &~b = -t\\ r &= aspect \times t, ~ &l = -r\end{aligned}\right.。 ????tr?=tan(2fovY?)n,=aspect×t, ? b=?tl=?r?
综上所述,透视投影矩阵
Mpersp=Mortho×Mpersp→ortho=(2r?l00002t?b00002n?f)00001)(000?r+l2000?t+b2000?n+f20001)(n0000n0000n+f?n×f0010)\begin{aligned}M_{persp}=&M_{ortho} \times M_{persp\rightarrow ortho} \\=&\left ( \begin{matrix} \frac{2}{r - l} & 0 & 0 & 0 \\ 0 & \frac{2}{t - b} & 0 & 0 \\ 0 & 0 & \frac{2}{n - f}) & 0\\ 0 & 0 & 0 & 1\end{matrix}\right ) \\&\left ( \begin{matrix} 0 & 0 & 0 & -\frac{r + l}{2} \\ 0 & 0 & 0 & -\frac{t + b}{2} \\ 0 & 0 & 0 & -\frac{n + f}{2} \\ 0 & 0 & 0 & 1\end{matrix}\right ) \\&\left ( \begin{matrix}n & 0 & 0 & 0 \\ 0 & n & 0 & 0 \\ 0 & 0 & n + f & - n \times f \\ 0 & 0 & 1 & 0\end{matrix}\right )\end{aligned} Mpersp?==?Mortho?×Mpersportho??????r?l2?000?0t?b2?00?00n?f2?)0?0001???????????0000?0000?0000??2r+l??2t+b??2n+f?1???????????n000?0n00?00n+f1?00?n×f0???????

Eigen::Matrix4f get_model_matrix(float rotation_angle)
{Eigen::Matrix4f model = Eigen::Matrix4f::Identity();// TODO: Implement this function// Create the model matrix for rotating the triangle around the Z axis.// Then return it.double rotation_radian = rotation_angle * MY_PI / 180;model << std::cos(rotation_radian), -std::sin(rotation_radian), 0, 0,std::sin(rotation_radian), std::cos(rotation_radian), 0, 0,0, 0, 1, 0,0, 0, 0, 1;   return model;
}Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio,float zNear, float zFar)
{// Students will implement this functionEigen::Matrix4f projection = Eigen::Matrix4f::Identity();// TODO: Implement this function// Create the projection matrix for the given parameters.// Then return it.float n = -zNear;float f = -zFar;float t = std::abs(n) * std::tan(.5f * eye_fov * MY_PI / 180);float b = -t;float r = aspect_ratio * t;float l = -r;Eigen::Matrix4f perspective_to_orthogonal = Eigen::Matrix4f::Identity();perspective_to_orthogonal << n, 0, 0, 0,0, n, 0, 0,0, 0, n + f, - n * f,0, 0, 1, 0;Eigen::Matrix4f orthogonal_projection = Eigen::Matrix4f::Identity();orthogonal_projection << 2.f/(r-l), 0, 0, 0,0, 2.f/(t-b), 0, 0,0, 0, 2.f/(n-f), 0,0, 0, 0, 1;projection = orthogonal_projection * perspective_to_orthogonal;return projection;
}