欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

OpenGL高级OpenGL篇--帧缓冲--后处理效果--22--1

程序员文章站 2022-07-04 11:06:47
...

参考:文章后半部分

这一节主要利用上一节的帧缓冲做后处理效果!
程序代码和上节一样。

不一样的是Shader代码,主要是片元shader:

下面是几种效果:
1.反相

#version 330 core
out vec4 fragColor;
in vec2 uv;

//自定义帧缓冲-颜色附件缓冲
uniform sampler2D screenTexture;

void main()
{	
	//反相:反转采样颜色即可
	fragColor=vec4(1-texture(screenTexture,uv).rgb,1.0);
}

2.灰度

#version 330 core
out vec4 fragColor;
in vec2 uv;

//自定义帧缓冲-颜色附件缓冲
uniform sampler2D screenTexture;

void main()
{	
	//灰度	
	fragColor=texture(screenTexture,uv);
	//平均灰度
	//float average=(fragColor.r+fragColor.g+fragColor.b)/3.0;
	//加权灰度:人眼会对绿色更加敏感一些,而对蓝色不那么敏感
	float average = 0.2126 * FragColor.r + 0.7152 * FragColor.g + 0.0722 * FragColor.b;
	fragColor=vec4(average,average,average,1.0);
}

3.核效果(卷积核),代码都一样,只是用不同的核,得到不同的效果

注:注意,核在对屏幕纹理的边缘进行采样的时候,由于还会对中心像素周围的8个像素进行采样,其实会取到纹理之外的像素。由于环绕方式默认是GL_REPEAT,所以在没有设置的情况下取到的是屏幕另一边的像素,而另一边的像素本不应该对中心像素产生影响,这就可能会在屏幕边缘产生很奇怪的条纹。为了消除这一问题,我们可以将屏幕纹理的环绕方式都设置为GL_CLAMP_TO_EDGE。这样子在取到纹理外的像素时,就能够重复边缘的像素来更精确地估计最终的值了

3.1:锐化:也有边缘检测的效果,周围八个像素 核中间的像素和;

float kernel[9] = float[](
        -1, -1, -1,
        -1,  9, -1,
        -1, -1, -1
    );

3.2:模糊:


float kernel[9] = float[](
    1.0, 2.0, 1.0,
    2.0, 4.0, 2.0,
    1.0, 2.0, 1.0  
);

保证9个采样加权为1,所以要除以16

float kernel[9] = float[](
    1.0 / 16, 2.0 / 16, 1.0 / 16,
    2.0 / 16, 4.0 / 16, 2.0 / 16,
    1.0 / 16, 2.0 / 16, 1.0 / 16  
);

3.3:边缘检测:和锐化有点类似,自己理解一下

float kernel[9] = float[](
        1, 1, 1,
        1, -8, 1,
        1, 1, 1
    );
#version 330 core
out vec4 fragColor;
in vec2 uv;

//自定义帧缓冲-颜色附件缓冲
uniform sampler2D screenTexture;

//偏移
const float offset = 1.0 / 300.0;  

void main()
{		
	//核效果
	 vec2 offsets[9] = vec2[](
        vec2(-offset,  offset), // 左上
        vec2( 0.0f,    offset), // 正上
        vec2( offset,  offset), // 右上
        vec2(-offset,  0.0f),   // 左
        vec2( 0.0f,    0.0f),   // 中
        vec2( offset,  0.0f),   // 右
        vec2(-offset, -offset), // 左下
        vec2( 0.0f,   -offset), // 正下
        vec2( offset, -offset)  // 右下
    );

    float kernel[9] = float[](
        -1, -1, -1,
        -1,  9, -1,
        -1, -1, -1
    );

    vec3 sampleTex[9];
    for(int i = 0; i < 9; i++)
    {
        sampleTex[i] = vec3(texture(screenTexture, uv.st + offsets[i]));
    }
    vec3 col = vec3(0.0);
    for(int i = 0; i < 9; i++)
        col += sampleTex[i] * kernel[i];

    fragColor = vec4(col, 1.0);	
}