Quick Links: Gideros Home | Download Gideros | Developer Guide
Radial blur effect class
  • hgy29hgy29 +1 -1 (+9 / -0 )
    Maintainer
    Here is a quick lua class to add a fast-but-not-perfect blur effect to any sprite (except stage).
    BlurEffect={}
    BlurEffect.VS_GL=[[
    attribute highp vec3 vVertex;
    attribute mediump vec2 vTexCoord;
    uniform highp mat4 vMatrix;
    varying mediump vec2 fTexCoord;
     
    void main() {
    vec4 vertex = vec4(vVertex,1.0);
    gl_Position = vMatrix*vertex;
    fTexCoord=vTexCoord;
    }
    ]]
     
    BlurEffect.FS_GL=[[
    uniform lowp vec4 fColor;
    uniform lowp sampler2D fTexture;
    varying mediump vec2 fTexCoord;
    uniform mediump vec4 fTexSize;
     
    void main() {
    mediump vec4 frag=vec4(0.0,0.0,0.0,0.0);
    mediump vec2 centerDir=normalize((fTexSize.xy/2.0-fTexCoord)/fTexSize.xy)*fTexSize.zw;
    for (int k=0;k<=5;k++)
    frag=frag+texture2D(fTexture, fTexCoord-centerDir*float(k));
    frag=frag/6.0;
    if (frag.a<=0.0) discard;
    gl_FragColor = frag;
    }
    ]]
     
    BlurEffect.Shader=Shader.new(BlurEffect.VS_GL,BlurEffect.FS_GL,Shader.FLAG_FROM_CODE,
    {
    {name="vMatrix",type=Shader.CMATRIX,sys=Shader.SYS_WVP,vertex=true},
    {name="fColor",type=Shader.CFLOAT4,sys=Shader.SYS_COLOR,vertex=false},
    {name="fTexture",type=Shader.CTEXTURE,vertex=false},
    {name="fTexSize",type=Shader.CFLOAT4,sys=Shader.SYS_TEXTUREINFO,vertex=false},
    },
    {
    {name="vVertex",type=Shader.DFLOAT,mult=3,slot=0,offset=0},
    {name="vColor",type=Shader.DUBYTE,mult=4,slot=1,offset=0},
    {name="vTexCoord",type=Shader.DFLOAT,mult=2,slot=2,offset=0},
    });
     
    local identity=Matrix.new()
    function BlurEffect.blur(spr)
    local sm=spr:getMatrix()
    spr:setMatrix(identity)
    local spx,spy,spw,sph=spr:getBounds(spr)
    if spw>=spr._blur_tgt:getWidth() or sph>=spr._blur_tgt:getHeight() then
    spr._blur_tgt=RenderTarget.new(spw,sph,true)
    local p=spr._blur_spr:getParent()
    spr._blur_spr:removeFromParent()
    spr._blur_spr:removeEventListener(Event.ENTER_FRAME,BlurEffect.blur,spr)
    spr._blur_spr=Bitmap.new(spr._blur_tgt)
    p:addChild(spr._blur_spr)
    spr._blur_spr._orig_spr=spr
    spr._blur_spr:setShader(BlurEffect.Shader)
    spr._blur_spr:addEventListener(Event.ENTER_FRAME,BlurEffect.blur,spr)
    end
    spr._blur_spr:setMatrix(sm)
    spr._blur_tgt:clear(0xFFFFFF,0)
    spr._blur_tgt:draw(spr)
    spr:setMatrix(sm)
    end
     
    function BlurEffect.apply(sprite)
    local spx,spy,spw,sph=sprite:getBounds(sprite)
    sprite._blur_tgt=RenderTarget.new(spw,sph,true)
    local p=sprite:getParent()
    sprite:removeFromParent()
    sprite._blur_spr=Bitmap.new(sprite._blur_tgt)
    p:addChild(sprite._blur_spr)
    sprite._blur_spr._orig_spr=sprite
    sprite._blur_spr:setShader(BlurEffect.Shader)
    sprite._blur_spr:addEventListener(Event.ENTER_FRAME,BlurEffect.blur,sprite)
    return sprite._blur_spr
    end
     
    function BlurEffect.cancel(sprite)
    if sprite._blur_spr then
    sprite._blur_spr:removeEventListener(Event.ENTER_FRAME,BlurEffect.blur,sprite)
    sprite._blur_tgt=nil
    local p=sprite._blur_spr:getParent()
    p:addChild(sprite)
    sprite._blur_spr:removeFromParent()
    sprite._blur_spr=nil
    end
    end
     
    function BlurEffect.isApplied(sprite)
    return sprite._blur_spr~=nil
    end

    UPDATED: 7.11.2017

    Usage:
    BlurEffect.apply(sprite) -- enable blur on 'sprite'
    BlurEffect.cancel(sprite) -- disable blur on 'sprite'
    BlueEffect.isApplied(sprite) -- test if blur is active on 'sprite'

  • Hi @hgy29,

    How exactly does that work?
    I either get huge white things(if applied directly a bitmap subsprite) or no image at all if applied to a game sprite.
    Do I need to do something special?
  • hgy29hgy29 +1 -1 (+3 / -0 )
    Maintainer
    Hi @kussakov,

    The original code would only work for static sprites without any kind of transform. I updated it to take transform changes into account a few minutes ago. Let me know if it works now.

    Likes: keszegh, antix, pie

  • Thanks @hgy29!

    Interesting.
    Now it kind of works, but:

    1. It now kills the app - I get only 1 FPS on windows player(i7 with nvidia GPU) and 5 FPS on Samsung galaxy S8. I have about 12 sprites with a blur. With just one sprite I get about 30-40 FPS.

    2. I can see only 1/4 of the sprite (the lower right quarter). I guess because the images have anchor point 0.5,0.5 or something.
  • antixantix +1 -1
    Member
    Would performance be better if you had all 12 sprites attached to one parent sprite and then ran the shader on that?

    Also could you use maybe a pool of RenderTargets instead of creating them on the fly to improve performance?
    Check out my DevBlog, my GitHub, and my games Falling Animals | Breaky Wall | Exetor
  • For sure, but that is not what I need.
    I am already doing that using the Bloom example. No decline in fps.
    However, I needed a way to apply this to some sprites only and I wanted to avoid all the trouble of having multiple containers, reordering the containers so that all looks nice, etc.
    The other problem with the bloom example is that I need some kind of dark background on the container(using shape), so having multiple containers will not work well.

    Not sure how to do a pool of RenderTargets...
  • antixantix +1 -1
    Member
    Ahh okay I see. Managing things in containers is a pain sometimes :D

    There's a thread here about pooled objects...
    http://giderosmobile.com/forum/discussion/6699/enter_frame-and-sprites/p1
    You could just use RenderTarget objects instead of Sprites. Depending on the actual size of your objects however it might chew a lot of texture RAM.
    Check out my DevBlog, my GitHub, and my games Falling Animals | Breaky Wall | Exetor
  • hgy29hgy29 +1 -1 (+1 / -0 )
    Maintainer
    Yes, there is a huge performance impact due to the fact that the sprite needs to be drawn to a rendertarget before the effect can be applied

    Likes: antix

  • antixantix +1 -1
    Member
    I wonder, are your blurs going to change in real-time on an object? If not you could apply the blur and set the result as the objects texture so only having to do the blur once when the object is created.
    Check out my DevBlog, my GitHub, and my games Falling Animals | Breaky Wall | Exetor
  • kussakov +1 -1 (+1 / -0 )
    Member
    @antix, that is a good idea. The blur does not change. I will try it. Thanks!

    Likes: antix

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Login with Facebook Sign In with OpenID

In this Discussion

Top Posters