文章目录
- 计算机图形学
- 一、Linear Algebra 线性代数
- 二、Transformation 变换
- 三、Rasterization 光栅化
- 四、Shading 着色
- Curves and Meshes 曲线和曲面
- Ray Tracing 光线追踪
- Animation/Simulation 动画与模拟
- Curves and Meshes 曲线和曲面
- Ray Tracing 光线追踪
- Animation/Simulation 动画与模拟
图片未能完全导入,接下来将持续更新。
Updating…
计算机图形学
本笔记对应课程:GAMES101-现代计算机图形学入门
一、Linear Algebra 线性代数
1.1 Vector
物理上:向量
数学上:矢量
方向和长度
1.1.1 向量的表示
a ⃗ \vec{a} a
1.1.2 向量的长度
∣ ∣ a ⃗ ∣ ∣ ||\vec{a}|| ∣∣a∣∣
1.1.3 单位向量
a ^ = a ⃗ / ∣ ∣ a ⃗ ∣ ∣ \widehat{a}=\vec{a}/||\vec{a}|| a =a/∣∣a∣∣
1.1.4 向量相加
三角形/平行四边形法则
1.1.5 向量的矩阵表示
A= ( x y ) \left( \begin{matrix} x\\ y \end{matrix} \right) (xy)
AT= ( x , y ) \left( \begin{matrix} x , y \end{matrix} \right) (x,y)
||A||= x 2 + y 2 \sqrt{x^2+y^2} x2+y2
1.1.6 向量的点乘(Dot Product)
a ⃗ ⋅ b ⃗ = ∣ ∣ a ⃗ ∣ ∣ ∣ ∣ b ⃗ ∣ ∣ cos θ \vec{a}·\vec{b}=||\vec{a}||||\vec{b}||\cos\theta a⋅b=∣∣a∣∣∣∣b∣∣cosθ
cos θ = a ⃗ ⋅ b ⃗ ∣ ∣ a ⃗ ∣ ∣ ∣ ∣ b ⃗ ∣ ∣ \cos\theta=\frac{\vec{a}·\vec{b}}{||\vec{a}||||\vec{b}||} cosθ=∣∣a∣∣∣∣b∣∣a⋅b
满足交换律、分配律、结合律
2D: a ⃗ ⋅ b ⃗ = ( x a y a ) ⋅ ( x b y b ) = x a y a + x b y b \vec{a}·\vec{b}=\left( \begin{matrix} x_a\\ y_a \end{matrix} \right)·\left( \begin{matrix} x_b\\ y_b \end{matrix} \right)=x_ay_a+x_by_b a⋅b=(xaya)⋅(xbyb)=xaya+xbyb
3D: a ⃗ ⋅ b ⃗ = ( x a y a z a ) ⋅ ( x b y b z b ) = x a y a + x b y b + z a z b \vec{a}·\vec{b}=\left( \begin{matrix} x_a \\ y_a \\ z_a \end{matrix} \right)·\left( \begin{matrix} x_b\\ y_b\\z_b \end{matrix} \right)=x_ay_a+x_by_b+z_az_b a⋅b=⎝⎛xayaza⎠⎞⋅⎝⎛xbybzb⎠⎞=xaya+xbyb+zazb
点乘的作用:
-
点乘可以告诉我们两个向量的方向性(是否接近)
-
可以求两个向量之间的夹角
1.1.7 向量的投影
b ⃗ 投 影 到 a ⃗ 上 : \vec{b}投影到\vec{a}上: b投影到a上:
b ⃗ ⊥ = k a ⃗ ∣ ∣ a ⃗ ∣ ∣ \vec{b}_\bot=k\frac{\vec{a}}{||\vec{a}||} b⊥=k∣∣a∣∣a
k = ∣ ∣ b ⃗ ⊥ ∣ ∣ = ∣ ∣ b ⃗ ∣ ∣ cos θ ( θ 是 a ⃗ 与 b ⃗ 的 夹 角 ) k=||\vec{b}_\bot||=||\vec{b}||\cos\theta\quad(\theta是\vec{a}与\vec{b}的夹角) k=∣∣b⊥∣∣=∣∣b∣∣cosθ(θ是a与b的夹角)
1.1.8 向量的叉乘(Cross Product)
a ⃗ × b ⃗ = − b ⃗ × a ⃗ \vec{a}×\vec{b}=-\vec{b}×\vec{a} a×b=−b×a(不满足交换律)
a ⃗ × b ⃗ = ∣ ∣ a ⃗ ∣ ∣ ∣ ∣ b ⃗ ∣ ∣ sin θ \vec{a}×\vec{b}=||\vec{a}||||\vec{b}||\sin\theta a×b=∣∣a∣∣∣∣b∣∣sinθ
向量的叉积与 a ⃗ \vec{a} a、 b ⃗ \vec{b} b均垂直
右手定则(从 a ⃗ \vec{a} a到 b ⃗ \vec{b} b旋转)
a ⃗ × a ⃗ = 0 ⃗ \vec{a}×\vec{a}=\vec{0} a×a=0
满足分配律、结合律
叉乘的矩阵表示:
-
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}×\vec{b}=\left( \begin{matrix} y_az_b-y_bz_a\\ z_ax_b-x_az_b\\x_ay_b-y_ax_b \end{matrix} \right) a×b=⎝⎛yazb−ybzazaxb−xazbxayb−yaxb⎠⎞
-
a ⃗ × b ⃗ = \vec{a}×\vec{b}= a×b=A* b ⃗ \vec{b} b= ( 0 − z a y a z a 0 − x a − y a x a 0 ) ( x b y b z b ) \left( \begin{matrix} 0&-z_a&y_a\\ z_a&0&-x_a\\-y_a&x_a&0 \end{matrix} \right) \left( \begin{matrix} x_b\\ y_b\\z_b \end{matrix} \right) ⎝⎛0za−ya−za0xaya−xa0⎠⎞⎝⎛xbybzb⎠⎞
叉乘的作用:
-
向量的叉乘可以用来建立三维坐标系
-
向量的叉乘在图形学里可用来判定左和右,以及内和外
1.2 Matrix 矩阵
1.2.1 矩阵乘法
(M×N)(N×P)=(M×P)
eg: ( 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{matrix} 1 & 3\\ 5 & 2\\0&4 \end{matrix} \right)\left( \begin{matrix} 3 & 6 &9&4\\ 2&7&8&3 \end{matrix} \right)=\left( \begin{matrix} 9&27&33&13\\ 19&44&61&26\\8&28&32&12 \end{matrix} \right) ⎝⎛150324⎠⎞(32679843)=⎝⎛9198274428336132132612⎠⎞
运算口诀:左管行,右管列,左行乘右列相加
不满足交换律,满足结合律和分配律
1.2.2 矩阵转置
(AB)T=BTAT
eg: ( 9 2 19 4 8 2 ) T = ( 9 19 8 2 4 2 ) \left( \begin{matrix} 9&2\\ 19&4\\8&2 \end{matrix} \right)^T=\left( \begin{matrix} 9&19&8\\ 2&4&2 \end{matrix} \right) ⎝⎛9198242⎠⎞T=(9219482)
1.2.3 矩阵的逆
单位矩阵:对角线元素是1,其余均是0
AA-1=A-1A=I
(AB)-1=B-1A-1
1.2.4 向量点乘和叉乘的矩阵表示
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}·\vec{b}=\vec{a}^T·\vec{b}=\left( \begin{matrix} x_a&y_a&z_a \end{matrix} \right)\left( \begin{matrix} x_b\\ y_b\\z_b \end{matrix} \right)=\left( \begin{matrix} x_ax_b+y_ay_b+z_az_b \end{matrix} \right) a⋅b=aT⋅b=(xayaza)⎝⎛xbybzb⎠⎞=(xaxb+yayb+zazb)
a ⃗ × b ⃗ = \vec{a}×\vec{b}= a×b=A* b ⃗ \vec{b} b= ( 0 − z a y a z a 0 − x a − y a x a 0 ) ( x b y b z b ) \left( \begin{matrix} 0&-z_a&y_a\\ z_a&0&-x_a\\-y_a&x_a&0 \end{matrix} \right) \left( \begin{matrix} x_b\\ y_b\\z_b \end{matrix} \right) ⎝⎛0za−ya−za0xaya−xa0⎠⎞⎝⎛xbybzb⎠⎞
二、Transformation 变换
2.1 2D transformation
2D变换
2.1.1 Scale Transform 缩放
缩放矩阵:
- 均匀缩放: ( x ′ y ′ ) = ( s 0 0 s ) ( x y ) \left( \begin{matrix} x^{'}\\ y^{'} \end{matrix} \right)=\left( \begin{matrix} s&0\\ 0&s \end{matrix} \right)\left( \begin{matrix} x\\ y \end{matrix} \right) (x′y′)=(s00s)(xy)
- 不均匀缩放: ( x ′ y ′ ) = ( s x 0 0 s y ) ( x y ) \left( \begin{matrix} x^{'}\\ y^{'} \end{matrix} \right)=\left( \begin{matrix} s_x&0\\ 0&s_y \end{matrix} \right)\left( \begin{matrix} x\\ y \end{matrix} \right) (x′y′)=(sx00sy)(xy)
2.1.2 Reflection Matrix 翻转
相对于y轴镜像操作: ( x ′ y ′ ) = ( − 1 0 0 1 ) ( x y ) \left( \begin{matrix} x^{'}\\ y^{'} \end{matrix} \right)=\left( \begin{matrix} -1&0\\ 0&1 \end{matrix} \right)\left( \begin{matrix} x\\ y \end{matrix} \right) (x′y′)=(−1001)(xy)
2.1.3 Shear Matrix 切变
在平面直角坐标系中,将每一点沿着平行于x轴的方向平移ay个单位,a为非零常数
水平方向切变: ( x ′ y ′ ) = ( 1 a 0 1 ) ( x y ) \left( \begin{matrix} x^{'}\\ y^{'} \end{matrix} \right)=\left( \begin{matrix} 1&a\\ 0&1 \end{matrix} \right)\left( \begin{matrix} x\\ y \end{matrix} \right) (x′y′)=(10a1)(xy)
2.1.4 Rotate 旋转
规定:无说明默认原点为旋转点,默认逆时针为旋转方向
旋转45度:
旋转 θ \theta θ角度:
( x ′ y ′ ) = ( A B C D ) ( x y ) \left( \begin{matrix} x^{'}\\ y^{'} \end{matrix} \right)=\left( \begin{matrix} A&B\\ C&D \end{matrix} \right)\left( \begin{matrix} x\\ y \end{matrix} \right) (x′y′)=(ACBD)(xy)
简单特殊点求ABCD:
-
x轴上点(1,0):
( x ′ y ′ ) = ( A B C D ) ( 1 0 ) \left( \begin{matrix} x^{'}\\ y^{'} \end{matrix} \right)=\left( \begin{matrix} A&B\\ C&D \end{matrix} \right)\left( \begin{matrix} 1\\ 0 \end{matrix} \right) (x′y′)=(ACBD)(10)
cos θ = A \cos\theta=A cosθ=A
sin θ = C \sin\theta=C sinθ=C
-
y轴上点(0,1):
( x ′ y ′ ) = ( A B C D ) ( 0 1 ) \left( \begin{matrix} x^{'}\\ y^{'} \end{matrix} \right)=\left( \begin{matrix} A&B\\ C&D \end{matrix} \right)\left( \begin{matrix} 0\\ 1 \end{matrix} \right) (x′y′)=(ACBD)(01)
− sin θ = B -\sin\theta=B −sinθ=B
cos θ = D \cos\theta=D cosθ=D
得到旋转矩阵: R θ = ( cos θ − sin θ sin θ cos θ ) R_\theta=\left( \begin{matrix} \cos\theta&-\sin\theta\\ \sin\theta&\cos\theta \end{matrix} \right) Rθ=(cosθsinθ−sinθcosθ)
R − θ = ( cos θ sin θ − sin θ cos θ ) = R θ T R_{-\theta}=\left( \begin{matrix} \cos\theta&\sin\theta\\ -\sin\theta&\cos\theta \end{matrix} \right)=R^T_\theta R−θ=(cosθ−sinθsinθcosθ)=RθT
R − θ = R θ − 1 R_{-\theta}=R^{-1}_\theta R−θ=Rθ−1
旋转矩阵是正交矩阵(矩阵的转置等于矩阵的逆)
2.1.5 Linear Transforms 线性变换
上述变换(缩放、翻转、切变、旋转)均为线性变换
形式: ( x ′ y ′ ) = ( a b c d ) ( x y ) \left( \begin{matrix} x^{'}\\ y^{'} \end{matrix} \right)=\left( \begin{matrix} a&b\\ c&d \end{matrix} \right)\left( \begin{matrix} x\\ y \end{matrix} \right) (x′y′)=(acbd)(xy)(矩阵乘原向量)
2.2 Homogeneous coordinates 齐次坐标
2.2.1 Translation 平移
x ′ = x + t x x^{'}=x+t_x x′=x+tx
y ′ = y + t y y^{'}=y+t_y y′=y+ty
( x ′ y ′ ) = ( a b c d ) ( x y ) + ( t x t y ) \left( \begin{matrix} x^{'}\\ y^{'} \end{matrix} \right)=\left( \begin{matrix} a&b\\ c&d \end{matrix} \right)\left( \begin{matrix} x\\ y \end{matrix} \right)+\left( \begin{matrix} t_x\\ t_y \end{matrix} \right) (x′y′)=(acbd)(xy)+(txty)(不是常规的线性变换)
如果只有平移, ( a b c d ) \left( \begin{matrix} a&b\\ c&d \end{matrix} \right) (acbd)是单位矩阵
2.2.2 引入齐次坐标
增加第三个坐标:
- 2D point = (x,y,1)T
- 2D vector = (x,y,0)T(向量具有平移不变性,因此增加的第三个坐标为0,保证平移后向量不变)
增加坐标后平移的矩阵表示:
(
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{matrix} x^{'}\\ y^{'}\\w^{'} \end{matrix} \right)=\left( \begin{matrix} 1&0&t_x\\ 0&1&t_y\\0&0&1 \end{matrix} \right)\left( \begin{matrix} x\\ y\\1 \end{matrix} \right)=\left( \begin{matrix} x+t_x\\ y+t_y\\1 \end{matrix} \right)
⎝⎛x′y′w′⎠⎞=⎝⎛100010txty1⎠⎞⎝⎛xy1⎠⎞=⎝⎛x+txy+ty1⎠⎞(可以表示成矩阵乘原向量的形式了)
增加的 w w w为1或0后的有效操作:
-
vector+vector=vector(在空间中两个向量相加,依据三角形/平行四边形法则,得到一个新的向量)
-
point-point=vector(在空间中两点相减,得到一个从被减数指向减数的向量)
-
point+vector=point(在空间中点和向量相加,相当于一个点沿着一个向量移动到一个新的点上)
-
point+point=这两个点的中点
在齐次坐标中,任何的 ( x y ω ) \left( \begin{matrix} x\\ y\\\omega \end{matrix} \right) ⎝⎛xyω⎠⎞作为一个2D的点是 ( x / w y / w 1 ) , w ≠ 0 \left( \begin{matrix} x/w\\ y/w\\1 \end{matrix} \right),w\neq0 ⎝⎛x/wy/w1⎠⎞,w=0
2.2.3 Affine Transformations 仿射变换
Affine map = linear map + translation
( x ′ y ′ ) = ( a b c d ) ( x y ) + ( t x t y ) \left( \begin{matrix} x^{'}\\ y^{'} \end{matrix} \right)=\left( \begin{matrix} a&b\\ c&d \end{matrix} \right)\left( \begin{matrix} x\\ y \end{matrix} \right)+\left( \begin{matrix} t_x\\ t_y \end{matrix} \right) (x′y′)=(acbd)(xy)+(txty)
所有的二维仿射变换,都可以表示为齐次变换:
( x ′ y ′ 1 ) = ( a b t x c d t y 0 0 1 ) ( x y 1 ) \left( \begin{matrix} x^{'}\\ y^{'}\\1 \end{matrix} \right)=\left( \begin{matrix} a&b&t_x\\ c&d&t_y\\0&0&1 \end{matrix} \right)\left( \begin{matrix} x\\ y\\1 \end{matrix} \right) ⎝⎛x′y′1⎠⎞=⎝⎛ac0bd0txty1⎠⎞⎝⎛xy1⎠⎞
2.2.4 2D Transformations
Scale: S ( s x , s y ) = ( s x 0 0 0 s y 0 0 0 1 ) S(s_x,s_y)=\left( \begin{matrix} s_x&0&0\\ 0&s_y&0\\0&0&1 \end{matrix} \right) S(sx,sy)=⎝⎛sx000sy0001⎠⎞
Rotation: R ( α ) = ( cos α − sin α 0 sin α cos α 0 0 0 1 ) R(\alpha)=\left( \begin{matrix} \cos\alpha&-\sin\alpha&0\\ \sin\alpha&\cos\alpha&0\\0&0&1 \end{matrix} \right) R(α)=⎝⎛cosαsinα0−sinα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{matrix} 1&0&t_x\\ 0&1&t_y\\0&0&1 \end{matrix} \right) T(tx,ty)=⎝⎛100010txty1⎠⎞
2.2.5 Inverse Transform 逆变换
2.2.6 Transform Ordering Matters 变换顺序很重要
R 45 ⋅ T ( 1 , 0 ) ≠ T ( 1 , 0 ) ⋅ R 45 R_{45}\cdot T_{(1,0)}\neq T_{(1,0)}\cdot R_{45} R45⋅T(1,0)=T(1,0)⋅R45
可以证明:
-
矩阵不满足交换律
-
图形变换顺序不同,得到的最终结果不同
操作的矩阵按变换顺序依次写在原向量左侧,应用顺序从右到左
根据二维仿射变换,齐次变换 ( x ′ y ′ 1 ) = ( a b t x c d t y 0 0 1 ) ( x y 1 ) \left( \begin{matrix} x^{'}\\ y^{'}\\1 \end{matrix} \right)=\left( \begin{matrix} a&b&t_x\\ c&d&t_y\\0&0&1 \end{matrix} \right)\left( \begin{matrix} x\\ y\\1 \end{matrix} \right) ⎝⎛x′y′1⎠⎞=⎝⎛ac0bd0txty1⎠⎞⎝⎛xy1⎠⎞中 t x t_x tx和 t y t_y ty表示在x和y轴平移的距离,所以:
T ( 1 , 0 ) ⋅ R 45 = ( cos 3 5 o − sin 4 5 o 1 sin 4 5 o cos 4 5 o 0 0 0 1 ) T_{(1,0)}\cdot R_{45}=\left( \begin{matrix} \cos35^o&-\sin45^o&1\\ \sin45^o&\cos45^o&0\\0&0&1 \end{matrix} \right) T(1,0)⋅R45=⎝⎛cos35osin45o0−sin45ocos45o0101⎠⎞
表示: A n ( . . . A 2 ( A 1 ( x ) ) ) = A n ⋅ ⋅ ⋅ A 2 ⋅ A 1 ⋅ ( x y 1 ) A_n(...A_2(A_1(x)))=A_n\cdot \cdot \cdot A_2\cdot A_1\cdot \left( \begin{matrix} x\\ y\\1 \end{matrix} \right) An(...A2(A1(x)))=An⋅⋅⋅A2⋅A1⋅⎝⎛xy1⎠⎞
矩阵满足结合律,而且 A n ⋅ ⋅ ⋅ A 2 ⋅ A 1 A_n\cdot \cdot \cdot A_2\cdot A_1 An⋅⋅⋅A2⋅A1仍得到3×3的矩阵,因此可以把前面的矩阵合成一个3×3矩阵
2.2.7 Decomposing Complex Transforms 复杂变换的分解
变换的矩阵表示: T ( c ) ⋅ R ( α ) ⋅ T ( − c ) T(c)\cdot R(\alpha)\cdot T(-c) T(c)⋅R(α)⋅T(−c)
2.3 3D Transforms
2.3.1 用齐次坐标表示三维坐标
- 3D point = (x,y,z,1)T
- 3D vector=(x,y,z,0)T
(x,y,z,w) (w!=0) 表示3D point (x/w,y/w,z/w)
2.3.2 三维空间中的仿射变换
( 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{matrix} x^{'}\\ y^{'}\\z^{'}\\1 \end{matrix} \right)=\left( \begin{matrix} a&b&c&t_x\\ d&e&f&t_y\\g&h&i&t_z\\0&0&0&1 \end{matrix} \right)\left( \begin{matrix} x\\ y\\z\\1 \end{matrix} \right) ⎝⎜⎜⎛x′y′z′1⎠⎟⎟⎞=⎝⎜⎜⎛adg0beh0cfi0txtytz1⎠⎟⎟⎞⎝⎜⎜⎛xyz1⎠⎟⎟⎞
对应不用齐次坐标的仿射变换:先线性变换,再平移
2.3.3 3D transformations
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{matrix} s_x&0&0&0\\ 0&s_y&0&0\\0&0&s_z&0\\0&0&0&1 \end{matrix} \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 z 0 0 0 1 ) T(t_x,t_y,t_z)=\left( \begin{matrix} 1&0&0&t_x\\ 0&1&0&t_y\\0&0&1&t_z\\0&0&0&1 \end{matrix} \right) T(tx,ty,tz)=⎝⎜⎜⎛100001000010txtytz1⎠⎟⎟⎞
Rotate:
- 绕着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{matrix} 1&0&0&0\\0&\cos\alpha&-\sin\alpha&0\\ 0&\sin\alpha&\cos\alpha&0\\0&0&0&1 \end{matrix} \right) Rx(α)=⎝⎜⎜⎛10000cosαsinα00−sinα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{matrix} \cos\alpha&0&\sin\alpha&0\\0&1&0&0\\ -\sin\alpha&0&\cos\alpha&0\\0&0&0&1 \end{matrix} \right) Ry(α)=⎝⎜⎜⎛cosα0−sinα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{matrix} \cos\alpha&-\sin\alpha&0&0\\ \sin\alpha&\cos\alpha&0&0\\0&0&1&0\\0&0&0&1 \end{matrix} \right) Rz(α)=⎝⎜⎜⎛cosαsinα00−sinαcosα0000100001⎠⎟⎟⎞
注: R y ( α ) R_y(\alpha) Ry(α)中 sin α 和 − sin α \sin\alpha和-\sin\alpha sinα和−sinα的位置与 R x ( α ) R_x(\alpha) Rx(α)和 R z ( α ) R_z(\alpha) Rz(α)相反,因为z叉乘x等于y,与x叉乘y等于z,y叉乘z等于x顺序相反
-
Compose any 3D rotation from R x , R y , R z R_x,R_y,R_z Rx,Ry,Rz
R x y z ( α , β , γ ) = R x ( α ) R y ( β ) R z ( γ ) R_{xyz}(\alpha,\beta,\gamma)=R_x(\alpha)R_y(\beta)R_z(\gamma) Rxyz(α,β,γ)=Rx(α)Ry(β)Rz(γ)( α , β , γ \alpha,\beta,\gamma α,β,γ称为欧拉角)
Rodrigues’ Rotation Formula(罗德里格斯旋转公式):
旋转轴:n(沿着某一个轴方向旋转,默认起点在原点上,方向是该轴的方向)
旋转角度: α \alpha α
注:N与叉乘矩阵形式相同
2.4 Viewing transformation 观测变换
2.4.1 View(视图)/Camera transformation
- Define the camera first
- Position e ⃗ \vec{e} e
- Look-at / gaze direction g ^ \widehat{g} g
- Up direction t ^ \widehat{t} t
- Key observation:如果相机和所有物体一起移动,“照片”将是相同的,所以:
- 我们可以把相机移动到原点(0,0,0),up direction在Y轴上,look-at direction在-Z轴上(把相机先放到一个标准位置上)
- 同时把物体随相机一起移动
-
Transform the camera by M v i e w M_{view} Mview :
- camera原图和移动后的图:
-
M v i e w M_{view} Mview 过程:
- Translates e to origin
- Rotates g to -Z
- Rotates t to Y
- Rotates (g x t) To X
-
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(先平移再旋转)
-
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{matrix} 1&0&0&-x_e\\ 0&1&0&-y_e\\0&0&1&-z_e\\0&0&0&1 \end{matrix} \right) Tview=⎝⎜⎜⎛100001000010−xe−ye−ze1⎠⎟⎟⎞
-
将g旋转到-Z,t旋转到Y,(g x t)旋转到x比较困难,所以我们考虑该旋转的逆操作:X到(g x t), Y到t, Z到-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{matrix} 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{matrix} \right) Rview−1=⎝⎜⎜⎛xg ×t yg ×t zg ×t 0xtytzt0x−gy−gz−g00001⎠⎟⎟⎞
旋转矩阵是正交矩阵,因此旋转矩阵的逆就是它的转置
所以: 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{matrix} 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{matrix} \right) Rview=⎝⎜⎜⎛xg ×t xtx−g0yg ×t yty−g0zg ×t ztz−g00001⎠⎟⎟⎞
-
2.4.2 Projection(投影) transformation
-
Orthographic(正交) projection
-
把一个[l, r] x [b, t] x [f, n] (左<右,底<高,远<近)的长方体映射为"canonical(正则、规范、标准)" cube [-1,1]3:
-
Translate (center to origin) first, then scale (length/width/height to 2):
原理:
- translate:中心点坐标是 ( r + l 2 , t + b 2 , n + f 2 ) (\frac{r+l}{2},\frac{t+b}{2},\frac{n+f}{2}) (2r+l,2t+b,2n+f),平移到 ( 0 , 0 , 0 ) (0,0,0) (0,0,0)
- scale:原图在x轴、y轴、z轴覆盖范围是r-l,t-b,n-f;“canonical(正则、规范、标准)” cube的覆盖范围是2
-
-
Perspective(透视) projection
-
两个图形对比可得:先把远平面“挤”成近平面大小,再做正交投影就可以了**(为什么这么操作???原理???)**
规定:近平面永远不变,远平面“挤”的时候z保持不变,远平面中心点不发生变化
-
Y-Z平面:
-
由Y-Z平面可以推导出: y ′ = n z y y^{'}=\frac{n}{z}y y′=zny
类比X-Z平面可得: x ′ = n z x x^{'}=\frac{n}{z}x x′=znx
-
齐次坐标表示为: ( x y z 1 ) ⇒ ( n x / z n y / z u n k n o w n 1 ) = = ( n x n y s t i l l u n k n o w n z ) \left( \begin{matrix} x\\ y\\z\\1 \end{matrix} \right)\Rightarrow \left( \begin{matrix} nx/z\\ ny/z\\unknown\\1 \end{matrix} \right)==\left( \begin{matrix} nx\\ ny\\still\quad unknown\\z \end{matrix} \right) ⎝⎜⎜⎛xyz1⎠⎟⎟⎞⇒⎝⎜⎜⎛nx/zny/zunknown1⎠⎟⎟⎞==⎝⎜⎜⎛nxnystillunknownz⎠⎟⎟⎞
-
-
因此得到**“squish” (persp to ortho)** projection: M p e r s p → o r t h o 4 × 4 M^{4\times 4}_{persp\rightarrow ortho} Mpersp→ortho4×4
由此可推导出:
为求第三行元素可用性质:
-
Any point on the near plane will not change:
所以 M p e r s p → o r t h o M_{persp\rightarrow ortho} Mpersp→ortho第三行元素的形式一定是 ( 0 0 A B ) \left( \begin{matrix} 0&0&A&B \end{matrix} \right) (00AB)(因为上式n2与x,y无关):
( 0 0 A B ) ( x y n 1 ) = n 2 \left( \begin{matrix} 0&0&A&B \end{matrix} \right)\left( \begin{matrix} x\\ y\\n\\1 \end{matrix} \right)=n^2 (00AB)⎝⎜⎜⎛xyn1⎠⎟⎟⎞=n2
可得: A n + B = n 2 An+B=n^2 An+B=n2
-
Any point’s z on the far plane will not change(且远平面中心点保持不变):
( 0 0 f 1 ) ⇒ ( 0 0 f 1 ) = = ( 0 0 f 2 f ) \left( \begin{matrix} 0\\0\\f\\1 \end{matrix} \right)\Rightarrow \left( \begin{matrix} 0\\ 0\\f\\1 \end{matrix} \right)==\left( \begin{matrix} 0\\ 0\\f^2\\f \end{matrix} \right) ⎝⎜⎜⎛00f1⎠⎟⎟⎞⇒⎝⎜⎜⎛00f1⎠⎟⎟⎞==⎝⎜⎜⎛00f2f⎠⎟⎟⎞
可得: A f + B = f 2 Af+B=f^2 Af+B=f2
综上所述可得:
-
-
最终: 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\rightarrow ortho} Mpersp=MorthoMpersp→ortho
-
field-of-view(fovY):垂直的可视角度
aspect ratio:宽高比
-
三、Rasterization 光栅化
MVP变换是模型变换(M)、视角变换(V)、投影变换(P)的统称。MVP变换操作的是三维空间中的点,经过MVP变换后会被映射到标准二维平面上(实际上这个标准二维平面仍保留了z轴坐标)。
在MVP变换后,我们得到了三维坐标在标准二维平面上的投影,接下来可以进行Viewport transform。
Viewport变换只做了一件事:将投影变换得到的标准二维平面调整到显示屏幕上。
因此,Viewport变换本质是一个放缩+平移的过程。
3.1 Canonical Cube to Screen
将标准立方体内的内容映射到屏幕空间
3.1.1 Raster and Pixel (光栅和像素)
-
Raster == screen in German
Rasterize == drawing onto the screen
-
Pixel(picture element)
- A pixel is a little square with uniform color(待定)
- Color is a mixture of (red,green,blue)
-
屏幕:
-
是一个二维数组,数组中的每个元素是一个像素
-
数组的大小(像素的个数)称为分辨率
-
一个像素内只能有一种颜色填充(不存在多种颜色或渐变等)
-
3.1.2 Screen space(屏幕空间)
Defining:
-
所有像素区间: ( 0 , 0 ) (0,0) (0,0)到 ( w i d t h − 1 , h e i g h t − 1 ) (width - 1,height - 1) (width−1,height−1)
eg:蓝色区域的坐标是 ( 2 , 1 ) (2,1) (2,1)
-
像素的中心: ( x + 0.5 , y + 0.5 ) (x + 0.5,y + 0.5) (x+0.5,y+0.5)
-
屏幕包含范围: ( 0 , 0 ) (0,0) (0,0)到 ( w i d t h , h e i g h t ) (width,height) (width,height)
3.1.3 Viewport transform(视口变换)
-
Irrelevant to z(先忽略z) and Transform in xy plane: [ − 1 , 1 ] 2 [-1,1]^2 [−1,1]2 to [ 0 , w i d t h ] × [ 0 , h e i g h t ] [0,width]\times [0,height] [0,width]×[0,height]
Viewport transform matrix:
先将原图宽高从2变为width和height,再将中心为(0,0)变为左下角为(0,0)(将中心从(0,0)移到(width/2,height/2))
3.2 Drawing to Raster Displays
3.2.1 Triangles - Fundamental Shape Primitives(三角形-基础图元)
- 基础图元:三角形可以看成是基础图元,用它可以构建出不同的图元
- 平面:一个三角形必定是一个平面
- 内外定义:三角形是可以通过顶点环绕顺序来描述其内外性的,方便做面剔除等操作**(???)**
- 插值:三角形内部插值十分方便**(???)**
3.2.2 Sampling(采样)
-
当输入三角形顶点坐标时,通过采样判断对应屏幕上的像素区域。
-
采样就是对方程离散化的一个过程,在这里我们通过对每一个像素进行判断,如果它的中心点在三角形内部,那么它就是属于三角形的。
- 判断每一个像素点的中心是否在三角形内部,是为1,否为0
-
判断一个点是否在三角形内部:
叉乘(需要沿着顶点顺序叉乘):
P 0 P 1 ⃗ × P 0 Q ⃗ > 0 : Q \vec{P_0P_1}\times \vec{P_0Q}>0:Q P0P1×P0Q>0:Q在 P 0 P 1 P_0P_1 P0P1的左侧
P 1 P 2 ⃗ × P 1 Q ⃗ > 0 : Q \vec{P_1P_2}\times \vec{P_1Q}>0:Q P1P2×P1Q>0:Q在 P 1 P 2 P_1P_2 P1P2的左侧
P 2 P 0 ⃗ × P 2 Q ⃗ < 0 : Q \vec{P_2P_0}\times \vec{P_2Q}<0:Q P2P0×P2Q<0:Q在 P 2 P 0 P_2P_0 P2P0的右侧
因此Q在三角形外(Q若在三角形内,叉乘结果应全是正数或负数)
注:点在三角形边上,暂时不做处理,可以自己规定(openGL等有明确规定)
3.2.3 光栅化加速方法
-
Bounding Box(包围盒):
-
直接用整个屏幕依次遍历所有像素点来绘制效率太低了,因此我们确定好一个包围盒,直接在包围盒里遍历像素点效率大大提高。包围盒取三角形三个顶点的最大和最小的X值和Y值。
-
确定好包围盒后,遍历此 bounding box 内的所有像素 。然后,使用像素中心的屏幕空间坐标来检查中心点是否在三角形内(即采样中提到的,用的是像素中心而非像素点来)。
-
-
选取三角形覆盖区域每一行的最左和最右(相当于每一行有一个单独的包围盒)。
注:适用于窄长及旋转过的三角形
3.3 Antialiasing(抗锯齿/反走样)
3.3.1 Sampling Artifacts in Computer Graphics
Artifact:Errors / Mistakes / Inaccuracies(计算机图形学中的专业术语)
-
Jaggies——sampling in space(锯齿)
-
Moiré Patterns——undersampling images(摩尔纹)
-
Wagon Wheel Illusion——sampling in time(车轮效应)
-
Many more…
走样问题本质:Signals are changing too fast (high frequency), but sampled too slowly.
信号变化太快(高频),但采样速度太慢。
3.3.2 Frequency Domain(频域)
频域是描述信号在频率方面特性时用到的一种坐标系。
-
Fourier Transform Decomposes A Signal Into Frequencies(傅里叶变换把信号分解成频率)
傅里叶变换可以把一个函数从时域(横轴是时间,纵轴是信号的变化)转变成频域(横轴是频率,纵轴是该频率信号的幅度)
-
时域与频域:
-
任何一个函数波形(如矩形波)都可以用多个正弦函数波形叠加而成:
-
在这几幅图中,最前面黑色的线就是所有正弦波叠加而成的总和,也就是越来越接近矩形波的那个图形。而后面依不同颜色排列而成的正弦波就是组合为矩形波的各个分量。这些正弦波按照频率从低到高从前向后排列开来,而每一个波的振幅都是不同的:
时域中低频分量蕴含能量大,因此幅度比较大;高频分量能量比较小,幅度比较小。
-
正弦波就是一个圆周运动在一条直线上的投影。所以频域的基本单元也可以理解为一个始终在旋转的圆:
-
综上所述可以得到时域与频域的关系,以及傅里叶级数的作用:
-
-
傅里叶变换和逆变换公式:
-
-
Aliases(走样)
- 更高的频率需要更快的采样,采样不足会导致“走样”。
- 在相同的采样方法下无法区分两种完全不同的频率,叫做“走样”。
3.3.3 Filtering(滤波)
Getting rid of certain frequency contents(去掉某些特定的频率)
-
滤波种类:
-
右图中按照箭头方向频率逐渐升高,即中心点为低频信号,往外拓展的为高频信号。
-
High-pass filter(高通滤波器):高频信号可以通过,只剩下图像的边界(信号发生剧烈变化的地方)。
-
Low-pass filter(低通滤波器):低频信号可以通过,模糊了图像的边界。
-
中通滤波器:留下高频信息和低频信息中间位置,即某一段的信息。
-
-
Convolution(卷积)
Filtering = Convolution (= Averaging)
- 卷积定义:
- 卷积定理:具体分为时域卷积定理和频域卷积定理,时域卷积定理即时域内的卷积对应频域内的乘积;频域卷积定理即频域内的卷积对应时域内的乘积,两者具有对偶关系。
- Box Filter是低通滤波器,其在时域越大,在频域上越小。
3.3.4 Sampling = Repeating Frequency Contents
时域上的采样就是在重复原始信号的频谱。
-
时域和频域上的采样:
- 时域上的乘积等于频域上的卷积:
- (左侧)时域:(a)ש=(e)
- (右侧)频域:(b)*(d)=(f)
- ©和(d)都是冲激函数:
- 时域上乘积以后获得的是对应冲激函数上有值的点。
- 频域上卷积之后相当于是对原图的复制粘贴在冲激函数上有值的位置。
-
- 时域上的乘积等于频域上的卷积:
-
Aliasing = Mixed Frequency Contents:
- (d)中 f s f_s fs的大小就是由采样频率来决定,采样越稀疏,原始信号复制粘贴的频谱之间的间隔越小,一旦发生混叠,就产生走样。
- 那么就可以知道消除走样的方法:(1)增加采样频率,相当于增大频域的间隔,使其不容易重叠。
(2)模糊化操作,使其不包含高频信号,以至于不会重叠。
3.3.5 Antialiasing
-
先进行滤波操作(把信号模糊,把高频信号砍掉),再采样。
-
对于三角形覆盖的每个像素,其平均值是内部被三角形覆盖的像素。
-
Antialiasing By Supersampling (MSAA):
多重采样抗锯齿:将一个像素分成多个小的像素,看每个小像素中心是否在三角形内,近似计算该像素的三角形覆盖率。
MSAA是反走样的模糊处理,不是增加分辨率。
- 未用MSAA前,每像素一个采样点:
- MSAA过程:
- 消耗:增大了计算量。
- 优化:不使用均匀分布,部分样本得到复用。
-
其它抗锯齿方法:
-
FXAA (Fast Approximate AA):先获得有锯齿的图,再处理去除锯齿(与采样无关,是一个在图像层面的抗锯齿方法)。
-
找到边界,换成没有锯齿的边界,(图像匹配)非常快。
-
方法和采样无关,采样虽然有误,但是这种方法可以弥补。
-
-
TAA (Temporal AA) :与时间相关,借助前面帧的信息。(???)
- 静态场景,相邻两帧用同一像素中不同位置上的点来采样。
- 复用上一帧的结果。
- 相当于把MSAA对应的样本分布在时间上。
-
-
Super resolution / super sampling:超分辨率/超采样
- From low resolution to high resolution
- Essentially still “not enough samples” problem:本质上仍然存在“样本不足”的问题
- DLSS (Deep Learning Super Sampling) :深度学习超采样**(???)**
3.4 Visibility / occlusion(可见性/闭塞)
3.4.1 Painter’s Algorithm(画家算法):
深度:物体离视点的距离
-
画家算法也叫作优先填充,它是三维计算机图形学中处理可见性问题的一种解决方法。当将三维场景投影到二维平面的时候,需要确定哪些多边形是可见的,哪些是不可见的。
-
“画家算法”表示头脑简单的画家首先绘制距离较远的场景,然后用绘制距离较近的场景覆盖较远的部分。画家算法首先将场景中的多边形根据深度进行排序( O ( n l o g n ) O(nlogn) O(nlogn)),然后按照顺序进行描绘。这种方法通常会将不可见的部分覆盖,这样就可以解决可见性问题。
-
在不可解的深度顺序下,画家算法可能无法解决可见性问题。在这个例子中,三角形 P、Q、R在深度上互相遮挡,我们无法确定三角形的深度顺序:
3.4.2 Z-Buffer(深度缓存/深度缓冲)
-
左边是渲染图(依据所指定的材料、灯光、背景等的设置,将场景中创建的几何对象实体化显示出来)
右边是深度缓存图(记录图像每个像素的最浅深度)
-
深度缓存算法(逐步替换深度值):
-
思路:
-
对于每一个像素点,缓存当前像素点最小深度(离我们最近的点)的值。
-
使用额外的缓存保存深度信息和值信息:
-
frame buffer:保存颜色值信息
-
depth buffer:保存深度信息
-
注意:为了简单起见,我们假设深度总是正的(-z),是物体到视点的距离,深度越小距离越近,深度越大距离越远。
-
-
伪代码:
-
example:
- 算法时间复杂度是 O ( n ) O(n) O(n)(假定每一个三角形覆盖的像素范围恒定),因为相比画家算法来说,深度缓存算法可以不关心画图的顺序问题(画家算法必须先画偏后面的物体,否则前方物体看你会被覆盖),只是不断比较找出当前像素的最小深度值。
- 如果在对MSAA的结果进行深度缓存操作,需要记录每一个采样点的深度。
- Z-buffer处理不了透明物体,需要进行其他的特殊操作。
-
四、Shading 着色
着色(图形学):对不同物体,应用不同材质的过程
4.1 A Simple Shading Model
一个简单的着色模型
4.1.1 Blinn-Phong Reflectance Model(Blinn-Phong反射模型)
Blinn-Phong反射模型是一个经验模型
包含的光照类型:
-
Specular highlights:高光
-
Diffuse reflection:漫反射
-
Ambient lighting:环境光(来自于环境的反射光,属于间接光照)
4.1.2 Shading is Local(着色是局部的)
可以认为物体在局部极小的范围内是平面
-
定义需要输入的数据:
-
观测点相对于着色点的观测方向 v
-
着色点的法线 n
-
光照方向 l
-
物体表面属性,比如color,shininess等
注意:因为定义的都是方向,所以都是单位向量,长度都是1
-
-
shading ≠ shadow:着色不会产生阴影
4.1.3 Diffuse Reflection(漫反射)
-
定义:打到一个物体表面上的光线被均匀地向各个方向反射
-
光照强度(光照能量)与光照方向和法线方向间夹角的余弦值成正比:
-
能量守恒:
对于一个点光源来说,能量集中在一个球壳上向外扩散,随着时间推移,每个球壳上的总能量保持不变,而球壳表面积越来越大。因此各个球壳上一点的光的强度和光线传播的距离的平方成反比:
-
I I I表示单位距离的球壳上一点的光的强度
-
r r r表示光源到着色点的距离
-
I / r 2 I/r^2 I/r2表示距离为r的球壳上着色点的光的强度
-
-
漫反射和观测方向v无关:
-
L d L_d Ld:漫反射值
-
k d k_d kd:漫反射系数,如果为1,表示该着色点完全不吸收能量,全部反射出去;如果为0,表明该着色点表面是黑的,吸收全部能量。
原理:如果该着色点本身有颜色,证明它吸收了部分能量,反射出去的是不吸收的能量。
-
I / r 2 I/r^2 I/r2:光线在该着色点的光照强度(能量)
-
m a x ( 0 , n ⋅ l ) max(0,n\cdot l) max(0,n⋅l):因为向量n和l点乘可以为负数,为负数时是折射的光,在此仅讨论反射光。
-
-
(综上可得)漫反射基本原理:不论从什么方向看,只要光源和物体位置不变,看到的物体亮度都是一样的。
注: k d k_d kd会影响物体整体亮度, k d k_d kd越大,物体越亮。
4.1.4 Specular highlights(高光)
-
定义:表面比较光滑(并非绝对光滑)的物体接收到光线照射时,能够沿着镜面反射方向的周围有一定的分布。当观察方向与镜面放射方向接近(在高光反射范围内),即v和R足够接近时可以看到高光。
-
高光向量与入射光线夹角的一半为法线向量,如果半程向量(即观测方向和入射方向夹角的一半)与法线向量十分接近,则说明观测方向与高光向量十分接近:
- n ⋅ h n\cdot h n⋅h越接近1,表明两个向量越接近;越接近0,表明越远。
- k s k_s ks:镜面反射系数,影响亮度。
- p p p:用来控制高光角度范围(图像中的高光大小)。
-
余弦次方图:
可以看出:仅用余弦或者较小次方的余弦去获得高光,高光随n和h间的角度变化太慢,导致得到的高光范围太大。
4.1.5 Ambient Lighting(环境光)
假设任何一个点接收到的环境光永远是相同的( I a I_a Ia), k a k_a ka是环境光系数,可以近似地得到被反射的环境光 L a L_a La。
-
环境光与入射光照方向和观测方向均无关。
-
环境光的作用是:保证物体没有一个地方完全是黑的,把所有的物体颜色相关的项相加并提升一个亮度展现出来。
4.1.6 Blinn-Phong Reflection Model
将之前讨论的漫反射项、高光、环境光全部相加得到的模型:
4.2 Shading Frequencies
着色频率
如上图,为何同样的几何模型,使用Blinn-Phong反射模型着色后的效果不一样?
因为它们的着色频率不一样,分别按照每个平面、每个顶点、每个像素点进行着色。
4.2.1 Shade each triangle(Flat shading)
逐三角形进行着色,通过三角形的两条边叉积求出每个三角形平面的法线,根据Blinn-Phong反射模型求出整个三角形平面的着色结果。
4.2.2 Shade each vertex(Gouraud shading)
逐顶点进行着色,求出三角形每个顶点的法线,每个顶点单独做着色,然后三角形内部按照差值的方法着色。
4.2.3 Shade each pixel(Phong shading)
逐像素进行着色,首先求出三角形的三个顶点的法线,然后使用插值的方法求出三角形内部每个像素点的法线,最后再求出三角形内部每个像素点的着色结果。
注意:Phong shading是着色频率,与Blinn-Phong着色模型不同。
4.2.4 三种不同频率的着色方法对比
在几何足够复杂的情况下,简单的着色方法也可以得到较好的效果。
4.2.5 逐顶点的法线
- 如果已知想表示的是球形,知道球心,直接连接球心和该顶点。
- 将周围共用该顶点的所有面的法线求平均(简单平均或者加权平均,权重按照面积比)。
4.2.6 逐像素的法线
注意:需要用到重心坐标。
4.3 Graphics(Real-time Rendering)Pipeline
图形管线/实时渲染管线
4.3.1 整个管线
具体过程:
- 输入三维空间中的点
- 将三维空间中的点投影到屏幕上
- 这些点会形成三角形(或者点、线)
- 进行光栅化处理(离散化的过程)
- 着色处理
- 最后输出
4.3.2 主要步骤
-
Vertex Processing
-
Rasterization
-
Fragment Processing
注:Gouraud shading:着色是发生在顶点处,Phong shading:着色是发生在像素处,因此shading可能在不同阶段进行。
纹理映射
4.3.3 Shader Program(着色器)
注:Shader是通用的,对每个顶点或像素进行一次着色。
分类:顶点着色器;像素(片段)着色器
4.3.4 Graphics Pipeline Implementation: GPUs
GPU:专门用于执行图形管道计算的处理器
独立GPU卡(NVIDIA GeForce Titan X)
集成GPU(英特尔CPU芯片的一部分)
4.4 Texture Mapping
纹理映射
4.4.1 为什么要纹理映射
希望能有一种方法定义物体上任何一个点的不同属性,比如漫反射系数 k d k_d kd。
4.4.2 任何一个三维物体的表面本质上都是二维的
地球仪与地图的关系(如下图),三维的地球仪上的任意一个地方(一点)可以同样对应到二维地图上的这个地方:
纹理映射的纹理,指定就是这些二维的图片。我们假设这些图我们可以随意的拉伸扭曲,那么我们就可以把这些图包裹到三维物体上,那么这个过程我们就可以称之为纹理映射。例如把地图裹到一个球上面,那么这个球就变成了地球仪。
4.4.3 纹理应用于表面
前面所说的映射是把纹理包裹到三维物体上,是一个很笼统的说法。实际上纹理映射,我们只需要知道物体表面上的点(也就是着色点)与纹理的对应关系,即三维表面的某个着色点是纹理上的哪个位置,然后着色时 k d k_d kd的取值按照纹理上的值即可。
4.4.4 纹理坐标可视化
每个三角形顶点分配一个纹理坐标(u,v)。
-
在纹理图中,设定从v最大向右下方到u最大的过程是从绿逐渐到红色的过程。
-
纹理映射实际上就是将右边图中每一个小三角形的顶点的坐标(u,v)映射到三维空间中的坐标,规定二维坐标(u,v)的范围都是0-1,因为这样做方便计算。
-
纹理可以被重复使用,但可能会有明显的纹理边缘,因此最好能实现无缝衔接。
4.5 Interpolation Across Triangles:Barycentric Coordinates
在三角形内部插值:重心坐标
4.5.1 引入重心坐标
-
目的:使一些在顶点上的操作在三角形内部进行一个平滑的过渡。
-
插值的操作内容:纹理坐标、颜色、法线等。
-
如何做插值:重心坐标。
4.5.2 定义重心坐标
-
定义:三角形所在平面上的任意一个点都可以用该三角形三个顶点坐标的线性组合来表示,这三个系数 ( α , β , γ ) (\alpha,\beta,\gamma) (α,β,γ)就叫做 ( x , y ) (x,y) (x,y)这一点的重心坐标。
-
注意点:
-
重心坐标的前提条件是 α + β + γ = 1 \alpha+\beta+\gamma=1 α+β+γ=1,因为如果不等于1,求得的点不在该三角形所在平面内。
-
重心坐标定义在一个三角形上,一个三角形对应一个重心坐标。
-
重心坐标可以表示的是三角形所在平面内的所有点(都可以用 ( α , β , γ ) (\alpha,\beta,\gamma) (α,β,γ)表示)。
-
在三角形内部的点还有一个额外的条件: α , β , γ \alpha,\beta,\gamma α,β,γ三个系数都是非负数 。
-
-
三角形顶点坐标也可以通过重心坐标求出:
4.5.3 求重心坐标的方法
-
通过顶点对应三角形面积比求重心坐标
-
每个顶点对应的三角形是在该顶点对面、与之不相邻的三角形。
-
三角形的重心刚好平分三角形为三个面积相等的三角形,因此可以轻易得到重心的重心坐标。
-
-
通过顶点坐标求重心坐标
4.5.6 用重心坐标插值
注:(1)VA, VB, VC可以是位置,纹理坐标,颜色,法线,深度,材质属性…
(2)三维空间中的三角形投影到二维空间后,重心坐标可能会改变;所以三维空间中的属性,应该在三维空间中做插值。
4.6 Applying Textures
纹理应用
4.6.1 简单的纹理映射:漫反射颜色
步骤:
- 对于显示屏幕上的每个点(x,y)
- 算出纹理坐标(u,v)
- 通过纹理坐标(u,v)求出对于的纹理颜色
- 将纹理颜色映射到对于的坐标点(x,y)
4.6.2 Texture Magnification(纹理放大)
-
纹理太小:
-
表现:我们可以发现右图明显的比左图模糊了很多,但是基本纹路来看他们是一模一样的,这是为什么呢?模糊其实就是因为我们纹理过小,在覆盖物体表面时被放大了所导致的。
-
原因:
-
我们的纹理本质上是一张图片,它也存在自身的分辨率,即由像素组成,每个像素有自己的下标,纹理上的像素我们常称为texel。uv对应的像素坐标我们也是可以计算出来的,例如我们纹理每行有1000个像素,那么当u=0.25时,对应的像素横坐标就是39(下标从0开始),v自然也是同理。
-
而我们物体表面最终会显示在屏幕上,屏幕自然也有它的像素,屏幕像素我们称之为pixel。我们每个屏幕像素都会对应到三角形内的一个点,而三角形内的点会有它对应的uv坐标,然后我们通过uv坐标可以找到纹理上对应的纹理像素。也就是说在使用纹理映射时,屏幕像素会对应到纹理像素上。
-
那么当纹理分辨率低时,也就是纹理内部的像素少,这样屏幕像素对应到纹理像素上,它可能就不是一个整数下标的纹理像素,而变成了浮点数。例如我们屏幕像素(50, 50) 对应到纹理像素(5,5),屏幕像素(51, 50) 对应到纹理像素(5.1,5),屏幕像素(52, 50) 对应到纹理像素(5.2,5),然后对于浮点数我们会四舍五入成整数,那么屏幕像素(50, 50),(51, 50),(52, 50)对应的纹理像素都是(5,5),也就是说当我们纹理太小的时候,我们多个屏幕像素会对应到一个相同的纹理像素上,所以产生了模糊。
-
-
纹理放大效果:
-
-
Bilinear Interpolation(双线性插值)
-
图中的每个小方格我们当做是一个纹理像素,黑点是纹理像素的中心点。此时我们有个屏幕像素对应到了纹理像素的红点位置。若按照四舍五入的方式,那么此时红点得到的纹理值就是最近黑点的纹理值,会造成我们前面所说的模糊问题。
-
首先,找到这个红点邻近的周围四个点,然后找到四个点中的左下角的点当作坐标轴的原点,确定红点在这个坐标轴的水平距离s和竖直距离t(s和t均位于0~1间,因为设定两个像素点的距离为1)。
-
然后,通过水平的插值求出u0和u1,进而通过竖直的插值求出红点的位置。至此可以得到这个点平滑过渡的颜色变化位置。
其中:lerp(x, v0, v1) = v0 + x(v1 - v0)表示x位于v0和v1之间,求x的具体位置。 验证式子正确性可令x=0和1分别代入,求得x分别位于v0和v1处。
-
双线性插值后,红点的颜色就会和边上四个像素结合起来,而不再简单的等于最近黑点的颜色。
除了双线性插值外,还有双三次插值(Bicubic interpolation),得到的效果就会更好。双三次插值取得则是周围十六个纹理像素做插值,不再是线性插值了,具体原理这里就不过多介绍了。
-
4.6.3 纹理太大
可能会导致更严重的问题,例如下图,在进行压缩后,图片远处出现了摩尔纹,近处会呈现锯齿状(走样)。
Curves and Meshes 曲线和曲面
Ray Tracing 光线追踪
Animation/Simulation 动画与模拟
浮点数。例如我们屏幕像素(50, 50) 对应到纹理像素(5,5),屏幕像素(51, 50) 对应到纹理像素(5.1,5),屏幕像素(52, 50) 对应到纹理像素(5.2,5),然后对于浮点数我们会四舍五入成整数,那么屏幕像素(50, 50),(51, 50),(52, 50)对应的纹理像素都是(5,5),也就是说当我们纹理太小的时候,我们多个屏幕像素会对应到一个相同的纹理像素上,所以产生了模糊。
-
纹理放大效果:
-
Bilinear Interpolation(双线性插值)
-
图中的每个小方格我们当做是一个纹理像素,黑点是纹理像素的中心点。此时我们有个屏幕像素对应到了纹理像素的红点位置。若按照四舍五入的方式,那么此时红点得到的纹理值就是最近黑点的纹理值,会造成我们前面所说的模糊问题。
-
首先,找到这个红点邻近的周围四个点,然后找到四个点中的左下角的点当作坐标轴的原点,确定红点在这个坐标轴的水平距离s和竖直距离t(s和t均位于0~1间,因为设定两个像素点的距离为1)。
-
然后,通过水平的插值求出u0和u1,进而通过竖直的插值求出红点的位置。至此可以得到这个点平滑过渡的颜色变化位置。
其中:lerp(x, v0, v1) = v0 + x(v1 - v0)表示x位于v0和v1之间,求x的具体位置。 验证式子正确性可令x=0和1分别代入,求得x分别位于v0和v1处。
-
双线性插值后,红点的颜色就会和边上四个像素结合起来,而不再简单的等于最近黑点的颜色。
除了双线性插值外,还有双三次插值(Bicubic interpolation),得到的效果就会更好。双三次插值取得则是周围十六个纹理像素做插值,不再是线性插值了,具体原理这里就不过多介绍了。
-
4.6.3 纹理太大
可能会导致更严重的问题,例如下图,在进行压缩后,图片远处出现了摩尔纹,近处会呈现锯齿状(走样)。