Quick Links: Gideros Home | Download Gideros | Developer Guide
Add drop shadow to a Sprite
  • If a single-colour sprite it too light in my game I want to apply a drop shadow to it. The intensity should depend on the average RGB lightness.

    image

    Option 1: Use a bitmap dropshadow and control the intensity with alpha. This is not ideal, because I have to create a drop shadow bitmap for every object that needs it.

    Option 2: SHADERS! Surely this must be possible using a shader? They are still a mystery to me, so I wouldn't know where to start.

    Option 3: Maybe there is a better way still?

    drop_shadow.png
    650 x 301 - 23K
    My Gideros games: www.totebogames.com
  • SinisterSoftSinisterSoft +1 -1 (+1 / -0 )
    Maintainer
    Maybe this will work:

    Anchor point in the middle, make a second sprite with the same texture, set colour transform to 0,0,0 then alpha to 0.5, make it very slightly larger and draw it first.

    Likes: antix

  • Cheers sinister. I think maybe drop shadows are a bit overkill for shaders. May just stick to the extra bitmap, so I have full control of how it looks.
    My Gideros games: www.totebogames.com
  • Xman +1 -1
    Member
    But this can not generate the feather edge for the shadow
  • antixantix +1 -1
    Member
    I think Shaders would be the only way to create a drop-shadow with feathering. If you get it working share the results, I could use a Shader that makes blurry stuff :)
  • pie +1 -1
    Member
    The Bloom example included in gideros seems to be a good starting point, even this one could be interesting to start writing your own (never tried it yet, but since it's coming from hgy29 I believe it will work :) )
    http://giderosmobile.com/forum/discussion/6682/radial-blur-effect-class#Item_1

    otherwise there is shadertoy

    http://giderosmobile.com/forum/discussion/6667/shadertoy-viewer-beta-shaders-from-www-shadertoy-com-in-gideros/p1

    there should be a drop shadow here! :)
  • antixantix +1 -1
    Member
    @pie the first one seems viable. You could make a sprite a bit larger than the original image, blur it, draw it to a rendertarget, and you would have your drop shadow.

    I should really have a look at all those other shaders sometime too :)

  • hgy29hgy29 +1 -1 (+3 / -0 )
    Maintainer
    Again quick try:
    local DropShadowVShader=
    [[
    attribute vec4 POSITION0;
    attribute vec2 TEXCOORD0;
     
    uniform mat4 g_MVPMatrix;
     
    varying mediump vec2 texCoord;
     
    void main()
    {
    gl_Position = g_MVPMatrix * POSITION0;
    texCoord = TEXCOORD0;
    }
    ]]
     
    local DropShadowFShader=[[
    uniform lowp sampler2D gTex;
    uniform mediump vec4 maskInfo;
     
    varying mediump vec2 texCoord;
    uniform mediump vec4 fTexSize;
     
    #ifdef GLES2
    precision mediump float;
    #endif
     
    void main()
    {
    vec4 texc= texture2D(gTex, texCoord);
    mediump float shadow=0.0;
    mediump vec2 centerDir=normalize((fTexSize.xy/2.0-texCoord)/fTexSize.xy)*fTexSize.zw;
    for (int k=0;k<=15;k++)
    {
    vec4 p=texture2D(gTex, texCoord+centerDir*float(k));
    shadow=shadow+p.a;
    }
    shadow=pow(2.0,shadow/16.0)-1.0;
    if (shadow<=0.0) discard;
    vec4 frag=mix(vec4(0.3,0.3,0.3,shadow),texc,texc.a);
    gl_FragColor = frag;
    }
    ]]
     
    local DropShadowShaderAttrs=
    {
    {name="POSITION0",type=Shader.DFLOAT,mult=3,slot=0,offset=0},
    {name="vColor",type=Shader.DUBYTE,mult=0,slot=1,offset=0},
    {name="TEXCOORD0",type=Shader.DFLOAT,mult=2,slot=2,offset=0}
    }
     
    local DropShadowShaderConstants={
    {name="g_MVPMatrix",type=Shader.CMATRIX,sys=Shader.SYS_WVP, vertex=true},
    {name="fTexSize",type=Shader.CFLOAT4,sys=Shader.SYS_TEXTUREINFO,vertex=false},
    {name="gTex",type=Shader.CTEXTURE,mult=1,vertex=false}
    }
     
     
    local DropShadowShader= Shader.new(
    DropShadowVShader,DropShadowFShader,
    Shader.FLAG_FROM_CODE,DropShadowShaderConstants,DropShadowShaderAttrs)
     
    local piece=Bitmap.new(Texture.new("shape.png",true))
    piece:setShader(DropShadowShader)
     
    application:setBackgroundColor(0xFFFFFF)
     
    stage:addChild(piece)
    piece:setPosition(50,50)

    Likes: pie, antix, Xman

  • keszegh +1 -1 (+1 / -0 )
    Member
    @hgy29, your nice shader examples should be collected somewhere visible, on the reference page or adding it always to a shader example project (added to the examples of gideros visible upon startup).

    Likes: pie

  • Xman +1 -1
    Member
    these shader for common effect may consider to included into the engine, and exported by Shader.SHADOW, Shader.BLUR, for easy to use as sprite:setShader(Shader.SHADOW)
  • hgy29hgy29 +1 -1 (+1 / -0 )
    Maintainer
    I had the idea to make them available as a plugin, since the new plugin system makes it easy to integrate into a final app. @Sinistersoft thinks I should write a book too :)

    But gideros needs a little more work to make them easy to use, in particular blur effect needs a rendertarget, and it would be good if gideros could automatically cache pre-rendered sprite hierarchy in a rendertarget for that purpose, when needed.
    But we need to be careful: what about nested effects/recursive render targets ?

    Gideros should also expose more internal state to the shaders: actual texture bounds, generalized support for texture regions, etc

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 Google Sign In with OpenID

In this Discussion

Top Posters