在講攝像機之前先介紹一下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的相機就說到這里了,如果文中有錯誤或者有補充的知識點歡迎留言討論钝荡,謝謝街立!
如果修改相機的向上朝向為X正方向的話,屏幕上的 圖像會逆時針旋轉90度埠通,而且再不是上下擺動赎离,變成了左右擺動。這是因為相機向上朝向由Y的正方向變?yōu)閄的正方向端辱,相機旋轉了90度蟹瘾,原來的右上角為綠色,旋轉之后變?yōu)樗{色掠手。原來是Y軸朝上憾朴,相機是上下滑動變?yōu)楝F(xiàn)在的X軸朝上而左右滑動。