【CG】计算机图形学(Computer Graphics)基础(其壹)

0 学习视频

B站GAMES101-现代计算机图形学入门-闫令琪

1 什么是计算机图形学

1.1 什么是好的画面?

画面足够亮。如果全局光照做的好,整个画面就会亮,看起来很舒服。

1.2 计算机图形学涉及到的领域

  1. 数学(透视)投影、曲线,表面
  2. 物理的照明和阴影
  3. 表示/操作3D中的形状
  4. 动画/仿真
  5. 硬件编程/写3D应用

1.3 为什么学计算机图形学?

  1. 创造并与真实虚拟世界交互
  2. 需要理解物理世界的所有方面
  3. 产生新的计算方法,展示方式,技术

1.4 计算机图形学的应用领域

  1. Video Games(游戏):不同的游戏风格。
  2. Movies(电影):特效是最简单的图形学应用。
  3. Animations(动画):模拟动画中的动效粒子、毛发等。
  4. Design(设计):灵活的设计效果和交互效果。
  5. Visualization(可视化):操纵可视化的信息变为视觉信息。
  6. Virtual Reality(虚拟现实):将现实中的一切放入VR眼镜。
  7. Digital Illustration(板绘):2D的笔触呈现3D的画面。
  8. Simulation(模拟):模拟一些常见的自然现象。
  9. GUI(Graphical User Interfaces,图形用户界面):使用图形的方式与用户交互。
  10. Typography(字体):矢量的字体可无线放大而不模糊。

1.5 课程概要

  1. Rasterization:光栅化

    • 定义:把三维空间中的几何形体显示在屏幕上。

    • 实时——每秒钟能够生成30幅画面/帧/FPS(Frame Per Second)

      否则是离线。

  2. Curves and Meshes:曲线和网格

    • 如何表示一条光滑的曲线,如何表示曲面,如何用简单的曲面通过细分的方法表现更复杂的曲面,如何保证图形的拓扑结构
  3. Ray Tracing:光线追踪

    • 动画和电影中着重使用,虽然慢,但效果好
    • trade off:为了达成既定的效果,不得不牺牲某些东西
  4. Animation/Simulation:动画/仿真

    • 关键帧动画
    • 弹簧-滑块系统

1.6 计算机视觉(CV) VS 计算机图形学(CG)

在这里插入图片描述

1.7 IDE(Integrated Development Environment)集成开发环境

  • 推荐的:

    • VS/VS Code
    • Qt Creator
  • 不推荐的:

    • CLion,Eclipse
    • Sublime Text,Vi/Vim,Emacs(编辑器)

1.8 图形学依赖学科

图形学依赖于:

  • 基础数学
    • 线性代数
    • 微积分
    • 统计
  • 基础物理
    • 光学
    • 力学
  • 其他
    • 信号处理
    • 数值分析
  • 还有一些美学

2 线性代数

  • 向量(点乘、叉乘……)
    • 空间中表示一个点就是一种向量表示法
  • 矩阵(矩阵和矩阵乘、矩阵和向量乘)
    • 像平移、旋转、缩放一个物体的操作可以转化为矩阵与向量的乘

2.1 向量(Vectors)

2.1.1 向量的基本知识

  • 数学上习惯称为向量,物理上习惯称为矢量

  • 表示:

    • a ⃗ \vec{a} a a
    • 在这里插入图片描述
    • 终点向量-起始向量: A B ⃗ \vec{AB} AB = B - A
  • 两个基本要素:方向、大小(长度)

  • 没有绝对的起始位置

2.1.2 向量的正则化(Vector Normalization)

  • 向量的长度写作 ∣ ∣ a ⃗ ∣ ∣ ||\vec a|| ∣∣a ∣∣
  • 单位向量
    • 长度为1的向量
    • 得到一个向量的单位向量(正则化/归一化/标准化): a ^ \widehat{a} a = a ⃗ \vec{a} a / ∣ ∣ a ⃗ ∣ ∣ ||\vec a|| ∣∣a ∣∣
    • 用于表示方向

2.1.3 向量的加法(Vector Addition)

在这里插入图片描述

  • 几何:平行四边形法则 & 三角形法则
  • 代数:只需简单地加向量坐标即可
2.1.3.1 笛卡尔坐标(Cartesian Coordinates)

在这里插入图片描述

  • X和Y可以是任何(通常是正交的单位)向量

A = ( x y ) A = \left(\begin {array}{c} x \\ y \\ \end{array}\right) A=(xy)      A T = ( x , y ) A^T= \left(\begin {array}{c} x,y \end{array}\right) AT=(x,y)      ∣ ∣ a ⃗ ∣ ∣ = x 2 + y 2 ||\vec a|| = \sqrt{x^2+y^2} ∣∣a ∣∣=x2+y2

2.1.4 向量的乘法(Vector Multiplication)

2.1.4.1 点乘(Dot(scalar) Product):得到一个标量(数)

a ⃗ ⋅ b ⃗ = ∣ ∣ a ⃗ ∣ ∣ ∣ ∣ b ⃗ ∣ ∣ cos ⁡ θ \vec{a} \cdot \vec{b} = ||\vec a||||\vec b||\cos\theta a b =∣∣a ∣∣∣∣b ∣∣cosθ

cos ⁡ θ = a ⃗ ⋅ b ⃗ ∣ ∣ a ⃗ ∣ ∣ ∣ ∣ b ⃗ ∣ ∣ \cos\theta = \frac{\vec{a} \cdot \vec{b}}{||\vec a||||\vec b||} cosθ=∣∣a ∣∣∣∣b ∣∣a b

  • 对于单位向量:

    • cos ⁡ θ = a ^ ⋅ b ^ \cos\theta = \widehat{a}\cdot \widehat{b} cosθ=a b
  • 性质:

    • 交换律: a ⃗ ⋅ b ⃗ = b ⃗ ⋅ a ⃗ \vec{a} \cdot \vec{b} = \vec{b} \cdot \vec{a} a b =b a
    • 结合律: a ⃗ ⋅ ( b ⃗ + c ⃗ ) = a ⃗ ⋅ b ⃗ + a ⃗ ⋅ c ⃗ \vec{a} \cdot (\vec{b} + \vec{c}) = \vec{a} \cdot \vec{b} + \vec{a} \cdot \vec{c} a (b +c )=a b +a c
    • 分配律: ( k a ⃗ ) ⋅ b ⃗ = a ⃗ ⋅ ( k b ⃗ ) = k ( a ⃗ ⋅ b ⃗ ) (k\vec{a}) \cdot \vec{b} = \vec{a} \cdot (k\vec{b}) = k(\vec{a} \cdot \vec{b}) (ka )b =a (kb )=k(a b )
2.1.4.1.1 笛卡尔坐标系中的点乘
  • 对应元素相乘,然后相加

    • 2D

      a ⃗ ⋅ b ⃗ = ( x a y a ) ⋅ ( x b y b ) = x a ⋅ x b + y a ⋅ y b \vec{a} \cdot \vec{b} = \left(\begin {array}{c} x_a \\ y_a \\ \end{array}\right)\cdot\left(\begin {array}{c} x_b \\ y_b \\ \end{array}\right)=x_a\cdot x_b + y_a \cdot y_b a b =(xaya)(xbyb)=xaxb+yayb

    • 3D

      a ⃗ ⋅ b ⃗ = ( x a y a z a ) ⋅ ( x b y b z b ) = x a ⋅ x b + y a ⋅ y b + z a ⋅ z b \vec{a} \cdot \vec{b} = \left(\begin {array}{c} x_a \\ y_a \\ z_a \\ \end{array}\right)\cdot\left(\begin {array}{c} x_b \\ y_b \\ z_b \\ \end{array}\right)=x_a\cdot x_b + y_a \cdot y_b + z_a \cdot z_b a b = xayaza xbybzb =xaxb+yayb+zazb

2.1.4.1.2 图形学中的点乘
  • 点乘用来得到两个向量间的夹角

    • 如,光源和表面间夹角的余弦值
  • 点乘用来得到一个向量在另一个向量上的投影

  • 点乘用来测量两个方向/向量有多接近。

    • 金属反光的高光范围
  • 分解向量。

  • 确定前/后方向:点乘的正负。

    • 在这里插入图片描述
2.1.4.1.2.1 点乘用来计算投影

在这里插入图片描述

  • b ⃗ ⊥ \vec{b}_\bot b b ⃗ \vec{b} b a ⃗ \vec{a} a 上的投影
    • b ⃗ ⊥ \vec{b}_\bot b 必须沿着 a ⃗ \vec{a} a (或沿着 a ^ \widehat{a} a )
      • b ⃗ ⊥ = k a ^ \vec{b}_\bot = k\widehat{a} b =ka
    • 它的长度k是多少?
      • k = ∣ ∣ b ⃗ ⊥ ∣ ∣ = ∣ ∣ b ⃗ ∣ ∣ cos ⁡ θ k= ||\vec{b}_\bot||= ||\vec{b}||\cos\theta k=∣∣b ∣∣=∣∣b ∣∣cosθ
2.1.4.2 叉乘(Cross(vector) Product):得到一个向量

在这里插入图片描述

  • 叉乘计算出的向量与两个初始向量正交
  • 由右手定则确定的方向(点赞:四指表示从a到b,得到拇指的方向就是叉乘结果的方向)
  • 在后来用于构造3D坐标系

性质(右手坐标系):

x ⃗ × y ⃗ = + z ⃗ \vec{x}\times\vec{y}=+\vec{z} x ×y =+z
y ⃗ × x ⃗ = − z ⃗ \vec{y}\times\vec{x}=-\vec{z} y ×x =z
y ⃗ × z ⃗ = + x ⃗ \vec{y}\times\vec{z}=+\vec{x} y ×z =+x
z ⃗ × y ⃗ = − x ⃗ \vec{z}\times\vec{y}=-\vec{x} z ×y =x
z ⃗ × x ⃗ = + y ⃗ \vec{z}\times\vec{x}=+\vec{y} z ×x =+y
x ⃗ × z ⃗ = − y ⃗ \vec{x}\times\vec{z}=-\vec{y} x ×z =y

注: 一些API如OpenGL中用的是左手坐标系

叉乘没有交换律,要添一个负号:

a ⃗ × b ⃗ = − b ⃗ × a ⃗ \vec{a}\times\vec{b}=-\vec{b}\times\vec{a} a ×b =b ×a

自身叉乘自身得到长度为0的向量:

a ⃗ × a ⃗ = 0 \vec{a}\times\vec{a}=0 a ×a =0

叉乘依然满足分配律和结合律:

( k a ⃗ ) × b ⃗ = a ⃗ × ( k b ⃗ ) = k ( a ⃗ × b ⃗ ) (k\vec{a}) \times \vec{b} = \vec{a} \times (k\vec{b}) = k(\vec{a} \times \vec{b}) (ka )×b =a ×(kb )=k(a ×b )

a ⃗ × ( b ⃗ + c ⃗ ) = a ⃗ × b ⃗ + a ⃗ × c ⃗ \vec{a} \times (\vec{b} + \vec{c}) = \vec{a} \times \vec{b} + \vec{a} \times \vec{c} a ×(b +c )=a ×b +a ×c

2.1.4.2.1 笛卡尔坐标系中的叉乘

a ⃗ × b ⃗ = ( y a z b − y b z a z a x b − x a z b x a y b − y a x b ) \vec{a}\times\vec{b}= \left(\begin {array}{c} y_az_b- y_bz_a\\ z_ax_b- x_az_b \\ x_ay_b- y_ax_b \\ \end{array}\right) a ×b = yazbybzazaxbxazbxaybyaxb

向量可以用矩阵形式表示

