iOS開發(fā)-OpenGLES進階教程2

教程

這一次的的內容是光照。

概念準備

所謂的光照,是GPU為每個三角形的頂點進行光線計算,再把結果進行插值,得出每個片元的最終顏色。
OpenGL ES的燈光模擬包括:環(huán)境光、漫反射光、鏡面反射光。
光線與幾何圖形相互作用的關鍵:計算出每個物體照射和發(fā)散出來多少光線。
光線計算依賴于表面法向量。法向量也是單位向量。
表面法向量可以通過平面內兩個點的叉積(矢量積)來計算。

光線計算過程還包括材質、聚光燈效果、衰減因子等,但是GLKit簡化了這一過程。

效果展示

光照

核心思路

如下圖,總共AI九個點,07八個面。E的z坐標是可變的,隨著UISlider的數值由-1到0變化。
為了方便觀察,繞X軸和Z軸旋轉了一定角度。
燈光用GLKBaseEffect類。

頂點-平面圖

具體細節(jié)

  • 頂點
    總共有9個頂點,具體坐標如下。前面為頂點坐標,后面為法線坐標。
static const SceneVertex vertexA = {{-0.5,  0.5, -0.5}, {0.0, 0.0, 1.0}};
static const SceneVertex vertexB = {{-0.5,  0.0, -0.5}, {0.0, 0.0, 1.0}};
static const SceneVertex vertexC = {{-0.5, -0.5, -0.5}, {0.0, 0.0, 1.0}};
static const SceneVertex vertexD = {{ 0.0,  0.5, -0.5}, {0.0, 0.0, 1.0}};
static const SceneVertex vertexE = {{ 0.0,  0.0, -0.5}, {0.0, 0.0, 1.0}};
static const SceneVertex vertexF = {{ 0.0, -0.5, -0.5}, {0.0, 0.0, 1.0}};
static const SceneVertex vertexG = {{ 0.5,  0.5, -0.5}, {0.0, 0.0, 1.0}};
static const SceneVertex vertexH = {{ 0.5,  0.0, -0.5}, {0.0, 0.0, 1.0}};
static const SceneVertex vertexI = {{ 0.5, -0.5, -0.5}, {0.0, 0.0, 1.0}};

重新緩存頂點數組

  • 平面
    SceneVertex是頂點的數據結構
    SceneTriangle是平面(三角形)的數據結構
//頂點
typedef struct {
    GLKVector3  position; //
    GLKVector3  normal;
}
SceneVertex;
//三角形
typedef struct {
    SceneVertex vertices[3];
}
SceneTriangle;
  • 光源
    配置漫反射光的顏色,還有光源的位置
    self.baseEffect = [[GLKBaseEffect alloc] init];
    self.baseEffect.light0.enabled = GL_TRUE;
    self.baseEffect.light0.diffuseColor = GLKVector4Make(
                                                         0.7f, // Red
                                                         0.7f, // Green
                                                         0.7f, // Blue
                                                         1.0f);// Alpha
    self.baseEffect.light0.position = GLKVector4Make(
                                                     1.0f,
                                                     1.0f,
                                                     0.5f,
                                                     0.0f);
    
    self.extraEffect = [[GLKBaseEffect alloc] init];
    self.extraEffect.useConstantColor = GL_TRUE;
  • 變換
    先旋轉,后平移
        GLKMatrix4 modelViewMatrix = GLKMatrix4MakeRotation(GLKMathDegreesToRadians(-60.0f), 1.0f, 0.0f, 0.0f);
        modelViewMatrix = GLKMatrix4Rotate(
                                           modelViewMatrix,
                                           GLKMathDegreesToRadians(-30.0f), 0.0f, 0.0f, 1.0f);
        modelViewMatrix = GLKMatrix4Translate(
                                              modelViewMatrix,
                                              0.0f, 0.0f, 0.25f);
        self.baseEffect.transform.modelviewMatrix = modelViewMatrix;
        self.extraEffect.transform.modelviewMatrix = modelViewMatrix; 
  • 法線繪制
    先設置光源顏色為綠色,畫頂點法線
    再設置光源顏色為黃色,畫光源線
    self.extraEffect.useConstantColor = GL_TRUE;
    self.extraEffect.constantColor =
    GLKVector4Make(0.0, 1.0, 0.0, 1.0);
    
    [self.extraEffect prepareToDraw];
    
    [self.extraBuffer drawArrayWithMode:GL_LINES
                       startVertexIndex:0
                       numberOfVertices:NUM_NORMAL_LINE_VERTS];
    
    self.extraEffect.constantColor =
    GLKVector4Make(1.0, 1.0, 0.0, 1.0);
    
    [self.extraEffect prepareToDraw];
    
    [self.extraBuffer drawArrayWithMode:GL_LINES
                       startVertexIndex:NUM_NORMAL_LINE_VERTS
                       numberOfVertices:(NUM_LINE_VERTS - NUM_NORMAL_LINE_VERTS)];

關鍵函數

  • 求法向量函數
GLKVector3 SceneTriangleFaceNormal(const SceneTriangle triangle);
  • 通過叉積求單位法向量函數
GLKVector3 SceneVector3UnitNormal(
                                  const GLKVector3 vectorA,
                                  const GLKVector3 vectorB)

總結

進階教程不只是圖形學知識的進階,代碼的規(guī)范也很重要,能避免一部分錯誤。
光照原理的內容可以參考這里,講解非常詳細,但是本次使用的GLKit,所以簡化了許多。
附上源碼

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容