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