a ⃗ × b ⃗ = A ∗ b = ( 0 − z a y a z a 0 − x a − y a x a 0 ) ( x b y b z b ) \vec{a}\times\vec{b}=A*b= \left(\begin {array}{c} 0 & -z_a & y_a\\ z_a & 0&-x_a \\ -y_a &x_a&0\\ \end{array}\right)\left(\begin {array}{c} x_b\\ y_b \\ z_b \\ \end{array}\right) a ×b =Ab= 0zayaza0xayaxa0 xbybzb

2.1.4.2.2 图形学中的叉乘

  • 确定左/右方向
    • 判定b在a的左侧还是右侧:b叉乘a:(右手螺旋定则,朝下)负值:a在b的右侧,b在a的左侧

      • a向左旋转得到b(逆时针旋转):b在a的左侧
      • a向右旋转得到b(顺时针旋转):b在a的右侧
  • 确定内部/外部
    • 判定P是否在三角形内部:内部

      • AB叉乘AP(右手螺旋定则,朝外):P在AB的左侧
      • BC叉乘BP(右手螺旋定则,朝外):P在BC的左侧
      • CA叉乘CP(右手螺旋定则,朝外):P在CA的左侧
2.1.4.2.2.1正交基础/坐标系
  • 重要的是代表点、坐标、位置
  • 通常,有多组坐标系
    • 全局,局部,世界,模型,模型的一个部分(头,手……)
  • 关键问题是在这些系统/基础间如何转换
2.1.4.2.2.2 正交坐标系
  • 3D中的任何3个向量

    ∣ ∣ u ⃗ ∣ ∣ = ∣ ∣ v ⃗ ∣ ∣ = ∣ ∣ w ⃗ ∣ ∣ = 1 ||\vec{u}||=||\vec{v}||=||\vec{w}||=1 ∣∣u ∣∣=∣∣v ∣∣=∣∣w ∣∣=1

    u ⃗ ⋅ v ⃗ = v ⃗ ⋅ w ⃗ = u ⃗ ⋅ w ⃗ = 0 \vec{u} \cdot \vec{v}=\vec{v} \cdot \vec{w}=\vec{u} \cdot \vec{w}=0 u v =v w =u w =0

    w ⃗ = u ⃗ × v ⃗ \vec{w} =\vec{u} \times \vec{v} w =u ×v (右手坐标系)

    利用投影(点乘)进行向量的分解:

    p ⃗ = ( p ⃗ ⋅ u ⃗ ) u ⃗ + ( p ⃗ ⋅ v ⃗ ) v ⃗ + ( p ⃗ ⋅ w ⃗ ) w ⃗ \vec{p} =(\vec{p}\cdot\vec{u})\vec{u}+(\vec{p}\cdot\vec{v})\vec{v}+(\vec{p}\cdot\vec{w})\vec{w} p =(p u )u +(p v )v +(p w )w

2.2 矩阵(Matrices)

  • 图形学中普遍用于表示变换(transformations)
    • 平移、旋转、缩放、错切

2.2.1 什么是矩阵

  • 带有数字的数组(m × n:m行,n列)

    • 一个3×2的矩阵:

    ( 1 3 5 2 0 4 ) \left(\begin {array}{c} 1 & 3\\ 5 & 2 \\ 0 &4\\ \end{array}\right) 150324

  • 矩阵的乘法和加法都是很简单的:对每个元素操作即可

2.2.1.1 矩阵-矩阵乘法
  • 矩阵A的列数必须和矩阵B的行数相等

    ( M × N ) ( N × P ) = ( M × P ) (M\times N)(N\times P)=(M\times P) (M×N)(N×P)=(M×P)

    ( 1 3 5 2 0 4 ) ( 3 6 9 4 2 7 8 3 ) = ( 9 27 33 13 19 44 61 26 8 28 32 12 ) \left(\begin {array}{c} 1 & 3\\ 5 & 2 \\ 0 &4\\ \end{array}\right)\left(\begin {array}{c} 3 & 6 & 9 & 4\\ 2 & 7 & 8 & 3 \\ \end{array}\right)=\left(\begin {array}{c} 9 & 27 & 33 & 13\\ 19 & 44 & 61 & 26 \\ 8 & 28 & 32 & 12 \\ \end{array}\right) 150324 (32679843)= 9198274428336132132612

  • 乘积中元素 (i,j) 是矩阵A的第i行和矩阵B的第 j 列相点乘

  • 性质

    • 不满足交换律 A B AB AB B A BA BA通常不同)

    • 结合律和分配律

      ( A B ) C = A ( B C ) (AB)C=A(BC) (AB)C=A(BC)

      A ( B + C ) = A B + A C A(B+C)=AB+AC A(B+C)=AB+AC

      ( A + B ) C = A C + B C (A+B)C=AC+BC (A+B)C=AC+BC

2.2.2.2 矩阵-向量乘法
  • 将向量当成是一个一列的矩阵(m×1)

  • 变换顶点的关键

  • 2D中关于y轴对称操作(镜像)

    ( − 1 0 0 1 ) ( x y ) = ( − x y ) \left(\begin {array}{c} -1 & 0\\ 0 & 1 \\ \end{array}\right)\left(\begin {array}{c} x \\ y \\ \end{array}\right)=\left(\begin {array}{c} -x \\ y \\ \end{array}\right) (1001)(xy)=(xy)

2.2.2.3 矩阵的转置(Transpose of a Matrix)
  • 交换行和列(ij→ji)

    ( 1 2 3 4 5 6 ) T = ( 1 3 5 2 4 6 ) \left(\begin {array}{c} 1 & 2\\ 3 & 4 \\ 5 &6\\ \end{array}\right)^T=\left(\begin {array}{c} 1 & 3 & 5\\ 2 & 4 &6\\ \end{array}\right) 135246 T=(123456)

  • 性质(乘积的转置=位置调换后分别转置再相乘)

    ( A B ) T = B T A T (AB)^T=B^TA^T (AB)T=BTAT

2.2.2.4 单位矩阵和逆矩阵

单位矩阵:对角阵(只有对角线上是非0数)

I 3 × 3 = ( 1 0 0 0 1 0 0 0 1 ) I_{3\times3}=\left(\begin {array}{c} 1 & 0 & 0\\ 0 & 1 & 0\\ 0 & 0 & 1\\ \end{array}\right) I3×3= 100010001

逆矩阵的性质与转置矩阵的性质类似。

A A − 1 = A − 1 A = I AA^{-1}=A^{-1}A=I AA1=A1A=I

A B − 1 = B − 1 A − 1 AB^{-1}=B^{-1}A^{-1} AB1=B1A1

2.2.2.5 矩阵形式的向量乘法
  • 点乘

    a ⃗ ⋅ b ⃗ = a ⃗ T b ⃗ = ( x a y a z a ) ( x b y b z b ) = ( x a x b + y a y b + z a z b ) \vec{a} \cdot \vec{b}=\vec{a} ^T \vec{b}=\left(\begin {array}{c} x_a & y_a & z_a\\ \end{array}\right)\left(\begin {array}{c} x_b \\ y_b \\ z_b \\ \end{array}\right)=(x_ax_b+y_ay_b+z_az_b) a b =a Tb =(xayaza) xbybzb =(xaxb+yayb+zazb)

  • 叉乘(向量a写成A*)

a ⃗ × b ⃗ = A ∗ b ⃗ = ( 0 − z a y a z a 0 − x a − y a x a 0 ) ( x b y b z b ) \vec{a} \times \vec{b}=A*\vec{b}=\left(\begin {array}{c} 0 & -z_a & y_a\\ z_a & 0 & -x_a\\ -y_a & x_a & 0\\ \end{array}\right)\left(\begin {array}{c} x_b \\ y_b \\ z_b \\ \end{array}\right) a ×b =Ab = 0zayaza0xayaxa0 xbybzb

2.3 变换

2.3.1 为什么学习变换

  • 模型变换(Modeling):translation,rotation,scaling
  • 视图变换(Viewing):(3D到2D)投影变换

2.3.2 2D中的变换:缩放,旋转,平移

齐次坐标系下:
Scale S ( s x , s y ) = ( s x 0 0 0 s y 0 0 0 1 ) S(s_x,s_y)=\left(\begin {array}{c} s_x & 0 & 0\\ 0 & s_y & 0\\ 0 & 0 & 1\\ \end{array}\right) S(sx,sy)= sx000sy0001

Rotation R ( α ) = ( cos ⁡ α − sin ⁡ α 0 sin ⁡ α cos ⁡ α 0 0 0 1 ) R(\alpha)=\left(\begin {array}{c} \cos\alpha & -\sin\alpha & 0\\ \sin\alpha & \cos\alpha & 0\\ 0 & 0 & 1\\ \end{array}\right) R(α)= cosαsinα0sinαcosα0001

Translation T ( t x , t y ) = ( 1 0 t x 0 1 t y 0 0 1 ) T(t_x,t_y)=\left(\begin {array}{c} 1 & 0 & t_x\\ 0 & 1 & t_y\\ 0 & 0 & 1\\ \end{array}\right) T(tx,ty)= 100010txty1

  • 用矩阵表示变换
2.3.2.1 缩放变换(Scale)
2.3.2.1.1 均匀缩放


x ′ = s x x\prime=sx x=sx

y ′ = s y y\prime=sy y=sy

[ x ′ y ′ ] = [ s 0 0 s ] [ x y ] \left[\begin {array}{c} x\prime \\ y\prime \\ \end{array}\right]=\left[\begin {array}{c} s & 0 \\ 0 & s\\ \end{array}\right]\left[\begin {array}{c} x\\ y\\ \end{array}\right] [xy]=[s00s][xy]

其中, [ s 0 0 s ] \left[\begin {array}{c} s & 0 \\ 0 & s\\ \end{array}\right] [s00s]是缩放矩阵。

2.3.2.1.2 非均匀缩放

[ x ′ y ′ ] = [ s x 0 0 s y ] [ x y ] \left[\begin {array}{c} x\prime \\ y\prime \\ \end{array}\right]=\left[\begin {array}{c} s_x & 0 \\ 0 & s_y\\ \end{array}\right]\left[\begin {array}{c} x\\ y\\ \end{array}\right] [xy]=[sx00sy][xy]

2.3.2.2 对称矩阵变换

水平翻转:
x ′ = − x x\prime=-x x=x

y ′ = y y\prime=y y=y

[ x ′ y ′ ] = [ − 1 0 0 1 ] [ x y ] \left[\begin {array}{c} x\prime \\ y\prime \\ \end{array}\right]=\left[\begin {array}{c} -1 & 0 \\ 0 & 1\\ \end{array}\right]\left[\begin {array}{c} x\\ y\\ \end{array}\right] [xy]=[1001][xy]

2.3.2.3 错切矩阵变换

  • y = 0 y=0 y=0时,水平位移为0
  • y = 1 y=1 y=1时,水平位移为a
  • 垂直方向偏移始终为0

[ x ′ y ′ ] = [ 1 a 0 1 ] [ x y ] \left[\begin {array}{c} x\prime \\ y\prime \\ \end{array}\right]=\left[\begin {array}{c} 1 & a \\ 0 & 1\\ \end{array}\right]\left[\begin {array}{c} x\\ y\\ \end{array}\right] [xy]=[10a1][xy]

2.3.2.4 2D的旋转变换

默认关于原点逆时针旋转

R θ = [ cos ⁡ θ − sin ⁡ θ sin ⁡ θ cos ⁡ θ ] R_\theta=\left[\begin {array}{c} \cos\theta & -\sin\theta \\ \sin\theta & \cos\theta\\ \end{array}\right] Rθ=[cosθsinθsinθcosθ]

推导过程:

在这里插入图片描述

旋转-θ°:

如果一个矩阵的逆等于它的转置,则称该矩阵为正交矩阵。

2.3.2.5 线性变换=矩阵变换(相同维度)

x ′ = a x + b y x\prime=ax+by x=ax+by

y ′ = c x + d y y\prime=cx+dy y=cx+dy

