1. 程式人生 > >OpenGL ES (10): 答疑解惑 -- 投影檢視矩陣和相機檢視變換矩陣

OpenGL ES (10): 答疑解惑 -- 投影檢視矩陣和相機檢視變換矩陣

1.介紹

之前的程式碼如下:


private final float[] mMVPMatrix = new float[16];
private final float[] mProjectionMatrix = new float[16];
private final float[] mViewMatrix = new float[16];
 
@Override
public void onSurfaceChanged(GL10 unused, int width, int height) {
    GLES20.glViewport(0, 0, width, height);
    float ratio = (float) width / height;
//得到投影矩陣
    Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
}

@Override
public void onDrawFrame(GL10 unused) {
//得到相機檢視變換矩陣
    Matrix.setLookAtM(mViewMatrix, 0, 0, 0, 5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

//結合
    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);
    //新的矩陣mMVPMatrix傳入,繪製圖形
    mTriangle.draw(mMVPMatrix);
}

可以看到我們分別是用兩個方法得到投影矩陣和相機檢視變換矩陣

  • Matrix.setLookAtM(mViewMatrix, 0, cx, cy, cz, tx, ty, tz, upx, upy, upz)
  • Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far)

下面詳細解釋這兩個方法。

2. 相機檢視變換矩陣 Matrix.setLookAtM(mViewMatrix, 0, cx, cy, cz, tx, ty, tz, upx, upy, upz)

Matrix.setLookAtM 
需要填充的引數 
float cx, //攝像機位置x 
float cy, //攝像機位置y 
float cz, //攝像機位置z 
float tx, //攝像機目標點x 
float ty, //攝像機目標點y 
float tz, //攝像機目標點z 
float upx, //攝像機UP向量X分量 
float upy, //攝像機UP向量Y分量 
float upz //攝像機UP向量Z分量 

  • tx,ty, tz,為影象的中心位置設定到原點即 tx = 0,ty = 0, tz = 0;
  • 攝像機的位置,即觀察者眼睛的位置 我們設定在目標點的正前方(位置z軸正方向),cx = 0, cy = 0, cz = 5;
  • 接著是攝像機頂部的方向了,很顯然相機旋轉,up的方向就會改變,這樣就會會影響到繪製圖像的角度。

例如設定up方向為y軸正方向,upx = 0,upy = 1,upz = 0。這是相機正對著目標影象,則繪製出來的效果如下圖所示 

如果設定up方向為x軸正方向,upx = 1,upy = 0,upz = 0,繪製的影象就會如下圖所示

顯然如果設定在z軸方向,影象就會看不見。

3.投影矩陣 Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far)

Matrix.frustumM 
需要填充的引數有 
float left, //near面的left 
float right, //near面的right 
float bottom, //near面的bottom 
float top, //near面的top 
float near, //near面距離 
float far //far面距離 

  • 先是left,right和bottom,top,這4個引數會影響影象左右和上下縮放比,所以往往會設定的值分別-(float) width / height和(float) width / height,top和bottom和top會影響上下縮放比,如果left和right已經設定好縮放,則bottom只需要設定為-1,top設定為1,這樣就能保持影象不變形。( 也可以將left,right 與bottom,top交換比例,即bottom和top設定為 -height/width 和 height/width, left和right設定為-1和1。 )
  • near和far引數稍抽象一點,就是一個立方體的前面和後面,near和far需要結合拍攝相機即觀察者眼睛的位置來設定,例如setLookAtM中設定cx = 0, cy = 0, cz = 5,near設定的範圍需要是小於5才可以看得到繪製的影象,如果大於5,影象就會處於眼睛的後面,這樣繪製的影象就會消失在鏡頭前,far引數影響的是立體圖形的背面,far一定比near大,一般會設定得比較大,如果設定的比較小,一旦3D圖形尺寸很大,這時候由於far太小,這個投影矩陣沒法容納圖形全部的背面,這樣3D圖形的背面會有部分隱藏掉的。