其他分享
首页 > 其他分享> > ShaderToy上后处理练习2——模糊

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)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fMQpCDfx-1623490386563)(后处理技术——模糊.assets/3/GIF 2021-4-22 20-15-05.gif)]

双重模糊(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)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xWLJCR3S-1623490386565)(后处理技术——模糊.assets/5/GIF 2021-4-22 21-00-31.gif)]

散景模糊(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);
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bac9bsGW-1623490386565)(后处理技术——模糊.assets/6/GIF 2021-4-23 20-56-46.gif)]

移轴模糊

配合全局模糊算法,例如上一节的,所以我们只需要:

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

结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RcefzpkV-1623490386567)(后处理技术——模糊.assets/8/GIF 2021-4-23 21-39-12.gif)]

光圈模糊(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);
}

结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8hzTIaQF-1623490386567)(后处理技术——模糊.assets/9/GIF 2021-4-24 13-17-23.gif)]

径向模糊(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);
}

结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jv4YXZDe-1623490386568)(后处理技术——模糊.assets/10/GIF 2021-4-24 13-34-50.gif)]

方向模糊(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