[ x ′ y ′ ] = [ a b c d ] [ x y ] \left[\begin {array}{c} x\prime\\ y\prime\\ \end{array}\right]=\left[\begin {array}{c} a&b\\ c&d\\ \end{array}\right]\left[\begin {array}{c} x\\ y\\ \end{array}\right] [xy]=[acbd][xy]

x ′ = M x x\prime=Mx x=Mx

2.3.3 齐次坐标系(Homogeneous coordinates)

2.3.3.1 为什么要用齐次坐标系

平移变换:

x ′ = x + t x x\prime=x+t_x x=x+tx

y ′ = y + t y y\prime=y+t_y y=y+ty

上述变换不能用矩阵形式表示。因此,平移变换不是线性变换,但是我们却不希望平移变换被当成特殊的情况考虑。

[ x ′ y ′ ] = [ a b c d ] [ x y ] + [ t x t y ] \left[\begin {array}{c} x\prime\\ y\prime\\ \end{array}\right]=\left[\begin {array}{c} a&b\\ c&d\\ \end{array}\right]\left[\begin {array}{c} x\\ y\\ \end{array}\right]+\left[\begin {array}{c} t_x\\ t_y\\ \end{array}\right] [xy]=[acbd][xy]+[txty]

2.3.3.2 解决办法:齐次坐标

添加一个维度(w维):

  • 二维的顶点 = ( x , y , 1 ) T 二维的顶点=(x,y,1)^T 二维的顶点=(x,y,1)T
  • 二维的向量 = ( x , y , 0 ) T 二维的向量=(x,y,0)^T 二维的向量=(x,y,0)T

向量具有平移不变性。加0是为了保护它。

如果结果为1或0,则为有效操作

  • v e c t o r + v e c t o r = v e c t o r vector+vector=vector vector+vector=vector
  • p o i n t − p o i n t = v e c t o r point-point=vector pointpoint=vector
  • p o i n t + v e c t o r = v e c t o r point+vector=vector point+vector=vector
  • p o i n t + p o i n t = ? ? point+point=?? point+point=??
    • p o i n t + p o i n t = 两点中点 point+point=两点中点 point+point=两点中点
2.3.3.3 平移变换的矩阵表示

( x ′ y ′ w ′ ) = ( 1 0 t x 0 1 t y 0 0 1 ) ⋅ ( x y 1 ) = ( x + t x y + t y 1 ) \left(\begin {array}{c} x\prime\\ y\prime\\ w\prime\\ \end{array}\right)=\left(\begin {array}{c} 1&0&t_x\\ 0&1&t_y\\ 0&0&1\\ \end{array}\right)\cdot\left(\begin {array}{c} x\\ y\\ 1\\ \end{array}\right)=\left(\begin {array}{c} x+t_x\\ y+t_y\\ 1\\ \end{array}\right) xyw = 100010txty1 xy1 = x+txy+ty1

2.3.3.4 在齐次坐标系中

( x y w ) \left(\begin {array}{c} x\\ y\\ w\\ \end{array}\right) xyw 表示二维中的点 ( x / w y / w 1 ) , w ≠ 0 \left(\begin {array}{c} x/w\\ y/w\\ 1\\ \end{array}\right),w≠0 x/wy/w1 w=0

2.3.3.5 仿射变换

仿射映射=线性映射+平移

( x ′ y ′ ) = ( a b c d ) ⋅ ( x y ) + ( t x t y ) \left(\begin {array}{c} x\prime\\ y\prime\\ \end{array}\right)=\left(\begin {array}{c} a&b\\ c&d\\ \end{array}\right)\cdot\left(\begin {array}{c} x\\ y\\ \end{array}\right)+\left(\begin {array}{c} t_x\\ t_y\\ \end{array}\right) (xy)=(acbd)(xy)+(txty)

仿射变换用齐次坐标形式表示:

( x ′ y ′ 1 ) = ( a b t x c d t y 0 0 1 ) ⋅ ( x y 1 ) \left(\begin {array}{c} x\prime\\ y\prime\\ 1\\ \end{array}\right)=\left(\begin {array}{c} a&b&t_x\\ c&d&t_y\\ 0&0&1\\ \end{array}\right)\cdot\left(\begin {array}{c} x\\ y\\ 1\\ \end{array}\right) xy1 = ac0bd0txty1 xy1

仿射变换中变换矩阵的最后一行永远是0 0 1,平移参数永远是写在最后一列的前两个数

2.3.3.6 逆变换

M − 1 M^{-1} M1是变换 M M M的逆变换,具有矩阵(逆矩阵)和几何(做了 M M M变换再做逆变换,相当于什么都没做)意义。

在这里插入图片描述

2.3.4 组合变换

在这里插入图片描述

先平移后旋转45°?

先旋转45°后平移!

  • 所有变换都能够通过基本变换得到

  • 变换的顺序很重要(矩阵乘法的顺序性)

    • 即矩阵乘法不满足交换律

      • R 45 ⋅ T ( 1 , 0 ) ≠ T ( 1 , 0 ) ⋅ R 45 R_{45}\cdot T_{(1,0)}≠T_{(1,0)}\cdot R_{45} R45T(1,0)=T(1,0)R45
    • 操作顺序:先旋转(在目标矩阵左侧写旋转变换矩阵,得到的结果),后平移(在旋转得到的结果矩阵左侧写平移变换矩阵)

      • 注意矩阵是从右向左逐个地应用的
        T ( 1 , 0 ) ⋅ R 45 [ x y 1 ] = [ 1 0 1 0 1 0 0 0 1 ] [ cos ⁡ 45 ° − sin ⁡ 45 ° 0 sin ⁡ 45 ° cos ⁡ 45 ° 0 0 0 1 ] [ x y 1 ] T_{(1,0)}\cdot R_{45}\left[\begin {array}{c} x\\ y\\ 1\\ \end{array}\right]=\left[\begin {array}{c} 1&0&1\\ 0&1&0\\ 0&0&1\\ \end{array}\right]\left[\begin {array}{c} \cos45\degree&-\sin45\degree&0\\ \sin45\degree&\cos45\degree&0\\ 0&0&1\\ \end{array}\right]\left[\begin {array}{c} x\\ y\\ 1\\ \end{array}\right] T(1,0)R45 xy1 = 100010101 cos45°sin45°0sin45°cos45°0001 xy1
2.3.4.1 组合变换的推广应用

仿射变换序列 A 1 , A 2 , A 3 , … A1,A2,A3,… A1A2A3

  • 按矩阵乘法组合

    • 对性能非常重要

      在这里插入图片描述

    • 矩阵乘法没有交换律,但是有结合律(先乘前面的矩阵,再乘上最后的矩阵)

2.3.4.2 分解复杂的组合变换

如何以任意一个点c为中心旋转?

  1. 将该中心点c转换为原点
  2. 旋转
  3. 平移回来(从原点移回c点)

在这里插入图片描述

矩阵表示:

T ( c ) ⋅ R ( α ) ⋅ T ( − c ) T(c)\cdot R(\alpha)\cdot T(-c) T(c)R(α)T(c)

2.3.5 3D中的变换

同样引入齐次坐标:

  • 三维的顶点 = ( x , y , z , 1 ) T 三维的顶点=(x,y,z,1)^T 三维的顶点=(x,y,z,1)T
  • 三维的向量 = ( x , y , z , 0 ) T 三维的向量=(x,y,z,0)^T 三维的向量=(x,y,z,0)T

类似的, ( x , y , z , w ) ( w ≠ 0 ) (x,y,z,w)(w≠0) (x,y,z,w)(w=0)表示三维中的点 ( x / w , y / w , z / w ) (x/w,y/w,z/w) (x/w,y/w,z/w)

使用4×4的矩阵表示仿射变换:

( x ′ y ′ z ′ 1 ) = ( a b c t x d e f t y g h i t z 0 0 0 1 ) ⋅ ( x y z 1 ) \left(\begin {array}{c} x\prime\\ y\prime\\ z\prime\\ 1\\ \end{array}\right)=\left(\begin {array}{c} a&b&c&t_x\\ d&e&f&t_y\\ g&h&i&t_z\\ 0&0&0&1\\ \end{array}\right)\cdot\left(\begin {array}{c} x\\ y\\ z\\ 1\\ \end{array}\right) xyz1 = adg0beh0cfi0txtytz1 xyz1

仿射变换中变换矩阵的最后一行永远是0 0 0 1,平移参数永远是写在最后一列的前三个数。

2.3.5.1 顺序是怎样的?

先线性变换,再平移。

2.3.5.2 3D中的缩放、平移、旋转

齐次坐标系下:
Scale S ( s x , s y , s z ) = ( s x 0 0 0 0 s y 0 0 0 0 s z 0 0 0 0 1 ) S(s_x,s_y,s_z)=\left(\begin {array}{c} s_x & 0 & 0&0\\ 0 & s_y & 0&0\\ 0 & 0 & s_z&0\\ 0 & 0 & 0&1\\ \end{array}\right) S(sx,sy,sz)= sx0000sy0000sz00001

Translation T ( t x , t y , t z ) = ( 1 0 0 t x 0 1 0 t y 0 0 1 t y 0 0 0 1 ) T(t_x,t_y,t_z)=\left(\begin {array}{c} 1 & 0 & 0&t_x\\ 0 & 1 &0& t_y\\ 0 & 0&1 & t_y\\ 0 & 0 & 0&1\\ \end{array}\right) T(tx,ty,tz)= 100001000010txtyty1

在这里插入图片描述

Rotation:绕x轴、y轴、z轴旋转
R x ( α ) = ( 1 0 0 0 0 cos ⁡ α − sin ⁡ α 0 0 sin ⁡ α cos ⁡ α 0 0 0 0 1 ) R_x(\alpha)=\left(\begin {array}{c} 1 & 0 & 0&0\\ 0 & \cos\alpha & -\sin\alpha&0\\ 0 & \sin\alpha & \cos\alpha&0\\ 0 & 0 & 0&1\\ \end{array}\right) Rx(α)= 10000cosαsinα00sinαcosα00001

R y ( α ) = ( cos ⁡ α 0 sin ⁡ α 0 0 1 0 0 − sin ⁡ α 0 cos ⁡ α 0 0 0 0 1 ) R_y(\alpha)=\left(\begin {array}{c} \cos\alpha & 0 & \sin\alpha&0\\ 0 & 1 & 0&0\\ -\sin\alpha & 0 & \cos\alpha&0\\ 0 & 0 & 0&1\\ \end{array}\right) Ry(α)= cosα0sinα00100sinα0cosα00001

R z ( α ) = ( cos ⁡ α − sin ⁡ α 0 0 sin ⁡ α cos ⁡ α 0 0 0 0 1 0 0 0 0 1 ) R_z(\alpha)=\left(\begin {array}{c} \cos\alpha & -\sin\alpha & 0&0\\ \sin\alpha & \cos\alpha & 0&0\\ 0 & 0 & 1&0\\ 0 & 0 & 0&1\\ \end{array}\right) Rz(α)= cosαsinα00sinαcosα0000100001

z z z叉乘 x x x得到 y y y,而不是 x x x叉乘 z z z,因此 R y R_y Ry看起来与 R x R_x Rx R z R_z Rz有所不同。

2.3.5.3 3D旋转组合

根据 R x R_x Rx R y R_y Ry R z R_z Rz构造任意的3D旋转:

R x , y , z ( α , β , γ ) = R x ( α ) R y ( β ) R z ( γ ) R_{x,y,z}(\alpha,\beta,\gamma)=R_x(\alpha)R_y(\beta)R_z(\gamma) Rx,y,z(α,β,γ)=Rx(α)Ry(β)Rz(γ)

  • 所谓的欧拉角

  • 常用于飞行模拟器:滚动(roll)、俯仰(pitch)、偏航(yaw)

在这里插入图片描述

2.3.5.4 罗德里格斯旋转公式
2.3.5.4.1 绕n轴旋转α角

在这里插入图片描述

2.3.5.4.2 如何推导

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.3.6 观测变换(Viewing transformation)

