FrameBuffer及离屏渲染

Framebuffer Get知识点

  • 1、给定的模型坐标可能只占有屏幕的一般或者一部分,可以通过平移缩放等操作让他占满全屏。
  • 2、渲染纹理图像倒立,可以通过旋转操作使他正常。
  • 3、绑定framebuffer后记得清理缓冲区
    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、创建framebuffer 步骤及代码,注意renderbuffer和纹理的尺寸要对应,否则会采样错误。
- (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 传递内存空间时,都乘了屏幕比例
    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 出错---");
        return 0;
    }
    glBindFramebuffer(GL_FRAMEBUFFER, renderbuffer);
    
    return frameBuffer;
}
  • 5、自定义framebuffer使用步骤:
    a、创建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、设置清屏
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] ;
  
  //核定义数组
    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] ;

//模糊效果定义数组
     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

灰度加权:

 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);

灰度加权效果:


Snip20200315_5.png
图像旋涡:

主要是在某个半径范围里,把当前采样点旋转一定角度,旋转以后当前点的颜色就被旋转后的点的颜色代替,因此整个半径范围里会有旋转的效果。如果旋转的时候旋转角度随着当前点离半径的距离递减,整个图像就会出现漩涡效果。这里使用的了抛物线递减因子:(1.0-(r/Radius)*(r/Radius) )。

precision mediump float;

const float PI = 3.14159265;
uniform sampler2D textureMap;

const float uD = 80.0; //旋转角度
const float uR = 0.5; //旋转半径

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
马赛克效果

马赛克效果就是把图片的一个相当大小的区域用同一个点的颜色来表示.可以认为是大规模的降低图像的分辨率,而让图像的一些细节隐藏起来。

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
浮雕效果

浮雕效果是指图像的前景前向凸出背景。实现思路:把图象的一个象素和左上方的象素进行求差运算,并加上一个灰度。这个灰度就是表示背景颜色。这里我们设置这个插值为128 (图象RGB的值是0-255)。同时,我们还应该把这两个颜色的差值转换为亮度信息,避免浮雕图像出现彩色像素。

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、绑定默认缓冲区,渲染frambuffer中的纹理到默认缓冲区,至屏幕layer上。

你可能感兴趣的:(FrameBuffer及离屏渲染)