ShaderToy上后处理练习2——模糊
2021/6/12 18:25:35
本文主要是介绍ShaderToy上后处理练习2——模糊,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
模糊算法
主要参考,或者说就是照着著名大佬QianMo的后处理教程写的,不过他是在Unity里面实现的,作为一个高品质后处理插件,然后本人是在ShaderToy上实现的,当然我都是在复现大佬的代码,推荐大家去读大佬的文章,地址:https://github.com/QianMo/GPU-Gems-Book-Source-Code
强烈安利!!!!
还有,就是,一些结果和代码不能一一对应,不过贴到ShaderToy上就能看到效果
高斯模糊
Commom
#define SIZE 5. #define STEP_SIZE (SIZE / iResolution.x * sin(iTime))
X
void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord / iResolution.xy; vec3 col; col += 0.40 * texture(iChannel0, uv).xyz; col += 0.15 * texture(iChannel0, uv + vec2(STEP_SIZE, 0.)).xyz; col += 0.15 * texture(iChannel0, uv - vec2(STEP_SIZE, 0.)).xyz; col += 0.10 * texture(iChannel0, uv + vec2(STEP_SIZE * 2., 0.)).xyz; col += 0.10 * texture(iChannel0, uv - vec2(STEP_SIZE * 2., 0.)).xyz; col += 0.05 * texture(iChannel0, uv + vec2(STEP_SIZE * 3., 0.)).xyz; col += 0.05 * texture(iChannel0, uv - vec2(STEP_SIZE * 3., 0.)).xyz; fragColor = vec4(col, 1.0); }
Y
void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord / iResolution.xy; vec3 col; col += 0.40 * texture(iChannel0, uv).xyz; col += 0.15 * texture(iChannel0, uv + vec2(0., STEP_SIZE)).xyz; col += 0.15 * texture(iChannel0, uv - vec2(0., STEP_SIZE)).xyz; col += 0.10 * texture(iChannel0, uv + vec2(0., STEP_SIZE * 2.)).xyz; col += 0.10 * texture(iChannel0, uv - vec2(0., STEP_SIZE * 2.)).xyz; col += 0.05 * texture(iChannel0, uv + vec2(0., STEP_SIZE * 3.)).xyz; col += 0.05 * texture(iChannel0, uv - vec2(0., STEP_SIZE * 3.)).xyz; fragColor = vec4(col, 1.0); }
以上循环X-Y
多次。
Image
void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord / iResolution.xy; vec3 col = texture(iChannel0, uv).xyz; fragColor = vec4(col, 1.0); }
result
方框模糊(Box Blur)
Commom
#define SIZE 5. #define STEP_SIZE (SIZE / iResolution.x * sin(iTime))
X
void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord / iResolution.xy; vec3 col; col += 0.2 * texture(iChannel0, uv).xyz; col += 0.2 * texture(iChannel0, uv + vec2(STEP_SIZE, 0.)).xyz; col += 0.2 * texture(iChannel0, uv - vec2(STEP_SIZE, 0.)).xyz; col += 0.2 * texture(iChannel0, uv + vec2(STEP_SIZE * 2., 0.)).xyz; col += 0.2 * texture(iChannel0, uv - vec2(STEP_SIZE * 2., 0.)).xyz; fragColor = vec4(col, 1.0); }
Y
void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord / iResolution.xy; vec3 col; col += 0.2 * texture(iChannel0, uv).xyz; col += 0.2 * texture(iChannel0, uv + vec2(0., STEP_SIZE)).xyz; col += 0.2 * texture(iChannel0, uv - vec2(0., STEP_SIZE)).xyz; col += 0.2 * texture(iChannel0, uv + vec2(0., STEP_SIZE * 2.)).xyz; col += 0.2 * texture(iChannel0, uv - vec2(0., STEP_SIZE * 2.)).xyz; fragColor = vec4(col, 1.0); }
以上循环X-Y
多次。
Image
void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord / iResolution.xy; vec3 col = texture(iChannel0, uv).xyz; fragColor = vec4(col, 1.0); }
result(error)
Kawase模糊(Kawase Blur)
Commom
#define TEXEL_SIZE (1. / iResolution * sin(iTime) * 2.) #define PIXEL_OFFSET 0.0
Blur(it递增)
void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord / iResolution.xy; float it = 0.0; // 1.,2.,3.,... vec3 col; col += 0.25 * texture(iChannel0, uv + vec2(PIXEL_OFFSET + it + 0.5, PIXEL_OFFSET + it + 0.5) * vec2(TEXEL_SIZE)).xyz; col += 0.25 * texture(iChannel0, uv + vec2(PIXEL_OFFSET + it - 0.5, PIXEL_OFFSET + it + 0.5) * vec2(TEXEL_SIZE)).xyz; col += 0.25 * texture(iChannel0, uv + vec2(PIXEL_OFFSET + it + 0.5, PIXEL_OFFSET + it - 0.5) * vec2(TEXEL_SIZE)).xyz; col += 0.25 * texture(iChannel0, uv + vec2(PIXEL_OFFSET + it - 0.5, PIXEL_OFFSET + it - 0.5) * vec2(TEXEL_SIZE)).xyz; fragColor = vec4(col, 1.0); }
Image
void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord / iResolution.xy; vec3 col = texture(iChannel0, uv).xyz; fragColor = vec4(col, 1.0); }
result(error)
双重模糊(Dual Blur)
Commom
#define SCALE 2.0 #define BLUR_SIZE (1./iResolution.x * sin(iTime) * 4.)
DownSample
void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord / iResolution.xy; float it = 1.0 * SCALE; float range = 1. / it; vec3 col; if(uv.x < range && uv.y < range) { uv = uv / vec2(range); col += 0.5 * texture(iChannel0, uv).xyz; col += 0.125 * texture(iChannel0, uv + vec2(1., 1.) * vec2(BLUR_SIZE)).xyz; col += 0.125 * texture(iChannel0, uv + vec2(-1., 1.) * vec2(BLUR_SIZE)).xyz; col += 0.125 * texture(iChannel0, uv + vec2(1., -1.) * vec2(BLUR_SIZE)).xyz; col += 0.125 * texture(iChannel0, uv + vec2(-1., -1.) * vec2(BLUR_SIZE)).xyz; } fragColor = vec4(col, 1.0); }
执行多次
UpSample
void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord / iResolution.xy; float it = 1.0 * SCALE; float range = 1. / it; vec3 col; if(uv.x < range && uv.y < range) { uv = uv * vec2(range); float A = 1. / 6.; float B = 1. / 12.; col += A * texture(iChannel0, uv + vec2(1., 1.) * vec2(BLUR_SIZE)).xyz; col += A * texture(iChannel0, uv + vec2(-1., 1.) * vec2(BLUR_SIZE)).xyz; col += A * texture(iChannel0, uv + vec2(1., -1.) * vec2(BLUR_SIZE)).xyz; col += A * texture(iChannel0, uv + vec2(-1., -1.) * vec2(BLUR_SIZE)).xyz; col += B * texture(iChannel0, uv + vec2(2., 0.) * vec2(BLUR_SIZE)).xyz; col += B * texture(iChannel0, uv + vec2(-2., 0.) * vec2(BLUR_SIZE)).xyz; col += B * texture(iChannel0, uv + vec2(0., -2.) * vec2(BLUR_SIZE)).xyz; col += B * texture(iChannel0, uv + vec2(0., 2.) * vec2(BLUR_SIZE)).xyz; } fragColor = vec4(col, 1.0); }
执行多次
Image
void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord / iResolution.xy; float it = 1.0 * SCALE; float range = 1. / it; vec3 col; uv = uv * vec2(range); float A = 1. / 6.; float B = 1. / 12.; col += A * texture(iChannel0, uv + vec2(1., 1.) * vec2(BLUR_SIZE)).xyz; col += A * texture(iChannel0, uv + vec2(-1., 1.) * vec2(BLUR_SIZE)).xyz; col += A * texture(iChannel0, uv + vec2(1., -1.) * vec2(BLUR_SIZE)).xyz; col += A * texture(iChannel0, uv + vec2(-1., -1.) * vec2(BLUR_SIZE)).xyz; col += B * texture(iChannel0, uv + vec2(2., 0.) * vec2(BLUR_SIZE)).xyz; col += B * texture(iChannel0, uv + vec2(-2., 0.) * vec2(BLUR_SIZE)).xyz; col += B * texture(iChannel0, uv + vec2(0., -2.) * vec2(BLUR_SIZE)).xyz; col += B * texture(iChannel0, uv + vec2(0., 2.) * vec2(BLUR_SIZE)).xyz; fragColor = vec4(col, 1.0); }
result(error)
散景模糊(Bokeh Blur)
Common
#define ITERATION 350 #define GOLDENROT (2.39996) //137 2.39996 0.381966 #define RADIUS (2. * sin(iTime / 3.)) #define PIXEL_SIZE (1.0 / iResolution.x) mat2 rot = mat2(cos(GOLDENROT), sin(GOLDENROT), -sin(GOLDENROT), cos(GOLDENROT));
Buffer A
void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord / iResolution.xy; vec4 accumulator; vec4 divisor; float r = 1.0; vec2 angle = vec2(0.0, RADIUS); for(int j = 0; j < ITERATION; j++) { r += 1.0 / r; angle = rot * angle; vec4 bokeh = texture(iChannel0, uv + PIXEL_SIZE * (r - 1.0) * angle); //bokeh = pow(bokeh, vec4(4.)); accumulator += bokeh * bokeh; divisor += bokeh; } accumulator = accumulator / divisor; fragColor = vec4(accumulator.xyz, 1.0); }
Image
// reference : https://www.shadertoy.com/view/4d2Xzw void mainImage( out vec4 fragColor, in vec2 fragCoord ) { // Normalized pixel coordinates (from 0 to 1) vec2 uv = fragCoord/iResolution.xy; // Time varying pixel color vec3 col = texture(iChannel0, uv).xyz; // Output to screen fragColor = vec4(col,1.0); }
移轴模糊
配合全局模糊算法,例如上一节的,所以我们只需要:
Common add
#define OFFSET (0.001) #define AREA (2.1 * sin(iTime)) #define SPREAD (5.) float TiltShiftMask(vec2 uv) { float cenY = uv.y * 2.0 - 1.0 + OFFSET; return pow(abs(cenY * AREA), SPREAD); }
Buffer A Change
void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord / iResolution.xy; vec4 accumulator; vec4 divisor; float r = 1.0; //Change vec2 angle = vec2(0.0, RADIUS * clamp(TiltShiftMask(uv), 0., 1.)); for(int j = 0; j < ITERATION; j++) { r += 1.0 / r; angle = rot * angle; vec4 bokeh = texture(iChannel0, uv + PIXEL_SIZE * (r - 1.0) * angle); //bokeh = pow(bokeh, vec4(4.)); accumulator += bokeh * bokeh; divisor += bokeh; } accumulator = accumulator / divisor; fragColor = vec4(accumulator.xyz, 1.0); }
结果
光圈模糊(Iris Blur)
同上配合全局模糊算法。
float IrisMask(vec2 uv) { vec2 center = uv * vec2(2.0) + vec2(OFFSET - 1.0); return pow(dot(center, center) * AREA, SPREAD); }
结果
粒状模糊(Grainy Blur)
Common
#define BLUR_RADIUS (1. / iResolution.x * 10. * sin(iTime)) #define ITERATION (450.)
Image
float rand(vec2 n) { return sin(dot(n, vec2(1233.224, 1743.335))); } void mainImage( out vec4 fragColor, in vec2 fragCoord ) { // Normalized pixel coordinates (from 0 to 1) vec2 uv = fragCoord/iResolution.xy; vec2 randomOffset = vec2(0.); vec3 col = vec3(0.); float random = rand(uv); for(float i = 0.; i < ITERATION; i = i + 1.) { random = fract(43758.5453 * random + 0.61432); randomOffset.x = (random - 0.5) * 2.0; random = fract(43758.5453 * random + 0.61432); randomOffset.y = (random - 0.5) * 2.0; col += texture(iChannel0, uv + randomOffset * vec2(BLUR_RADIUS)).xyz; } col = col / ITERATION; // Output to screen fragColor = vec4(col, 1.0); }
结果
径向模糊(Radial Blur)
Common
#define BLUR_RADIUS (1. / iResolution.x * 1.) #define ITERATION (45.)
Image
vec2 getCent() { return iMouse.xy / iResolution.xy; } vec3 RadialBlur(vec2 uv) { vec2 blurV = (getCent() - uv) * BLUR_RADIUS; vec3 col; for(float j = 0.; j < ITERATION; j = j + 1.0) { col += texture(iChannel0, uv).xyz; uv += blurV; } return col / ITERATION; } void mainImage( out vec4 fragColor, in vec2 fragCoord ) { // Normalized pixel coordinates (from 0 to 1) vec2 uv = fragCoord/iResolution.xy; vec3 col = RadialBlur(uv); // Output to screen fragColor = vec4(col, 1.0); }
结果
方向模糊(Directional Blur)
Common
#define PI (3.14156) #define ANGLE (PI * 1. * cos(iTime / 3.)) #define BLUR_RADIUS (5. * sin(iTime)) #define ITERATION (100.)
Image
vec2 getDirection() { float sinVal = (sin(ANGLE) * BLUR_RADIUS * 0.05f) / ITERATION; float cosVal = (cos(ANGLE) * BLUR_RADIUS * 0.05f) / ITERATION; return vec2(sinVal, cosVal); } vec3 DirectionalBlur(vec2 uv) { vec3 col; vec2 dir = getDirection(); for(float k = -1. * ITERATION; k < ITERATION; k = k + 1.) { col += texture(iChannel0, uv - dir * k).xyz; } col = col / (ITERATION * 2.); return col; } void mainImage( out vec4 fragColor, in vec2 fragCoord ) { // Normalized pixel coordinates (from 0 to 1) vec2 uv = fragCoord/iResolution.xy; vec3 col = DirectionalBlur(uv); // Output to screen fragColor = vec4(col, 1.0); }
结果
cosVal);
}
vec3 DirectionalBlur(vec2 uv)
{
vec3 col;
vec2 dir = getDirection();
for(float k = -1. * ITERATION; k < ITERATION; k = k + 1.) { col += texture(iChannel0, uv - dir * k).xyz; } col = col / (ITERATION * 2.); return col;
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
// Normalized pixel coordinates (from 0 to 1)
vec2 uv = fragCoord/iResolution.xy;
vec3 col = DirectionalBlur(uv); // Output to screen fragColor = vec4(col, 1.0);
}
结果
这篇关于ShaderToy上后处理练习2——模糊的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-06-26结对编程到底难不难?答案在这里
- 2024-06-19《2023版Java工程师》课程升级公告
- 2024-06-15matplotlib作图不显示3D图,怎么办?
- 2024-06-1503-Loki 日志监控
- 2024-06-1504-让LLM理解知识 -Prompt
- 2024-06-05做软件测试需要懂代码吗?
- 2024-06-0514-ShardingSphere的分布式主键实现
- 2024-06-03为什么以及如何要进行架构设计权衡?
- 2024-05-31全网首发第二弹!软考2024年5月《软件设计师》真题+解析+答案!(11-20题)
- 2024-05-31全网首发!软考2024年5月《软件设计师》真题+解析+答案!(21-30题)