Setting alpha of objects without adding lots of drawcalls

I have a game with 30-50 GO objects on screen. Each has two sprites a character and a hover thing. The hover thing can be active the closer the cursor is to the character GO.

But setting the alpha for the hover for all of these with sprite.set_constant adds a ton of drawcalls!! How can I smoothly animate alpha of these sprites without the performance impact?

Until we have custom vertex formats, it’s going to be tricky.

One idea is ofc to have these objects in the gui world.

Another idea might be to encode the alpha in the z component of the position and use that as the alpha modifier. E.g. when the cursor is closer to the object, the z increases, and when it’s further away, the z decreases. And having a known range between e.g. [0.4, 0.5], you can then easily set the alpha in the shader.

6 Likes

I see that Defold generates vertex buffers every frame to batch the draw of sprites and meshes/models with materials of the “World” vertex space. The different values of uniform constants break these batches.

I think that it will be useful to have material constants that Defold adds as attributes of vertices. Yes, the engine will generate a bit more data to draw sprites. But the different alpha values are not going to break batches anymore!

So, those new material constants can have float and vec4 data types. It’ll be enough.

How can look a modified sprite.vp/sprite.fp, without tint constant:

uniform highp mat4 view_proj;

// positions are in world space
attribute highp vec4 position;
attribute mediump vec2 texcoord0;
attribute lowp float alpha; // ADDED

varying mediump vec2 var_texcoord0;
varying lowp float var_alpha; // ADDED

void main()
{
    gl_Position = view_proj * vec4(position.xyz, 1.0);
    var_texcoord0 = texcoord0;
    var_alpha = alpha; // ADDED
}
varying mediump vec2 var_texcoord0;
varying lowp float var_alpha; // ADDED

uniform lowp sampler2D texture_sampler;

void main()
{
    gl_FragColor = texture2D(texture_sampler, var_texcoord0.xy) * var_alpha; // MODIFIED
}
11 Likes

It makes sense. One thing: not only alpha, but vec4 tint.
Also add this tint to the editor as sprite component property.

8 Likes

It’s really useful because breaking batches is not obvious, so it would be cool to have it in standard materials

6 Likes

It would be great to implement this idea! (by aglitchman)

4 Likes

I have been asking this for a longtime… :slight_smile:

@Pkeod: I would suggest to quantize the alpha somehow and to prepare different sprites for each alpha value. Of course this could be expensive in texture space if the sprite is quite large…

3 Likes

wow! so, different alphas cause breaking the batch?! so sad…

5 Likes

That’s a good idea for overlays. What we ended up doing to reduce drawcalls is very aggressively disabling the extra sprite components since alpha at 0 still adds a drawcall but disabled component does not. For some things (that were previously set dynamically) we did prebake the alpha into the sprite too instead of manually setting it at runtime.

2 Likes

I added an issue, and please vote it up!

5 Likes