v4vendeta's homepage

home | project | blog| other

光栅化软渲染器_几何阶段

将三维模型显示在屏幕上一般需要以下几个步骤

模型坐标变换

我们所建立的坐标系是世界坐标系,渲染的物体在世界坐标系中的位置是要人为规定的,每个模型都有自己独立的坐标系,第一步就是将物体在模型坐标系的坐标转换成世界坐标系的坐标

可以用将点左乘平移和旋转矩阵来达到目的

平移和旋转的次序不同,变换的结果也不同(矩阵乘法运算无交换律)

Model矩阵 \(\\M=R(\alpha) T(t)\)

视图变换

我们只需要渲染在摄像机视野范围内的物体

我们希望 \(\vec{eyepos}-\vec {at}\)指向\(z\)轴负方向,即相机朝向的方向是屏幕里侧

构建View矩阵

已知三个向量\(eyepos,at,up\) 根据空间几何的知识可以推算出视图坐标系的坐标基 \(\\zaxis=eyepos-at\\ xaxis=up\times zaxis\\ yaxis=zaxis\times xaxis\) \(\\V=\begin{bmatrix} xaxis_x&xaxis_y&xaxis_z&0\\ yaxis_x&yaxis_y&yaxis_z&0\\ zaxis_x&zaxis_y&zaxis_z&0\\ 0&0&0&1 \end{bmatrix}\) 将摄像机平移到原点 \(\\V=\begin{bmatrix} xaxis_x&xaxis_y&xaxis_z&-dot(xaxis,eyepos)\\ yaxis_x&yaxis_y&yaxis_z&-dot(yaxis,eyepos)\\ zaxis_x&zaxis_y&zaxis_z&-dot(zaxis,eyepos)\\ 0&0&0&1 \end{bmatrix}\)

实际管线中是把世界坐标中的物体转换到摄像机坐标系中,因此要左乘V的逆矩阵(\(V^{-1}V^{-T}=I,V^T=V^{-1}\)) \(\\View=V^{-1}=\begin{bmatrix} xaxis_x&yaxis_x&zaxis_x&0\\ xaxis_y&yaxis_y&zaxis_y&0\\ xaxis_z&yaxis_z&zaxis_z&0\\ -dot(xaxis,eyepos)&-dot(yaxis,eyepos)&-dot(zaxis,eyepos)&1 \end{bmatrix}\)

投影变换

投影变换我们仅考虑透视投影,我们的摄像机所看到的范围是一个视锥体

设投影变换前的点$p(px,py,pz)$,第一步我们将视锥体内的点映射到近平面,根据相似三角形得到下面两个等式(z坐标均为负值) \(\frac{px}{pz}=\frac{px'}{z_{near}}\\ \frac{py}{pz}=\frac{py'}{z_{near}}\\\)

将矩形内的x,y映射成[-1,1] \(\frac{py'}{H}=\frac{py''}{2}\\ py''=\frac{py}{pz}\frac{1}{tan(\frac{fov}{2})}\\\) \(\frac{px'}{H·aspect\_ratio}=\frac{px''}{2}\\ px''=\frac{px}{pz}\frac{1}{tan(\frac{fov}{2})·aspect\_ratio}\)

这样我们就获得了变换后的x,y坐标,也就得到透视矩阵的前两行 我们希望w保存z坐标,即w=-z \(\\\begin{bmatrix} \frac{1}{tan(\frac{fov}{2})·aspect\_ratio}&0&0&0\\ 0&\frac{1}{tan(\frac{fov}{2})}&0&0\\ .&.&.&.\\ .&.&-1&. \end{bmatrix}\)

当Frustum内的点投影到近剪裁平面的时候,所有位于线段p’p上的点,最终都会投影到p’点。

我们当然可以直接取p点的z值,不过在图形API中,为了方便光栅化阶段对屏幕空间的坐标插值,将z映射为1/z的非线性形式,将z’‘写成1/z的一次表达式形式,如下 \(\\z''=\frac{a\ pz+b}{-pz}\)

将z端点带入,近平面z=near时为-1,z=far时为1

解得 \(\\a=\frac{-(z_{near}+z_{far})}{z_{far}-z_{near}}\\ b=\frac{-2z_{near}z_{far}}{z_{far}-z_{near}}\)

最终的透视投影矩阵 \(\\P_{perspective}=\begin{bmatrix} \frac{1}{aspect\_ratio·tan(\frac{fov}{2})}&0&0&0\\ 0&\frac{1}{tan(\frac{fov}{2})}&0&0&\\ 0&0&\frac{-(z_{near}+z_{far})}{z_{far}-z_{near}}&\frac{-2z_{near}z_{far}}{z_{far}-z_{near}}\\ 0&0&-1&0 \end{bmatrix}\)

裁剪

裁剪这一步的作用是提高渲染效率,剔除裁剪空间外部的图形,如果空间边缘分割了某个图形,将其分裂成数个小三角形再进行下一步渲染

透视除法

齐次坐标的意义

在欧几里得空间内,两条平行的线是永远无法相交的

然而,在投影空间中,情况就不再如此,例如,当火车铁路远离眼睛时,上图的铁路变得越来越窄。最后,两个平行导轨在地平线上相遇,这个点的距离无穷大

为了从同裁剪坐标(x,y,w)转换为笛卡尔坐标,我们只需将x和y 除以w; \(\\ \begin{bmatrix}x\\ y\\z \end{bmatrix} =\begin{bmatrix} \frac{x}{z}\\ \frac{y}{z}\\ \frac{z}{z} \end{bmatrix}\)

屏幕映射

将区间为[-1,1]的x,y坐标映射到屏幕空间上 \(\\x=\frac{1}{2}w*(x+1)\\ y=\frac{1}{2}h*(y+1)\)

以上这些步骤也是渲染管线中几何阶段的主要步骤,下一章我们将介绍光栅化的过程

reference:

《Real-Time Rendering Fourth Edition》 https://www.zhihu.com/question/38356223

.. ... ...