FrameBuffer及離屏渲染

Framebuffer Get知識點(diǎn)

  • 1条获、給定的模型坐標(biāo)可能只占有屏幕的一般或者一部分牌柄,可以通過平移縮放等操作讓他占滿全屏。
  • 2歧蕉、渲染紋理圖像倒立灾部,可以通過旋轉(zhuǎn)操作使他正常。
  • 3惯退、綁定framebuffer后記得清理緩沖區(qū)
    glBindRenderbuffer(GL_RENDERBUFFER, self.myColorRenderBuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, self.myColorFrameBuffer);

glDisable(GL_DEPTH_TEST);
glClearColor(1.0f, 0, 0, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

  • 4赌髓、創(chuàng)建framebuffer 步驟及代碼,注意renderbuffer和紋理的尺寸要對應(yīng)催跪,否則會采樣錯(cuò)誤锁蠕。
- (GLuint)createCustomFrameBuffer{
    GLuint frameBuffer;
    glGenFramebuffers(1, &frameBuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
    
    //1、綁定顏色緩沖  用于離屏渲染
    GLuint texture;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    CGSize screenSize = [UIScreen mainScreen].bounds.size;
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, screenSize.width*[UIScreen mainScreen].scale, screenSize.height*[UIScreen mainScreen].scale, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    self.frameTexture = texture;
    
    //2懊蒸、綁定深度緩沖和模板緩沖(使用renderbuffer)注意renbuderbuffer和texture 傳遞內(nèi)存空間時(shí)荣倾,都乘了屏幕比例
    GLuint renderbuffer;
    glGenRenderbuffers(1, &renderbuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, screenSize.width*[UIScreen mainScreen].scale, screenSize.height*[UIScreen mainScreen].scale);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderbuffer);
    self.frameRenderBuffer = renderbuffer;
    
    //GL_FRAMEBUFFER_COMPLETE
    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
        NSLog(@"frambuffer 出錯(cuò)---");
        return 0;
    }
    glBindFramebuffer(GL_FRAMEBUFFER, renderbuffer);
    
    return frameBuffer;
}
  • 5、自定義framebuffer使用步驟:
    a骑丸、創(chuàng)建framebuffer舌仍,并綁定自定義的framebuffer.
 glUseProgram(self.grassProgram);
    //glViewport(0, 0, screenSize.width*3, screenSize.height*3);
    glBindRenderbuffer(GL_RENDERBUFFER, self.myColorRenderBuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, self.myColorFrameBuffer);

    glDisable(GL_DEPTH_TEST);
    glClearColor(1.0f, 0, 0, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
}

b妒貌、設(shè)置清屏
c、繪制物體 在frambuffer上glBindTexture(GL_TEXTURE_2D, self.frameTexture);
d1铸豁、后期處理及效果

  • 邊檢測
