
总结计算机图形学更适合精通高等数学和线性代数的美術理论生文章目录虚拟照相机观察变换相机的控制【世界坐标系 - 相机坐标系】如何使用这个矩阵进行变换总 - 投影变换【正交投影】 - Orthographic Projection视景体裁剪体投影规范化Projection Normalization【透视投影】 - Perspective Projection【视椎体】怎么理解两种定义透视投影视见体类似于正交投影的棱台视见体 【frustum】利用视域FoVField of View定义的视见体 【perspective】投影规范化【四种正方体对比】模型变换 正交投影棱台指定视见体的透视投影 视域指定视见体的透视投影虚拟照相机观察变换投影线相交于投影中心COPCenter of Projection而COP对应于人眼或者相机镜头从COP点发出投影光线将物体投影在投影平面上而成像。只要顶点着色器输出的顶点位于裁剪体或视见体内部那么这些顶点会被送入绘制流水线后面的光栅化模块。【说人话就是东西如果在视野内那么就画出来】相机的控制如果我们加入自定义的相机姿态那么对相机的控制则尤为重要因为相机的位置和朝向将决定怎么发出投影射线而将物体投影到投影平面上。设置照相机的位置和方向当顶点经过模-视变换之后将位于相机坐标系中使用投影变换也就是说把指定的投影正交投影或透视投影应用到顶点上。并将默认的视见体内部对象变换到指定的裁剪立方体的内部【世界坐标系 - 相机坐标系】变换就是设置一个矩阵然后乘以三维顶点的坐标考虑齐次坐标系得到变换之后的坐标值。模-视变换是建模变换和观察变换的级联建模变换矩阵 将对象变换到世界坐标(一般来说建模变换矩阵是单位阵我们不需要额外处理。即m o d e l M a t r i x I 4 modelMatrixI_4modelMatrixI4)观察变换 将世界坐标转换到相机坐标对于照相机来说其初始方向通常指向z轴负方向这样才能看见位于相机前方的模型。考虑一个位于原点的对象由于照相机初始位置也在原点方向指向z轴负方向如果该对象需要在z轴正方向的投影平面在OpenGL中通常是近裁剪平面上成像那么必须要将相机沿着z轴正方向往后移动一定距离。相机移动之后的位置称为观察参考点VRPView Reference Point考虑采用规范化变换Normalization Transformation来表示相机坐标系并指定相机的位置观察平面法向量VPNView-plane Normal向上查看矢量VUPView-up Vector【正上方】只是暂时用形成平面就可以和正方向向量叉乘算出右方向向量了最后再返回来算UP向量其中VPN指定了相机的胶片平面而平面是由其法向量决定的。如果只是指定了VPN相机还可以绕VPN旋转此时我们再加上VUP就能完全固定一个相机的位置了。视点相机位置e ( e y e x , e y e y , e y e z ) e(eye_x,eye_y,eye_z )e(eyex,eyey,eyez)参考点相机指向的另一个点a ( a x , a y , a z ) a(a_x,a_y,a_z )a(ax,ay,az)那么V P N e − a VPN e-aVPNe−a归一化(normalize)n V P N ∣ V P N ∣ \mathbf{n} \frac{VPN}{|VPN|}n∣VPN∣VPN正是因为归一化后面点积这个向量便直接得出该新坐标轴上的投影其实除以了一个模长 1相机看向的是 $(0,0,0)$ 相机的上方即VUP 一直是 $(0,1,0)$ 那么做叉积×即可得出VPN ??设VUP,VPN归一化后为u \mathbf{u}u,v \mathbf{v}v通过采用u,v,n 右/上/前 即可定义出相机的观察变换矩阵旋转矩阵viewMatrix [ u 1 u 2 u 3 0 v 1 v 2 v 3 0 n 1 n 2 n 3 0 0 0 0 1 ] \text{viewMatrix} \begin{bmatrix} u_1 u_2 u_3 0 \\ v_1 v_2 v_3 0 \\ n_1 n_2 n_3 0 \\ 0 0 0 1 \end{bmatrix}viewMatrixu1v1n10u2v2n20u3v3n300001( u 1 , u 2 , u 3 ) (u1, u2, u3)(u1,u2,u3)就是新x轴向量了。我们看 当前点 的新x的值就是看在其上的投影—— 向量点积还需要将相机从坐标原点移动到视点 (因为标架坐标系是eye在原点旋转的 —— 向量投影 视图矩阵中的变换)平移矩阵T [ 1 0 0 − x 0 1 0 − y 0 0 1 − z 0 0 0 1 ] T \begin{bmatrix} 1 0 0 -x \\ 0 1 0 -y \\ 0 0 1 -z \\ 0 0 0 1 \end{bmatrix}T100001000010−x−y−z1这里的 x y z 其实就是 eye的反不过在新的标架下eye也要变换。做点积上面归一化有提及原理所以最终的相机观察矩阵viewMatrix [ u x u y u z − x u x − y u y − z u z v x v y v z − x v x − y v y − z v z n x n y n z − x n x − y n y − z n z 0 0 0 1 ] \begin{bmatrix} u_x u_y u_z -x u_x - y u_y - z u_z \\ v_x v_y v_z -x v_x - y v_y - z v_z \\ n_x n_y n_z -x n_x - y n_y - z n_z \\ 0 0 0 1 \end{bmatrix}uxvxnx0uyvyny0uzvznz0−xux−yuy−zuz−xvx−yvy−zvz−xnx−yny−znz1其他物体都乘以这个矩阵按照原先世界坐标系的位置反向移动了就移动到相机坐标系了。如何使用这个矩阵进行变换Pcamera(u,v,n)相机坐标系中的坐标 ViewMatrix*Pword(x,y,z)世界坐标系中的位置例子总 - 投影变换在经过三维物体的模-视变换后场景中的三维物体即被放在了相机能够观察到的位置。而投影变换的目的则是定义一个视景体View Volume使得视景体外多余的部分被裁减掉最终进入到投影平面上的只是视景体内的部分。投影包含正交投影Orthographic Projection和透视投影Perspective Project两种。【正交投影】 - Orthographic Projection将在世界坐标系所有单位的 z 坐标变为 0 那他们就在 x 轴和 y轴所在的平面上了或者将 x 轴和 y轴所在的平面 平移移动到哪里就只能看到哪里的“切面”那么假如有一个球你只要不切到这个球那么你看到的永远是一个圆。视景体裁剪体投影规范化Projection Normalization在OpenGL的渲染管线中定义了一个标准视景体 x ± 1 ; y ± 1 ; z ± 1 x±1;y±1;z±1x±1;y±1;z±1(使用的投影矩阵)【透视投影】 - Perspective Projection人类看到的相机拍到的二维平面却能看出三维的效果如下图比如左上角的正方体红色边应该是平行的但是无限延长会交于一点你可以去楼道观察两边的墙壁或者拍张照比划比划。【视椎体】怎么理解这就是视椎体(Frustum)表示相机能看到的区域。你可以用左右手张开地挡在自己的头前方模拟这个视野其实汽车车灯照明效果就是这样的相比于正交投影的视景体对于透视投影我们也需要设置一个视景体来裁剪三维物体如下也就是说在视景体内部的三维物体才能被投影到投影平面上剩下超出的部分则被裁减掉。在透视投影中由于投影中心在理想情况下是一个点所以形成的视景体构成一个截头椎体Frustum。两种定义透视投影视见体类似于正交投影的棱台视见体 【frustum】利用视域FoVField of View定义的视见体 【perspective】投影规范化【四种正方体对比】模型变换 正交投影棱台指定视见体的透视投影 视域指定视见体的透视投影类各种参数放在一起喽相机视角及运动轨迹观察左上 : 模型变换右上 : 正交投影左下 : 棱台指定视见体的透视投影右下 : 视域指定视见体的透视投影我们不断加大 scale对于 模型变换 来说是增大尺寸即靠近物体甚至穿透。由于相机始终看向中心最终会穿过中点看回来。如图现在看到的是背面。而对于 正交投影来说 是“减小”可视空间“选择更小的区域并铺满窗口”即只看这区域即放大了。减为负的可视空间反向放大看到的即如图x和y都变为 -x -y对于下面两个透视投影左边棱台可见看起来更大一点正是因为near离得近。见本文的“两种定义透视投影视见体”