Unity Shader总结(三)——顶点变换之蕾姆的呆毛在哪里

注意,以下求法的原理不再赘述。最简单的求法请直接跳转文末总结。

概述

蕾姆睡醒发现头上有根呆毛,这根呆毛在屏幕上的坐标到底是多少?
在这里插入图片描述
流程为:模型空间( P m o d e l P_{model} Pmodel)——>世界空间( P w o r l d P_{world} Pworld)——>观察空间( P v i e w P_{view} Pview)——>裁剪空间( P c l i p P_{clip} Pclip)——>屏幕空间
假设呆毛顶点的模型坐标为(0,2,4),扩展到齐次坐标系下为(0,2,4,1)

一、模型空间——>世界空间(模型变换)

在这里插入图片描述
计算其变换矩阵,注意顺序(缩放(zxy)、旋转、平移,从右向左)
M m o d e l = [ 1 0 0 t x 0 1 0 t y 0 0 1 t z 0 0 0 1 ] [ c o s ( θ ) 0 s i n ( θ ) 0 0 1 0 0 − s i n ( θ ) 0 c o s ( θ ) 0 0 0 1 ] [ k x 0 0 0 0 k y 0 0 0 0 k z 0 0 0 0 1 ] M_{model}=\begin{bmatrix} 1&0 &0 & t_{x}\\ 0& 1 & 0 &t_{y} \\ 0& 0& 1& t_{z}\\ 0& 0& 0&1 \end{bmatrix}\begin{bmatrix} cos(\theta)&0 &sin(\theta) & 0\\ 0& 1& 0 &0\\ -sin(\theta)& 0& cos(\theta)\\ 0& 0& 0&1 \end{bmatrix}\begin{bmatrix} k_{x}&0 &0 & 0\\ 0& k_{y} & 0 &0\\ 0& 0& k_{z}& 0\\ 0& 0& 0&1 \end{bmatrix} Mmodel=100001000010txtytz1cos(θ)0sin(θ)00100sin(θ)0cos(θ)0001kx0000ky0000kz00001               = [ 1 0 0 5 0 1 0 0 0 0 1 25 0 0 0 1 ] [ − 0.866 0 0.5 0 0 1 0 0 − 0.5 0 − 0.866 0 0 0 1 ] [ 2 0 0 0 0 2 0 0 0 0 2 0 0 0 0 1 ] =\begin{bmatrix} 1&0 &0 & 5\\ 0& 1 & 0 &0 \\ 0& 0& 1& 25\\ 0& 0& 0&1 \end{bmatrix}\begin{bmatrix} -0.866&0 &0.5 & 0\\ 0& 1& 0 &0\\ -0.5& 0& -0.866\\ 0& 0& 0&1 \end{bmatrix}\begin{bmatrix} 2&0 &0 & 0\\ 0&2& 0 &0\\ 0& 0& 2& 0\\ 0& 0& 0&1 \end{bmatrix} =100001000010502510.86600.5001000.500.86600012000020000200001               = [ − 1.732 0 1 5 0 2 0 0 − 1 0 − 1.732 25 0 0 0 1 ] =\begin{bmatrix} -1.732&0 &1 & 5\\ 0&2& 0 &0\\ -1& 0& -1.732& 25\\ 0& 0& 0&1 \end{bmatrix} =1.7320100200101.732050251
计算其世界坐标
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 = [ − 1.732 0 1 5 0 2 0 0 − 1 0 − 1.732 25 0 0 0 1 ] [ 0 2 4 1 ] = [ 9 4 18.072 1 ] =\begin{bmatrix} -1.732&0 &1 & 5\\ 0&2& 0 &0\\ -1& 0& -1.732& 25\\ 0& 0& 0&1 \end{bmatrix}\begin{bmatrix} 0\\ 2\\ 4\\ 1 \end{bmatrix}=\begin{bmatrix} 9\\ 4\\ 18.072\\ 1 \end{bmatrix} =1.7320100200101.7320502510241=9418.0721

二、世界空间——>观察空间(观察变换)(右手坐标系)

在这里插入图片描述
这里变换矩阵两种求法,道理一样,搞不清的话直接按法一做,不影响。

法一:

M v i e w = M t r a n s l a t i o n M r o t a t i o n M s c a l e = [ 1 0 0 0 0 0.866 0.5 − 3.66 0 0.5 − 0.866 − 13.66 0 0 0 1 ] M_{view}=M_{translation}M_{rotation}M_{scale}=\begin{bmatrix} 1&0 &0 & 0\\ 0&0.866& 0.5&-3.66\\ 0& 0.5& -0.866& -13.66\\ 0& 0& 0&1 \end{bmatrix} Mview=MtranslationMrotationMscale=100000.8660.5000.50.866003.6613.661

法二:

