iOS開發(fā)學習OpenGL ES系列 -- 攝像機

在講攝像機之前先介紹一下3D渲染中的MVP:分別是模型矩陣(model)、觀察矩陣(view)岩瘦、投影矩陣(Projection)揉燃。其中模型矩陣操作的是單個3D模型,可以進行平移约急、縮放寇仓、旋轉或者組合變換。觀察矩陣可以理解為3D世界中的攝像機烤宙,當攝像機的位置發(fā)生改變遍烦,拍攝的角度不一樣,呈現(xiàn)在屏幕上的效果自然會有變化躺枕。這一操作會改變物體的頂點位置服猪。投影矩陣在上一篇講過,分為正射投影和透視投影拐云,透視投影有遠小近大的效果罢猪,更為真實。這里大概了解一下MVP叉瘩,接下來修改代碼正式步入3D世界膳帕,這里引入了三個矩陣,所以頂點著色器中需要添加接受屬性:

attribute vec4 position;
attribute vec4 color;

varying vec4 fColor;

uniform mat4 pMatrix;
uniform mat4 vMatrix;
uniform mat4 mMatrix;

void main(void) {
    fColor = color;
    mat4 mvp = pMatrix * vMatrix * mMatrix;
    gl_Position = mvp * position;
}

mMatrix、vMatrix危彩、pMatrix分別是模型矩陣攒磨、觀察矩陣、投影矩陣汤徽。這里將mvp直接相乘娩缰,結果再與position相乘。注意相乘的順序先進行模型矩陣變換谒府,再是觀察矩陣拼坎,最后是投影矩陣變換。

相應的工程中添加三個屬性:

GLKMatrix4 projectionMatrix; // 投影矩陣
GLKMatrix4 modelMatrix; // 模型矩陣
GLKMatrix4 cameraMatrix; // 觀察矩陣

在viewDidLoad中進行初始化:

// projectionMatrix 投影矩陣完疫。 呈現(xiàn)更為真實的3D效果這里設置投影矩陣為透視投影泰鸡。
 float aspect = self.view.frame.size.width / self.view.frame.size.height;
 float fovyRadians =GLKMathDegreesToRadians(90);
 projectionMatrix = GLKMatrix4MakePerspective(fovyRadians, aspect, 0.0, 100.0);
 
 // modelMatrix 模型矩陣 初始化模型矩陣為單位矩陣
 modelMatrix = GLKMatrix4Identity;
 
 // cameraMatrix 觀察矩陣
 cameraMatrix = GLKMatrix4MakeLookAt(0, 0, 2, 0, 0, 0, 0, 1, 0);

GLKit提供了創(chuàng)建觀察矩陣的函數(shù):
GLKMatrix4MakeLookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ)

參數(shù)float eyeX, float eyeY, float eyeZ定義攝像機的位置。float centerX, float centerY, float centerZ攝像機看向的點壳鹤。光是這樣還不行鸟顺,相機還可以自轉360.所以還需要float upX, float upY, float upZ三個參數(shù)確定相機向上的朝向。我們可以設置這9個參數(shù)以控制攝像機從不同的角度觀察物體器虾。

目前創(chuàng)建的觀察矩陣是固定的不動的讯嫂,我們把projectionMatrix、modelMatrix和cameraMatrix賦值到Vertex Shader:

GLuint modeLocation = glGetUniformLocation(program, "mMatrix");
glUniformMatrix4fv(modeLocation, 1, 0, modelMatrix.m);
    
GLuint projectionLocation = glGetUniformLocation(program, "pMatrix");
glUniformMatrix4fv(projectionLocation, 1, 0, projectionMatrix.m);
    
GLuint cameraLocation = glGetUniformLocation(program, "vMatrix");
glUniformMatrix4fv(cameraLocation, 1, 0, cameraMatrix.m);

運行效果:

這跟前面的透視投影沒什么區(qū)別兆沙。上一篇中視點在(0欧芽,0,0)位置葛圃,可視區(qū)域在Z軸負方向千扔,成像在(0,0库正,0)和可視區(qū)域之間曲楚。而這里設置相機在(0,0褥符,2)位置龙誊,朝向(0,0喷楣,0)也就是Z的負方向趟大,其余設置一樣。所以這里創(chuàng)建觀察矩陣其實就是代替了上一篇中的視點铣焊,所以展示效果是一樣的逊朽。只不過前面的默認視點在(0,0曲伊,0)位置固定不動叽讳,而這里我們可以通過修改GLKMatrix4MakeLookAt的參數(shù)來控制相機位置與方向,以展示出物體不同角度的圖像。下面我們重新定義觀察矩陣:

