我的博客和笔记我的博客和笔记
首页
文章
  • TurboLink
  • TinyEncrypt
  • UnrealStyleGuide
  • AxTrace
  • Cyclone
  • 数学相关
  • 图形学
  • 密码学
  • 编程语言
关于
GitHub
首页
文章
  • TurboLink
  • TinyEncrypt
  • UnrealStyleGuide
  • AxTrace
  • Cyclone
  • 数学相关
  • 图形学
  • 密码学
  • 编程语言
关于
GitHub
  • 我的文章

    • 从抛币协议到智能合约

      • Part1
      • Part2
    • JPEG算法解密

      • Part1
      • Part2
      • Part3
      • Part4
      • Part5
      • Github
    • SPH算法简介

      • Part1
      • Part2
      • Part3
      • Part4
      • Github
    • 赌博中的数学:Martingle策略
    • 如何生成一个随机的圆形
    • 一个简单的DH密钥协商算法的实现
    • 如何计算线段和圆的交点
    • 一道数学趣题
    • 斐波那契数列和1/89
    • 匀速贝塞尔曲线运动的实现

      • Part1
      • Part2
  • 开源项目

    • TurboLink
    • TinyEncrypt
    • UnrealStyleGuide
    • AxTrace
    • Cyclone
  • 学习笔记

    • 数学相关

      • 常用数学符号
      • 群
      • 数论(一)
      • 数论(二)
      • 数论(三)
      • 概率
    • 密码学

      • RSA
      • 抛币协议
      • 智能扑克协议
    • 图形学

      • 数学基础

        • 矢量
        • 矩阵
        • 立体角
        • 几何变换(一)
        • 几何变换(二)
        • 法线变换
        • 摄像机变换
          • 8. 视图变换管线概览
          • 9. 摄像机视图变换(Viewing/Camera Transformation)
            • 9.1 定义
            • 9.2 计算
          • 10. 透视投影变换(Perspective Projective Transformations)
            • 10.1 定义
            • 10.2 求解过程
          • 11. 正交投影变换(Orthogonal Projection Transformations)
            • 11.1 定义
            • 11.2 求解过程
      • 光照模型

        • 传统光照模型
        • 光度学
        • 双向反射分布函数(BRDF)
        • 微平面理论(一)
        • 微平面理论(二)
        • 微平面理论(三)
        • 光照方程
      • 环境光渲染

        • 环境光渲染(一)
        • 环境光渲染(二)
    • 编程语言

      • JavaScript

        • 环境搭建
        • 基本语法
        • 函数
        • 对象和类

几何变换(四)


8. 视图变换管线概览

一个物体从独立的物体最终转换为2D图像,期间经过如下坐标变换

  • Modeling transformation: 由局部坐标系(Local Space)转换为世界坐标系(World Space)
  • Viewing transformation: 由世界坐标系(World Space)转换为摄像机坐标系(View Space)
  • Projection transformation: 由摄像机坐标系(View Space)转换为标准设备坐标系NDC(Normalized Device Coordinate)
  • Viewport transformation: 由NDC坐标系转换为视口坐标系(Screen coordinate System)

9. 摄像机视图变换(Viewing/Camera Transformation)

9.1 定义

视图变换是将物体的世界坐标系转换到摄像机的坐标系

摄像机坐标系以观察点(eye)为原点,向前方向为-z轴,x轴指向右侧(右手坐标系) 所以

z→′=eye−lookatx→′=up→×z→′y→′=z→′×x→′

9.2 计算

根据坐标系变换公式,设摄像机在世界坐标系中的位置为e,摄像机的三个轴的单位轴向量为i′→,j′→,k′→视图变换矩阵为

Mview=[ix′iy′iz′−e→⋅i→′jx′jy′jz′−e→⋅j→′kx′ky′kz′−e→⋅k→′0001]

10. 透视投影变换(Perspective Projective Transformations)

10.1 定义

投影变换是将物体从摄像机坐标系转换到标准设备坐标系(NDC),也就是坐标值在一个[−1,1]3的盒子里(Canonical view volume) 可以将这个过程分为两步,首先构造一个坐标转换,将摄像机的摄影范围构成的视锥体(Frustum)变形成一个立方体(Cuboid),然后再将这个立方体转化为成标准设备坐标系下(NDC)的标准观察体CCV(Canonical View Volume)

NDC坐标系在不同的系统上有不同的约定,在DirectX中,近平面到远平面映射到[0,1],在OpenGL则是把近平面到远平面映射到[−1,1],但一般都把NDC坐标系设为左手坐标系。

10.2 求解过程

10.2.1 从视锥体到立方体

设摄像机坐标系中的点p(x,y,z),转换后的坐标为(x′,y′,z′),由定义可知p投影到摄像机近裁剪面上的点为p′(x′,y′),由相似三角形可知

y′=nyzx′=nxz

设这个转换矩阵为Mpersp→ortho, 可知

Mpersp→ortho[xyz1]=[nxznyzz′1]

对于表示一个点的其次坐标,所有数值乘以一个同样的数,所表达的意义相同,所以[nx/z,ny/z,z′,1]=[nx,ny,z′z,z],这里先暂时忽略z轴,可以得到

