Clip Space、NDC、Screen Space

Unity3D - Shader - 模型、世界、觀察、裁剪空間坐標(biāo)轉(zhuǎn)換
Unity3D Shaders中Loacl、World、Camera space之間的轉(zhuǎn)換(翻譯)
容易混淆的Clip Space vs NDC,透視除法

先看兩張圖片:


空間轉(zhuǎn)換流程圖
空間變換

可以看到裁剪空間(Clip Space)最后會轉(zhuǎn)換到屏幕空間(Screen Space),最終輸出到屏幕上并顯示正確的圖像,模型空間-->世界空間-->觀察空間,這幾步是比較容易理解的,直接通過矩陣轉(zhuǎn)換就可以得到相應(yīng)的坐標(biāo),但是裁剪空間-->屏幕空間,其實(shí)還有兩個(gè)中間步驟:轉(zhuǎn)換到NDC(標(biāo)準(zhǔn)化設(shè)備坐標(biāo))與屏幕映射(OpenGL好像叫視口變換)。
先解釋下裁剪空間,觀察空間實(shí)際就是相機(jī)為原點(diǎn)的空間,而相機(jī)可分為透視模式和正交模式,透視模式的可視區(qū)域是一個(gè)梯形的椎體,正交模式是一個(gè)矩形,如下:

透視投影

正交投影

無論哪種模式,都是有可視范圍的,超出可視范圍(近裁剪平面、遠(yuǎn)裁剪平面和上下左右邊界)的物體就看不到,看不到的東西就沒有必要渲染,所以要將不可見的物體裁剪掉,留下可見的范圍內(nèi)的物體就可以了,所以裁剪空間實(shí)際上是在觀察空間的基礎(chǔ)上增加了一個(gè)區(qū)域限制,把坐標(biāo)限制在可見的范圍內(nèi)。

轉(zhuǎn)換到裁剪空間后經(jīng)過GPU的裁剪處理就可以得到最終需要被渲染的物體頂點(diǎn)坐標(biāo)了,接下來GPU會做透視除法將頂點(diǎn)轉(zhuǎn)換到NDC中,透視除法將裁剪空間中頂點(diǎn)的4個(gè)分量都除以w分量,就從裁剪空間轉(zhuǎn)換到了NDC了,NDC是一個(gè)長寬高取值范圍為[-1,1]的立方體,具體的推導(dǎo)就不展開說了,網(wǎng)上有很多大牛的詳細(xì)推導(dǎo)過程。


NDC

注:在DirectX里面,NDC的z方向取值范圍是[0,1],在Unity中可以用UNITY_NEAR_CLIP_VALUE獲取z方向近平面的值,在openGL環(huán)境下是-1.0,DirectX中是0.0。

將頂點(diǎn)坐標(biāo)都轉(zhuǎn)換到NDC后,下一步就是屏幕映射,這個(gè)就取決于最終要渲染到的窗體分辨率,注意是窗體分辨率,不是屏幕分辨率,因?yàn)樵谝苿?dòng)平臺上一般不允許改變渲染窗體的分辨率,通常是全屏顯示,也就是屏幕分辨率,而pc上修改窗體大小改變分辨率就比較普遍,最終通過屏幕映射得到屏幕空間的坐標(biāo)。在Unity中,屏幕空間左下角的像素坐標(biāo)是(0,0),右上角是(pixelWidth,pixelHeight)。
(Vertex Shader) => Clip Space => (透視除法) => NDC => (視口變換) => Screen Space => (Fragment Shader)
不過這些Unity會自動(dòng)幫助我們完成,我們只需要知道原理就可以了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容