根据transform组件可以发现摄像机在世界空间中的变换经过了先旋转后平移(注意属性还是从下往上看,之后不再赘述),那么,要把摄像机变回初始状态就是先平移(0,-10,10)后旋转(-30,0,0),注意数值不是照抄。
M v i e w = M r o t a t i o n M t r a n s l a t i o n M_{view}=M_{rotation}M_{translation} Mview=MrotationMtranslation

两种方法结果一样,求观察坐标:
P v i e w = M v i e w P w o r l d P_{view}=M_{view}P_{world} Pview=MviewPworld
             = [ 1 0 0 0 0 0.866 0.5 − 3.66 0 0.5 − 0.866 − 13.66 0 0 0 1 ] [ 9 4 18.072 1 ] = [ 9 8.84 − 27.31 1 ] =\begin{bmatrix} 1&0 &0 & 0\\ 0&0.866& 0.5&-3.66\\ 0& 0.5& -0.866& -13.66\\ 0& 0& 0&1 \end{bmatrix}\begin{bmatrix} 9\\ 4\\ 18.072\\ 1 \end{bmatrix}=\begin{bmatrix} 9\\ 8.84\\ -27.31\\ 1 \end{bmatrix} =100000.8660.5000.50.866003.6613.6619418.0721=98.8427.311

三、观察空间——>裁剪空间

3.1 透视投影

在这里插入图片描述
近、远裁剪平面高度:

n e a r C l i p P l a n e H e i g h t = 2 ⋅ N e a r ⋅ tan ⁡ F O V 2 nearClipPlaneHeight=2\cdot Near\cdot \tan \frac{FOV}{2} nearClipPlaneHeight=2Neartan2FOV
f a r C l i p P l a n e H e i g h t = 2 ⋅ F a r ⋅ tan ⁡ F O V 2 farClipPlaneHeight=2\cdot Far\cdot \tan \frac{FOV}{2} farClipPlaneHeight=2Fartan2FOV

摄像机横纵比:

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 P l a n e H e i g h t Aspect=\frac{nearClipPlaneWidth}{nearPlaneHeight} Aspect=nearPlaneHeightnearClipPlaneWidth

A s p e c t = f a r C l i p P l a n e W i d t h f a r P l a n e H e i g h t Aspect=\frac{farClipPlaneWidth}{farPlaneHeight} Aspect=farPlaneHeightfarClipPlaneWidth

裁剪矩阵(也叫投影矩阵):
M f r u s t u m = [ cot ⁡ F O V 2 A s p e c t 0 0 0 0 cot ⁡ F O V 2 0 0 0 0 − F a r + N e a r F a a r − N e a r − 2 ⋅ N e a r ⋅ F a r F a r − N e a r 0 0 − 1 0 ] M_{frustum}=\begin{bmatrix} \frac{\cot \frac{FOV}{2}}{Aspect} & 0& 0 & 0\\ 0& \cot \frac{FOV}{2}& 0& 0\\ 0 & 0 & -\frac{Far+Near}{Faar-Near} &-\frac{2\cdot Near\cdot Far}{Far-Near} \\ 0 & 0 & -1 &0 \end{bmatrix} Mfrustum=Aspectcot2FOV0000cot2FOV0000FaarNearFar+Near100FarNear2NearFar0

裁剪坐标(本质上就是对x,y,z缩放,z还多了个平移):
P c l i p = M f r u s t u m P v i e w P_{clip}=M_{frustum}P_{view} Pclip=MfrustumPview

           = [ cot ⁡ F O V 2 A s p e c t 0 0 0 0 cot ⁡ F O V 2 0 0 0 0 − F a r + N e a r F a a r − N e a r − 2 ⋅ N e a r ⋅ F a r F a r − N e a r 0 0 − 1 0 ] [ x y z 1 ] =\begin{bmatrix} \frac{\cot \frac{FOV}{2}}{Aspect} & 0& 0 & 0\\ 0& \cot \frac{FOV}{2}& 0& 0\\ 0 & 0 & -\frac{Far+Near}{Faar-Near} &-\frac{2\cdot Near\cdot Far}{Far-Near} \\ 0 & 0 & -1 &0 \end{bmatrix}\begin{bmatrix} x\\ y\\ z\\ 1 \end{bmatrix} =Aspectcot2FOV0000cot2FOV0000FaarNearFar+Near100FarNear2NearFar0xyz1

           = [ x cot ⁡ F O V 2 A s p e c t y cot ⁡ F O V 2 − z F a r + N e a r F a a r − N e a r − 2 ⋅ N e a r ⋅ F a r F a r − N e a r − z ] =\begin{bmatrix} x\frac{\cot \frac{FOV}{2}}{Aspect}\\ y \cot \frac{FOV}{2}\\ -z\frac{Far+Near}{Faar-Near} -\frac{2\cdot Near\cdot Far}{Far-Near}\\ -z \end{bmatrix} =xAspectcot2FOVycot2FOVzFaarNearFar+NearFarNear2NearFarz

