Need help for Sprite Outline shader

Hi Defold Masters :slight_smile:

I have a problem with outline shader for sprites.
First of all I’m not sure if this is the right way to do it.
i’ll be glad if anyone can help me.

My problems:

  • Since var_texcoord0 is based on the whole atlas, I couldn’t find a way to calculate the correct offset value. If the atlas is big, than I need a very small float like ‘0.001’. if it is small need something bigger like ‘1.0’. How can I(or should I) calculate the right offset for all ?

Here is the difference ( Small Atlas / Large Atlas):
SmallAtlas
LargeAtlas

  • My other problem is; playing a sprite anim cause a change on outline’s static area. I’m not sure how to handle Flip-book animations:

SpriteAnim

This is the simple fragment code that I use:

varying mediump vec2 var_texcoord0;
uniform lowp sampler2D DIFFUSE_TEXTURE;
uniform lowp vec4 spriteSize; //Fragment Constant for sprite size

const vec4 bordercolor = vec4(1.0, 1.0, 1.0, 0.0);


void main()
{
	vec4 col = texture2D(DIFFUSE_TEXTURE, var_texcoord0);
	float offset = 0.001; //float offset = 1.0/spriteSize.x;

	if (col.a > 0.1)
	gl_FragColor = col;
	else {
		float a = texture2D(DIFFUSE_TEXTURE, vec2(var_texcoord0.x + offset, var_texcoord0.y)).a ;
		a += texture2D(DIFFUSE_TEXTURE, vec2(var_texcoord0.x, var_texcoord0.y - offset)).a;
		a += texture2D(DIFFUSE_TEXTURE, vec2(var_texcoord0.x - offset, var_texcoord0.y)).a;
		a += texture2D(DIFFUSE_TEXTURE, vec2(var_texcoord0.x, var_texcoord0.y + offset)).a;
	
		if ( a > 0.9)
		gl_FragColor = bordercolor;
		else
		gl_FragColor = col;
	}
}

1 Like

Why do you need to calculate the offset based on the sprite width? You don’t want super tiny objects to have a outline as big as they? Handling flip-booked sprites is definitely going to be tricky. I would probably have a script called sprite_outline that have a exposed value, the default value could be something that covers 90% of the cases but then you or the artist could tweak the number. The script just passes the value along to the shader.

I have to check the nearest alpha value on every direction. So I can add a border pixel on correct place. This is why I use offset.
var_texcoord0 depend on whole Atlas not the sprite width(I’m not using sprite width anyway).
Same sprite on different atlas(with different sizes) occur a problem which a describe above. When whole Atlas gets bigger, offset must be smaller or vice versa.

Hello,

Did someone ended up with a good solution for this?

Thanks in advance!

2 Likes

I do it this way:

  1. render all characters on separate render target
  2. copy this render target to another one in black color and blur horizontally
  3. copy result #2 to another render target and blur vertically
  4. combine result of #1 and #3 in the main render target.

You know the size of your texture this way, as you created render targets with particular size. My goal was a blurred outline, for the sharp one you don’t have to blur, just offset I suppose.

1 Like