# Issue turning a square sprite into a circle using shaders

**URL:** <https://forum.defold.com/t/issue-turning-a-square-sprite-into-a-circle-using-shaders/83236>\
**Category:** Questions\
**Created:** [September 15, 2026, 7:59pm UTC](https://forum.defold.com/t/issue-turning-a-square-sprite-into-a-circle-using-shaders/83236 "2026-09-15T19:59:29Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ohm](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/ohm/32/44386_2.png) [@Ohm](https://forum.defold.com/u/Ohm)\
**Post date:** [September 15, 2026, 7:59pm UTC](https://forum.defold.com/t/issue-turning-a-square-sprite-into-a-circle-using-shaders/83236/1 "2026-09-15T19:59:29Z")

</div>

I have a 64 x 64 pixel white square that I’m trying to clip with a shader so I have a nice smooth edged circle. It’s a sprite.

I can’t however, get the alpha for work on the edges.

This is what I’m trying to make, minus the red. This was done with a shader.  
This is the sample code for this test, but not the code I’m working with:

```glsl
varying mediump vec2 var_texcoord0;

uniform lowp sampler2D texture_sampler;
uniform lowp vec4 tint;

void main()
{
	vec4 tex = texture2D(texture_sampler, var_texcoord0);

	vec2 p = var_texcoord0 * 2.0 - 1.0;
	float d = length(p);
	float alpha = 1.0 - smoothstep(0.70, 1.0, d);

	vec3 outside_colour = vec3(1.0, 0.0, 0.0); // red
	vec3 inside_colour = tex.rgb;

	vec3 final_colour = mix(outside_colour, inside_colour, alpha);

	gl_FragColor = vec4(final_colour, tint.a);
}

```

 ![image](https://forum-defold-uploads.b-cdn.net/original/3X/1/d/1daaaa53c4925a4205ccbfdbbde4454b56e92f23.png)

But my issue is when I try to apply it with alpha, it just renders as a solid white square. (I have blend mode Alpha on the sprite). This is the code I’m working with.

```glsl
varying mediump vec2 var_texcoord0;

uniform lowp sampler2D texture_sampler;
uniform lowp vec4 tint;

void main()
{
	vec4 tex = texture2D(texture_sampler, var_texcoord0);

	vec2 p = var_texcoord0 * 2.0 - 1.0;
	float d = length(p);
	float alpha = 1.0 - smoothstep(0.70, 1.0, d);

	gl_FragColor = vec4(tex.rgb, alpha);
}

```

 ![image](https://forum-defold-uploads.b-cdn.net/original/3X/9/0/9049809a5f6d2af735490c55e13fc25a92f76894.png)

One other thing, when I run an actual build of the game, these both disappear completely anyway. I can only see them in the editor, so that’s another issue I have after I eventually get this alpha thing fixed…

I did also test directly applying alpha, and it worked… so I’m really confused.

```glsl
void main()
{
	gl_FragColor = vec4(0.0, 0.0, 1.0, 0.05);
}

```

 ![image](https://forum-defold-uploads.b-cdn.net/original/3X/4/5/4552f673a27a88b449c26199ec50c9b32a843758.png)

My material settings:

 ![image](https://forum-defold-uploads.b-cdn.net/original/3X/1/2/1246cd270fc899443b1c44199da05c0d03330960.png)

My sprite’s atlas settings (its the only image on the atlas and I turned off extrude borders)

 ![image](https://forum-defold-uploads.b-cdn.net/original/3X/3/8/381ed17f5e4afd8c5d5c2b0ad6f67c81934530aa.png)

---

<div class="post-metadata">

**Author:** ![Dragosha](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/dragosha/32/5103_2.png) [@Dragosha](https://forum.defold.com/u/Dragosha)\
**Post date:** [September 16, 2026, 5:21am UTC](https://forum.defold.com/t/issue-turning-a-square-sprite-into-a-circle-using-shaders/83236/2 "2026-09-16T05:21:49Z")

</div>

By default, the renderer has the pre-multiplied alpha channel enabled. This means you need to multiply the color component by the alpha value.

P.S. I don’t know what your plan is, but most likely, UV-based corner rounding (var\_texcoord0) will stop working as soon as you add more sprites to the atlas.

---

<div class="post-metadata">

**Author:** ![Mathias](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/mathias/32/44015_2.png) [@Mathias](https://forum.defold.com/u/Mathias)\
**Post date:** [September 16, 2026, 5:52am UTC](https://forum.defold.com/t/issue-turning-a-square-sprite-into-a-circle-using-shaders/83236/3 "2026-09-16T05:52:33Z")

</div>

> [@Dragosha](#):
>
> By default, the renderer has the pre-multiplied alpha channel enabled

Hi, could explain please why it is this way and what’s the point? I’ve seen that in all the builtins material shaders, and I am doing it in mine, but I dont understand what is the use of multiplying alpha to all color?

---

<div class="post-metadata">

**Author:** ![Dragosha](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/dragosha/32/5103_2.png) [@Dragosha](https://forum.defold.com/u/Dragosha)\
**Post date:** [September 16, 2026, 6:32am UTC](https://forum.defold.com/t/issue-turning-a-square-sprite-into-a-circle-using-shaders/83236/4 "2026-09-16T06:32:13Z")

</div>

See ‘fragment shader’ section, point [4] here:

> **[The rendering process - Shader programs in Defold](https://defold.com/manuals/shader/index.html#the-rendering-process)**
>
> Shader programs are at the core of graphics rendering. They are programs written in a C-like language called GLSL (GL Shading Language) that the graphics hardware run to perform operations on either the underlying 3D data (the vertices) or the pixels...

`gl_FragColor = vec4(tex.rgb, alpha);` - \> `gl_FragColor = vec4(tex.rgb*alpha, alpha);`

---

<div class="post-metadata">

**Author:** ![Mathias](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/mathias/32/44015_2.png) [@Mathias](https://forum.defold.com/u/Mathias)\
**Post date:** [September 16, 2026, 8:34am UTC](https://forum.defold.com/t/issue-turning-a-square-sprite-into-a-circle-using-shaders/83236/5 "2026-09-16T08:34:17Z")

</div>

Thank you for the reference. But my point is I understand why we must do this in the shader "  
The color value of the tint gets premultiplied with its alpha value since all runtime textures already contain premultiplied alpha  
"  
But I dont understand why runtime textures are already premultiplied by alpha..?  
Why does the runtime do this internally?  
That’s just for my deeper understanding of the rendering pipeline.

---

<div class="post-metadata">

**Author:** ![Mathias\_Westerdahl](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/mathias_westerdahl/32/228_2.png) [@Mathias\_Westerdahl](https://forum.defold.com/u/Mathias_Westerdahl)\
**Post date:** [September 16, 2026, 8:50am UTC](https://forum.defold.com/t/issue-turning-a-square-sprite-into-a-circle-using-shaders/83236/6 "2026-09-16T08:50:36Z")

</div>

It’s an old trick and it’s about being able to do filtering and mipmapping of the textures correctly.  
Some reading materials:

- [https://www.realtimerendering.com/blog/gpus-prefer-premultiplication/](https://www.realtimerendering.com/blog/gpus-prefer-premultiplication/)
- [Beware of Transparent Pixels - Adrian Courrèges](https://www.adriancourreges.com/blog/2017/05/09/beware-of-transparent-pixels/)
- [Premultiplied alpha | Krzysztof Narkowicz](https://knarkowicz.wordpress.com/2009/11/18/premultiplied-alpha/)

---

<div class="post-metadata">

**Author:** ![Mathias](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/mathias/32/44015_2.png) [@Mathias](https://forum.defold.com/u/Mathias)\
**Post date:** [September 17, 2026, 6:11am UTC](https://forum.defold.com/t/issue-turning-a-square-sprite-into-a-circle-using-shaders/83236/7 "2026-09-17T06:11:44Z")

</div>

Thank you! That’s why I love this forum: many people who know things and want to share their knowledge! Je m’endormirais moins bête ce soir

---

<div class="post-metadata">

**Author:** ![Mathias](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/mathias/32/44015_2.png) [@Mathias](https://forum.defold.com/u/Mathias)\
**Post date:** [September 17, 2026, 6:14am UTC](https://forum.defold.com/t/issue-turning-a-square-sprite-into-a-circle-using-shaders/83236/8 "2026-09-17T06:14:03Z")

</div>

Hi, I kind of highjacked your post sorry, did you manage to fix your problem?  
Does premultiplying alpha on the tint color fix it?

---

<div class="post-metadata">

**Author:** ![vinicius](https://forum-defold.b-cdn.net/letter_avatar_proxy/v4/letter/v/bcef8e/32.png) [@vinicius](https://forum.defold.com/u/vinicius)\
**Post date:** [September 17, 2026, 1:46pm UTC](https://forum.defold.com/t/issue-turning-a-square-sprite-into-a-circle-using-shaders/83236/9 "2026-09-17T13:46:49Z")

</div>

In the OP’s case, they are creating a alpha value instead of reading it from the texture, they will need to pre-multiply by the computed alpha AND by the tint’s alpha, so something like this should work

```glsl
varying mediump vec2 var_texcoord0;
uniform lowp sampler2D texture_sampler;
uniform lowp vec4 tint;

void main()
{
	vec4 tex = texture2D(texture_sampler, var_texcoord0);

	vec2 p = var_texcoord0 * 2.0 - 1.0;
	float d = length(p);
	float alpha = 1.0 - smoothstep(0.70, 1.0, d);

	gl_FragColor = vec4(tex.rgb*alpha*tint.a, alpha*tint.a);
}

```

Note, that I am assuming OP wants to use `tint.a` for an extra overall transparency. And I used the multiplying approach, but you could use other approaches like

```glsl
gl_FragColor = vec4(tex.rgb*(alpha + tint.a), alpha + tint.a);

```

Or if you don’t care for `tint.a` at all (which I believe was OP’s original intent) then just don’t use it.

```glsl
gl_FragColor = vec4(tex.rgb*alpha, alpha);

```

Alternatively, you can do it without pre-multiplying but you will have to mix your texture with black like this

```glsl
varying mediump vec2 var_texcoord0;
uniform lowp sampler2D texture_sampler;
uniform lowp vec4 tint;

void main()
{
	vec4 tex = texture2D(texture_sampler, var_texcoord0);

	vec2 p = var_texcoord0 * 2.0 - 1.0;
	float d = length(p);
	float alpha = 1.0 - smoothstep(0.70, 1.0, d);

	vec3 outside_colour = vec3(0.0, 0.0, 0.0); // black
	vec3 inside_colour = tex.rgb;

	vec3 final_colour = mix(outside_colour, inside_colour, alpha);

	gl_FragColor = vec4(final_colour, alpha); //not tint.a
}

```

This works because now we are setting the transparency color to zero (black) which means when it blends (add) with the framebuffer color it won’t add anything to the resulting color even though it is not being pre-multiplied.

When I hear

> [@Dragosha](#):
>
> By default, the renderer has the pre-multiplied alpha channel enabled.

My understanding is that in Defold the OpenGL blending function is set as:

```cpp
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glBlendEquation(GL_FUNC_ADD);

```

Which means the blending equation is:

C\_final = C\_src + C\_dst \* (1 - aplha\_src)

You can see that C\_src (the color you are currently processing in your shader) is not affected by alpha, so transparency effect will work only if you pre-multiply it or if you make C\_src black like I did in the alternative solution.