变换后的坐标必须满足 x , y , z ϵ [ − ω , ω ] x,y,z\epsilon [-\omega ,\omega ] x,y,zϵ[ω,ω],其中 ω \omega ω的值为原先的 − z -z z(就是结果中前三个数在第四个数的正负范围内),不满足这个条件的图元那就舍弃或裁剪。

带入数值:
P c l i p = M f r u s t u m P v i e w = [ 1.299 0 0 0 0 1.732 0 0 0 0 − 1.286 − 11.429 0 0 − 1 0 ] [ 9 8.84 − 27.31 1 ] P_{clip}=M_{frustum}P_{view}=\begin{bmatrix} 1.299&0 &0 & 0\\ 0&1.732& 0&0\\ 0& 0& -1.286& -11.429\\ 0& 0& -1&0 \end{bmatrix}\begin{bmatrix} 9\\ 8.84\\ -27.31\\ 1 \end{bmatrix} Pclip=MfrustumPview=1.29900001.73200001.28610011.429098.8427.311

                                          = [ 11.691 15.311 23.693 27.31 ] =\begin{bmatrix} 11.691\\ 15.311\\ 23.693\\ 27.31 \end{bmatrix} =11.69115.31123.69327.31
x , y , z x,y,z x,y,z都在-27.31~27.31的范围内,不用裁剪或舍弃

3.2 正交投影

在这里插入图片描述

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 H e i g h t = 2 ⋅ S i z e nearClipPlaneHeight=farClipPlaneHeight=2\cdot Size nearClipPlaneHeight=farClipPlaneHeight=2Size
n e 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 W i d t h nearClipPlaneWidth=farClipPlaneWidth nearClipPlaneWidth=farClipPlaneWidth
                                            = A s p e c t ⋅ n e a r C l i p P l a n e H e i g h t =Aspect\cdot nearClipPlaneHeight =AspectnearClipPlaneHeight

裁剪矩阵:

M o r t h o = [ 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 a r − N e a r − F a r + N e a r F a a r − N e a r 0 0 0 1 ] M_{ortho}=\begin{bmatrix} \frac{1}{Aspect\cdot Size}& 0 & 0 & 0\\ 0& \frac{1}{Size}& 0 & 0\\ 0 & 0 &-\frac{2}{Faar-Near} &-\frac{Far+Near}{Faar-Near} \\ 0& 0 &0 &1 \end{bmatrix} Mortho=AspectSize10000Size10000FaarNear2000FaarNearFar+Near1

裁剪坐标:
P c l i p = M o r t h o P v i e w P_{clip}=M_{ortho}P_{view} Pclip=MorthoPview

           = [ x A s p e c t ⋅ S i z e y S i z e − 2 z F a a r − N e a r − F a r + N e a r F a r − N e a r 1 ] =\begin{bmatrix} \frac{x}{Aspect\cdot Size}\\ \frac{y}{Size}\\ -\frac{2z}{Faar-Near} -\frac{Far+Near}{Far-Near}\\ 1 \end{bmatrix} =AspectSizexSizeyFaarNear2zFarNearFar+Near1

四、裁剪空间——>屏幕空间

在这一步中有两个步骤:1.通过齐次除法得NDC坐标; 2.屏幕映射(就是一个缩放过程)
合在一起的公式:
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 ω + p i x e l W i d t h 2 screen_{x}=\frac{clip_{x}\cdot pixelWidth}{2\cdot clip_{\omega }}+\frac{pixelWidth}{2} screenx=2clipωclipxpixelWidth+2pixelWidth

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 ω + p i x e l H e i g h t 2 screen_{y}=\frac{clip_{y}\cdot pixelHeight}{2\cdot clip_{\omega }}+\frac{pixelHeight}{2} screeny=2clipωclipypixelHeight+2pixelHeight

上一步中通过透视法求出的裁剪坐标为(11.691,15.311,23.692,27.31)
假设像素宽度为400,高度为300,那么,把它投影到NDC再映射到屏幕空间中的过程为:
s c r e e n x = 11.691 ⋅ 400 2 ⋅ 27.31 + 400 2 = 285.617 screen_{x}=\frac{11.691\cdot 400}{2\cdot 27.31}+\frac{400}{2}=285.617 screenx=227.3111.691400+2400=285.617

s c r e e n y = 15.311 ⋅ 300 2 ⋅ 27.31 + 300 2 = 234.096 screen_{y}=\frac{15.311\cdot 300}{2\cdot 27.31}+\frac{300}{2}=234.096 screeny=227.3115.311300+2300=234.096

得出,呆毛在屏幕上的像素位置为(285.617,234.096)。

五、总结

蕾姆不会长呆毛。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值