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,uv,xyz,练习,texture,后处理,vec2,iChannel0,col 来源: https://blog.csdn.net/JMXIN422/article/details/117851800