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

教程

這一次的的內(nèi)容是光照。

概念準(zhǔn)備

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

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

效果展示

光照

核心思路

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

頂點-平面圖

具體細(xì)節(jié)

  • 頂點
    總共有9個頂點,具體坐標(biāo)如下。前面為頂點坐標(biāo),后面為法線坐標(biāo)。
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}};

重新緩存頂點數(shù)組

  • 平面
    SceneVertex是頂點的數(shù)據(jù)結(jié)構(gòu)
    SceneTriangle是平面(三角形)的數(shù)據(jù)結(jié)構(gòu)
//頂點
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;
  • 變換
    先旋轉(zhuǎn),后平移
        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; 
  • 法線繪制
    先設(shè)置光源顏色為綠色,畫頂點法線
    再設(shè)置光源顏色為黃色,畫光源線
    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)];

關(guān)鍵函數(shù)

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

總結(jié)

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

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

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容