Shader 坐标转换
生活随笔
收集整理的這篇文章主要介紹了
Shader 坐标转换
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
轉(zhuǎn)自:http://www.ownself.org/blog/2010/kong-jian-zuo-biao-zhuan-huan.html
??? 這個比較基礎(chǔ)了,不過基礎(chǔ)最重要,往往應(yīng)該理解透徹,并且反復(fù)復(fù)習(xí)。
??? 我們知道在3D畫面渲染過程中對于模型的計算的一部分被稱為Transforming and Lighting(T&L)階段,其中Lighting表示光照,而Transforming就是指的坐標(biāo)變換,這兩部分的計算也是3D場景中計算最重要基礎(chǔ)的一步。??? 空間坐標(biāo)變換主要的工作就是將處于局部坐標(biāo)系的模型轉(zhuǎn)換到用戶屏幕所在的屏幕坐標(biāo)系內(nèi)。
??? 而這個過程的計算上主要是來自線性代數(shù)中的知識,我們知道在線性代數(shù)中,線性的變換是可以用矩陣來表示的,而通過將向量[x,y,z,w]同變換矩陣相乘即可完成相應(yīng)的變換,這正是我們實現(xiàn)空間坐標(biāo)變換的數(shù)學(xué)基礎(chǔ),在3D圖形學(xué)中,空間坐標(biāo)變換一般分為三個步驟——世界變換、視角變換、投影變換,而完成這些變換就是由矩陣運算來完成的。
??? 世界變換
??? 我們知道所有模型都是獨立創(chuàng)建的,他們擁有自己獨立的一個局部坐標(biāo)系來描述模型內(nèi)部各個面片頂點之間位置的關(guān)系,當(dāng)我們將這些模型放在一起來組建游戲場景的時候,邏輯上他們就處在了同一個坐標(biāo)系內(nèi)來描述模型與模型之間位置與角度的關(guān)系,這個坐標(biāo)系我們所說的世界坐標(biāo)系,而將模型中的每一個頂點從局部坐標(biāo)系轉(zhuǎn)換到世界坐標(biāo)系的過程,我們稱之為世界變換。
??? 世界變換是通過將模型中每一個頂點乘以世界變換矩陣來完成的,通常情況下這個世界變換矩陣是通過一系列變換矩陣的結(jié)合形成的一個包含了所有變換內(nèi)容的矩陣來完成計算的,包括平移、旋轉(zhuǎn)、縮放等等變換。
??? 在3D圖形學(xué)里的矩陣變換同2D圖形學(xué)里一樣,只是多了一維坐標(biāo),一般的變換矩陣如下圖所示:
???
??? 單獨平移矩陣和縮放矩陣如下圖所示,也比較好理解,其中Tx,Ty,Tz分別表示在各個坐標(biāo)軸上平移的距離,Sx,Sy,Sz分別表示在各個坐標(biāo)方向上縮放的倍數(shù)。
???
??? 旋轉(zhuǎn)矩陣在理解上需要一點點推導(dǎo),以2維空間下圍繞原點旋轉(zhuǎn)為例,大家可以畫一個草圖來幫助推導(dǎo),設(shè)點(x,y)與原點的連線同X軸的角度為b,以此方向繼續(xù)旋轉(zhuǎn)a度,至點(x’,y’),我們可知旋轉(zhuǎn)軌跡所在圓的半徑R=x/cosb,R=y/sinb。而x’=R*cos(a+b),y’=R*sin(a+b),根據(jù)合角公式拆開,再將前面的式子帶入,可得x’=xcosa-ysina;y’=xsina+ycosa。
??? 3維空間下以此相推可分別得出圍繞X軸方向旋轉(zhuǎn)、圍繞Y軸方向旋轉(zhuǎn)、圍繞Z軸方向旋轉(zhuǎn)的變換矩陣:
??? ?
??? 另外3維空間下圍繞任意軸旋轉(zhuǎn)的旋轉(zhuǎn)變換矩陣是通過平移矩陣和圍繞各個軸旋轉(zhuǎn)的矩陣復(fù)合而得出的。
??? 在世界坐標(biāo)系里的任何一個模型的狀態(tài)都可以通過若干中變換矩陣的組合來表明它的唯一狀態(tài),通過矩陣相乘來得到最終的變換矩陣,需要注意的是因為所有的變換矩陣都是相對坐標(biāo)系的原點完成的,所以變換矩陣相乘時候的順序關(guān)系很重要,相互顛倒會產(chǎn)生完全不同的變換矩陣。
??? 視角變換
??? 通過世界變換,我們將所有的模型都轉(zhuǎn)換到一個統(tǒng)一的世界坐標(biāo)系中,但是在游戲中我們的觀察點不可能總是世界坐標(biāo)系的原點,面向著Z軸的正方向。攝像機和模型是同樣可以游離于場景中的任何地點,面向任意角度的,所以這就需要通過視角變換來實現(xiàn)。
??? 一個視角變換通常是由一次平移變換和三次旋轉(zhuǎn)變換來完成的,平移矩陣負(fù)責(zé)將相機從默認(rèn)的世界坐標(biāo)系的原點平移到正確的位置,三次旋轉(zhuǎn)分別負(fù)責(zé)圍繞三個坐標(biāo)軸的旋轉(zhuǎn),將相機調(diào)整至正確的朝向。
??? 說的很抽象,但實際上可以理解為將轉(zhuǎn)換到世界坐標(biāo)下的各個模型再轉(zhuǎn)換到以攝像機為原點的攝像機坐標(biāo)系下,當(dāng)然在游戲中是不需要手動生成這個矩陣的,我們只需要提供相機的位置,朝向等等參數(shù),API會幫我們生成正確的視角矩陣。
??? 投影變換
??? 投影變換的工作就是將攝影空間中的三維物體投影到二維的平面上,邏輯上也就是用戶的屏幕區(qū)域。這種三維到二維的變換過程就是投影變換,即從取景空間到投影空間的變換。
??? 投影變換分為兩種基本的投影變換:正交投影和透視投影
??? 正交投影中,投影向量和觀察平面垂直,物體坐標(biāo)沿觀察坐標(biāo)系的Z軸平行投影到觀察平面上,觀察點和觀察平面間的距離不會影響物體的投影大小。工程設(shè)計中的頂視圖、前視圖和側(cè)視圖就是典型的正交投影,正交投影沒有透視關(guān)系,可以利用正交投影來完成D3D渲染2D游戲畫面。
??? 而透視投影實現(xiàn)的是一個縮放、透視的投影。透視投影的特點是:距離攝像機越遠的物體在投影平面上的成像越小。更像人眼所能看到的現(xiàn)實世界中的透視關(guān)系。
??? 下面我們來根據(jù)透視投影的幾何關(guān)系來推導(dǎo)一下透視投影下的投影矩陣的生成:
??? 在游戲中,當(dāng)以透視的方法從攝像機來觀察場景的時候,會在場景內(nèi)形成一個金字塔形狀的可見區(qū)域,又因為遠近兩個裁剪面的存在,所以實際上可見區(qū)域是一個截體,透視投影矩陣的作用是將這個取景截體轉(zhuǎn)換成一個立方體(將近攝像機端拉伸),分別將X和Y坐標(biāo)映射到投影平面的正確的位置上,同時保持深度信息不變,因為截體的近端比遠端小,所以靠近攝像機的對象將被放大,而遠離攝像機的對象,則會相對保持原樣。
???? 到齊次裁剪空間的映射是通過一個4×4的投影矩陣實現(xiàn)的。在這個投影矩陣中,除了其他的變換功能外,還要保證變換后的點w坐標(biāo)等于攝像機空間中的點的z坐標(biāo)的負(fù)值,這樣,將變換后的點的坐標(biāo)分量除以w坐標(biāo)后,就可以生成裁剪空間中相應(yīng)的三維點。
??? 我們設(shè)圖中可視區(qū)中一點P(Px,Py,Pz),將P點同攝像機相連同投影面交于一點(x,y,z),這個點就是投影變換后P所應(yīng)該在的點,遠近裁剪面到攝像機的距離分別是d和Zf。根據(jù)相似三角形,我們可以知道x=d*Px/Pz;y=d*Py/Pz,設(shè)投影平面的四個邊框的橫縱坐標(biāo)位置分別是r,l,t,b(右左上下)。為了滿足取景截體到齊次空間的映射,我們還需要需要將投影后的x,y坐標(biāo)映射到[-1,1]區(qū)間,而通常的,將z坐標(biāo)映射到[0,1]區(qū)間,映射后的坐標(biāo)為x’,y’,z’。根據(jù)兩個平面內(nèi)坐標(biāo)同平面的線性比例關(guān)系,我們繼續(xù)推導(dǎo):
???
??? Z軸的線性關(guān)系相對簡單,但是因為在光柵化過程中為避免透視失真而進行的乘以z倒數(shù)的插值操作(顯卡的工作,為什么要這樣的具體原理還理解不夠透徹,以后補齊),所以這里要建立關(guān)于1/z的映射,這樣就可以對投影深度值進行線性插值了:
???
??? 將所得的x’,y’,z’同Px,Py,Pz所對應(yīng)的關(guān)系進一步整理,就可以得到最終的正確的投影矩陣了。這個投影矩陣也是D3D中所用的投影矩陣,雖然我們通常都是提供相機的fov,朝向,位置等參數(shù)利用API生成, 但是理解原理是非常重要的,關(guān)于正交投影的投影矩陣大家也可以利用類似的步驟推導(dǎo)出來。
???
總結(jié)
以上是生活随笔為你收集整理的Shader 坐标转换的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WLK冰冠城堡传说中的橙斧影之哀伤任务详
- 下一篇: 铜包银网线网吧布线为什么传输距离变短,布