OSG 如何用Shader得到物體的世界座標

2021-04-28 06:53:27 字數 1363 閱讀 6250

來自:

最近群裡面有個朋友問我關於如何得到opengl世界座標的問題,當時我還弄錯了,誤以為gl_modelviewmatrix*gl_vertex就是世界座標。因最近也突然遇到了世界座標的問題,所以花了一些時間來研究這個問題,網上也有人問,但或許沒有答案,或許是錯的。

其實,opengl的轉換管道直接將gl_vertex,也就是物體座標,用gl_modelviewmatrix相乘,得到的是眼座標。如果將gl_modelviewmatirx拆分為gl_modelmatrix和gl_viewmatrix,那麼問題就好解決了。但事實上沒有提供。要清楚opengl其實沒有世界座標系,世界座標系是應用程式的概念。其實可以將opengl的攝像機看作是固定的,其座標系就是眼座標系,移動攝像機和移動物體的位置是乙個相反的轉換,對於觀察者來說根本不知道是攝像機在動,還是物體在動(想想大衛的大變自由女神像的魔術吧,呵呵)

說回來,最終的變換是這樣的:

eyepos=viewmatrix * modelmatrix * modelvertex

在opengl裡面viewmatrix和modelmatrix合併了,因為opengl裡面並沒有設定攝像機的引數,所以opengl並不知道viewmatrix到底是什麼。viewmatrix是使用者自己定義的,所以如果能夠得到這個viewmatrix並能得到其逆矩陣,就可以得到worldpos:

worldpos=viewmatrixinv * viewmatrix * modelmatrix * modelvertex

傳統的opengl程式裡面,你得自己計算這個viewmatrixinv,還好osg的camera提供了乙個getviewmatrixinverse()方法,通過這個方法我們就可以輕鬆的獲得viewmatrixinv,然後傳遞給vertex shader(用乙個uniform就可以),然後進行這個計算就可以了。

記得每一幀都需要update這個viewmatrixinv,只需要乙個updatecallback就可以了。

好了,看幾個圖,我用3dsmax建立了兩個盒子,為了便於觀察,模型的頂點值限制在0-1之間,然後用osgexp匯出,沒有選中flatten static transform這樣就不會把模型定點轉換成世界座標系的頂點。

源**中可以改變gl_fragcolor=的值來修改為相應的座標系的值顯示。

本來是就是想找如何獲得世界座標的,然後發現我的**中沒有用到glulookat,那麼應該是沒有gl_viewmatrix,直接gl_modelviewmatrix*gl_vertex獲得看看》<

glgetdoublev(gl_modelview_matrix,mview); //獲得gl_modelviewmatrix

如何用rowId得到row 物件

在一些事件中,比如afterrowinsert gridid,rowid 這些事件中,沒有cellid,這樣就無法用常用的方法得到cell物件 和row物件 而netadvantage中的igtbl getrowbyid cellid 的id需要是cell的id 所以無法直得得到row物件 但是我們...

如何用rowId得到row 物件

在一些事件中,比如afterrowinsert gridid,rowid 這些事件中,沒有cellid,這樣就無法用常用的方法得到cell物件 和row物件 而netadvantage中的igtbl getrowbyid cellid 的id需要是cell的id 所以無法直得得到row物件 但是我們...

如何用js得到當前頁面的url資訊方法

設定或獲取物件指定的檔名或路徑。alert window.location.pathname 設定或獲取整個 url 為字串。alert window.location.href 設定或獲取與 url 關聯的埠號碼。alert window.location.port 設定或獲取 url 的協議部分...