渲染管线整个流程如下:
首先是顶点输入,通过模型变换,相机变换和投影变换变换到一个标准坐标系中ndc(
模型变换
模型变换有最基本平移旋转和尺度变换,推倒下次写
(x,y,z)表示当前坐标,(x’,y’,z’)表示转换后的坐标,其次坐标公式表示如下:
- 平移变换
⎡⎣⎢⎢⎢x′y′z′1⎤⎦⎥⎥⎥=⎡⎣⎢⎢⎢⎢100001000010txtytz1⎤⎦⎥⎥⎥⎥⎡⎣⎢⎢⎢xyz1⎤⎦⎥⎥⎥ - 旋转变换
- x轴旋转
⎡⎣⎢⎢⎢x′y′z′1⎤⎦⎥⎥⎥=⎡⎣⎢⎢⎢10000cosθxsinθx00−sinθxcosθx00001⎤⎦⎥⎥⎥⎡⎣⎢⎢⎢xyz1⎤⎦⎥⎥⎥ - y轴旋转
⎡⎣⎢⎢⎢x′y′z′1⎤⎦⎥⎥⎥=⎡⎣⎢⎢⎢⎢cosθy0−sinθy00100sinθy0cosθy00001⎤⎦⎥⎥⎥⎥⎡⎣⎢⎢⎢xyz1⎤⎦⎥⎥⎥ - z轴旋转
⎡⎣⎢⎢⎢x′y′z′1⎤⎦⎥⎥⎥=⎡⎣⎢⎢⎢cosθzsinθz00−sinθzcosθz0000100001⎤⎦⎥⎥⎥⎡⎣⎢⎢⎢xyz1⎤⎦⎥⎥⎥
- x轴旋转
相机变换
假设右手坐标系,与opengl一致看向-z轴,如下
相对于世界的相机观察如下:
相机y轴代表view up向量,相机x轴代表view side向量,-z轴代表了朝向,可以代表物体和相机的距离。
计算相机矩阵有二种方法:
- 相机相对原点的位置E,相机的朝向
vdir 和vup ,都是单位化过,vside=vdir×vup ,如果不知道vup ,通常程序会设置一个垂直向上的方向vworld_up ,比如(0,1,0)。
根据施密特正交:
计算
vup=vworld_up−(vworld_up⋅vdir)vdir
注意当vworld_up 和vdir 方向一致的时候(vworld_up⋅vdir)vdir=1⋅vdir 得到vup=0 vworldup 和vdir 方向相反也是得到0
如果采用这种方法要避免world_up与观察方向一致。
解决方法是出现这种情况是指定任意的一个向量,比如i,j 。 - 知道E和三个旋转值roll,pitch ,yaw,可以直接得到相机矩阵
把世界坐标转换到相机坐标:Mworld→view
通常我们直接求解从世界坐标系转换到相机坐标系的矩阵比较困难,但是找到一个从相机坐标系到世界坐标系的转换矩阵比较Mview→world
即得到这个矩阵后,对它求逆(invert())即可。
假设一开始世界坐标(黑色基)与相机坐标系(红色基)重合,相机相对世界坐标先旋转后平移到图3,把小人转换到相机坐标系,先进行一个逆平移,再进行一个逆旋转即可得到,
即相机到世界的变换通过一个旋转和一个平移的仿射变换
记原点到相机位置的向量记为vpos
假设旋转的三个列向量量为u,v,w
Mview→world=TR=[i,j,k,vpos][u,v,w,1]Mview→world=M−1view→world=([E0Tvpos1][R0T01])−1=[R−10T−(R−1vpos)1]=[RT0T−(RTvpos)1]
通常R为正交矩阵即R−1=RT
光照
下次写
投影变换
投影定义
用一个线性变换把n空间的点变换到m空间(m
视锥
通常视锥把空间限制在一个6面的突面体,在这个体内的物体会被渲染或者一个截断无限金字塔。