2.3.6.1 视图/摄像机变换(View /Camera transformation)
2.3.6.1.1 什么是视图变换

想想怎么拍一张照片(mvp变换

  • 找一个好地方并把人员组织好(模型变换
  • 找一个好的“角度”架设摄像机(视图变换
  • 茄子!(投影变换
2.3.6.1.2 如何表示视图变换

首先需要定义摄像机:

  • 位置(Position) e ⃗ \vec{e} e

  • 查看/凝视方向(Look-at / gaze direction) g ^ \widehat{g} g

  • 向上方向(Up direction) t ^ \widehat{t} t

    (假设是Perp模式去查看)

在这里插入图片描述

关键观测点(Key observation)

如果摄像机和所有的物体一起移动,那么“相片”都将是一样的

始终把摄像机视为:

  • 处在原点,以y轴方向为向上方向,看向-z轴

  • 其他物体跟随着相机移动

通过 M v i e w M_{view} Mview转换相机:

  • 所以它处在原点,以 Y Y Y轴方向为向上方向,看向 − Z -Z Z

在这里插入图片描述

M v i e w M_{view} Mview的数学表示:

M v i e w = R v i e w T v i e w M_{view}=R_{view}T_{view} Mview=RviewTview

  • e e e 转换为原点
    T v i e w = [ 1 0 0 − x e 0 1 0 − y e 0 0 1 − z e 0 0 0 1 ] T{view}=\left[\begin {array}{c} 1 & 0 & 0&-x_e\\ 0 & 1 & 0&-y_e\\ 0 & 0 & 1&-z_e\\ 0 & 0 & 0&1\\ \end{array}\right] Tview= 100001000010xeyeze1

  • g g g 旋转到 − z -z z

  • t t t 旋转到 y y y

  • ( g × t ) (g×t) (g×t) 旋转到 x x x

    在这里插入图片描述

    考虑其旋转: x x x ( g × t ) (g×t) (g×t) y y y t t t z z z − g -g g

    R v i e w − 1 = [ x g ^ × t ^ x t x − g 0 y g ^ × t ^ y t y − g 0 z g ^ × t ^ z t z − g 0 0 0 0 1 ] R^{-1}_{view}=\left[\begin {array}{c} x_{\widehat{g}\times \widehat{t}} & x_t & x_{-g}&0\\ y_{\widehat{g}\times \widehat{t}} & y_t & y_{-g}&0\\ z_{\widehat{g}\times \widehat{t}} & z_t & z_{-g}&0\\ 0 & 0 & 0&1\\ \end{array}\right] Rview1= xg ×t yg ×t zg ×t 0xtytzt0xgygzg00001 转换成 R v i e w = [ x g ^ × t ^ y g ^ × t ^ z g ^ × t ^ 0 x t y t z t 0 x − g y − g z − g 0 0 0 0 1 ] R_{view}=\left[\begin {array}{c} x_{\widehat{g}\times \widehat{t}} & y_{\widehat{g}\times \widehat{t}} & z_{\widehat{g}\times \widehat{t}}&0\\ x_t & y_t & z_t & 0\\ x_{-g} & y_{-g}&z_{-g}&0\\ 0 & 0 & 0&1\\ \end{array}\right] Rview= xg ×t xtxg0yg ×t ytyg0zg ×t ztzg00001

    正交矩阵:逆=转置

2.3.7 投影变换(Projection transformation)

2.3.7.1 计算机图形学中的投影
  • 3D到2D

  • 正交投影:常用于工程制图

    在这里插入图片描述

  • 透视投影:近大远小,与人眼成像原理相同

  • 透视投影 vs 正交投影

2.3.7.2 正交投影(Orthographic projection)
  • 一种简单的理解方式

    • 摄像机位于原点,看向 − Z -Z Z 轴,向上方向是 Y Y Y

    • 忽略掉 Z Z Z

    • 将矩形结果转换到 [ − 1 , 1 ] 2 [-1,1]^2 [1,1]2

  • 一般来说

    • 我们想映射一个长方体 [ l , r ] × [ b , t ] × [f,n] [l,r]\times[b,t]\times\textbf{[f,n]} [l,r]×[b,t]×[f,n]到“canonical(正则、规范、标准)”的立方体 [ − 1 , 1 ] 3 [-1,1]^3 [1,1]3

      • 定义一个长方体
        • [ l , r ] [l,r] [l,r] X X X轴上左<右
        • [ b , t ] [b,t] [b,t] Y Y Y轴上下<上
        • [f,n] \textbf{[f,n]} [f,n] -Z \textbf{-Z} -Z轴上远<近
      • 把该立方体的中心平移到原点
      • 缩放成“标准”立方体
    • 变换矩阵

      • 首先平移(立方体中心到原点),然后缩放(长/宽/高到2
        M o r t h o = [ 2 r − l 0 0 0 0 2 t − b 0 0 0 0 2 n − f 0 0 0 0 1 ] [ 1 0 0 − r + l 2 0 1 0 − t + b 2 0 0 1 − n + f 2 0 0 0 1 ] M_{ortho}=\left[\begin {array}{c} \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{array}\right]\left[\begin {array}{c} 1 & 0 & 0&-\frac{r+l}{2}\\ 0 &1 &0 & -\frac{t+b}{2}\\ 0 & 0&1&-\frac{n+f}{2}\\ 0 & 0 & 0&1\\ \end{array}\right] Mortho= rl20000tb20000nf200001 1000010000102r+l2t+b2n+f1
  • 注意

    • 看向 − Z -Z Z轴导致near近>far远(n>f)
    • 这就是为什么OpenGL(一个图形API)使用左手定则
2.3.7.3 透视投影(Perspective projection)
  • 常用于CG,艺术,视觉领域
  • 近大远小
  • 平行线不再平行;而是收敛到一个点

在这里插入图片描述

  • 回顾:齐次坐标的性质
    • ( x , y , z , 1 ) , ( k x , k y , k z , k ≠ 0 ) , ( x z , y z , z 2 , z ≠ 0 ) (x,y,z,1),(kx,ky,kz,k≠0),(xz,yz,z^2,z≠0) (x,y,z,1),(kx,ky,kz,k=0),(xz,yz,z2,z=0)都代表3D中相同的点 ( x , y , z ) (x,y,z) (x,y,z)
    • 例如, ( 1 , 0 , 0 , 1 ) (1,0,0,1) (1,0,0,1) ( 2 , 0 , 0 , 2 ) (2,0,0,2) (2,0,0,2)都代表 ( 1 , 0 , 0 ) (1,0,0) (1,0,0)
2.3.7.3.1 如何进行透视投影

在这里插入图片描述

  • 首先将截锥体转化(挤压)为长方体 ( n → n , f → f ) , ( M p e r s p → o r t h o ) (n→n,f→f),(M_{persp→ortho}) (nn,ff),(Mpersportho)

  • 其次做正交投影( M o r t h o M_{ortho} Mortho,已知)

    • 摄像机视锥的定义

      • 垂直视野(vertical field-of-view,fovY)和宽高比(aspect ratio)(假设对称,即l=-r,b=-t)

        在这里插入图片描述

    • 如何从fovY和宽高比得到l,r,b,t?

      在这里插入图片描述

2.3.7.3.2 如何得到变换矩阵
  • 回顾一个关键的想法:找到(挤压后)点 ( x ′ , y ′ , z ′ ) (x',y',z') (x,y,z)和原始点 ( x , y , z ) (x,y,z) (x,y,z)转换间的关系
    在这里插入图片描述
    y ′ = n 2 y y\prime=\frac{n}{2}y y=2ny     x ′ = n z x x\prime=\frac{n}{z}x x=znx

  • 齐次坐标表示:

    在这里插入图片描述

  • 因此,挤压(透视转化为正交)投影需要做的就是

    在这里插入图片描述

  • 已经足够弄清楚 M p e r s p → o r t h o M_{persp→ortho} Mpersportho的一部分值

在这里插入图片描述

  • 如何得到 M p e r s p → o r t h o M_{persp→ortho} Mpersportho的第三行?

    观察到:第三行负责 z ′ z^\prime z

    • 任何一个点在近处的平面上不会改变

      在这里插入图片描述

      • 因此,第三行的形式一定为(0 0 A B)

      在这里插入图片描述

      ​ 根据上述,可以得到:

      在这里插入图片描述

    • 任何一个点z轴在远处的平面上不会变

      取远平面的中心点

    在这里插入图片描述

    • 联立上述两式,可求得A与B:

      在这里插入图片描述

  • 最终,得到了变换矩阵 M p e r s p → o r t h o M_{persp→ortho} Mpersportho

  • 接下来

    • 做正交投影
    • M p e r s p = M o r t h o M p e r s p → o r t h o M_{persp}=M_{ortho}M_{persp→ortho} Mpersp=MorthoMpersportho

3 光栅化

3.1 规范立方体到屏幕

  • 什么是屏幕?

    • 一个像素数组
    • 数组的大小:分辨率
    • 一种典型的光栅显示
  • Raster(光栅)== 德语中屏幕的意思

    • 光栅化(Rasterize)== 把物体绘制到屏幕上
  • Pixel(像素,“picture element”的简称)

    • 目前来说,一个像素是一种具有均匀颜色的小方块
    • 颜色是(red,green,blue)的混合物
  • 定义屏幕空间

    • 屏幕的左下角位于坐标原点
    • 像素的坐标形式是(x,y),x和y都是整数
    • 像素的范围是从(0,0)到(width-1,height-1)
    • 像素(x,y)的中心坐标是(x+0.5,y+0.5)
    • 屏幕的覆盖范围是从(0,0)到(width,height)

在这里插入图片描述

  • 规范立方体到屏幕

    • 先忽略z轴
    • 在xy平面中转换: [ − 1 , 1 ] 2 [-1,1]^2 [1,1]2 [ 0 , w i d t h ] × [ 0 , h e i g h t ] [0,width]×[0,height] [0,width]×[0,height]

  • 视口变换矩阵:

    M v i e w p o r t = ( w i d t h 2 0 0 w i d t h 2 0 h e i g h t 2 0 h e i g h t 2 0 0 1 0 0 0 0 1 ) M_{viewport}=\left(\begin {array}{c} \frac{width}{2} & 0 & 0&\frac{width}{2}\\ 0 &\frac{height}{2} &0 & \frac{height}{2}\\ 0 & 0&1&0\\ 0 & 0 & 0&1\\ \end{array}\right) Mviewport= 2width00002height0000102width2height01

3.2 不同的光栅显示设备

  • Oscilloscope:示波器

  • Cathode Ray Tube(CRT):阴极射线管

    在这里插入图片描述

  • 电视——光栅显示CRT

    光栅扫描(调制强度):

    隔行扫描:用于压缩视频,但会产生画面撕裂

  • 帧缓冲区:用于光栅显示的内存

  • 平板显示屏

    • LCD(Liquid Crystal Display)显示屏(液晶显示器)

      • 原理:液晶通过自己的不同排布影响光的极化(偏振方向)

    • color LCD,OLED显示屏

  • LED(Light emitting diode,发光二极管)阵列显示屏

  • 电泳(电子墨水)显示屏:刷新率较低

3.3 光栅化三角形

3.3.1 三角形-最基础的多边形

3.3.1.1 为什么是三角形?


在这里插入图片描述

  • 大多数基本多边性都可以分解成三角形
  • 独有的属性
    • 保证是平面的
    • 内外部明确定义
    • 三角形顶点内插值定义明确(重心插值)
3.3.1.2 三角形上一些边界点如何用像素表示
  • 输入:在屏幕上三角形的位置投影
  • 输出:像素集合

在这里插入图片描述

3.3.2 像素的中心点与三角形的位置关系

3.3.2.1 采样函数

在一个点处通过采样的方式评估

采样:将一个函数离散化的过程。

例子:

	for (int x = 0; x < xmax; ++x)
		output[x] = f(x);

采样在图形学中是一个核心思想,可以采样时间(1D),区域(2D),方向(2D),CT卷(3D)。

3.3.2.2 光栅化:2D采样

在这里插入图片描述

3.3.2.3 通过采样判断是否每个像素的中心点都在三角形内部

在这里插入图片描述

3.3.2.4 定义一个返回值是布尔值的函数: i n s i d e ( t r i , x , y ) inside(tri,x,y) inside(tri,x,y)(x,y不一定是整数)

在这里插入图片描述

3.3.2.5 光栅化=采样一个2D形式函数
	for (int x = 0; x < xmax; ++x)
		for (int y = 0; y < ymax; ++y)
			image[x][y] = inside(tri,x+0.5,y+0.5);

3.3.3 回顾:采样位置

在这里插入图片描述

3.3.3.1 评估采样函数结果

在这里插入图片描述

3.3.3.2 怎么判断一个点是否在三角形内?回顾:三个叉积!

在这里插入图片描述

3.3.3.3 如果一个点恰好在三角形边界上

这个样本点是在三角形1上,还是三角形2上,还是都在?

在这里插入图片描述

要么不做处理,要么做特殊处理。

3.3.3.4 需要检查屏幕上的所有像素吗?

不需要,用一个Bounding Box!(轴向包围盒,AABB)

在这里插入图片描述

增量三角形遍历(适用于窄的、旋转一定角度的三角形)

每一行像素只遍历最左到最右在三角形内的

在这里插入图片描述

3.3.3.5 实际LCD显示屏的光栅化

在这里插入图片描述

注意RGB像素的几何形状,但在计算机图形学中,假设像素是均匀颜色的小方块。

右侧:拜尔阵列(Bayer Pattern)。

人眼对绿色更敏感,绿色像素多些。

3.3.3.6 彩色打印机的屏幕显示方式

减色系统

在这里插入图片描述

3.3.3.7 采样信号显示

在这里插入图片描述

像素填充:锯齿(Jaggies)!

在这里插入图片描述

对比:

在这里插入图片描述

原因:

采样率对于信号来说不够高,产生了信号走样(Aliasing)问题。

在这里插入图片描述

4 抗锯齿/反走样

4.1 采样理论

采样理论普遍应用于计算机图形学:

  • 光栅化:采样2D中的坐标
  • 照片:采样图片传感器平面
  • 视频:采样时间

4.1.1 采样瑕疵(Sampling Artifacts/Errors/Mistakes/Inaccuracies)

  • 锯齿(Jaggies)—— 空间中采样
  • 摩耳轮(Moiré Patterns)—— 下采样图片(空间中采样)
  • 马车车轮幻觉(假运动)Wagon Wheel Illusion(False Motion)——采样时间
  • ……

4.1.2 采样瑕疵的原因

信号变化地太快(频率高),而采样的频率太慢。

4.1.3 如何做反走样——在采样之前先做一个模糊/滤波

4.1.3.1 光栅化——采样空间中的点

在这里插入图片描述

注意已光栅化的三角形中像素值是纯红或纯白的的锯齿

4.1.3.2 光栅化——反走样采样

在这里插入图片描述

注意已光栅化的三角形中像素值取了中心值的抗锯齿边缘

4.1.3.3 点采样VS反走样
4.1.3.3.1 点采样

4.1.3.3.2 反走样

4.1.3.4 模糊与采样的顺序能否颠倒?不行!

原因?

1、为什么下采样会导致走样?

2、为什么预先模糊后采样能反走样?

4.1.4 频域(Frequency Domain)

4.1.4.1 正弦波与余弦波

4.1.4.2 频率

周期 = 频率分之一

4.1.4.3 傅里叶级数展开

任何一个周期函数,都可以把它写成一系列正弦和余弦函数的线性组合以及一个常数项。

在这里插入图片描述

f ( x ) = A 2 + 2 A cos ⁡ ( t ω ) π f(x)=\frac{A}{2}+\frac{2A\cos(t\omega)}{\pi} f(x)=2A+π2Acos(tω)

在这里插入图片描述
f ( x ) = A 2 + 2 A cos ⁡ ( t ω ) π − 2 A cos ⁡ ( 3 t ω ) 3 π f(x)=\frac{A}{2}+\frac{2A\cos(t\omega)}{\pi}-\frac{2A\cos(3t\omega)}{3\pi} f(x)=2A+π2Acos(tω)3π2Acos(3tω)

在这里插入图片描述
f ( x ) = A 2 + 2 A cos ⁡ ( t ω ) π − 2 A cos ⁡ ( 3 t ω ) 3 π + 2 A cos ⁡ ( 5 t ω ) 5 π f(x)=\frac{A}{2}+\frac{2A\cos(t\omega)}{\pi}-\frac{2A\cos(3t\omega)}{3\pi}+\frac{2A\cos(5t\omega)}{5\pi} f(x)=2A+π2Acos(tω)3π2Acos(3tω)+5π2Acos(5tω)

在这里插入图片描述
f ( x ) = A 2 + 2 A cos ⁡ ( t ω ) π − 2 A cos ⁡ ( 3 t ω ) 3 π + 2 A cos ⁡ ( 5 t ω ) 5 π − 2 A cos ⁡ ( 7 t ω ) 7 π + … f(x)=\frac{A}{2}+\frac{2A\cos(t\omega)}{\pi}-\frac{2A\cos(3t\omega)}{3\pi}+\frac{2A\cos(5t\omega)}{5\pi}-\frac{2A\cos(7t\omega)}{7\pi}+… f(x)=2A+π2Acos(tω)3π2Acos(3tω)+5π2Acos(5tω)7π2Acos(7tω)+

4.1.4.4 傅里叶变换:将信号分解为频率(时域→频域)
4.1.4.5 逆傅里叶变换:将频率合成信号


在这里插入图片描述

4.1.4.6 更高的频率需要更高频的采样

4.1.4.7 下采样导致了频率走样

高频信号采样不足:样本错误地看起来来自低频信号。

走样(aliases):两种信号采用同种采样方式得到的是一样的无法区分的结果。

4.1.5 滤波(Filtering=Getting rid of某个特定频段)

4.1.5.1 可视化图片频段(频谱)

傅里叶变换:时域→频域

4.1.5.2 仅滤去低频(边缘)——高通滤波器(只剩下高频,留下图像的边界)

在这里插入图片描述

4.1.5.3 过滤去高频(模糊)——低通滤波器(只剩下低频,留下基本信息)

在这里插入图片描述

4.1.5.4 过滤去高频和低频

在这里插入图片描述

4.1.6 滤波=卷积(=平均)Filtering = Convolution(=Averaging)

4.1.6.1 卷积

卷积:在滑动窗口的过程中,对应做点乘操作写回信号中心位置。

在这里插入图片描述
在这里插入图片描述

4.1.6.2 卷积定理

空间域中的卷积等于频域中的乘积,反之亦然

选项1:

  • 通过空间域中的卷积滤波

选项2:

  • 转换到频域(傅里叶变换)
  • 把卷积内核转换到频域(傅里叶变换),两者相乘(频域结果)
  • 转换为空间域(逆傅里叶变换)

在这里插入图片描述

4.1.6.3 滤波器(卷积和)

在这里插入图片描述

滤波器函数="低通"滤波器

在这里插入图片描述

更宽的卷积内核=较低的频率

在这里插入图片描述

4.1.7 采样=重复原始信号的频谱Sampling=Reapting Frequency Contents

在这里插入图片描述

4.1.8 走样=混叠频谱Aliasing=Mixed Frequency Contents

在这里插入图片描述

4.1.9 反走样

4.1.9.1 如何降低走样瑕疵?

选项1:提高采样频率

  • 关键是增加了傅里叶域中复制频谱之间的距离
  • 更高的分辨率显示,传感器,帧缓存……
  • 但是:代价昂贵且可能需要很高的分辨率

选项2:抗锯齿/反走样

  • 在复制频谱之前对“较窄”的频谱进行傅里叶变换
  • 即在采样前过滤掉高频(留下低频的)
4.1.9.2 反走样 = 限制,再重复

在这里插入图片描述

4.2 实际中的反锯齿

4.2.1 实际中的预滤波器(模糊)

一个1像素宽的盒状滤波器(低通,模糊)

在这里插入图片描述

4.2.2 通过在像素域中进行卷积实现反走样

解决方案:

  • 使用1像素的模糊卷积核卷积f(x,y)
    • 回顾:卷积=滤波=平均
  • 然后对每个像素的中心采样

4.2.3 通过计算平均像素值实现反走样

在光栅化一个三角形时,像素域f(x,y)内的平均值 = inside(triangle,x,y)等于三角形覆盖的像素:

在这里插入图片描述

4.2.4 通过更多的采样点反走样Antialiasing By Supersampling(MSAA)

4.2.4.1 超采样Superampling

通过采样一个像素内的多个位置并平均其值来近似估计1像素盒式滤波器的效果:
在这里插入图片描述

4.2.4.2 点采样:每个像素一个样本

在这里插入图片描述

4.2.4.3 超采样:第1步

在每个像素中取 N × N N\times N N×N 的样本:

4.2.4.4 超采样:第2步

计算每个像素“内部”的 N × N N\times N N×N样本的平均值:
在这里插入图片描述

在这里插入图片描述

4.4.4.5 超采样:结果

以下是显示器发出的相应信号:

在这里插入图片描述

4.2.5 MSAA的代价

  • 计算代价提升

4.2.6 里程碑

除了MSAA,其他反走样方法:

  • FXAA(Fast Approximate AA):快速近似反走样,是一种图像后处理操作。
  • TAA(Temporal AA):复用上一帧的信息。

4.2.7 超分辨率/超采样

  • 从低分辨率到高分辨率
  • 仍会导致“样本不足”问题
  • DLSS(Deep Learning Super Sampling):深度学习超采样

4.3 遮挡与可见性

4.3.1 画家算法

灵感来自油画家如何上色,由远及近,层层覆盖

需要对n个三角形的深度进行排序( O ( n l o g n ) O(n logn) O(nlogn)

以下三角形两两覆盖,形成了环(互相遮挡),画家算法不再适用

在这里插入图片描述

4.3.2 深度缓存(Z-buffering)

深度缓存算法是当前常用的算法。

思路:

  • 存储当前每个样本(像素)的深度值(z-value)
  • 需要一个额外的缓存区存储深度值
    • 帧缓存(frame buffer)存储颜色值
    • 深度缓存(depth buffer/z-buffer)存储深度

重要提示:

为了简单,假设z轴总是正向的

  • z越小,越近
  • z越大,越远
4.3.2.1 深度缓存例子

在这里插入图片描述

4.3.2.2 深度缓存(Z-buffer)算法

初始化深度缓存为∞

在光栅化过程中:
在这里插入图片描述

在这里插入图片描述

4.3.2.3 深度缓存(Z-buffer)算法的复杂度
  • 对于n个三角形:O(n)(假设一个一个覆盖)
  • 如何在线性时间内排序n个三角形?
    • 这里并没有排序
    • 只是记录最小值,比较
  • 深度缓存算法与绘制三角形的顺序无关,得到的结果都是一致的(假设在同一个像素的深度都是不同的(浮点型表示))

最重要的可见性算法

  • 通过所有的GPU硬件实现

5 着色

5.1 光照与阴影

5.1.1 到目前为止,我们涉及到了什么?

在这里插入图片描述

  • 物体和摄像机在世界中的位置
  • 计算物体相对于摄像机的位置
  • 投影物体到屏幕上
  • 采样三角形的覆盖范围

5.1.2 着色(Shading)的定义

  • 在Merriam-Webster字典中
    • 名词
    • 用平行线或色块表示插图或图表中的明暗
  • 在计算机图形学中
    • 将不同材质应用到不同物体的过程

5.1.3 一个简单的着色模型(ShadingsModel)——Blinn-Phong反射模型

5.1.3.1 透视观察
  • 镜面高光(直接光照)
  • 漫反射
  • 环境光照(间接光照)

在这里插入图片描述

5.1.3.2 着色是局部的

计算在特定着色点光线向摄像机反射的结果

输入:(单位向量只关注方向)

  • 观察者方向Viewer direction: v ⃗ \vec{v} v

  • 表面的法向量Surface normal: n ⃗ \vec{n} n

  • 光线方向Light direction: l ⃗ \vec{l} l (对于许多灯光)

  • 表面的参数Surface parameters(颜色,亮度,…)

在这里插入图片描述

考虑着色不考虑产生阴影!(shading ≠ shadow

5.1.3.3 漫反射
  • 光线均匀地散落

    • 对于所有地观察方向,表面颜色是相同地

    在这里插入图片描述

  • 但多少光(能量)被接收了?

    • Lanbert的余弦法则

    在这里插入图片描述

当表面有一定角度时,表面的法线方向与光照方向的夹角是 c o s θ cosθ cosθ

5.1.3.4 光的衰减

在这里插入图片描述

5.1.3.5 Lambertian(漫反射)着色
  • 着色与观察方向无关
    • L d L_d Ld:漫反射光
    • k d k_d kd:漫反射系数(颜色(R,G,B)表示)
    • ( I / r 2 ) (I/r^2) (I/r2):到达着色点的能量
    • m a x ( 0 , n ⃗ ⋅ l ⃗ ) max(0,\vec{n}·\vec{l}) max(0,n l ):被着色点吸收的能量(取最大值,表示如果点乘是负值,没物理意义,这里考虑的不是折射而是反射)

在这里插入图片描述

  • 产生漫反射效果

在这里插入图片描述

5.1.3.6 镜面高光

镜面高光的强度取决于观察方向

  • 反射方向接近镜面反射方向R

在这里插入图片描述

v ⃗ \vec{v} v (观察)方向接近于镜面反射方向 ⇔ \Leftrightarrow 法线(normal)方向与半程向量(half vector)方向接近

  • 通过单位向量点乘测量方向的“接近程度”

在这里插入图片描述

通常高光是白色,因此 k s k_s ks为(255,255,255)。

5.1.3.7 余弦的指数图

随着指数 p p p 增加,反射夹角减小。

在这里插入图片描述

产生的高光效果

在这里插入图片描述

5.1.3.8 环境光照

着色不依赖于任何东西

  • 添加不变的颜色忽略照明并填充黑色阴影
  • 这是近似的/假的!

在这里插入图片描述

5.1.3.9 Blinn-Phong反射模型

在这里插入图片描述

5.1.4 着色频率(Shading Frequencies)

在这里插入图片描述

面、点、像素应用着色(插值)。

5.1.4.1 逐三角形着色(平面着色)flat shading
  • 三角形的平面是一个平面——得到一个法向量
  • 不适用于光滑的表面

在这里插入图片描述

5.1.4.2 逐顶点着色(Gouraud shading)
  • 每一个顶点做一次着色,三角形内部的颜色通过插值求得
  • 每个顶点都有一个法向量

在这里插入图片描述

5.1.4.3 逐像素着色(Phong shading)
  • 每一个顶点做一次着色,三角形内部的颜色通过插值求得
  • 对每个像素着色
  • 不是Blinn-Phong反射模型

在这里插入图片描述

5.1.4.4 着色频率:面,顶点还是像素

在这里插入图片描述

5.1.4.5 定义逐顶点的法向量

最理想是通过潜在的几何图形得到顶点的法向量

  • 如,考虑一个球体

    在这里插入图片描述

否则必须通过三角形平面推断出顶点的法向量

  • 一个简单的方案:求顶点相邻(周围)平面法线的均值(加权平均效果更好,和三角形面积有关)

在这里插入图片描述

在这里插入图片描述

5.1.4.6 定义逐像素的法向量

对顶点的法线做重心插值

在这里插入图片描述

别忘了归一化插值方向,变成单位向量

5.2 图形(实时渲染)管线Graphics(Real-time Rendering) Pipeline

在这里插入图片描述

  • 输入在三维空间中的顶点
  • 把顶点投影到屏幕上
  • 得到三角形在屏幕上的投影
  • 光栅化
  • 着色
  • 输出:图像(像素)

5.2.1 图形管线示例

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

Shader控制顶点和像素如何着色

在这里插入图片描述

5.2.1.1 着色器程序(Shader Programs)
  • 编程处理顶点vertex和片段fragment阶段

  • 是对一个单一顶点(或片段fragment)如何操作的描述

    • 如果写的是对顶点的着色操作,称为顶点着色器(vertax shader)
    • 如果写的是对像素的着色操作,称为像素着色器(fragment/pixel shader)
  • 一个GLSL(OpenGL的着色语言)fragment shader的例子:

    • 着色器函数每个fragment执行一次
    • 在屏幕上采样位置输出当前fragment表面的颜色
    • 这个shader执行在该点寻找并获取表面材质的颜色,然后表现漫反射光照计算

在这里插入图片描述

网站推荐:在线编写shader

5.2.1.2 目标:实时渲染高度复杂的3D场景
5.2.1.3 图形管道实现:GPUs(Graphics Pipeline Implementations)

专门用于处理执行图形管线的计算

在这里插入图片描述

5.2.1.4 GPU:异构多核处理器

在这里插入图片描述

5.3 纹理映射

不同位置的颜色不同

在这里插入图片描述

5.3.1 表面是二维的

  • 表面存在于三维空间
  • 任何三维表面的点都是二维的,三维表面对应一张二维图像(纹理)

在这里插入图片描述

5.3.1.1 纹理应用到表面

在这里插入图片描述

5.3.1.2 可视化纹理坐标

每个三角形顶点被表示乘一个纹理坐标(u,v)[0,1]

在这里插入图片描述

在这里插入图片描述

5.3.1.3 纹理可被重复使用多次!

在这里插入图片描述

5.4 三角形内部插值:重心坐标

5.4.1 在三角形内部插值

为什么需要插值?

  • 确定顶点的值
  • 在三角形中得到一个平滑过渡的值

需要插入什么值?

  • 纹理坐标,颜色,法向量

5.4.2 重心坐标

5.4.2.1 重心坐标的定义

重心坐标(Barycentric Coordinates)是定义在三角形 ( α , β , γ ) (\alpha,\beta,\gamma) (α,β,γ)上的一个坐标系

在这里插入图片描述

重心坐标:在三角形ABC所在的平面内,任何一个点 ( x , y ) (x,y) (x,y)都可以表示乘A、B、C这三个点坐标的线性组合。满足上述式子。

特殊的,如果点 ( x , y ) (x,y) (x,y)在三角形内部,还需要满足三个坐标系数 α 、 β 、 γ \alpha、\beta、\gamma αβγ都是非负的。

5.4.2.2 A、B、C点的重心坐标

在这里插入图片描述

A ( 1 , 0 , 0 ) B ( 0 , 1 , 0 ) C ( 0 , 0 , 1 ) A(1,0,0) B(0,1,0) C(0,0,1) A(1,0,0)B(0,1,0)C(0,0,1)

5.4.2.3 任意点的重心坐标——面积比

在这里插入图片描述

5.4.2.4 三角形重心的重心坐标

在这里插入图片描述

5.4.2.5 重心坐标公式

在这里插入图片描述

5.4.3 使用重心坐标

5.4.3.1 对顶点线性插值

在这里插入图片描述

V A , V B , V C V_A,V_B,V_C VAVBVC可以是位置,纹理坐标(u,v),颜色,法向量,深度,材质属性……

然而,在投影变换下,重心坐标不是不变的!

5.5 应用纹理

5.5.1 简单的纹理映射:漫反射颜色

对每个光栅化在屏幕上的样本 ( x , y ) (x,y) (x,y)(通常是一个像素的中心):

( u , v ) (u,v) (u,v)=评估在 ( x , y ) (x,y) (x,y)的纹理坐标(使用重心坐标)

texcolor=texture.sample(u,v);将样本颜色设置为texcolor(通常是漫反射系数Kd)

5.5.2 纹理放大(如果纹理太小了怎么办?)

一般不希望出现这样的情况——纹理分辨率不足

纹理上的一个像素——texel(纹理元素、纹素)

在这里插入图片描述

近似(四舍五入)、双线性插值、双三次插值(取临近的16个点)

5.5.2.1 双线性插值(Bilinear Interpolation)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

5.5.3 纹理放大(如果纹理太大了怎么办?)

5.5.3.1 点采样纹理的问题——走样

在这里插入图片描述

5.5.3.2 在纹理中屏幕像素覆盖的“区域”

在这里插入图片描述

5.5.3.3 超采样(MSAA)能抗走样吗?

可以!但耗费性能!

在这里插入图片描述

5.5.3.4 走样——超采样?

超采样(MSAA)能抗走样吗?

  • 可以,质量高,但耗性能
  • 当高度减少时,一个像素包含很多纹理
  • 一个像素中的信号频率太大
  • 需要更高的采样频率

换一个思路理解这个问题

  • 如果我们不采样呢?
  • 只需要得到一个范围内的平均值!
5.5.3.5 点查询vs.范围(平均值)查询

在这里插入图片描述

5.5.3.6 范围查询

不同的像素→不同的覆盖区域范围大小
在这里插入图片描述

5.5.4 Mipmap——允许(fast,approx.,square)范围查询

Mipmap:快,不准(近似),方形范围查询

5.5.4.1 Mipmap(L. Williams 83)

在这里插入图片描述

在这里插入图片描述

引入了多大的额外存储量?

原来的1/3

5.5.4.2 计算Mipmap的第D层

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

微分计算

5.5.4.3 Mipmap层的可视化——颜色渐变不连续是到不同的层进行了查询

在这里插入图片描述

5.5.4.4 三线性插值(Trilinear Interpolation)

Mipmap层与层
在这里插入图片描述
在这里插入图片描述

5.5.4.5 Mipmap的限制

远处模糊过分了(Overblur)
在这里插入图片描述

5.5.4.6 各向异性过滤(Anisotropic Filtering)——局部解决三线性插值的问题

在这里插入图片描述

Ripmaps和summed区域表

  • 可以查询轴对齐的矩形区域
  • 对角线覆盖范围仍是一个问题

在这里插入图片描述

EWA过滤

  • 使用多查询
  • 加权平均值
  • Mipmap层级仍有帮助
  • 可以处理不规则的覆盖范围
  • 额外开销是原来的三倍

在这里插入图片描述

5.5.4.7 纹理中不规则的像素覆盖范围

在这里插入图片描述

5.6 纹理的应用

5.6.1 许多,许多纹理的应用

在现代GPU中,纹理=内存+范围查询(过滤)

  • 通常的方法是将数据进行查询(fragment计算)

许多的应用:

  • 环境光照Environment lighting

  • 存储微曲线测定值Store microgeometry

  • 纹理函数Procedural textures

  • 实体建模Solid modeling

  • 批量渲染Volume rendering

  • ……

5.6.1.1 环境贴图Environment Map

在这里插入图片描述

经典模型:犹他壶、斯坦福兔子、斯坦福龙、康奈尔盒子

假设环境光来自无限远处,记录一个方向的即可(从同一个方向来,强度都是一样的),没有深度意义

5.6.1.2 环境光Environment Lighting

在这里插入图片描述

5.6.1.3 球形环境贴图Spherical Environment Map

在这里插入图片描述

5.6.1.4 球形贴图的问题——易失真/扭曲(顶部和底部)!

在这里插入图片描述

5.6.1.5 立方体映射——解决球形贴图的问题

在这里插入图片描述

一个从球心出发的向量映射到立方体沿着该方向打到面上的点

立方体用6个方形纹理映射

在这里插入图片描述

5.6.2 纹理会影响着色!

  • 纹理不仅仅代表颜色

    • 如果它存储了高度/法向量呢?
    • 凹凸贴图/法线贴图(Bump/normal mapping)
    • 假的几何细节

在这里插入图片描述

5.6.2.1 凹凸贴图Bump Mapping

添加表面细节而并不添加更多的三角形

  • 对每个像素垂直平面的的法向量(仅着色计算时)

  • 每个由纹理定义的纹素有一个“高度”

  • 如何修正法向量?

在这里插入图片描述

5.6.2.2 凹凸贴图如何扰动法向量(在平面上flatland)
  • 原本平面的法线 n ( p ) = ( 0 , 1 ) n(p)=(0,1) n(p)=(0,1)
  • p p p点的切线 d p = c ∗ [ h ( p + 1 ) − h ( p ) ] dp=c*[h(p+1)-h(p)] dp=c[h(p+1)h(p)]
  • 扰动法线是 n ( p ) = ( − d p , 1 ) . n o r m a l i z e d ( ) n(p)=(-dp,1).normalized() n(p)=(dp,1).normalized()(垂直,逆时针旋转90°,归一化)

在这里插入图片描述

5.6.2.3 凹凸贴图如何扰动法向量(在三维中)
  • 原本平面的法线 n ( p ) = ( 0 , 0 , 1 ) n(p)=(0,0,1) n(p)=(0,0,1)
  • p点的切线(求导)
    • d p / d u = c 1 ∗ [ h ( u + 1 ) − h ( u ) ] dp/du=c1*[h(u+1)-h(u)] dp/du=c1[h(u+1)h(u)]
    • d p / d v = c 2 ∗ [ h ( v + 1 ) − h ( v ) ] dp/dv=c2*[h(v+1)-h(v)] dp/dv=c2[h(v+1)h(v)]
  • 扰动法线是 n = ( − d p / d u , − d p / d v , 1 ) . n o r m a l i z e d ( ) n=(-dp/du,-dp/dv,1).normalized() n=(dp/du,dp/dv,1).normalized()
  • 需要注意这是局部坐标系
5.6.2.4 位移贴图Displacement mapping——一个更高级的方法
  • 与凹凸贴图使用相同的纹理
  • 实际操作时移动顶点位置
  • 需要模型做的很细致,三角形多

在这里插入图片描述

DirectX(图形API)提供一个方法:动态的曲面细分,根据需要做位移贴图

5.6.2.5 3D噪声函数+实体建模

在这里插入图片描述

5.6.2.6 提供预先计算的着色

在这里插入图片描述

5.6.2.7 3D纹理和体渲染

在这里插入图片描述

6 几何Geometry

6.1 几何介绍

6.1.1 几何形体的例子

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

6.1.2 几何形体不同的代表

6.1.2.1 许多代表几何的方式

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 隐式几何 Implicit
    • 代数表面 algebraic surface
    • 水平集 level sets
    • 距离函数 distance functions
  • 显式几何 Explicit
    • 点云 point cloud
    • 多边形面 polygon mesh
    • 细分 subdivision,非均匀有理b-样条 NURBS

6.1.3 隐式几何

基于分类的点

  • 点满足一些特定的关系(函数)

例子:一个球,所有三维中的点满足 x 2 + y 2 + z 2 = 1 x^2+y^2+z^2=1 x2+y2+z2=1

更一般地, f ( x , y , z ) = 0 f(x,y,z)=0 f(x,y,z)=0

6.1.3.1 隐式表面——采样困难

f ( x , y , z ) = ( 2 − x 2 + y 2 ) 2 + z 2 − 1 f(x,y,z)=(2-\sqrt {x^2+y^2})^2+z^2-1 f(x,y,z)=(2x2+y2 )2+z21

哪些点会满足这个函数( f ( x , y , z ) = 0 f(x,y,z)=0 f(x,y,z)=0)?

在这里插入图片描述

6.1.3.2 隐式表面——判断点在面内部还是外部很简单

在这里插入图片描述

6.1.3.3 显式表示

所有的点直接给出或者通过参数映射的方式给出

在这里插入图片描述

马鞍面

6.1.3.4 显式表面——采样简单

在这里插入图片描述

6.1.3.5 显式表面——判断点在面内部还是外部很难

在这里插入图片描述

6.1.3.6 没有最好的表示方法——几何很难

根据需要选择最合适的表示方法

6.1.3.7 代数表面(隐式)——不直观

在这里插入图片描述

6.1.3.8 Constructive Solid Geometry (CSG)(隐式)

通过布尔运算组合隐式几何

在这里插入图片描述

在这里插入图片描述

6.1.3.9 距离函数(隐式)

不同于布尔,通过使用距离函数把表面融合到一起:

给定空间中从任何地方到物体的最小距离(可以标记距离)

在这里插入图片描述

在这里插入图片描述

6.1.3.10 融合距离函数(隐式)

在这里插入图片描述

6.1.3.11 距离函数的应用

在这里插入图片描述

6.1.3.12 水平集方法(隐式)

闭合方程很难描述复杂的形状

代替方式:存储近似函数的值表

在这里插入图片描述

法线在曲面内部插值等于0

提供更明确的形状控制(类似纹理)

6.1.3.13 医学数据中的水平集(CT,MRI等)

在这里插入图片描述

6.1.3.14 物理模拟中的水平集

水平集到气液边界的距离
在这里插入图片描述

6.1.3.15 分形Fractals(隐式)

在所有尺度上细节表现出自相似性

“语言”是用于描述自然现象

难以控制的形状!

在这里插入图片描述

6.1.3.16 隐式表示

优点:

  • 紧凑的描述(例如,函数)
  • 特定的查询容易(内部对象,到表面的距离)
  • 适用于射线到平面的交叉
  • 对于简单图形,精确描述/没有采样错误
  • 易于处理拓扑的变化(例如,流体)

缺点:

  • 很难表示复杂的图形

6.1.4 显式几何

6.1.4.1 点云(显式)
  • ( x , y , z ) (x,y,z) (x,y,z)的列表(list)

  • 易表示任何类型的几何

  • 在大型数据集中很有用(>>1point/pixel)

  • 经常转换成多边形面Mesh

  • 难以绘制下采样区域

在这里插入图片描述

在这里插入图片描述

6.1.4.2 多边形面(显式)
  • 存储顶点和四边形(通常是三角形或四边形)

  • 更容易处理/模拟,自适应采样

  • 更复杂的数据结构

在这里插入图片描述

6.1.4.3 Wavefront Object File(.obj)格式
  • 常用于图形学研究

  • 只是一个指定顶点,法线,纹理坐标和它们之间联系的一个文本文件

在这里插入图片描述

6.2 曲线(显示表示)

6.2.1 应用

  • 相机路径Camera Path
  • 曲线动画Animation Curves
  • 矢量字体Vector Fonts

6.2.2 Bézier Curves(贝塞尔曲线)

6.2.2.1 用切线定义立方体的贝塞尔曲线

在这里插入图片描述

6.2.2.2 画一条贝塞尔曲线(De Castelijau算法)
6.2.2.2.1 考虑三个点(二次贝塞尔)
  1. 插入使用线性插值得到的一个点

在这里插入图片描述
2. 在两条线段上都插入一个点
在这里插入图片描述
3. 递归

在这里插入图片描述

  1. 用上述算法找到所有在 [ 0 , 1 ] [0,1] [0,1]上的 t t t

在这里插入图片描述

6.2.2.22 总共四个输入点

同样递归线性插值

在这里插入图片描述

6.2.3 评估贝塞尔曲线(代数公式)

de Casteljau算法给出了参数金字塔

在这里插入图片描述

例子:

三个点的二次贝塞尔曲线

在这里插入图片描述

n个点贝塞尔曲线的Bernstein形式:

在这里插入图片描述

Bernstein多项式: B i n ( t ) = ( n i ) t i ( 1 − t ) n − i B^n_i(t)=\left(\begin {array}{c} n \\ i\\ \end{array}\right)t^i(1-t)^{n-i} Bin(t)=(ni)ti(1t)ni

在这里插入图片描述

例子:

3D中的控制点:

b 0 = ( 0 , 2 , 3 ) , b 1 = ( 2 , 3 , 5 ) , b 2 = ( 6 , 7 , 9 ) , b 3 = ( 3 , 4 , 5 ) \textbf{b}_0=(0,2,3),\textbf{b}_1=(2,3,5),\textbf{b}_2=(6,7,9),\textbf{b}_3=(3,4,5) b0=(0,2,3),b1=(2,3,5),b2=(6,7,9),b3=(3,4,5)

这些点定义了三维中的贝塞尔曲线,是一个 t t t的立方多项式:

b n ( t ) = b 0 ( 1 − t ) 3 + b 1 3 t ( 1 − t ) 2 + b 2 3 t 2 ( 1 − t ) + b 3 t 3 \textbf{b}^n(t)=\textbf{b}_0(1-t)^3+\textbf{b}_13t(1-t)^2+\textbf{b}_23t^2(1-t)+\textbf{b}_3t^3 bn(t)=b0(1t)3+b13t(1t)2+b23t2(1t)+b3t3

6.2.3.1 贝塞尔曲线的性质

插值端点

  • 对于三次贝塞尔(四个控制点):
    b ( 0 ) = b 0 ; b ( 1 ) = b 3 \textbf{b}(0)=\textbf{b}_0;\textbf{b}(1)=\textbf{b}_3 b(0)=b0;b(1)=b3

切线的终点

  • 对于三次贝塞尔(四个控制点):
    b ′ ( 0 ) = 3 ( b 1 − b 0 ) ; b ′ ( 1 ) = 3 ( b 3 − b 2 ) \textbf{b}^\prime(0)=3(\textbf{b}_1-\textbf{b}_0);\textbf{b}^\prime(1)=3(\textbf{b}_3-\textbf{b}_2) b(0)=3(b1b0);b(1)=3(b3b2)

仿射变换属性

  • 对贝塞尔曲线做仿射变换和对其上的顶点做仿射变换结果相同

凸包性质(Contex hull property)

  • 曲线一定要在控制点形成的凸包内
6.2.3.1.1 什么是凸包(Convex Hull)

凸包:能够包围一系列给定的几何形体的最小凸多边形。

在这里插入图片描述

6.2.4 逐段(Piecewise)贝塞尔曲线

6.2.4.1 高阶贝塞尔曲线——难以控制、罕见

在这里插入图片描述

6.2.4.2 逐段贝塞尔曲线

相反,将许多低阶的贝塞尔曲线相接

逐段三次(四个控制点)贝塞尔是最常见的技术

在这里插入图片描述

广泛用于文字、路径、插画、主题Keynote…

6.2.4.3 逐段贝塞尔曲线——连续性

给定两个贝塞尔曲线

在这里插入图片描述

第一段的终止点等于第二段的起始点(几何上连在一起)

C 0 C^0 C0连续: a n = b 0 \textbf{a}_n=\textbf{b}_0 an=b0

在这里插入图片描述

切线连续(一阶导数连续)

C 1 C^1 C1连续: a n = b 0 = 1 2 ( a n − 1 + b 1 ) \textbf{a}_n=\textbf{b}_0=\frac{1}{2}(\textbf{a}_{n-1}+\textbf{b}_1) an=b0=21(an1+b1)

在这里插入图片描述

6.2.5 其他类型的曲线(样条)splines

  • Splines(样条)

    • 通过给定的点集构造一条连续的曲线满足一定连续性
    • 简单说,就是一个可控的曲线

    在这里插入图片描述

  • B-splines(B-样条)

    • basis splines(奇函数样条)的缩写
    • 需要比贝塞尔曲线更多的信息
    • 满足所有贝塞尔曲线的重要性质(即,超集)

6.3 曲面

把贝塞尔曲线扩展到面

在这里插入图片描述

在这里插入图片描述

6.3.1 Bezier表面

6.3.1.1 二次贝塞尔曲面

在这里插入图片描述

6.3.3.2 用参数(u,v)评估表面位置

对于双-三次贝塞尔曲面

输入:4×4的控制点

输出:用(u,v)表示的二维表面,范围在[0,1]2

在这里插入图片描述

6.3.3.3 方法:可分离的一维de Casteljau算法

目标:评估对应的表面位置(u,v)

  • 使用de Casteljau评估在4条贝塞尔曲线上的每一个u
  • 使用一维de Casteljau评估在“移动”曲线上的点v

在这里插入图片描述

6.3.2 三角形和四边形

6.3.2.1 细分Subdivision,简化simplification,正规化regularization

在这里插入图片描述

6.3.2.2 网格细分(上采样)

在这里插入图片描述

增加分辨率

6.3.2.3 网格简化(下采样)

在这里插入图片描述

减少分辨率;试图保留形状/表现

6.3.2.4 网格正规化(相同的三角形)

在这里插入图片描述

修改采样分布以提高质量

6.3.3 细分Subdivision

6.3.3.1 Loop细分Loop Subdivision(三角形网格)

在这里插入图片描述

常见的三角形面细分规则:

  1. 创建更多的三角形(顶点)

    • 将每个三角形分成4个

    在这里插入图片描述

  2. 调整它们的位置

    • 根据权重分配新的顶点位置

      • 新/旧顶点以不同方式更新

        在这里插入图片描述

      • 对于新顶点:

        在这里插入图片描述

        在这里插入图片描述

      • 对于旧顶点

      在这里插入图片描述

6.3.3.2 Loop细分结果

在这里插入图片描述

6.3.3.3 Catmull-Clark细分(一般网格)

在这里插入图片描述

定义四边形、非四边形面、奇异点(度不为4的点)

每个细分步骤:

  • 在每个面上添加顶点
  • 取每条边的中点
  • 连接所有新顶点

在这里插入图片描述

在一次细分后:增加了非四边形面数的奇异点,之后不再增加

有多少奇异点?4个

它们的度是多少?旧:5、新:3

有多少非四边形面?0个

在这里插入图片描述

在这里插入图片描述

6.3.3.4 Catmull-Clark顶点更新规则(四边形网格)

面上的点、边上的点、顶点

在这里插入图片描述

6.3.3.5 融合:整体形状和折痕

Loop细分的折痕

在这里插入图片描述

Catmull-Clark细分的折痕

在这里插入图片描述

6.3.4 网格(曲面)简化Mesh Simplification

目标:在保持整体形状的同时减少网格数量

在这里插入图片描述

6.3.4.1 边坍缩(Collapsing An Edge)
  • 假设我们是边缘折叠简化一个曲面(edge collapsing)

在这里插入图片描述

6.3.4.2 二次误差度量(Quadric Error Metrics)
  • 曲面简化引入了多少几何误差?
  • 不是一个好的表示顶点局部平均值的办法
  • 二次误差:新顶点到与它相关的面的距离的平方和(L2距离)达到最小

在这里插入图片描述

6.3.4.3 边坍缩的二次误差
  • 边坍缩的成本是多少?
  • 想法:计算边的中点,计算二次误差

在这里插入图片描述

  • 更好的想法:选择二次误差最小的点
  • 更多细节:Garland&Heckbert 1997
6.3.4.4 通过二次误差简化

迭代的边坍缩

哪个边?通过二次误差度量(Garland&Heckbert 1997)分配得分

  • 取包含三角形面到表面的距离和的近似
  • 用最小的得分迭代边坍缩(堆)
  • 贪婪算法…结果很好!
6.3.4.5 二次误差曲面简化

在这里插入图片描述

6.4 阴影

6.4.1 阴影映射/图(Shadow mapping)——只能处理点光源投射出的阴影(硬阴影)

  • 一种图像-空间算法
    • 在计算阴影过程中,不需要知道场景中的几何信息
    • 必须处理走样问题
  • 关键思想
    • 不在阴影里的点必须同时被光源和摄像机看见

6.4.2 步骤1:从光源出发渲染

  • 光源深度图

    在这里插入图片描述

6.4.3 步骤2A:从摄像机出发渲染

  • 摄像机标准图(有深度)

在这里插入图片描述

6.4.4 步骤2B:投影回光源

  • 摄像机可见的点投影回光源

在这里插入图片描述

在这里插入图片描述

6.4.5 可视化阴影映射

  • 将Dist(light,shading point)与shadow map比较

在这里插入图片描述

6.4.6 阴影映射

  • 众所周知的渲染技术
    • 早期动画的基本阴影技术和任何3D视频游戏

6.4.7 阴影映射的问题

  • 硬阴影(仅限点光源)

  • 质量取决于阴影地图分辨率(基于图像的技术的普遍问题)

  • 涉及scale,bias,容差tolerance浮点深度值的比较

  • 硬阴影vs.软阴影

    在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/777240.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java基础:面向对象(一)

一、概念 物以类聚&#xff0c;分类的思维模式&#xff0c;思考问题首先会解决问题需要哪些分类&#xff0c;然后对这些分类进行单独思考。最后&#xff0c;才对某个分类下的细节进行面向过程的思索。面向对象适合处理复杂的问题&#xff0c;适合处理需要多人协作的问题!对于描…

vulhub靶场之DEVGURU:1

1 信息收集 1.1 主机发现 arp-scan -l 发现主机IP地址为“192.168.1.11 1.2 端口发现 nmap -sS -sV -A -T5 -p- 192.168.1.11 发现端口为&#xff1a;22&#xff0c;80&#xff0c;8585 1.3 目录扫描 dirsearch -u 192.168.1.11 发现存在git泄露 2 文件和端口访问 2…

idea中没有显示‘‘Spring‘‘一栏 (已解决)

第一步: 随便找一个Bean(即直接或者间接使用Component的类) 第二步: 找到左边的图标, 右键这个图标, 然后选择如下选项: 第三步: 成功 然后就成功了, 可以看到具体的bean了以及其bean的关系图等.

MySQL的Geometry数据处理之WKB方案

MySQL的Geometry数据处理之WKT方案&#xff1a;https://blog.csdn.net/qq_42402854/article/details/140134357 MySQL的Geometry数据处理之WKT方案中&#xff0c;介绍WTK方案的优点&#xff0c;也感受到它的繁琐和缺陷。比如&#xff1a; 需要借助 ST_GeomFromText和 ST_AsTex…

主从复制原理及操作

主从复制的概念 主从复制是一种在数据库系统中常用的数据备份和读取扩展技术&#xff0c;通过将一个数据库服务器&#xff08;主服务器&#xff09;上的数据变更自动同步到一个或多个数据库服务器&#xff08;从服务器&#xff09;上&#xff0c;以此来实现数据的冗余备份、读…

数据库之SQL(二)

目录 一、简述SQL中如何将“行”转换为“列” 二、简述SQL注入 三、如何将一张表的部分数据更新到另一张表 四、WHERE和HAVING的区别 一、简述SQL中如何将“行”转换为“列” 我们以MySQL数据库为例&#xff0c;来说明行转列的实现方式。 首先&#xff0c;假设我们有一张分…

WAIC 2024:科技界的摇滚狂欢,你错过了什么?

大数据产业创新服务媒体 ——聚焦数据 改变商业 2024年7月5日&#xff0c;WAIC 2024举办的第二天。数据猿作为受邀媒体&#xff0c;在今天继续亲历这一场关于未来的盛会。在这片汇聚了全球顶尖科技力量的舞台上&#xff0c;见证了人工智能领域的最新成果&#xff0c;感受到了科…

Midjourney对图片细微调整和下载保存

点击v2是对第二图片细微调整。 点击u3对第3张图片进行放大。 保存图片: 对点击u3放大的图片&#xff0c;双击 , 右键保存图片

hdu物联网硬件实验3 按键和中断

学院 班级 学号 姓名 日期 成绩 实验题目 按键和中断 实验目的 实现闪灯功能转换 硬件原理 无 关键代码及注释 /* Button Turns on and off a light emitting diode(LED) connected to digital pin 13, when pressing a pushbutton attached…

招聘一个1-3年经验的Java工程师:企业视角的技能与素质要求

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1…

Spring的核心基础:感受一下对象工厂

“欢迎来到Spring&#xff01;”的小项目 &#xff08;1&#xff09;写一个HelloSpring的类&#xff0c;采用setter方法注入userName&#xff0c;写一个简单的show方法。 package com.itzhoutao; public class HelloSpring{private String userName;public void setUserName…

Spring源码十一:事件驱动

上一篇Spring源码十&#xff1a;BeanPostProcess中&#xff0c;我们介绍了BeanPostProcessor是Spring框架提供的一个强大工具&#xff0c;它允许我们开发者在Bean的生命周期中的特定点进行自定义操作。通过实现BeanPostProcessor接口&#xff0c;开发者可以插入自己的逻辑&…

核心实验:基于Web前端的性能测试分析!

实验简介 本实验主要利用IE和Chrome的F12开发人员工具结合Web前端测试分析相关知识&#xff0c;对常见网站进行基于前端的性能测试分析&#xff0c;本实验将不会使用到测试开发相关技术&#xff0c;而是纯粹意义上的手工测试&#xff0c;但却是很容易找到系统前端性能及设计问…

AI行业的非零和博弈:解读Mustafa Suleyman的观点

引言 在人工智能&#xff08;AI&#xff09;领域&#xff0c;微软AI公司的CEO Mustafa Suleyman最近在阿斯彭思想节上的访谈引起了广泛关注。与CNBC记者Andrew Ross Sorkin的对话中&#xff0c;Suleyman不仅分享了他对OpenAI人事变动的看法&#xff0c;还深入探讨了AI行业的现…

2024年亚太中文赛数学建模竞赛B题 洪水灾害的数据分析与预测详细思路解析

2024年亚太中文赛数学建模竞赛B题 洪水灾害的数据分析与预测详细思路解析 解题方法&#xff1a; 首先就是对数据进行数据的预处理包括缺失值和异常值处理&#xff0c;之后就是分析哪些指标与洪水的发生有着密切的关联&#xff0c;可以使用相关性分析&#xff08;建议使用斯皮尔…

InetAddress.getLocalHost().getHostAddress()阻塞导致整个微服务崩溃

InetAddress.getLocalHost().getHostAddress()阻塞导致整个微服务崩溃 import java.net.InetAddress;public class GetHostIp {public static void main(String[] args) {try {long start System.currentTimeMillis();String ipAddress InetAddress.getLocalHost().getHostA…

Python和MATLAB微机电健康推导算法和系统模拟优化设计

&#x1f3af;要点 &#x1f3af;惯性测量身体活动特征推导健康状态算法 | &#x1f3af;卷积网络算法学习惯性测量数据估计六自由度姿态 | &#x1f3af;全球导航卫星系统模拟&#xff0c;及惯性测量动态测斜仪算法、动态倾斜算法、融合算法 | &#x1f3af;微机电系统加速度…

Docker搭建MySQL双主复制详细教程

在此之前需要提前安装好Docker和 Docker Compose 。 一、创建目录 首先创建一个本地数据挂载目录。 mkdir -p master1-data master2-data二、编写docker-compose.yml version: 3.7services:mysql-master1:image: mysql:5.7.36container_name: mysql-master1environment:MYSQL_…

解决分布式环境下session共享问题

在分布式环境下&#xff0c;session会存在两个问题 第一个问题:不同域名下&#xff0c;浏览器存储的jsessionid是没有存储的。比如登录时认证服务auth.gulimall.com存储了session&#xff0c;但是搜索服务search.gulimall.com是没有这个session的&#xff1b; 第二个问题&…

分库分表真的适合你的系统吗?

曾几何时&#xff0c;“并发高就分库&#xff0c;数据大就分表”已经成了处理 MySQL 数据增长问题的圣经。 面试官喜欢问&#xff0c;博主喜欢写&#xff0c;候选人也喜欢背&#xff0c;似乎已经形成了一个闭环。 但你有没有思考过&#xff0c;分库分表真的适合你的系统吗&am…