Mpersp→ortho[xyz1]=[nxny?z]

由此可以推断出,这个矩阵的第1,2和4行

[n0000n00????0010][xyz1]=[nxny?z]

考虑特殊情况,近平面上的任意一点[x,y,n]经过这个矩阵转换后

[n0000n00????0010][xyn1]=[nxny?n]

由于近平面上的点经过转换后坐标不变,所以[nx,ny,?,n]=[x,y,n,1],而[x,y,n,1]作为其次坐标,所有数值都乘以n,可以得到[x,y,n,1]==[nx,ny,n2,n],所以

[n0000n00????0010][xyn1]=[nxnyn2n]

同理,远平面上的任意一个点[x,y,f,1]转换后为[x′,y′,f,1],可以得到

[n0000n00????0010][xyf1]=[x′y′f2n]

由此可知,第三行的数值和x,y无关,一定是形如[0,0,A,B]这样的形式,且

An+B=n2Af+B=f2

可以得到

A=f+nB=−nf

得到这个转换矩阵为

Mpersp→ortho=[n0000n0000f+n−nf0010]

10.2.2 从立方体到标准观察体

这一步相对简单很多,只要将观察体的中心的z挪到原点,做一定的放缩,并且将z轴反转即可

Mortho→cvv=[1000010000−100001][2/w00002/h00002/(n−f)00001][10000100001−(n+f)/20001]=[2/w00002/h0000−2/(n−f)(n+f)/(n−f)0001]

10.2.3 合并后的矩阵

最终得到合并后的投影矩阵为

Mpersp→cvv=Mortho→cvvMpersp→ortho=[2nw00002nh0000−n+fn−f2nfn−f0010]

在大部分工程项目中,摄像机的输入参数一般是如下几个

  • 宽高比 aspect=w/h
  • 视场角fov,tan⁡(fov/2)=−h/2n
  • 近裁剪距离 near=|n|=−n
  • 远裁剪距离 far=|f|=−f

将这些值带入上面的公式,可以得到

Mpersp→cvv=[−1aspect.tan⁡(fov/2)0000−1tan⁡(fov/2)0000−near+farnear−far−2near.farnear−far0010]

一般来说,当针对一个空间点做矩阵转换时,如果M[ux,uy,uz,1]T=[vx,vy,vz,1]T,那么

(kM)[ux,uy,uz,1]T=k[vx,vy,vz,1]T=[kvx,kvy,kvz,k]T=[vx,vy,vz,1]T

可知kM在针对空间点转换矩阵中等同于M,所以为了表达方便,经常将上面得到的这个矩阵乘以-1,得到

Mpersp→cvv=[1aspect⋅tan⁡(fov/2)00001tan⁡(fov/2)0000near+farnear−far2near⋅farnear−far00−10]

有时候也会使用Zero-To-One的CVV坐标,也就是z轴是从0到1,这种情况下的转换矩阵为:

Mpersp→cvv=[1aspect⋅tan⁡(fov/2)00001tan⁡(fov/2)0000farnear−farnear⋅farnear−far00−10]

10.2.4 深度插值

设摄像机坐标系中有一个线段(x1,z1),(x2,z2),在摄像机近平面上的投影为(x1′,n),(x2′,n),线段上有一点为(x,z),投影为(x′,n) 可知

xx′=znx=zx′n

设线段的方程为ax+bz=c,带入可得

azx′n+bz=c1z=ax′cn+bc

当投影点x′在投影线段上线性移动时,x′=(1−t)x1′+tx2′,可得

1z=acn((1−t)x1′+tx2′)+bc=(ax1′cn+bc)(1−t)+(ax2′cn+bc)t=1z1(1−t)+1z2t

也就是说,当投影点x′在投影线段上线性移动时,原线段上的点的深度值的倒数是线性变换的

11. 正交投影变换(Orthogonal Projection Transformations)

11.1 定义

正交投影没有“远大近小”的效果

11.2 求解过程

相比透视投影,正交投影只需要将一个立方体形状的摄影范围最终映射到标准设备坐标系(NDC)下的一个标准立方体(Cuboid)即可

Mortho→cvv=[1000010000−100001][2/(r−l)00002/(t−b)00002/(n−f)00001][100−(l+r)/2010−(t+b)/2001−(n+f)/20001]=[2/(r−l)00(l+r)/(l−r)02/(t−b)0(b+t)/(b−t)00−2/(n−f)(n+f)/(n−f)0001]

同理,在工程中一般标注一个正交投影摄像机的主要参数如下

  • 近裁剪距离 near=|n|=−n
  • 远裁剪距离 far=|f|=−f
  • 左侧裁剪面坐标 left=l
  • 右侧裁剪面坐标 left=l
  • 上侧裁剪面坐标 top=t
  • 下侧裁剪面坐标 bottom=t 带入上面的公式可以得到
Mortho→cvv=[2right−left00left+rightleft−right02top−bottom0bottom+topbottom−top002near−farnear+farnear−far0001]
Prev
法线变换