OpenGL 你不知道的左右手座標系

2021-09-08 17:47:39 字數 2494 閱讀 8633

眾所周知,opengl使用的是右手座標系,而direct3d使用的是左手座標系。

除了上面z軸的方向不一樣外,左右手座標系的還有其他區別:

正向旋轉方向:在左手系中用left-hand rule判別,正方向是順時針方向。在右手系中,用right-hand rule判別,是逆時針方向。

叉積的方向:在右手座標系中,叉積的方向通過right-hand rule確定,而在左手座標系中,叉積的方向則由left-hand rule 確定。

world space 座標系

world space 是定義物理世界位置的客觀空間,left hand 和 right hand只是提供了兩種不同的描述空間的方法,但描述的都是同乙個世界。左右手坐

標係之間的轉換並沒有改變所描述的世界,真實世界中的時鐘不管是在左手系還是右手系,都是按照順時針方向旋轉的。

view座標系

無論是左手系還是右手系,world座標系都描述了同乙個世界空間,而你這麼觀察這個客觀的世界空間,就取決於你所使用的座標系了,這是opengl跟

direct3d最主要的差別。下面先看個例子,

攝像機設定都是eyepos(0, 0, 15), lookat(0, 0, 0), upvec(0, 1, 0),紅色方塊的位置都是(-3, 0, 0),綠色方塊的位置都是(3, 0, 0),

那麼為什麼opengl跟direct3d是左右顛倒的呢?個人覺得是因為view座標系是左手還是右手的關係,在direct3d中,view空間座標系是left hand,

z軸就是viewdirection(lookat - eyeposition),當攝像機在(0,0,15)的地方往原點看的時候,確實是(-3,0,0)處紅色的方塊出現在(3,0,0)

出綠色方塊的右邊。而在opengl中,view空間座標系是right hand, z軸其實是-viewdirection, 所以結果就是紅色的方塊出現在綠色方塊的左邊。

由此可見,左右手座標系其實是左右顛倒的兩個世界。

左右手座標系的轉換

上面也看到了,左右手座標系渲染出來的2d影象結果是不一樣的,左右顛倒,那如何使左右手座標系渲染出相同的2d影象呢,有兩種方法。

方法一:反轉所有vertex的x軸座標和camera的x座標,左右手座標系其實是左右顛倒的兩個座標系。

方法二:對用左右手座標系渲染出來的2d影象進行水平方向上的反轉。

在modern opengl 中使用左手座標系

眾所周知,在固定管線的opengl中只能使用右手座標系,opengl並沒有提供api讓你在左右手座標系中切換。而在可程式設計管線的opengl中,就沒有那麼

多限制了,所有的vertex transform都由你來控制。事實上,你直接把左手座標系的頂點和矩陣傳給opengl shader也是沒有問題的,在vertex shader

使用mul(v, matrix)變換頂點,得到的會是跟direct3d同樣的結果。注意是跟direct3d同樣的結果,而不是跟固定管線opengl相同的結果,事實上,正如

上面所說,左右手座標系渲染的結果的左右顛倒的。唯一要區別的是viewport的z,在opengl中,裁剪空間的z座標是[-1. 1],而在direct3d中是[0, 1],

而經過viewport變化後,不管是opengl還是direct3d, z都是[0, 1], opengl的視口變化是 z=(z/w + 1) / 2 ,而direct3d是z=(z/w),這對depth

test不受影響,depth test只比較相對位置遠近,但depth buffer的值就不同了。所以需要對project matrix做一些調整,才能讓他們寫到depth buffer中

的數值相同。具體來說,如果要讓opengl流水線接受d3d的project matrix,就需要乘上

相當於把project space的頂點z都作了z = z * 2 – 1的操作,所以經過viewport變換就一致了。

你不知道的 和

開發中,編寫有一定逼格的 是每個程式猿都追求的。經常用來判斷的符號 和 也經常用來定義變數哦,你知道嗎?邏輯與 在有乙個運算元不是布林值的情況下,就不一定返回布林值。比如以下情況 1 第乙個運算元是物件,返回第二個數 var myinfo console.log myinfo 2 輸出22 第二個運...

你不知道的box shadow

我們可以僅使用乙個div利用shadow配合animation實現很多豐富的效果 github 求 必需。水平陰影的位置。允許負值。v shadow 必需。垂直陰影的位置。允許負值。blur 可選。模糊距離。spread 可選。陰影的尺寸。color 可選。陰影的顏色。請參閱 css 顏色值。ins...

你不知道的 gitignore

乙個.gitignore檔案顯式地指定了哪些檔案不應被git追蹤,即被git忽略掉。在被gitignore之前已經被git追蹤的檔案不受gitignore規則的影響。關於gitignore規則的詳情請繼續往下看。gitignore檔案中的每一行都指定了一種匹配模式。通常來說,git會從多個可能的規則...