Unity Shader 各個空間坐標的獲取方式及xyzw含義
一、對象/模型空間 OS(Object/Model Space):float4
定義:以模型(通常為模型的重心)為原點的空間,一般默認物體前方為z軸,右邊為x軸,上方為y軸。
posOS.xyzw含義
x[-精度范圍上限,精度范圍上限]:本地坐標x值。
y[-精度范圍上限,精度范圍上限]:本地坐標y值。
z[-精度范圍上限,精度范圍上限]:本地坐標z值。
w[0,1]:如果有位移變換的話,需要將坐標轉換至齊次坐標系下,因此w值為1,否則一般為0,不清楚怎么用的話直接寫1.0。
求posOS
二、世界空間 WS(World Space):float4
定義:一般來說世界空間就是游戲空間,其原點放置在游戲空間的中心。
posWS.xyzw含義
x[-精度范圍上限,精度范圍上限]:世界坐標x值。
y[-精度范圍上限,精度范圍上限]:世界坐標y值。
z[-精度范圍上限,精度范圍上限]:世界坐標z值。
w[0,1]:如果有位移變換的話,需要將坐標轉換至齊次坐標系下,因此w值為1,否則一般為0,不清楚怎么用的話直接寫1.0。
求posWS
三、觀察空間 VS(View Space):float4
定義:以相機為原點的坐標空間。(ps:觀察空間與屏幕空間不一樣,觀察空間是一個三維空間,屏幕空間是二維空間)。
posVS.xyzw含義
x[-精度范圍上限,精度范圍上限]:觀察空間坐標x值。
y[-精度范圍上限,精度范圍上限]:觀察空間坐標y值。
z[-精度范圍上限,精度范圍上限]:觀察空間坐標z值。
w[0,1]:如果有位移變換的話,需要將坐標轉換至齊次坐標系下,因此w值為1,否則一般為0,不清楚怎么用的話直接寫1.0。
求posVS
四、裁剪空間 CS(Clip Space):float4
定義:與投影矩陣計算后也被稱為齊次裁剪空間(HCS Homogeneous Clip Space),這個用于變換的矩陣叫做裁剪矩陣(Clip Matrix),也被稱為投影矩陣(Projection Matrix)。
透視投影posCS.xyzw含義
x[-w , w]:裁剪空間下x軸坐標。
y[-w , w]:裁剪空間下x軸坐標。
z[-w, w]:裁剪空間下z軸坐標,離相機越遠z值越大。
w[Near, Far]:用來判斷坐標是否在視錐體外部,-w<= x/y/z <= w 的話則點在視錐體內部。

x[-1 , 1]:裁剪空間下x軸坐標。
y[-1 , 1]:裁剪空間下x軸坐標。
z[-1, 1]:裁剪空間下z軸坐標,離相機越遠z值越大。
w[1]:用來判斷坐標是否在視錐體外部,-w<= x/y/z <= w 的話則點在視錐體內部。
求posCS
五、歸一化設備坐標 NDC(Normalized Device Coordinates):float4
定義:用齊次坐標系的w分量去除以x、y、z分量。
透視投影posNDC.xyzw含義
x[-1 , 1]:NDC空間x坐標。
y[-1 , 1]:NDC空間y坐標。
z[-w, w]:posNDC.z == posCS.z。
w[Near, Far]:posNDC.w == posCS.w。

正交投影posNDC.xyzw含義
x[-1 , 1]:NDC空間x坐標。
y[-1 , 1]:NDC空間y坐標。
z[-1, 1]:posNDC.z == posCS.z。
w[1]:posNDC.w == posCS.w。

求posNDC
六、屏幕空間 SS(Screen Space):float2
定義:當裁剪工作完畢后,就需要進行真正的投影,也就是說需要把視錐體投影到屏幕空間(Screen Space)。經過這一步變換就會得到真正的像素位置,而不是虛擬的三維坐標。
posSS.xyzw含義
x[0, ScreenPixelWidth]:屏幕x軸坐標。
y[0, ScreenPixelWidth]:屏幕y軸坐標。
z、w:posSS.zw == posCS.zw,具體查看ComputeScreenPos()方法
通常z分量會被用于深度緩沖。?一個傳統方式是把ClipzClipw的值直接存入深度緩存中,但這并不是必須的。通常驅動廠商會根據硬件來選擇最好的存儲格式。?Clipw?也并不會被拋棄,它在后續(xù)的工作中會起到重要的作用,例如進行透視校正差值。
求posSS
七、視口空間 VP(ViewPort Space):float2
定義:屏幕空間除以屏幕分辨率得到的就是視口空間(viewport space)中的坐標。
posVP.xy含義:
x[0, 1]:歸一化后的屏幕X坐標,左下角為0,右上角為1。
y[0, 1]:歸一化后的屏幕Y坐標,左下角為0,右上角為1。
求取視口空間中的坐標 VPPos(View Port Position)
方式一:就是把屏幕坐標歸一化,這樣屏幕左下角就是(0,0),右上角就是(1,1)。如果已知屏幕坐標的話,只需要把xy值除以屏幕分辨率即可。
VPOS.xyzw含義(注意是輸入語義VPOS的xyzw含義)
x[0, ScreenParamsX):屏幕空間中像素x坐標。(ps: 屏幕像素可以在_ProjectionParams中拿到)
y[0, ScreenParamsY):屏幕空間中像素y坐標。
z[0, 1]:在攝像機的近裁剪平面處,z值為0,在遠裁剪平面處,z值為1。
w[?1Near,1Far?]:Near、Far對應了Camera組件中設置的近裁剪平面和遠裁剪平面距離相機的遠近;如果使用的是正交投影,那么w分量的值恒為1。(ps: Near、Far可以在_ProjectionParams中拿到)
方式二:通過Unity提供的ComputeScreenPos函數,首先在頂點著色器計算結果,然后在片元著色器進行一個齊次除法運算即可得到視口空間下的坐標。
引用:《Unity Shader入門精要》learnopengl-cn 坐標系統
https://learnopenglcn.readthedocs.io/zh/latest/01%20Getting%20started/08%20Coordinate%20Systems/
https://zhuanlan.zhihu.com/p/505030222