學習OpenGL ES之基于CubeMap的反射效果

本系列所有文章目錄

獲取示例代碼


本文將為大家介紹如何使用CubeMap制作反射效果峭沦,反射效果可以讓材質具備光滑的質感,比如汽車的烤漆逃糟,就非常適合使用反射效果吼鱼。先上2張效果圖。我使用的是Blender內置的猴頭模型進行的渲染測試绰咽。


Cube Map

我們首先來了解一下什么是CubeMap菇肃。即使你不了解CubeMap,但你一定知道全景圖取募。隨便打開一個XX地圖琐谤,進入全景模式,就可以360度無死角的觀察周邊的環(huán)境了玩敏。地圖的全景模式大多使用的是Cube Map的方式斗忌,使用上下左右前后各6張圖质礼,分別貼在以觀察者為中心的正方體上,這樣就可以形成一個假的3D環(huán)境了织阳。讀者可以從這個網站下載用于CubeMap的圖片眶蕉,下載下來的圖片都已經標記好了應該在的位置,使用起來還是很方便的唧躲。neg開頭的表示在負軸上造挽,pos表示在正軸上。比如posx就是x正軸上的面所使用的貼圖惊窖。


這個網站還可以預覽Cube Map的全景效果刽宪。點擊WebGL Preview即可。


在Shader中使用Cube Map

Shader提供了表示CubeMap的內置類型samplerCube界酒,samplerCubesampler2D一樣圣拄,都是貼圖,不同的是需要使用textureCube進行采樣毁欣,采樣的時候需要傳遞規(guī)范化后的三維向量而不是二維的UV庇谆。采樣的代碼如下。

textureCube(envMap, reflectVec)

textureCube會采樣reflectVec向量在Cube Map上指向的點的像素凭疮》苟可以理解為求解向量和標準正方體的相交點。例子中我們根據(jù)法向量和視線向量計算用于采樣的reflectVec反射向量执解。然后把采樣的顏色用于環(huán)境色的計算寞肖。

// 計算環(huán)境光
vec3 ambient = vec3(light.ambientIndensity) * material.ambientColor;
vec3 reflectVec = normalize(reflect(-eyeVector, transformedNormal));
ambient += 0.5 * diffuseStrength *  textureCube(envMap, reflectVec).rgb;

Shader很簡單,只有這部分的變化衰腌。

準備Cube Map

接下來我們在OC代碼中為Shader準備Cube Map新蟆,Cube Map需要6張圖,我通過前面說的網站下載了一套Cube Map貼圖右蕊,按照posx琼稻,negx,posy,negy,posz屏箍,negz的順序命名為cube-1,cube-2嘀掸,....,GLKit生成CubeMap的API需要按照這樣順序將圖片傳遞給它规惰,生成CubeMap的代碼如下睬塌。

- (void)createCubeTexture {
    NSMutableArray *files = [NSMutableArray new];
    for (int i = 0; i < 6; ++i) {
        NSString *filename = [NSString stringWithFormat:@"cube-%d", i + 1];
        NSString *filePath = [[NSBundle mainBundle] pathForResource:filename ofType:@"jpg"];
        [files addObject:filePath];
    }
    NSError *error;
    self.cubeTexture = [GLKTextureLoader cubeMapWithContentsOfFiles:files options:nil error:&error];
}

將Cube Map傳遞給Shader

為了將Cube Map傳遞給Shader,我為GLContext寫了一個新的方法。

- (void)bindCubeTexture:(GLKTextureInfo *)textureInfo to:(GLenum)textureChannel uniformName:(NSString *)uniformName {
    glActiveTexture(textureChannel);
    glBindTexture(GL_TEXTURE_CUBE_MAP, textureInfo.name);
    GLuint textureID = (GLuint)textureChannel - (GLuint)GL_TEXTURE0;
    [self setUniform1i:uniformName value:textureID];
}

和2D貼圖主要的不同就是綁定到的target不一樣衫仑,這里綁定到了GL_TEXTURE_CUBE_MAP上,其他的操作和2D貼圖都是一樣的堕花。最后在渲染時調用這個方法文狱。這里我綁定到了通道3的紋理上。

[obj.context bindCubeTexture:self.cubeTexture to:GL_TEXTURE3 uniformName:@"envMap"];

創(chuàng)建猴頭模型

使用之前編寫的WavefrontOBJ類可以很方便的加載猴頭的模型缘挽。

- (void)createMonkey {
    UIImage *normalImage = [UIImage imageNamed:@"metal.jpg"];
    GLKTextureInfo *normalMap = [GLKTextureLoader textureWithCGImage:normalImage.CGImage options:nil error:nil];
    UIImage *diffuseImage = [UIImage imageNamed:@"metal.jpg"];
    GLKTextureInfo *diffuseMap = [GLKTextureLoader textureWithCGImage:diffuseImage.CGImage options:nil error:nil];
    
    NSString *objFile = [[NSBundle mainBundle] pathForResource:@"smoothMonkey" ofType:@"obj"];
    WavefrontOBJ *sphere = [WavefrontOBJ objWithGLContext:self.glContext objFile:objFile diffuseMap:diffuseMap normalMap:normalMap];
    sphere.modelMatrix = GLKMatrix4Identity;
    [self.objects addObject:sphere];
}

到此瞄崇,基于CubeMap的反射效果就完成了,該技術的重點就是Cube Map壕曼,掌握了它苏研,其他都很簡單。大家看完可能會發(fā)現(xiàn)這種反射效果無法反射周邊的幾何體腮郊,只能反射指定的CubeMap摹蘑。如果我想制作一面鏡子,可以反射周邊的物體轧飞,該怎么辦呢衅鹿?這就是我下一篇文章將介紹的內容,如何制作實時的鏡面反射效果过咬。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末大渤,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子掸绞,更是在濱河造成了極大的恐慌泵三,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件衔掸,死亡現(xiàn)場離奇詭異烫幕,居然都是意外死亡,警方通過查閱死者的電腦和手機具篇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門纬霞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人驱显,你說我怎么就攤上這事诗芜。” “怎么了埃疫?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵伏恐,是天一觀的道長。 經常有香客問我栓霜,道長翠桦,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮销凑,結果婚禮上丛晌,老公的妹妹穿的比我還像新娘。我一直安慰自己斗幼,他們只是感情好澎蛛,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蜕窿,像睡著了一般谋逻。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上桐经,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天毁兆,我揣著相機與錄音,去河邊找鬼阴挣。 笑死气堕,一個胖子當著我的面吹牛,可吹牛的內容都是我干的畔咧。 我是一名探鬼主播送巡,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼盒卸!你這毒婦竟也來了骗爆?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤蔽介,失蹤者是張志新(化名)和其女友劉穎摘投,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體虹蓄,經...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡犀呼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了薇组。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片外臂。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖律胀,靈堂內的尸體忽然破棺而出宋光,到底是詐尸還是另有隱情,我是刑警寧澤炭菌,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布罪佳,位于F島的核電站,受9級特大地震影響黑低,放射性物質發(fā)生泄漏赘艳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蕾管。 院中可真熱鬧枷踏,春花似錦、人聲如沸掰曾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽婴梧。三九已至,卻和暖如春客蹋,著一層夾襖步出監(jiān)牢的瞬間塞蹭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工讶坯, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留番电,地道東北人。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓辆琅,卻偏偏與公主長得像漱办,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子婉烟,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內容