void main(){

    lowp float offset = 1.0 / 300.0;
       
    lowp vec2 v[9];
    v[0] = vec2(-offset,offset);
    v[1] = vec2(0.0,offset);
    v[2] = vec2( offset,  offset);
    v[3] = vec2(-offset,  0.0);
    v[4] = vec2( 0.0,    0.0);
    v[5] = vec2( offset,  0.0);
    v[6] = vec2(-offset, -offset);
    v[7] = vec2( 0.0,   -offset);
    v[8] = vec2( offset, -offset);
    
    lowp float kernel[9] ;
 //邊緣檢測
    kernel[0] = 1.0 ;
       kernel[1] =  1.0;
       kernel[2] = 1.0 ;
       kernel[3] = 1.0;
       kernel[4] = -8.0;
       kernel[5] = 1.0;
       kernel[6] = 1.0 ;
       kernel[7] = 1.0 ;
       kernel[8] = 1.0 ;
    
    lowp vec3 sampleTex[9];
    
    for (int i=0 ; i < 9; i++){
       sampleTex[i] = vec3(texture2D(boxTexture,outTextCoord.st+v[i]));
      }
     lowp vec3 col = vec3(0.0);
      for(int i = 0; i < 9; I++)
          col += sampleTex[i] * kernel[I];
    gl_FragColor = vec4(col,1.0);

邊檢測效果:


Snip20200315_2.png

核效果:

void main(){
    lowp float offset = 1.0 / 300.0;
       
    lowp vec2 v[9];
    v[0] = vec2(-offset,offset);
    v[1] = vec2(0.0,offset);
    v[2] = vec2( offset,  offset);
    v[3] = vec2(-offset,  0.0);
    v[4] = vec2( 0.0,    0.0);
    v[5] = vec2( offset,  0.0);
    v[6] = vec2(-offset, -offset);
    v[7] = vec2( 0.0,   -offset);
    v[8] = vec2( offset, -offset);
    
    lowp float kernel[9] ;
  
  //核定義數(shù)組
    kernel[0] = -1.0;
    kernel[1] = -1.0;
    kernel[2] = -1.0;
    kernel[3] = -1.0;
    kernel[4] = 9.0;
    kernel[5] = -1.0;
    kernel[6] = -1.0;
    kernel[7] = -1.0;
    kernel[8] = -1.0;
   lowp vec3 sampleTex[9];
    
    for (int i=0 ; i < 9; i++){
       sampleTex[i] = vec3(texture2D(boxTexture,outTextCoord.st+v[i]));
      }
     lowp vec3 col = vec3(0.0);
      for(int i = 0; i < 9; I++)
          col += sampleTex[i] * kernel[I];
      
    
    gl_FragColor = vec4(col,1.0);
}

核效果:


Snip20200315_3.png

模糊效果:

void main(){
    lowp float offset = 1.0 / 300.0;
       
    lowp vec2 v[9];
    v[0] = vec2(-offset,offset);
    v[1] = vec2(0.0,offset);
    v[2] = vec2( offset,  offset);
    v[3] = vec2(-offset,  0.0);
    v[4] = vec2( 0.0,    0.0);
    v[5] = vec2( offset,  0.0);
    v[6] = vec2(-offset, -offset);
    v[7] = vec2( 0.0,   -offset);
    v[8] = vec2( offset, -offset);
    
    lowp float kernel[9] ;

//模糊效果定義數(shù)組
     kernel[0] = 1.0 / 16.0;
    kernel[1] =  2.0 / 16.0;
    kernel[2] = 1.0 / 16.0;
    kernel[3] = 2.0 / 16.0;
    kernel[4] = 4.0 / 16.0;
    kernel[5] = 2.0 / 16.0;
    kernel[6] = 1.0 / 16.0;
    kernel[7] = 2.0 / 16.0;
    kernel[8] = 1.0 / 16.0;
  lowp vec3 sampleTex[9];
    
    for (int i=0 ; i < 9; i++){
       sampleTex[i] = vec3(texture2D(boxTexture,outTextCoord.st+v[i]));
      }
     lowp vec3 col = vec3(0.0);
      for(int i = 0; i < 9; I++)
          col += sampleTex[i] * kernel[I];
      
    
    gl_FragColor = vec4(col,1.0);
}

效果圖:


Snip20200315_4.png

灰度加權(quán):

 gl_FragColor = texture2D(boxTexture,outTextCoord);
    gl_FragColor = vec4(gl_FragColor.r*0.2126+gl_FragColor.g*0.7152+gl_FragColor.b*0.0722,gl_FragColor.r*0.2126+gl_FragColor.g*0.7152+gl_FragColor.b*0.0722,gl_FragColor.r*0.2126+gl_FragColor.g*0.7152+gl_FragColor.b*0.0722,1.0);

灰度加權(quán)效果:


Snip20200315_5.png
圖像旋渦:

主要是在某個(gè)半徑范圍里灌曙,把當(dāng)前采樣點(diǎn)旋轉(zhuǎn)一定角度,旋轉(zhuǎn)以后當(dāng)前點(diǎn)的顏色就被旋轉(zhuǎn)后的點(diǎn)的顏色代替推姻,因此整個(gè)半徑范圍里會有旋轉(zhuǎn)的效果平匈。如果旋轉(zhuǎn)的時(shí)候旋轉(zhuǎn)角度隨著當(dāng)前點(diǎn)離半徑的距離遞減框沟,整個(gè)圖像就會出現(xiàn)漩渦效果藏古。這里使用的了拋物線遞減因子:(1.0-(r/Radius)*(r/Radius) )。

precision mediump float;

const float PI = 3.14159265;
uniform sampler2D textureMap;

const float uD = 80.0; //旋轉(zhuǎn)角度
const float uR = 0.5; //旋轉(zhuǎn)半徑

varying vec2 outText;

void main()
{
    ivec2 ires = ivec2(512, 512);
    float Res = float(ires.s);

    vec2 st = outText;
    float Radius = Res * uR;

    vec2 xy = Res * st;

    vec2 dxy = xy - vec2(Res/2., Res/2.);
    float r = length(dxy);

    float beta = atan(dxy.y, dxy.x) + radians(uD) * 2.0 * (-(r/Radius)*(r/Radius) + 1.0);//(1.0 - r/Radius);

    vec2 xy1 = xy;
    if(r<=Radius)
    {
        xy1 = Res/2. + r*vec2(cos(beta), sin(beta));
    }

    st = xy1/Res;

    vec3 irgb = texture2D(textureMap, st).rgb;

    gl_FragColor = vec4( irgb, 1.0 );
}
Snip20200705_39.png
馬賽克效果

馬賽克效果就是把圖片的一個(gè)相當(dāng)大小的區(qū)域用同一個(gè)點(diǎn)的顏色來表示.可以認(rèn)為是大規(guī)模的降低圖像的分辨率,而讓圖像的一些細(xì)節(jié)隱藏起來忍燥。

precision mediump float;

varying vec2 outText;
uniform sampler2D textureMap;
const vec2 TexSize = vec2(400.0, 400.0);
const vec2 mosaicSize = vec2(8.0, 8.0);

void main()
{
    vec2 intXY = vec2(outText.x*TexSize.x, outText.y*TexSize.y);
    vec2 XYMosaic = vec2(floor(intXY.x/mosaicSize.x)*mosaicSize.x, floor(intXY.y/mosaicSize.y)*mosaicSize.y);
    vec2 UVMosaic = vec2(XYMosaic.x/TexSize.x, XYMosaic.y/TexSize.y);
    vec4 color = texture2D(textureMap, UVMosaic);
    gl_FragColor = color;
}
Snip20200705_40.png
浮雕效果

浮雕效果是指圖像的前景前向凸出背景拧晕。實(shí)現(xiàn)思路:把圖象的一個(gè)象素和左上方的象素進(jìn)行求差運(yùn)算,并加上一個(gè)灰度梅垄。這個(gè)灰度就是表示背景顏色厂捞。這里我們設(shè)置這個(gè)插值為128 (圖象RGB的值是0-255)。同時(shí),我們還應(yīng)該把這兩個(gè)顏色的差值轉(zhuǎn)換為亮度信息队丝,避免浮雕圖像出現(xiàn)彩色像素靡馁。

precision mediump float;
    varying vec2 outText;
    uniform sampler2D textureMap;
    const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);
    const vec2 TexSize = vec2(100.0, 100.0);
    const vec4 bkColor = vec4(0.5, 0.5, 0.5, 1.0);

    void main()
    {
        vec2 tex = outText;
        vec2 upLeftUV = vec2(tex.x-1.0/TexSize.x, tex.y-1.0/TexSize.y);
        vec4 curColor = texture2D(textureMap, outText);
        vec4 upLeftColor = texture2D(textureMap, upLeftUV);
        vec4 delColor = curColor - upLeftColor;
        float luminance = dot(delColor.rgb, W);
        gl_FragColor = vec4(vec3(luminance), 0.0) + bkColor;
    }
