第四章 数学计算
正交矩阵
M − 1 = M T M^{-1}=M^T M−1=MT时,M为正交矩阵
推论/不计算 M − 1 M^{-1} M−1判断是否为正交矩阵:其每一行所表示的向量为单位向量,并且每一行向量之间互相垂直
-
性质1:其逆矩阵/转置矩阵也是正交矩阵
-
性质2:正交矩阵的积也是正交矩阵
齐次坐标:使用四维矩阵来计算变换过程
仿射变换:合并线性变换和平移变换的变换(因为平移变换是非线性的,所以需要多加一个纬度来表示平移)
四维矩阵
变换矩阵
M = [ M 3 ∗ 3 t 3 ∗ 1 0 1 ∗ 3 1 ] M=\left[\begin{matrix} M_{3*3}&t_{3*1}\\0_{1*3}&1\end{matrix}\right] M=[M3∗301∗3t3∗11]
M 3 ∗ 3 M_{3*3} M3∗3缩放、旋转矩阵
t 3 ∗ 1 t_{3*1} t3∗1平移
点和方向的矩阵
p = [ x y z 0 / 1 ] p=\left[\begin{matrix} x\\y\\z\\0/1\end{matrix}\right] p=⎣⎢⎢⎡xyz0/1⎦⎥⎥⎤
第四行为0时表示方向
第四行为1时表示点
表示方向时,应用平移矩阵不会被影响
点/方向矩阵应用变化矩阵时,为右乘即 p ′ = M p p'=Mp p′=Mp
平移矩阵
[ 1 0 0 t x 0 1 0 t y 0 0 1 t z 0 0 0 1 ] \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] ⎣⎢⎢⎡100001000010txtytz1⎦⎥⎥⎤
缩放矩阵
[ k x 0 0 0 0 k y 0 0 0 0 k z 0 0 0 0 1 ] \left[\begin{matrix} k_x&0&0&0\\0&k_y&0&0 \\0&0&k_z&0\\ 0&0&0&1 \end{matrix}\right] ⎣⎢⎢⎡kx0000ky0000kz00001⎦⎥⎥⎤
按x轴旋转矩阵
[ 1 0 0 0 0 c o s α − s i n α 0 0 s i n α c o s α 0 0 0 0 1 ] \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] ⎣⎢⎢⎡10000cosαsinα00−sinαcosα00001⎦⎥⎥⎤
按y轴旋转矩阵
[ c o s α 0 s i n α 0 0 1 0 0 − s i n α 0 c o s α 0 0 0 0 1 ] \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] ⎣⎢⎢⎡cosα0−sinα00100sinα0cosα00001⎦⎥⎥⎤
按z轴旋转矩阵
[ c o s α − s i n α 0 0 s i n α c o s α 0 0 0 0 1 0 0 0 0 1 ] \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] ⎣⎢⎢⎡cosαsinα00−sinαcosα0000100001⎦⎥⎥⎤
重要推论
- 平移矩阵必定不是正交矩阵
- 缩放矩阵的缩放为1时为正交矩阵
- 如果 k x = k y = k z = k k_x=k_y=k_z=k kx=ky=kz=k并且只考虑方向不考虑位置的话(降维到三维),乘 1 k 1\over k k1后为正交矩阵
- 如果非等比例缩放,则不为正交矩阵
- 旋转矩阵必然是正交矩阵,同时由性质2得旋转矩阵无论怎么旋转依旧是正交矩阵
复合变换
由于矩阵乘法不满足交换律,所以要注意变化顺序
绝大情况下,变换顺序为先缩放再旋转再平移
p ′ = M 平 移 M 旋 转 M 缩 放 p p'=M_{平移}M_{旋转}M_{缩放}p p′=M平移M旋转M缩放p
复合旋转的坐标系选择以及旋转顺序选择
对于旋转 ( θ x , θ y , θ z ) (\theta_x,\theta_y,\theta_z) (θx,θy,θz),Unity规定旋转顺序为zxy
很明显有两种旋转坐标选择,
- 一种是总是按最开始的坐标系E进行旋转
- 另一种是让坐标系E跟着一起旋转
如果第一种的旋转顺序为zxy
那么第二种的旋转顺序就是yxz,此时两种旋转的结果相同
Unity中说明的是第一种情况
空间坐标系的转换
对于父坐标空间P和子空间坐标C需要进行点A的坐标的转换
A p = M c − p A c A_p=M_{c-p}A_c Ap=Mc−pAc
A c = M p − c A p = M c − p − 1 A p A_c=M_{p-c}A_p=M_{c-p}^{-1}A_p Ac=Mp−cAp=Mc−p−1Ap
设C在P下的单位坐标为 [ x ⃗ , y ⃗ , z ⃗ ] \left[\begin{matrix} \vec x,\vec y,\vec z \end{matrix}\right] [x,y,z]
C的原点坐标为 O ⃗ c \vec O_c Oc
A在C下的坐标为(a,b,c)
则A在P下的坐标为
A p = O ⃗ c A_p=\vec O_c Ap=Oc+ [ x ⃗ y ⃗ z ⃗ ] [ a b c ] \left[\begin{matrix} \vec x&\vec y&\vec z \end{matrix}\right] \left[\begin{matrix} a\\b\\c \end{matrix}\right] [xyz]⎣⎡abc⎦⎤
展开到齐次坐标系
A p = [ 1 0 0 x O c 0 1 0 y O c 0 0 1 z O c 0 0 0 1 ] [ ∣ ∣ ∣ 0 x ⃗ y ⃗ z ⃗ 0 ∣ ∣ ∣ 0 0 0 0 1 ] [ a b c 1 ] A_p=\left[\begin{matrix} 1&0&0&x_{Oc} \\0&1&0&y_{Oc}\\0&0&1&z_{Oc}\\0&0&0&1\end{matrix}\right] \left[\begin{matrix} |&|&|&0 \\ \vec x&\vec y&\vec z&0\\|&|&|&0\\0&0&0&1\end{matrix}\right] \left[\begin{matrix} a\\b\\c\\1 \end{matrix}\right] Ap=⎣⎢⎢⎡100001000010xOcyOczOc1⎦⎥⎥⎤⎣⎢⎢⎡∣x∣0∣y∣0∣z∣00001⎦⎥⎥⎤⎣⎢⎢⎡abc1⎦⎥⎥⎤
A p = [ ∣ ∣ ∣ x O c x ⃗ y ⃗ z ⃗ y O c ∣ ∣ ∣ z O c 0 0 0 1 ] [ a b c 1 ] A_p=\left[\begin{matrix} |&|&|&x_{Oc} \\ \vec x&\vec y&\vec z&y_{Oc}\\|&|&|&z_{Oc}\\0&0&0&1\end{matrix}\right] \left[\begin{matrix} a\\b\\c\\1 \end{matrix}\right] Ap=⎣⎢⎢⎡∣x∣0∣y∣0∣z∣0xOcyOczOc1⎦⎥⎥⎤⎣⎢⎢⎡abc1⎦⎥⎥⎤
A p = [ ∣ ∣ ∣ ∣ x ⃗ y ⃗ z ⃗ O ⃗ ∣ ∣ ∣ ∣ 0 0 0 1 ] [ a b c 1 ] A_p=\left[\begin{matrix} |&|&|&| \\ \vec x&\vec y&\vec z& \vec O\\|&|&|&|\\0&0&0&1\end{matrix}\right] \left[\begin{matrix} a\\b\\c\\1 \end{matrix}\right] Ap=⎣⎢⎢⎡∣x∣0∣y∣0∣z∣0∣O∣1⎦⎥⎥⎤⎣⎢⎢⎡abc1⎦⎥⎥⎤
所以
M c − p = [ ∣ ∣ ∣ ∣ x ⃗ y ⃗ z ⃗ O ⃗ ∣ ∣ ∣ ∣ 0 0 0 1 ] M_{c-p}=\left[\begin{matrix} |&|&|&| \\ \vec x&\vec y&\vec z& \vec O\\|&|&|&|\\0&0&0&1\end{matrix}\right] Mc−p=⎣⎢⎢⎡∣x∣0∣y∣0∣z∣0∣O∣1⎦⎥⎥⎤
由于第四列为平移用,所以对于方向,我们只需要三维的矩阵就可以进行变换,
M c − p = [ ∣ ∣ ∣ x ⃗ y ⃗ z ⃗ ∣ ∣ ∣ ] M_{c-p}=\left[\begin{matrix} |&|&| \\ \vec x&\vec y&\vec z\\|&|&|\\ \end{matrix}\right] Mc−p=⎣⎡∣x∣∣y∣∣z∣⎦⎤
又由于C的x轴可以表示为 【 1 , 0 , 0 】 T 【1,0,0】^T 【1,0,0】T,因此两者相乘后的结果为取第一列。
最终理解为C的x轴在P下取第一列,y轴取第二列,z轴取第三列
进一步:
如果 M c − p M_{c-p} Mc−p为正交矩阵,
M p − c = M c − p − 1 = M c − p T = [ − x ⃗ − − y ⃗ − − z ⃗ − ] M_{p-c}=M_{c-p}^{-1}=M_{c-p}^T=\left[\begin{matrix} -&\vec x&- \\ -&\vec y&-\\-&\vec z&-\\ \end{matrix}\right] Mp−c=Mc−p−1=Mc−pT=⎣⎡−−−xyz−−−⎦⎤
此时理解P的x轴在C下取 M c − p M_{c-p} Mc−p第一行,y轴取第二行,z轴取第三行
小结,若 M A − B M_{A-B} MA−B为正交矩阵,其每一列是A在B下的xyz轴的表示,每一行都是B在A下的xyz轴的表示
M A − B = [ ∣ ∣ ∣ x ⃗ A y ⃗ A z ⃗ A ∣ ∣ ∣ ] = [ − x ⃗ B − − y ⃗ B − − z ⃗ B − ] = M B − A − 1 M_{A-B}=\left[\begin{matrix} |&|&| \\ \vec x_A&\vec y_A&\vec z_A\\|&|&|\\ \end{matrix}\right]=\left[\begin{matrix} -&\vec x_B&- \\ -&\vec y_B&-\\-&\vec z_B&-\\ \end{matrix}\right]=M_{B-A}^{-1} MA−B=⎣⎡∣xA∣∣yA∣∣zA∣⎦⎤=⎣⎡−−−xByBzB−−−⎦⎤=MB−A−1
模型空间变换世界空间
模型空间:在美术建模时设置的原点(一般为重心)位置和坐标系,其它所有点和方向按这个坐标系存储在模型空间中。Unity里推荐为左手坐标系,即z轴前,x轴右,y轴上
世界空间:以游戏世界的中心为原点展开的坐标系,相对来说是绝对的。Unity里为左手坐标系
设某点p在模型空间坐标为为 p ⃗ m o d e l \vec p_{model} pmodel
转为其次空间下得到 ( p ⃗ m o d e l , 1 ) (\vec p_{model},1) (pmodel,1)
设p在世界中进行了缩放、旋转、平移
则变换矩阵为 M m o d e l = M 平 移 M 旋 转 M 缩 放 M_{model}=M_{平移}M_{旋转}M_{缩放} Mmodel=M平移M旋转M缩放
则p世界坐标为 p w o r l d = M m o d e l p m o d e l p_{world}=M_{model}p_{model} pworld=Mmodelpmodel
世界空间变换观察空间
观察空间:也称摄像机空间,是右手坐标系,即x朝右,y朝上,但z朝后
设摄像机从世界原点旋转了 r ⃗ \vec r r,平移了 d ⃗ \vec d d
则通过逆向这些操作让点从世界空间转换到观察空间
(可以看到通过逆操作点的位置将会变换到以原点为摄像机的位置,即所求的点相对于摄像机位置)
先进行逆平移再逆旋转,但由于最终摄像机的z轴是反向的,所以还需要z轴反向
M v i e w = M n e g a t e M 逆 旋 转 M 逆 平 移 M_{view}=M_{negate}M_{逆旋转}M_{逆平移} Mview=MnegateM逆旋转M逆平移
M n e g a t e = [ 1 0 0 0 0 1 0 0 0 0 − 1 0 0 0 0 0 ] M_{negate}=\left[\begin{matrix} 1&0&0&0 \\ 0&1&0& 0\\0&0&-1&0\\0&0&0&0\end{matrix}\right] Mnegate=⎣⎢⎢⎡1000010000−100000⎦⎥⎥⎤
现在p的观察空间的位置为 p v i e w = M v i e w p w o r l d p_{view}=M_{view}p_{world} pview=Mviewpworld
视锥体
由六个面组成,其中最重要的为近裁切面和远裁切面,在Unity中用摄像机的Far和Near确定
- 透视视图,通过FOV控制视角缩放
- 正交视图,通过Size控制视角大小
观察空间转化到裁剪空间
裁剪矩阵
用来为裁剪做准备的矩阵,不是最终的结果
- 对于透视视图,我们希望在转化后视锥体的近裁切面为一个边长为2Near的正方形,远裁切面为一个边长为2Far的正方形,其高度为Far-Near
- 对于正交视图我们希望在转化后视锥体变成一个边长为2的正方体
透视情况
对于近裁剪平面的高度(两条竖直的绿线)和远裁剪平面的高度(两条竖直的棕色线),值为
n e a r C l i p P l a n e H e i g h t = 2 ⋅ N e a r ⋅ t a n F O V 2 nearClipPlaneHeight=2 \cdot Near \cdot tan \frac {FOV}{2} nearClipPlaneHeight=2⋅Near⋅tan2FOV
f a r C l i p P l a n e H e i g h t = 2 ⋅ F a r ⋅ t a n F O V 2 farClipPlaneHeight=2 \cdot Far \cdot tan \frac {FOV}{2} farClipPlaneHeight=2⋅Far⋅tan2FOV
还缺少横向的宽的信息(图里看不到),一般用Aspect表示宽高比
A s p e c t = n e a r C l i p P l a n e W i d t h n e a r C l i p P l a n e H e i g h t = f a r C l i p P l a n e W i d t h f a r C l i p P l a n e H e i g h t Aspect=\frac {nearClipPlaneWidth} {nearClipPlaneHeight}=\frac{farClipPlaneWidth}{farClipPlaneHeight} Aspect=nearClipPlaneHeightnearClipPlaneWidth=farClipPlaneHeightfarClipPlaneWidth
通过这些信息,计算投影矩阵
M f r u s t u m = [ c o t F O V 2 A s p e c t 0 0 0 0 c o t F O V 2 0 0 0 0 − F a r + N e a r F a r − N e a r − 2 F a r ⋅ N e a r F a r − N e a r 0 0 − 1 0 ] M_{frustum}=\left[\begin{matrix} \frac{cot\frac{FOV}{2}}{Aspect}&0&0&0 \\ 0&cot\frac{FOV}{2}&0& 0\\0&0&-\frac{Far+Near}{Far-Near}&-\frac{2Far\cdot Near}{Far-Near}\\0&0&-1&0\end{matrix}\right] Mfrustum=⎣⎢⎢⎢⎡Aspectcot2FOV0000cot2FOV0000−Far−NearFar+Near−100−Far−Near2Far⋅Near0⎦⎥⎥⎥⎤
计算p在裁剪空间的坐标:
p c l i p = [ x ′ y ′ z ′ w ′ ] = M f r u s t u m p v i e w = M f r u s t u m [ x y z 1 ] = [ x c o t F O V 2 A s p e c t y ⋅ c o t F O V 2 − z F a r + N e a r F a r − N e a r − 2 F a r ⋅ N e a r F a r − N e a r − z ] p_{clip}=\left[\begin{matrix} x'\\y'\\z'\\w' \end{matrix}\right]=M_{frustum}p_{view}=M_{frustum}\left[\begin{matrix} x\\y\\z\\1 \end{matrix}\right]=\left[\begin{matrix} x\frac{cot\frac{FOV}{2}}{Aspect}\\y\cdot cot\frac{FOV}{2}\\-z\frac{Far+Near}{Far-Near}-\frac{2Far\cdot Near}{Far-Near}\\-z \end{matrix}\right] pclip=⎣⎢⎢⎡x′y′z′w′⎦⎥⎥⎤=Mfrustumpview=Mfrustum⎣⎢⎢⎡xyz1⎦⎥⎥⎤=⎣⎢⎢⎢⎡xAspectcot2FOVy⋅cot2FOV−zFar−NearFar+Near−Far−Near2Far⋅Near−z⎦⎥⎥⎥⎤
如果点p不想被裁剪,必须满足
−
w
′
≤
x
′
≤
w
′
−
w
′
≤
y
′
≤
w
′
−
w
′
≤
z
′
≤
w
′
-w'\leq x'\leq w'\\ -w'\leq y'\leq w'\\ -w'\leq z'\leq w'
−w′≤x′≤w′−w′≤y′≤w′−w′≤z′≤w′
同时注意到z’是必然大于0的,并且z‘越大,离摄像头越远
正交情况
远近剪裁平面高度是相同的,都为2*size,其宽为 A s p e c t ⋅ w i d t h Aspect\cdot width Aspect⋅width;
通过这些信息,计算投影矩阵
M f r u s t u m = [ 1 A s p e c t ⋅ s i z e 0 0 0 0 1 s i z e 0 0 0 0 − 2 f a r − n e a r − F a r + N e a r F a r − N e a r 0 0 0 1 ] M_{frustum}=\left[\begin{matrix} \frac{1}{Aspect\cdot size}&0&0&0 \\ 0&\frac{1}{size}&0& 0\\0&0&-\frac{2}{far-near}&-\frac{Far+ Near}{Far-Near}\\0&0&0&1\end{matrix}\right] Mfrustum=⎣⎢⎢⎡Aspect⋅size10000size10000−far−near2000−Far−NearFar+Near1⎦⎥⎥⎤
计算p在裁剪空间的坐标:
p c l i p = [ x ′ y ′ z ′ w ′ ] = M f r u s t u m p v i e w = M f r u s t u m [ x y z 1 ] = [ x A s p e c t ⋅ s i z e y s i z e − 2 z F a r − N e a r − F a r + N e a r F a r − N e a r 1 ] p_{clip}=\left[\begin{matrix} x'\\y'\\z'\\w' \end{matrix}\right]=M_{frustum}p_{view}=M_{frustum}\left[\begin{matrix} x\\y\\z\\1 \end{matrix}\right]=\left[\begin{matrix} \frac{x}{Aspect\cdot size}\\\frac{y}{size}\\-\frac{2z}{Far-Near}-\frac{Far + Near}{Far-Near}\\1 \end{matrix}\right] pclip=⎣⎢⎢⎡x′y′z′w′⎦⎥⎥⎤=Mfrustumpview=Mfrustum⎣⎢⎢⎡xyz1⎦⎥⎥⎤=⎣⎢⎢⎡Aspect⋅sizexsizey−Far−Near2z−Far−NearFar+Near1⎦⎥⎥⎤
其裁剪公式和透视相同
裁剪空间变换屏幕空间
标准齐次除法
标准齐次除法,又名透视除法,最终是为了得到归一化的设备坐标
最终透视的视锥体也会变成一个边长为2的正方体
计算方式:将 p c l i p p_{clip} pclip中的xyz除掉w
映射平面
转换到归一化设备坐标后,xyz的取值范围为[-1,1]
屏幕的左下角为(0,0),右上角为(pixelWidth,pixelHeight)
因此最后
s
c
r
e
e
n
x
=
c
l
i
p
x
⋅
p
i
x
e
l
W
i
d
t
h
2
⋅
c
l
i
p
w
+
p
i
x
e
l
W
i
d
t
h
2
s
c
r
e
e
n
y
=
c
l
i
p
y
⋅
p
i
x
e
l
H
e
i
g
h
t
2
⋅
c
l
i
p
w
+
p
i
x
e
l
H
e
i
g
h
t
2
screen_x=\frac{clip_x\cdot pixelWidth}{2\cdot clip_w}+\frac{pixelWidth}{2}\\ screen_y=\frac{clip_y\cdot pixelHeight}{2\cdot clip_w}+\frac{pixelHeight}{2}
screenx=2⋅clipwclipx⋅pixelWidth+2pixelWidthscreeny=2⋅clipwclipy⋅pixelHeight+2pixelHeight
一般来说,这个变换由unity完成,顶点着色器转换到裁剪空间
法线变换
当模型发生非等比例缩放时,物体的表面将会变形,原来模型顶点存储的的法线 N A N_A NA如果直接按缩放矩阵计算会失效。
顶点同时还存在着另一个矢量:切矢量 T A ⃗ \vec {T_A} TA,和法线垂直,和纹理空间对齐,他允许非等比例缩放
接下来的计算都是有关方向的,所以只使用3维
- 已知 T A ⃗ ⋅ N A ⃗ = 0 \vec{T_A}\cdot \vec{N_A}=0 TA⋅NA=0,非等比例缩放后变成物体B
- T B ⃗ = M A − B T A ⃗ \vec{T_B}=\vec{M_{A-B}T_A} TB=MA−BTA
- 并且 N B ⃗ \vec{N_B} NB需要满足 T B ⃗ ⋅ N B ⃗ = 0 \vec{T_B}\cdot \vec{N_B}=0 TB⋅NB=0
- 所以 T B ⃗ ⋅ N B ⃗ = ( M A − B T A ) ⃗ ⋅ ( G N A ) ⃗ = 0 \vec{T_B}\cdot \vec{N_B}=\vec{(M_{A-B}T_A)}\cdot \vec{(GN_A)}=0 TB⋅NB=(MA−BTA)⋅(GNA)=0
- ( M A − B T A ) ⃗ ⋅ ( G N A ) ⃗ = ( M A − B T A ) T ( G N A ) = T A T ( M A − B T G ) N A = 0 \vec{(M_{A-B}T_A)}\cdot \vec{(GN_A)}=(M_{A-B}T_A)^{T}(GN_A)=T_A^T(M_{A-B}^TG)N_A=0 (MA−BTA)⋅(GNA)=(MA−BTA)T(GNA)=TAT(MA−BTG)NA=0
- 注意上式中第一个等号的转换:左边是两个向量相乘点积,右边是将 ( M A − B T A ) (M_{A-B}T_A) (MA−BTA)进行转置,使其变成 1 ∗ n 1*n 1∗n矩阵并将右边也看作 n ∗ 1 n*1 n∗1矩阵,相乘得到 1 ∗ 1 1*1 1∗1矩阵即实数
- T A T ( M A − B T G ) N A = T A ⃗ ( M A − B T G ) N A ⃗ = 0 T_A^T(M_{A-B}^TG)N_A=\vec{T_A}(M_{A-B}^TG)\vec{N_A}=0 TAT(MA−BTG)NA=TA(MA−BTG)NA=0
- 当 M A − B T G = I M_{A-B}^TG=I MA−BTG=I时,原式转换为 T A ⃗ ⋅ N A ⃗ = 0 \vec{T_A}\cdot \vec{N_A}=0 TA⋅NA=0成立
- 也就是说, G = ( M A − B T ) − 1 = ( M A − B − 1 ) T G=(M_{A-B}^T)^{-1}=(M_{A-B}^{-1})^{T} G=(MA−BT)−1=(MA−B−1)T时,上式成立
- 进一步的,如果 M A − B M_{A-B} MA−B为正交矩阵, G = ( M A − B T ) − 1 = M A − B G=(M_{A-B}^T)^{-1}=M_{A-B} G=(MA−BT)−1=MA−B
- 如果含有等比例缩放, G = 1 k M A − B G=\frac 1 k M_{A-B} G=k1MA−B
Unity 内置变量
矩阵
变量名 | 描述 |
---|---|
UNITY_MATRIX_MVP | 当前模型 * 视图 * 投影矩阵。模型空间转裁剪空间 |
UNITY_MATRIX_MV | 当前模型 * 视图矩阵。模型空间转观察空间 |
UNITY_MATRIX_V | 当前视图矩阵。世界空间转观察空间 |
UNITY_MATRIX_P | 当前投影矩阵。观察空间转裁剪空间 |
UNITY_MATRIX_VP | 当前视图 * 投影矩阵。世界空间转裁剪空间 |
UNITY_MATRIX_T_MV | UNITY_MATRIX_MV的转置矩阵。 |
UNITY_MATRIX_IT_MV | UNITY_MATRIX_MV的逆转置矩阵,常用于法线从模型转观察 |
unity_ObjectToWorld | 当前模型矩阵。模型空间转世界空间 |
unity_WorldToObject | 当前世界矩阵的逆矩阵。世界空间转模型空间,转置后变成逆矩阵 |
摄像机
名称 | 类型 | 值 |
---|---|---|
_WorldSpaceCameraPos | float3 | 摄像机的世界空间位置。 |
_ProjectionParams | float4 | x 是 1.0(如果当前使用翻转投影矩阵进行渲染,则为 –1.0),y 是摄像机的近平面,z 是摄像机的远平面,w 是远平面的倒数。 |
_ScreenParams | float4 | x 是摄像机目标纹理的宽度(以像素为单位),y 是摄像机目标纹理的高度(以像素为单位),z 是 1.0 + 1.0/宽度,w 为 1.0 + 1.0/高度。 |
_ZBufferParams | float4 | 用于线性化 Z 缓冲区值。x 是 (1-远/近),y 是 (远/近),z 是 (x/远),w 是 (y/远)。 |
unity_OrthoParams | float4 | x 是正交摄像机的宽度,y 是正交摄像机的高度,z 未使用,w 在摄像机为正交模式时是 1.0,而在摄像机为透视模式时是 0.0。 |
unity_CameraProjection | float4x4 | 摄像机的投影矩阵。 |
unity_CameraInvProjection | float4x4 | 摄像机投影矩阵的逆矩阵。 |
unity_CameraWorldClipPlanes[6] | float4 | 摄像机视锥体平面世界空间方程,按以下顺序:左、右、底、顶、近、远。 |
时间
名称 | 类型 | 值 |
---|---|---|
_Time | float4 | 自关卡加载以来的时间 (t/20, t, t2, t3),用于将着色器中的内容动画化。 |
_SinTime | float4 | 时间正弦:(t/8, t/4, t/2, t)。 |
_CosTime | float4 | 时间余弦:(t/8, t/4, t/2, t)。 |
unity_DeltaTime | float4 | 增量时间:(dt, 1/dt, smoothDt, 1/smoothDt)。 |
光照
前向光照
名称 | 类型 | 值 |
---|---|---|
_LightColor0*(在 UnityLightingCommon.cginc 中声明)* | fixed4 | 光源颜色。 |
_WorldSpaceLightPos0 | float4 | 方向光:(世界空间方向,0)。其他光源:(世界空间位置,1)。 |
_LightMatrix0*(在 AutoLight.cginc 中声明)* | float4x4 | 世界/光源矩阵。用于对剪影和衰减纹理进行采样。 |
unity_4LightPosX0、unity_4LightPosY0、unity_4LightPosZ0 | float4 | *(仅限 ForwardBase 通道)*前四个非重要点光源的世界空间位置。 |
unity_4LightAtten0 | float4 | *(仅限 ForwardBase 通道)*前四个非重要点光源的衰减因子。 |
unity_LightColor | half4[4] | *(仅限 ForwardBase 通道)*前四个非重要点光源的颜色。 |
unity_WorldToShadow | float4x4[4] | 世界/阴影矩阵。聚光灯的一个矩阵,方向光级联最多有四个矩阵。 |
延迟光照
名称 | 类型 | 值 |
---|---|---|
_LightColor | float4 | 光源颜色。 |
_LightMatrix0 | float4x4 | 世界/光源矩阵。用于对剪影和衰减纹理进行采样。 |
unity_WorldToShadow | float4x4[4] | 世界/阴影矩阵。聚光灯的一个矩阵,方向光级联最多有四个矩阵。 |
顶点光照
最多可为 Vertex
通道类型设置 8 个光源;始终从最亮的光源开始排序。因此,如果您希望 一次渲染受两个光源影响的对象,可直接采用数组中前两个条目。如果影响对象 的光源数量少于 8,则其余光源的颜色将设置为黑色。
名称 | 类型 | 值 |
---|---|---|
unity_LightColor | half4[8] | 光源颜色。 |
unity_LightPosition | float4[8] | 视图空间光源位置。方向光为 (-direction,0);点光源/聚光灯为 (position,1)。 |
unity_LightAtten | half4[8] | 光源衰减因子。x 是 cos(spotAngle/2) 或 –1(非聚光灯);y 是1/cos(spotAngle/4) 或 1(非聚光灯);z 是二次衰减;w 是平方光源范围。 |
unity_SpotDirection | float4[8] | 视图空间聚光灯位置;非聚光灯为 (0,0,1,0)。 |
雾和环境光
名称 | 类型 | 值 |
---|---|---|
unity_AmbientSky | fixed4 | 梯度环境光照情况下的天空环境光照颜色。 |
unity_AmbientEquator | fixed4 | 梯度环境光照情况下的赤道环境光照颜色。 |
unity_AmbientGround | fixed4 | 梯度环境光照情况下的地面环境光照颜色。 |
UNITY_LIGHTMODEL_AMBIENT | fixed4 | 环境光照颜色(梯度环境情况下的天空颜色)。旧版变量。 |
unity_FogColor | fixed4 | 雾效颜色。 |
unity_FogParams | float4 | 用于雾效计算的参数:(density / sqrt(ln(2))、density / ln(2)、–1/(end-start) 和 end/(end-start))。x 对于 Exp2 雾模式很有用;y 对于 Exp 模式很有用,z 和 w 对于 Linear 模式很有用。 |
其它
名称 | 类型 | 值 |
---|---|---|
unity_LODFade | float4 | 使用 LODGroup 时的细节级别淡入淡出。x 为淡入淡出(0 到 1),y 为量化为 16 级的淡入淡出,z 和 w 未使用。 |
_TextureSampleAdd | float4 | 根据所使用的纹理是 Alpha8 格式(值设置为 (1,1,1,0))还是不是该格式(值设置为 (0,0,0,0))由 Unity 仅针对 UI 自动设置。 |