學(xué)習(xí)OpenGL ES之紋理投影效果

本系列所有文章目錄

獲取示例代碼


本文作為OpenGL ES高級篇的開篇,將為大家介紹如何把一張紋理貼圖投影到復(fù)雜的幾何體上难审。下面是例子運(yùn)行的結(jié)果提针。



下面是未開啟紋理投影的效果圖。



這張是用來投影的紋理圖封断。

涉及到的重要知識點(diǎn)

  1. 基本幾何體的渲染
  2. 法線貼圖
  3. 紋理坐標(biāo)
  4. 投影矩陣

前兩個知識點(diǎn)是為了渲染場景,例子渲染的場景很簡單,使用3個來自obj文件的正方體,加上4張貼圖纳令,只要看過前面的文章,可以很容易的理解代碼克胳。紋理坐標(biāo)和投影矩陣是實(shí)現(xiàn)這個效果的關(guān)鍵平绩。

基本原理

這個效果和真實(shí)生活中的投影儀很像。假設(shè)我們把投影儀當(dāng)做一個攝像機(jī)漠另,并且設(shè)置好投影矩陣捏雌,如下圖所示。那么投影儀就具備了MVP中的VP兩個矩陣了笆搓。

3D物體的頂點(diǎn)經(jīng)過投影儀的VP和自身的M變換后就會變成投影儀空間的坐標(biāo)性湿。因?yàn)樗薪?jīng)過投影變換的點(diǎn)如果在可視范圍內(nèi),它的x满败,y都會落在-1和1之間肤频,所以我們可以將投影儀空間的坐標(biāo)當(dāng)做UV來使用,UV的范圍是01算墨,-11的范圍只要加1再乘以0.5就可以很方便的變換成0~1的范圍宵荒。這樣我們就可以根據(jù)頂點(diǎn)在投影儀空間的坐標(biāo)來獲取UV了。

Fragment Shader

本文使用的Fragment Shader在fragment.glsl文件中净嘀。首先我們添加投影的紋理貼圖和投影矩陣报咳。

// projectors
uniform mat4 projectorMatrix;
uniform sampler2D projectorMap;
uniform bool useProjector;

useProjector主要用作開關(guān)投影效果。projectorMatrix由投影儀的投影矩陣和觀察矩陣相乘而來挖藏。

接著根據(jù)投影儀空間的坐標(biāo)計算UV暑刃。

vec4 positionInProjectorSpace = projectorMatrix * modelMatrix * vec4(fragPosition, 1.0);
positionInProjectorSpace /= positionInProjectorSpace.w;
vec2 projectorUV = (positionInProjectorSpace.xy + 1.0) * 0.5;

positionInProjectorSpace /= positionInProjectorSpace.w;之所以要除以w,是因?yàn)槿绻闶褂玫氖峭敢曂队熬仃嚹っ撸敲从锌赡躻不為1岩臣,這時候需要xyzw都除以w保證xy范圍的正確性。

最后我們判斷UV的坐標(biāo)來決定是否接受到了投影宵膨。UV超出0~1范圍的說明不在投影儀的可視范圍內(nèi)架谎,所以不需要進(jìn)行投影處理。這里我使用4:6的比例簡單的混合了兩種顏色柄驻。你也可以把它當(dāng)做光照顏色來處理狐树,使用它計算diffuse和specular的顏色。

if (projectorUV.x >= 0.0 && projectorUV.x <=1.0 && projectorUV.y >= 0.0 && projectorUV.y <=1.0) {
    projectorColor = texture2D(projectorMap, projectorUV);
    gl_FragColor = vec4(finalColor * 0.4 + projectorColor.rgb * 0.6, 1.0);
} else {
    gl_FragColor = vec4(finalColor, 1.0);
}

上面便是Fragment Shader中和投影效果相關(guān)的代碼鸿脓。

生成并刷新投影儀的矩陣

我們回到OC代碼來生成投影儀需要的VP矩陣抑钟。每次渲染時我都會刷新projectorMatrix涯曲,讓它圍繞y軸旋轉(zhuǎn)。只要讓camera的up向量圍繞y軸旋轉(zhuǎn)就可以做到這一點(diǎn)在塔。隨著projectorMatrix的旋轉(zhuǎn)幻件,投影的紋理也會隨之旋轉(zhuǎn)。

@property (assign, nonatomic) GLKMatrix4 projectorMatrix;
...