Snip20200705_41.png

d2、綁定默認(rèn)緩沖區(qū)机久,渲染frambuffer中的紋理到默認(rèn)緩沖區(qū)臭墨,至屏幕layer上。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末膘盖,一起剝皮案震驚了整個(gè)濱河市胧弛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌侠畔,老刑警劉巖结缚,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異软棺,居然都是意外死亡红竭,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進(jìn)店門喘落,熙熙樓的掌柜王于貴愁眉苦臉地迎上來茵宪,“玉大人,你說我怎么就攤上這事揖盘∶汲” “怎么了?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵兽狭,是天一觀的道長憾股。 經(jīng)常有香客問我鹿蜀,道長,這世上最難降的妖魔是什么服球? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任茴恰,我火速辦了婚禮,結(jié)果婚禮上斩熊,老公的妹妹穿的比我還像新娘往枣。我一直安慰自己,他們只是感情好粉渠,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布分冈。 她就那樣靜靜地躺著,像睡著了一般霸株。 火紅的嫁衣襯著肌膚如雪雕沉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天去件,我揣著相機(jī)與錄音坡椒,去河邊找鬼。 笑死尤溜,一個(gè)胖子當(dāng)著我的面吹牛倔叼,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播宫莱,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼丈攒,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了梢睛?” 一聲冷哼從身側(cè)響起肥印,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎绝葡,沒想到半個(gè)月后深碱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡藏畅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年敷硅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片愉阎。...
    茶點(diǎn)故事閱讀 38,716評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡绞蹦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出榜旦,到底是詐尸還是另有隱情幽七,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布溅呢,位于F島的核電站澡屡,受9級特大地震影響猿挚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜驶鹉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一绩蜻、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧室埋,春花似錦办绝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至肉盹,卻和暖如春昔驱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背上忍。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留纳本,地道東北人窍蓝。 一個(gè)月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像繁成,于是被迫代替她去往敵國和親吓笙。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評論 2 350

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