我們只針對可編譯管線因?yàn)檫@樣效率高。(這里是個(gè)人理解)
1.模型矩陣:modo_matrix
本質(zhì):
就是管理模型當(dāng)前頂點(diǎn)的矩陣。可以理解成我們在現(xiàn)實(shí)世界中有一個(gè)星球叫火星,無論我們看不看它(通??床灰姡?,它都在那里位移和旋轉(zhuǎn)。這時(shí)模型矩陣就是火星自己的矩陣。它包含了自己的(位移、旋轉(zhuǎn)、縮放)矩陣的集合。當(dāng)然有就相乘沒有就算了。
作用:
用于改變模型所有頂點(diǎn)的狀態(tài)。(強(qiáng)調(diào)排除一切其他知識的影響,這就是物體自己的本質(zhì)特性)
運(yùn)算:
M=P(縮放)*R(旋轉(zhuǎn)矩陣)*T(位移矩陣)*Point(每個(gè)頂點(diǎn))
最后算頂點(diǎn)效率會(huì)非常高。
2.視圖矩陣:view_matrix
本質(zhì):
用來影響我們的視點(diǎn)的矩陣,這個(gè)矩陣與攝像機(jī)狀態(tài)關(guān)系非常密切。大家或許可以想象成我們的眼睛。這也是我們根據(jù)現(xiàn)實(shí)生活的理解,這樣想是沒有錯(cuò)的。但在算法中實(shí)際上是我們使用期望相機(jī)的位置和看向的方向來作用于3D空間中的每個(gè)點(diǎn),屏幕中渲染的始終都是各種運(yùn)算之后的結(jié)果。(這個(gè)結(jié)果是2D的結(jié)果,也就是3D數(shù)據(jù)最后運(yùn)算成像素的結(jié)果)。從算法的理解來講實(shí)際上攝像機(jī)沒有動(dòng),而是世界中的物體被影響在動(dòng)。這樣想我們就知道這個(gè)攝像機(jī)是我們現(xiàn)象出的位置,我們把這個(gè)位置當(dāng)作參數(shù)傳入矩陣,就會(huì)達(dá)到我們期望的目的。這或許難以理解,我們可以想象成,我們想看的地方的物體,實(shí)際上隨著我們的意念(這個(gè)意念就是算法)在動(dòng)。
好比我們用手機(jī)拍攝水杯,手機(jī)不能動(dòng),但我想看水杯的右邊,我可以把水杯往左邊移動(dòng)一點(diǎn)。這樣也能達(dá)到和移動(dòng)手機(jī)相同的效果。
說到這要說一下相機(jī)的位置,相機(jī)的初始位置在(0,0,0)的位置看向z軸負(fù)方向(0,0,-1)。這個(gè)位置也就固定了,隨后都是用期望相機(jī)的位置參與矩陣運(yùn)算,來影響物體。如果我們只看結(jié)論(從現(xiàn)實(shí)生活的角度思考),我們可以這樣想,相機(jī)的期望位置是由我們給的參數(shù)決定。
作用:
很明確就是用來達(dá)到在不同位置看向某個(gè)點(diǎn)的目的。(實(shí)際上是改變物體的屬性)
運(yùn)算:
如果我們自己構(gòu)建的話,v矩陣相機(jī)的位置可以包含相機(jī)的旋轉(zhuǎn)角度和平移矩陣,
這時(shí)矩陣的位置參數(shù)就是相機(jī)的位置取反(期望相機(jī)位置)。方向沒有旋轉(zhuǎn)就不乘。
這樣的話:V=R(相機(jī)旋轉(zhuǎn))*T(相機(jī)位置取反)。
但這樣一來R就復(fù)雜了,旋轉(zhuǎn)就會(huì)3個(gè)方向繞x,y,z軸。構(gòu)建起來麻煩。好在OpenGL有個(gè)lookAt()矩陣能直接簡單的達(dá)到這個(gè)目的。所以我們可以V=gluLookAt(...)但最數(shù)學(xué)庫V=glm::lookAt()來構(gòu)建。這樣可以認(rèn)為的來讓V*M高效的構(gòu)成MV模型視口矩陣再發(fā)送給統(tǒng)一變量。實(shí)際上lookat()矩陣的構(gòu)建算法就是在構(gòu)建相機(jī)的視線坐標(biāo)系(現(xiàn)象出來的坐標(biāo)系),是通過視點(diǎn)和位置和世界坐標(biāo)系y軸來構(gòu)建矩陣,最后作用于所有物體。他需要三個(gè)參數(shù)即eye(視線),center(視點(diǎn)),up(y軸)。
3.透視投影矩陣:prespective_matrix
本質(zhì):
上面所說的攝像機(jī)其實(shí)是視點(diǎn),就是看向哪個(gè)方向的哪一點(diǎn),但是我們要看的是一個(gè)空間而不是點(diǎn),這時(shí)我們就需要視野,這個(gè)矩陣就是在給我們提供視野。好比我們的眼睛,能把從一點(diǎn)擴(kuò)散出一個(gè)圓錐體空間的物體投影在視網(wǎng)膜上。但是在電腦上一般屏幕是矩形的,所以我們最常用的就是以屏幕擴(kuò)散出一個(gè)棱錐體的空間,將其投影在屏幕上。為啥是錐體,因?yàn)橐w現(xiàn)一種近大遠(yuǎn)小的視覺效果(透視效果)。
作用:
通過獲取屏幕縱橫比和垂直角度等來構(gòu)建要把物體投影出來的矩陣。
運(yùn)算:
glm::perspective()
最終shader:
gl_position=p*mv*point
當(dāng)然我主要講的的理解沒有推到,也沒有圖片因?yàn)榫W(wǎng)上到處都是,圖片和推導(dǎo)步驟,但是我們寫程序是很多都已經(jīng)封裝成函數(shù)如glm::,最難的是理解。我沒理解的時(shí)候我看著函數(shù)或者矩陣等就感覺莫名奇妙,完全不懂。但是理清了矩陣的含義就容易看懂代碼和推導(dǎo)了。
4.空間
實(shí)際上shader中存在空間這種概念
模型空間(又稱局部空間):
模型空間就是指,物體本身處在的空間。當(dāng)我們剛剛拿到或者用3DMAX這種工具繪制出一個(gè)模型,這個(gè)模型就擁有了一系列屬性,如頂點(diǎn)坐標(biāo)、索引。那么這時(shí)我們解析出來的數(shù)據(jù)在還沒有與矩陣作用時(shí)。就處在物體空間。就算我們用OpenGL進(jìn)行繪制,他也是處在一個(gè)模型屬性一開始定義好的位置(初始位置)。
世界空間:
顧名思義,他是指在世界坐標(biāo)系下的空間。也就是模型數(shù)據(jù)在與模型矩陣作用后,所處在的空間。通常我們會(huì)進(jìn)行位移、縮放、旋轉(zhuǎn)。
視覺空間(又稱相機(jī)空間)
相機(jī)被OpenGL默認(rèn)為在世界坐標(biāo)系的(0,0,0)處看向Z軸負(fù)方向也就是視點(diǎn)(0,0,-1)。他是用來告訴窗口,我們所看到的空間中的所有點(diǎn)在什么位置。當(dāng)與模型矩陣相結(jié)合后作用與每個(gè)點(diǎn)后,每個(gè)點(diǎn)就沒被影響到相應(yīng)的視線空間的位置。這時(shí)模型就處在相機(jī)空間中。注意相機(jī)空間,相機(jī)永遠(yuǎn)在世界坐標(biāo)的原點(diǎn)。
剪切空間(也就是投影空間)
它是用來告訴屏幕我們需要看到的視野范圍,在范圍視野之外就應(yīng)該被剪切(丟棄)。通常是棱錐裝的投影體,當(dāng)前面所說的模型、視圖矩陣和投影矩陣相結(jié)合時(shí),模型就會(huì)處在剪切空間中。最后屏幕上看到的是上面處理后的最終效果。
目錄
VSC++2019+QT+OpenGL
QT+OpenGL一之繪制立方體(三角形圖元)
QT+OpenGL二之紋理貼圖
QT+OpenGL三之矩陣簡解
QT+OpenGL四之相機(jī)的移動(dòng)和旋轉(zhuǎn)
QT+OpenGL五之繪制不同的模型(vao,vbo機(jī)制)
QT+OpenGL六之天空盒
QT+OpenGL七之使用EBO
QT+OPenGL八之模型準(zhǔn)備
QT+OPenGL九之模型解碼
QT+OPenGL十之光照模型
QT+OPenGL十一之漫反射和鏡面反射貼圖
QT+OPenGL十二之定向光
QT+OPenGL十三之真正的點(diǎn)光源和聚光燈
QT+OPenGL十四之多光源混合的問題
QT+OPenGL十五之深度緩沖區(qū)
QT+OPenGL十六之模板緩沖區(qū)
QT+OPenGL十七幀緩沖區(qū)(離屏渲染)
QT+OPenGL十八抗鋸齒
QT+OPenGL十九鏡面反射效率調(diào)整
QT+OPenGL二十Gamma校正