對OpenGLES中的空間變換的理解

2021-08-08 04:33:28 字數 2617 閱讀 2057

今天翻看以前用cocos2d-x寫的vr小遊戲的**,有乙個

模組功能是判斷固定在螢幕中心的一條射線是否觸碰到了其他3d物體。這套**原來是從學長寫的遊戲中直接扒出來的,沒有細細研究,今天正好看到了,就藉此總結一下在opengles中空間的轉換。

在opengles中,物體會在五個空間中變換,如圖所示:

(來自網路)

1.物體空間:

物體空間指的就是乙個3d物體最開始所在的地方,也就是說當我們把乙個正方體匯入3dmax或其他建模軟體中時,它的中心總是在(0,0,0)點,它的乙個頂點可能是(1,1,1)這個座標就是它在自己物體空間的座標。

2.世界空間

如果直接將物體轉換到世界空間當中,它們一定都會集中在(0,0,0)這個點。為了能讓它們擺放在不同的位置,從而引進了世界空間這個概念,具體的做法就是需要將物體空間座標系中每個點的座標乘以模型矩陣(model matrix)。

模型矩陣是一種變化矩陣,將物體座標系中的每個頂點都乘上模型矩陣,就可以實現平移、旋轉、縮放等操作,從而將其從物體空間轉換到世界空間當中。

3.觀察空間

現在所有的物體都已經加在進了場景,而且在世界空間中井井有條的擺放好了,是不是還少了點什麼~沒錯,沒有攝像機呀,只有在加入乙個攝像機才能最終讓你看到,不然擺放好的東西就沒有任何意義了。嗯~這時候就需要再將處於世界空間中的物體乘上乙個觀察矩陣(view matrix),這時就將世界空間中的物體轉換到了觀察空間中了。

4.剪裁空間

在opengles中,最終成現在使用者眼前的畫面一定是你所構建的世界的一部分,也就是說由於

攝像機視野,位置的不同,最終會有一部分物體會被剔除出畫面,剪裁空間要做的就是這部分工作——將落在剪裁空間之外的點剔除掉。

為了將物體從觀察空間轉換到剪裁空間,我們需要使用觀察矩陣乘上投影矩陣(project matrix),將最終入選的點篩選出來(如果只是圖元的一部分超出了剪裁體積,opengles則會將其重構)。投影矩陣建立的觀察箱被稱為平截頭體,投影矩陣還有乙個功能就是將3d的物體投影到2d的螢幕上,其原理很像我們的視網膜成像。

正交投影:正交投影的平截頭體類似於乙個長方體,也就是說,觀察空間的物體無論距離攝像機遠近投影到畫面的大小都是一樣的,這適合一些2d遊戲或是非真實的繪製。

透視投影:透視投影則是更加貼近現實生活的一種投影,簡單的來說就是近大遠小的效果。這種效果的實現源於透視投影矩陣

,投影矩陣將給定的平截頭體範圍對映到裁剪空間,除此之外還修改了每個頂點座標的w值,從而使得離觀察者越遠的頂點座標w分量越大。被變換到裁剪空間的座標都會在-w到w的範圍之間(這個w可以模擬現實生活中投影機到螢幕的距離)。這也就可以解釋頂點著色器中gl_position的值為啥是vec4了~(因為它要根據最後乙個w算大小呀~當然透視除法和剪裁都是opengles自己處理的)。

5.視口空間

最後一步就是將已經將3d場景轉換成為2d的畫面對應轉換到螢幕上,如果手機是1920x1080的解析度就是將畫面轉換成為2073600個畫素點,在opengles中我們使用的是glviewport這個函式設定視口。

洋洋灑灑總結了這麼多,在電腦前從6點多一下子坐到了快10點啦,希望這些能夠對大家理解有所幫助,也希望**有不對的地方,和我多多交流討論~

對了我先前說的那個cocos的模組,就是先獲得螢幕的中間點的座標,然後得到乙個螢幕中點的近距離點與遠距離點,再乘unproject也就是投影矩陣的逆矩陣,把這個線段從剪裁空間轉換到觀察空間,然後歸一化得到乙個方向向量,最後使用api判斷這個方向的射線是否觸碰到了選單的包圍盒,從而進一步判斷的。

下面是這部分的**:

size size = director::getinstance()->getwinsize(); 

//獲取螢幕的尺寸

vec3 nearp(size.width / 2

, size.height / 2

, 0.0);

//近距離點

vec3 farp(size.width / 2

, size.height / 2

, 1.0);

//遠距離點

cameracontrol::mycamera->unproject(size, &nearp, &nearp);

//轉換為攝像機下的座標(螢幕座標)

cameracontrol::mycamera->unproject(size, &farp, &farp);

vec3 direction;

//方向向量

vec3::subtract(farp, nearp, &direction);

//獲取方向向量

direction.normalize();

//歸一化

ray ray;

//宣告射線

ray._origin = nearp;

//射線的起點

ray._direction = direction;

//射線的方向向量

opengles基本變換的實質

我們在三維座標系中對物體進行旋轉,縮放,平移,從表面上看是直接針對物體的,但實際上並不是,這些變換是針對座標系的,opengles中 變換的實現機制可以理解為首先通過矩陣對座標系進行變換,然後根據傳入渲染管線的原始頂點座標在最終變換結果座標系中的位置來進行繪製,見下圖加深理解 變換過程 1,左側的原...

座標變換,空間變換的本質

座標變換或空間變換,本質是相對座標的變化,絕對座標沒變。世界空間有兩個物體a,b。將a變換到b的座標空間意思是 將a從世界空間變換到b的區域性座標空間,也就是在b的區域性座標系中重新表示a的座標 也就是求出a在b座標系中的相對座標 做法很簡單 1,a b 得到乙個向量 v,2,把v分解 投影 到b的...

MATLAB中對矩陣的變換

矩陣的變換主要有對角陣,三角陣,矩陣的轉置,矩陣的旋轉,矩陣的翻轉,矩陣求逆等操作。下面我將對以上幾種操作進行總結。對角矩陣 只有對角線上有非零元素的矩陣。數量矩陣 對角線上的元素相等的對角矩陣。單位矩陣 對角線上的元素都為1的矩陣。提取矩陣中對角線的元素 diag a 提取矩陣a的主對角線元素,產...