// cameraMatrix = GLKMatrix4MakeLookAt(0, 0, 2, 0, 0, 0, 0, 1, 0);
cameraMatrix = GLKMatrix4MakeLookAt(0, 1, 2, 0, 0, 0, 0, 1, 0);

把相機的y軸改為1岛蚤,看一下效果:

改變了相機的y值邑狸,朝向和向上不變,很明顯有俯視向下看的感覺灭美。

// cameraMatrix = GLKMatrix4MakeLookAt(0, 1, 2, 0, 0, 0, 0, 1, 0);
cameraMatrix = GLKMatrix4MakeLookAt(0, sin(change), 3, 0, 0, 0, 0, 1, 0);

這次讓相機的y在[-1,1]之間變化推溃,修改z為3昂利,并去掉旋轉届腐,看下效果:

首先看到的圖像肯定是變小了,這是因為相機的z修改為3蜂奸,把距離拉遠了1個單位犁苏。再觀察感覺矩形是在繞著X軸自轉,其實并不這樣扩所,因為我們改變相機的y是在[-1,1]之間围详,并且z是固定的,所以只能是直線性的上下移動祖屏,也就造成了這種最終效果助赞。

這里還可以修改GLKMatrix4MakeLookAt的float upX, float upY, float upZ來控制相機的向上朝向。

// cameraMatrix = GLKMatrix4MakeLookAt(0, sin(change), 3, 0, 0, 0, 0, 1, 0);
cameraMatrix = GLKMatrix4MakeLookAt(0, sin(change), 3, 0, 0, 0, 1, 0, 0);

這里設置相機朝向為x正方向袁勺,效果圖就不上傳了雹食,有興趣的可以自己嘗試修改這些參數(shù)來控制相機。當然需要注意的是物體的可視區(qū)域與相機位置期丰。否則你有可能什么都看不到群叶。

關于OpenGL ES的相機就說到這里了,如果文中有錯誤或者有補充的知識點歡迎留言討論钝荡,謝謝街立!

本例源碼:LearningOpenGL ES GitHub

如果修改相機的向上朝向為X正方向的話,屏幕上的 圖像會逆時針旋轉90度埠通,而且再不是上下擺動赎离,變成了左右擺動。這是因為相機向上朝向由Y的正方向變?yōu)閄的正方向端辱,相機旋轉了90度蟹瘾,原來的右上角為綠色,旋轉之后變?yōu)樗{色掠手。原來是Y軸朝上憾朴,相機是上下滑動變?yōu)楝F(xiàn)在的X軸朝上而左右滑動。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末喷鸽,一起剝皮案震驚了整個濱河市众雷,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖砾省,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鸡岗,死亡現(xiàn)場離奇詭異,居然都是意外死亡编兄,警方通過查閱死者的電腦和手機轩性,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來狠鸳,“玉大人揣苏,你說我怎么就攤上這事〖妫” “怎么了卸察?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長铅祸。 經常有香客問我坑质,道長,這世上最難降的妖魔是什么临梗? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任涡扼,我火速辦了婚禮,結果婚禮上盟庞,老公的妹妹穿的比我還像新娘吃沪。我一直安慰自己,他們只是感情好茫经,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布巷波。 她就那樣靜靜地躺著,像睡著了一般卸伞。 火紅的嫁衣襯著肌膚如雪抹镊。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天荤傲,我揣著相機與錄音垮耳,去河邊找鬼。 笑死遂黍,一個胖子當著我的面吹牛终佛,可吹牛的內容都是我干的。 我是一名探鬼主播雾家,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼铃彰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了芯咧?” 一聲冷哼從身側響起牙捉,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤竹揍,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后邪铲,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體芬位,經...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年带到,在試婚紗的時候發(fā)現(xiàn)自己被綠了昧碉。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡揽惹,死狀恐怖被饿,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情永丝,我是刑警寧澤锹漱,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布箭养,位于F島的核電站慕嚷,受9級特大地震影響,放射性物質發(fā)生泄漏毕泌。R本人自食惡果不足惜喝检,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望撼泛。 院中可真熱鬧挠说,春花似錦、人聲如沸愿题。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽潘酗。三九已至杆兵,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間仔夺,已是汗流浹背琐脏。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留缸兔,地道東北人日裙。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像惰蜜,于是被迫代替她去往敵國和親昂拂。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內容