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

教程

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

概念準(zhǔn)備

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

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

效果展示

光照

核心思路

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

頂點(diǎn)-平面圖

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

  • 頂點(diǎn)
    總共有9個(gè)頂點(diǎn),具體坐標(biāo)如下歹篓。前面為頂點(diǎn)坐標(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}};

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

  • 平面
    SceneVertex是頂點(diǎn)的數(shù)據(jù)結(jié)構(gòu)
    SceneTriangle是平面(三角形)的數(shù)據(jù)結(jié)構(gòu)
//頂點(diǎn)
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è)置光源顏色為綠色,畫頂點(diǎn)法線
    再設(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é)

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市刀闷,隨后出現(xiàn)的幾起案子熊泵,更是在濱河造成了極大的恐慌,老刑警劉巖甸昏,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件顽分,死亡現(xiàn)場離奇詭異,居然都是意外死亡施蜜,警方通過查閱死者的電腦和手機(jī)卒蘸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來翻默,“玉大人缸沃,你說我怎么就攤上這事⌒扌担” “怎么了趾牧?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長肯污。 經(jīng)常有香客問我翘单,道長梯皿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任县恕,我火速辦了婚禮东羹,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘忠烛。我一直安慰自己属提,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布美尸。 她就那樣靜靜地躺著冤议,像睡著了一般。 火紅的嫁衣襯著肌膚如雪师坎。 梳的紋絲不亂的頭發(fā)上恕酸,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天,我揣著相機(jī)與錄音胯陋,去河邊找鬼蕊温。 笑死,一個(gè)胖子當(dāng)著我的面吹牛遏乔,可吹牛的內(nèi)容都是我干的义矛。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼盟萨,長吁一口氣:“原來是場噩夢啊……” “哼凉翻!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起捻激,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤制轰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后胞谭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體垃杖,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年韭赘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了缩滨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,117評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡泉瞻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出苞冯,到底是詐尸還是另有隱情袖牙,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布舅锄,位于F島的核電站鞭达,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜畴蹭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一坦仍、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧叨襟,春花似錦繁扎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至右犹,卻和暖如春提澎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背念链。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工盼忌, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人掂墓。 一個(gè)月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓碴犬,卻偏偏與公主長得像,于是被迫代替她去往敵國和親梆暮。 傳聞我的和親對象是個(gè)殘疾皇子服协,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容