// update projector matrix
GLKMatrix4 projectorProjectionMatrix = GLKMatrix4MakeOrtho(-2, 2, -2, 2, -100, 100);
GLKMatrix4 projectorCameraMatrix = GLKMatrix4MakeLookAt(0, 4, 0, 0, 0, 0, cos(self.elapsedTime), 0, sin(self.elapsedTime));
self.projectorMatrix = GLKMatrix4Multiply(projectorProjectionMatrix, projectorCameraMatrix);

然后把projectorMatrix賦值給uniform就可以了蛔溃。

[obj.context setUniformMatrix4fv:@"projectorMatrix" value: self.projectorMatrix];

本例中我使用的是正交投影绰沥,如果你想嘗試透視投影,可以自行修改測試贺待。

投影紋理

針對投影紋理需要處理的事情很簡單徽曲,初始化&設(shè)置uniform。

UIImage *projectorImage = [UIImage imageNamed:@"squarepants.jpg"];
self.projectorMap = [GLKTextureLoader textureWithCGImage:projectorImage.CGImage options:nil error:nil];
...
[obj.context bindTexture:self.projectorMap to:GL_TEXTURE2 uniformName:@"projectorMap"];

紋理投影效果有什么用麸塞?

比如槍擊游戲里的彈痕就可以使用這種技術(shù)來實(shí)現(xiàn)秃臣,將彈痕貼圖投影到任何你打中的地方。而且投影貼圖完全可以是動態(tài)的哪工,加上法線貼圖等等奥此。你可以發(fā)揮自己的想象,做出一些更有意思的效果雁比。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末稚虎,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子偎捎,更是在濱河造成了極大的恐慌蠢终,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鸭限,死亡現(xiàn)場離奇詭異蜕径,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)败京,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來梦染,“玉大人赡麦,你說我怎么就攤上這事∨潦叮” “怎么了泛粹?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長肮疗。 經(jīng)常有香客問我晶姊,道長,這世上最難降的妖魔是什么伪货? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任们衙,我火速辦了婚禮钾怔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蒙挑。我一直安慰自己宗侦,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布忆蚀。 她就那樣靜靜地躺著矾利,像睡著了一般。 火紅的嫁衣襯著肌膚如雪馋袜。 梳的紋絲不亂的頭發(fā)上男旗,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天,我揣著相機(jī)與錄音欣鳖,去河邊找鬼察皇。 笑死,一個胖子當(dāng)著我的面吹牛观堂,可吹牛的內(nèi)容都是我干的让网。 我是一名探鬼主播,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼师痕,長吁一口氣:“原來是場噩夢啊……” “哼溃睹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起胰坟,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤因篇,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后笔横,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體竞滓,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年吹缔,在試婚紗的時候發(fā)現(xiàn)自己被綠了商佑。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡厢塘,死狀恐怖茶没,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情晚碾,我是刑警寧澤抓半,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站格嘁,受9級特大地震影響笛求,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一探入、第九天 我趴在偏房一處隱蔽的房頂上張望狡孔。 院中可真熱鬧,春花似錦新症、人聲如沸步氏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽荚醒。三九已至,卻和暖如春隆嗅,著一層夾襖步出監(jiān)牢的瞬間界阁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工胖喳, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留泡躯,地道東北人。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓丽焊,卻偏偏與公主長得像较剃,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子技健,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評論 2 355

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

  • 轉(zhuǎn)載注明出處:點(diǎn)擊打開鏈接 Shader(著色器)是一段能夠針對3D對象進(jìn)行操作写穴、并被GPU所執(zhí)行的程序。Shad...
    游戲開發(fā)小Y閱讀 3,374評論 0 4
  • <轉(zhuǎn)>我也忘了轉(zhuǎn)自哪里,抱歉,感謝原作者 什么是Shader Shader(著色器)是一段能夠針對3D對象進(jìn)行操作...
    星易乾川閱讀 5,595評論 1 16
  • 本系列所有文章目錄[http://www.reibang.com/p/df4c8f9bc08d] 獲取示例代碼[...
    handyTOOL閱讀 3,483評論 0 4
  • 我們總是希望在自己迷茫的時候雌贱,有人提一盞燈站在你身前照亮未開的路啊送,在自己沉浸于窘迫時,有人用盆涼水狠狠滴澆醒你欣孤,在...
    戴樹枝的面具閱讀 840評論 1 1
  • 曾幾度發(fā)出疑問降传,這樣的生活是否真的是自己所要篷朵?一直以來,好像也沒有給自己設(shè)立目標(biāo)婆排,只想開心順其自然的過款票,過到實(shí)在覺...
    絳珠公子閱讀 252評論 0 0