radial blur 阅读笔记

http://oos.moxiecode.com/js_webgl/codevember2017/index9.html
效果图:
这里写图片描述

就是这种有点像彗星拖尾的效果,且这个方向是指向屏幕中央的,当然也可以修改。

代码着色器:
作者@oosmoxiecode,参考的也是 IQ大神 https://www.shadertoy.com/view/4sfGRn

这里直接注释IQ的代码了,都差不多。oos 就是写的可读性更高一些。

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 p = -1.0 + 2.0*fragCoord/iResolution.xy; // 从[0,1]变换到[-1,1]

    vec3  col = vec3(0.0);
    vec2  d = (vec2(0.0,0.0)-p)/64.0; // 求当前着色位置到屏幕中心的方向向量,这步是关键
    float w = 1.0;
    vec2  s = p;
    // i<10 说明这个过程要叠加10次,越多则效果越强
    for( int i=0; i<10; i++ )
    {
        vec3 res = deform( s ); // 取原texture像素,deform 是扭曲,非必要
        col += w*smoothstep( 0.0, 1.0, res );
        w *= .98; 
        s += d;
    }
    col = col * 3.5 / 64.0;

    fragColor = vec4( col, 1.0 );
}

oos 则加了一个限制条件,只有像素颜色值高于某个阈值才拿来做颜色叠加,因此白色的部分会有更强的效果,暗色的就没有:


    uniforms: {

        "tDiffuse": { type: "t", value: null },
        "tMap":   { type: "t", value: null },
        "steps":    { type: "f", value: 100.0 },
        "strength": { type: "f", value: 0.95 },
        "expo":     { type: "f", value: 5.0 },
        "threshold":    { type: "f", value: 0.7 },
        "center":   { type: "v2", value: new THREE.Vector2( 0.5, 0.5 ) },

    },

        "uniform float steps;",
        "uniform float strength;",
        "uniform float expo;",
        "uniform float threshold;",
        "uniform sampler2D tDiffuse;",
        "uniform sampler2D tMap;",
        "uniform vec2 center;",

        "varying vec2 vUv;",

        "void main() {",

            "vec2 s = vUv;",

            "vec3 total = vec3(0.0);",
            "vec2 d = (center-vUv)/steps;", // 中间往外放射线的效果
            "float w = 1.0;",

            //"float t = 0.7;",

            //"for( int i=0; i<int(steps); i++ ) {",
            "for( int i=0; i<40; i++ ) {", // hardcode since the above fails in angle...
                "vec3 res = texture2D( tMap, s).xyz;",
                "if (res.x > threshold || res.y > threshold || res.z > threshold) {",
                    //"res = vec3(1.0,1.0,1.0);",
                    // 越接近白色,放射效果越强
                    "res *= 5.0;",
                "} else {",
                    "res = vec3(0.0,0.0,0.0);",
                "}",
                "res = smoothstep(0.0,1.0,res);", 
                "total += w*res;",
                "w *= strength;", // strength < 1, w 逐渐减小
                "s += d;", // 沿放射方向,从vUv到屏幕中心
            "}",
            "total /= steps;",

            //"gl_FragColor = vec4( total*expo, 1.0);",
            "vec3 dif = texture2D( tDiffuse, vUv).xyz;",
            "gl_FragColor = vec4( mix(total*expo, dif*2.0, 0.5), 1.0);",
            //"gl_FragColor = vec4( total*expo, 1.0);",


        "}"

这个程序的思路可以想象为,每个像素朝着屏幕中心看一段距离(由 for 的次数决定),如果看到的范围内有符合

(res.x > threshold || res.y > threshold || res.z > threshold) 

的像素,就拿来作为当前着色像素的一个叠加的颜色。关键是要记住 GPU程序都是处理单个像素的,每次只能为当前着色的像素处理颜色。
很显然 center不一定是中间位置。利用这个可以更灵活地做效果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值