顯示具有 Face culling 標籤的文章。 顯示所有文章
顯示具有 Face culling 標籤的文章。 顯示所有文章

2023年3月30日 星期四

Custom Projection Matrix to fit Vulkan default viewport

➡️ 前篇


客製化Projeciton Matrix

為了fit Vulkan奇怪的NDC

需要

Mb * Ma = Projection Matrix

Ma怎麼來?

Ma

Mb怎麼來?

當NDC的z落在-1~1之間 🐞
Mb

Fix 🐞

vulkan NDC的z落在0~1之間才對
OpenGL才是落在-1~1之間

vulkan tutorial裡有1行
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
就是在指定NDC要用0~1

code from GLM setup.hpp

這樣一來

Mb其實是
A = F/(F-N)
B= -NF/(F-N)
 

比較一下

(MbMa)和GLM的perspectiveRH_ZO
只差在 Result[1][1]的正負

這代表

➡️ 前篇 的結果2修正後的結果3
其實是同個投影矩陣!?


Vulkan在clip space做Face culling嗎?

➡️ 前篇


clip space就是projection space


A X B = n 
n和Vc_to_eye的夾角沒有 > 90度的話
這個三角面可以顯示

用這種方法,三角形應該要顯示
結果1沒有
所以Vulkan不是這樣做的

從 NDC 變換到 view port space

➡️ 前篇


Flipping the Vulkan viewport


設定完viewport的屬性後
Vulkan會自行計算Red、Green、Center這些參數
再用這些參數把NDC座標變換到viewport

DX、OpenGL、Vulkan在那做Face cullng?

 

開場

設定逆時鐘方向是三角形的正面


這是我們的三角形和camera設定

使用glm::lookAt,預設是右手的Camera

為什麼3角形沒有出來?

結果1
程式碼來自vulkan tutorial

但是他的可以

結果2
程式碼來自vulkan tutorial

然後改成這樣也行?

結果3


to NDC space


肉眼可見DirectX、openGL、Vulkan
大家在NDC三角形都是逆時針

如果vulkan是在這裡做face culling
結果1就會看到三角形

結果1並沒看到
所以不是在這裡做!

viewport space

變換到viewport space


判定順時鐘、逆時鐘的座標系必須是
x軸從銀幕左往右
y軸從銀幕下往上

所以我們先自己鏡射一下
如果是在這裡做face culling
Vulkan是逆時鐘
結果1就會看到三角形

結果1並沒看到
所以也不是在這裡做!

那麼現在

假設存在1個 Face cullng space

用來判定face culling

這樣一來
DirectX和OpenGL都是逆時鐘,看得到三角形
而Vulkan是順時鐘,看不到
結果1相符

結果2

代表在camera space先沿著y軸方向鏡射

再乘上projection matrix
Vulkan是順時針
所以不是在NDC做

Vulkan在Screen Spcae是順時鐘
Vulkan在face culling space是逆時鐘

所以結果2看的到

這是一個負負得正的結果

結果3

客製化Projeciton Matrix

去fit這種奇怪的NDC



在Screen Space是順時鐘
在face culling space是逆時鐘

所以結果3看的到

參考資料


Sascha的方法

我們使用右手的Camera

 

直接修改viewport

相當於下面的紅色區塊

在Face culling space是逆時鐘方向

所以能正常顯示

不需要變換到Face culling space

仔細看完VkFrontFace Manual Page
發現它使用的是矩阵求三角形面积的結果再*(-1) 

VkFrontFace Manual Page

因為
viewport space和Face culling space判定的結果就是差1個負號