[预言家]:这将是一个插满Flag、充满着迷之气息、啪啪打脸不断的自学笔记系列…
终于下定决心来开坑ShaderLab啦!
虽然目前版本的Shader Graph一片大好,但是还是觉得作为一个立志成为TA的人再怎么着也要学学Shader!
把ShaderLab和ShaderGraph放在一起学习也是因为我认为它们俩相辅相成(萌新那放不下连连看的执念)
搞明白了graph的节点,写到lab里无非是些语法的问题;搞明白了lab里的语法,写一个shader无非是如何设计出酷炫的效果的问题(一个不知天高地厚的萌新如是说)
本篇文章将对ShaderLab编程无关,但是对于理解Shader很重要的一些基本常识做一个总结。因为只是总结,所以不会对涉及到的计算机图形学相关公式给出计算或推导过程,如有需要可自行移步相关教程或帖子。
(墙裂推荐GAMES101-现代计算机图形学入门-闫令琪,推导过程十分清晰)
(#Flag1-对于一些有图更好理解的地方,抽空补图)
计算机图形学的基本计算
向量乘法
1. 点乘 Dot (Scalar) Product —— 得到数值
1.1 计算方法
a ⃗ \vec a a = ( a 1 a_{1} a1, a 2 a_{2} a2,…, a n a_{n} an), b ⃗ \vec b b = ( b 1 b_{1} b1, b 2 b_{2} b2,…, b n b_{n} bn)
a ⃗ \vec a a · b ⃗ \vec b b = a 1 a_{1} a1 b 1 b_{1} b1 + a 2 a_{2} a2 b 2 b_{2} b2 + … + a n a_{n} an b n b_{n} bn
a ⃗ \vec a a · b ⃗ \vec b b = | a ⃗ \vec a a| · | b ⃗ \vec b b | c o s θ cosθ cosθ
当 a ⃗ \vec a a 、 b ⃗ \vec b b 为单位向量时, c o s θ cosθ cosθ = a ⃗ \vec a a · b ⃗ \vec b b
1.2 计算机图形学中的应用
#抽空补图
- 计算一个向量在另一个向量上的投影 → 在两个垂直的方向上分解向量
- 计算向量方向的偏离程度
c o s θ cosθ cosθ 越接近1, θ θ θ 越小,二者越靠近;反之, θ θ θ 越大,二者越远。 - 判断物体前后/正反
利用点乘后值的正负判断,若< 0,则 c o s θ cosθ cosθ < 0,为背面;反之,为正面。
2. 叉乘 Cross Product —— 得到向量
2.1 计算方法
a ⃗ \vec a a × b ⃗ \vec b b = - b ⃗ \vec b b × a ⃗ \vec a a → 不满足交换律
| a ⃗ \vec a a × b ⃗ \vec b b| = | a ⃗ \vec a a| | b ⃗ \vec b b| s i n θ sinθ sinθ
a ⃗ \vec a a × a ⃗ \vec a a = 0 ⃗ \vec 0 0, 0 ⃗ \vec 0 0为长度为0的向量(嗯?)
右手定则:四指方向为 a ⃗ \vec a a 指向 b ⃗ \vec b b,拇指方向为结果向量的指向。
右手系: x ⃗ \vec x x × y ⃗ \vec y y = z ⃗ \vec z z (详见下文旋转矩阵)
2.2 计算机图形学中的应用
#抽空补图
- 判断左右
- 判断里外
矩阵运算
1. 乘法
前提 & 结果:[m × n] × [n × p] = [m × p]
特点:不满足交换律,但满足结合律
1.1 计算方法
C[m × p] = A[m × n] × B[n × p],其实就是在每个对应的数字做向量点积,举例:
A A_{} A = [ 1 2 3 4 5 6 7 8 ] \begin{bmatrix} 1&2&3&4\\5&6&7&8\end{bmatrix} [15263748], B B_{} B = [ 9 10 0 1 2 3 4 5 ] \begin{bmatrix} 9&10\\0&1&\\ 2&3\\ 4&5\end{bmatrix} ⎣⎢⎢⎡902410135⎦⎥⎥⎤,求第一行第二列的数字,就用A矩阵中的第一行[1,2,3,4]乘以B矩阵中的第二列[10,1,3,5],得出结果为1×10+2×1+3×3+4×5 = 41
1.2 计算机图形学中的应用
- 坐标变换:从平移、旋转、缩放,到坐标系变换。具体见下文。
2. 转置
2.1 计算方法
就直接转置嘛
2.2 计算机图形学中的应用
待补充
3. 逆
3.1 计算方法
逆矩阵 * 矩阵 = 单位矩阵
3.2 计算机图形学中的应用
待补充
(怎么感觉把整个矩阵这里水过去了…)
齐次坐标下的坐标变换
1. 旋转
绕某一轴旋转 = 在其他两轴所组成的平面进行旋转
R x ( y o z ) R_{x(yoz)} Rx(yoz) = [ 1 0 0 0 0 c o s θ − s i n θ 0 0 s i n θ c o s θ 0 0 0 0 1 ] \begin{bmatrix} 1&0&0&0\\0&cosθ&-sinθ&0\\ 0&sinθ&cosθ&0\\ 0&0&0&1\end{bmatrix} ⎣⎢⎢⎡10000cosθsinθ00−sinθcosθ00001⎦⎥⎥⎤
R y ( z o x ) R_{y(zox)} Ry(zox) = [ c o s θ 0 s i n θ 0 0 1 0 0 − s i n θ 0 c o s θ 0 0 0 0 1 ] \begin{bmatrix} cosθ&0&sinθ&0\\ 0&1&0&0\\ -sinθ&0&cosθ&0\\ 0&0&0&1\end{bmatrix} ⎣⎢⎢⎡cosθ0−sinθ00100sinθ0cosθ00001⎦⎥⎥⎤
R z ( x o y ) R_{z(xoy)} Rz(xoy) = [ c o s θ − s i n θ 0 0 s i n θ c o s θ 0 0 0 0 1 0 0 0 0 1 ] \begin{bmatrix} cosθ&-sinθ&0&0\\ sinθ&cosθ&0&0\\ 0&0&1&0\\ 0&0&0&1\end{bmatrix} ⎣⎢⎢⎡cosθsinθ00−sinθcosθ0000100001⎦⎥⎥⎤
R x R_{x} Rx和 R z R_{z} Rz直接在二维旋转矩阵的基础上插入所绕轴,并用0和1替代。
R y R_{y} Ry表现出来的 s i n θ sinθ sinθ的正负和 R x R_{x} Rx和 R z R_{z} Rz相反,可以理解为:
在 z o x zox zox平面中,并没有按照 x y z xyz xyz的顺序相乘(如 x o y xoy xoy、 x o z xoz xoz、 y o z yoz yoz),所以要在 θ θ θ前加一个负号,化简后得到了 s i n θ sinθ sinθ与 R x R_{x} Rx、 R z R_{z} Rz相反的 R y R_{y} Ry
至于为啥 R y R_{y} Ry是 z o x zox zox不是 x o z xoz xoz,可以画一个右手系的坐标系,然后用向量叉乘的右手定则比划一下就了解啦。
2. 缩放
S S_{} S = [ S x 0 0 0 0 S y 0 0 0 0 S z 0 0 0 0 1 ] \begin{bmatrix} Sx&0&0&0\\0&Sy&0&0\\ 0&0&Sz&0\\ 0&0&0&1\end{bmatrix} ⎣⎢⎢⎡Sx0000Sy0000Sz00001⎦⎥⎥⎤
3. 平移
T T_{} T = [ 1 0 0 T x 0 1 0 T y 0 0 1 T z 0 0 0 1 ] \begin{bmatrix} 1&0&0&Tx\\0&1&0&Ty\\ 0&0&1&Tz\\ 0&0&0&1\end{bmatrix} ⎣⎢⎢⎡100001000010TxTyTz1⎦⎥⎥⎤
4. 复合变换
将想要的变换一路左乘,最后可以利用结合律来合成一个复合变换矩阵。
由于变换的默认参照点是原点,在每次进行变换前,都要先乘 T T_{} T把变换的中心点平移至原点,随后再乘 S S_{} S、 R R_{} R进行缩放、旋转,最后再乘以 T − 1 T^{-1}_{} T−1的逆矩阵,平移回初始位置。
注意:复合变换矩阵中,最后做平移变换(关系到做变换时需不需要另外再乘一个平移矩阵)
到这里基本的图形学计算就都复习完咯!撒花!
下次好好整理复习渲染流水线!
…
…
哈哈…回头看了看似乎又成了一篇又臭又长的入坑文呢…
(写这个文章最喜欢的地方竟然是敲latex哈哈哈哈哈还自己蒙出来个 T − 1 T^{-1}_{} T−1写法感觉有点好玩噗)