aiv01 / aiv-fast2d

Hardware accelerated 2D library
GNU Lesser General Public License v3.0
8 stars 7 forks source link

Sprite: Additive and Multiply color should take into account transparency #72

Open fdefelici opened 4 years ago

fdefelici commented 4 years ago

Understand if it is possible to avoid coloring transparent pixel when using Additive and Multiply coloring in Sprite and InstancedSprite

DoctorWho406 commented 3 years ago

Taking transparency into account when using Additive Tint and Multiply Tint would be ideal for creating time-related fade effects. In particular with the Multiply. For now when the Multiply is invoked to modify only the transparency the whole sprite disappears. On the contrary with the AdditiveTint the Sprite becomes transparent but also the other colors change.

fdefelici commented 3 years ago

@DoctorWho406 Could you integrate the issue by providing some code samples that show off what your are describing?

DoctorWho406 commented 3 years ago

@fdefelici Sure, as soon as I have a minute at work I'll do it.

DoctorWho406 commented 3 years ago

For the Add I used the following code and as a result I got a slightly transparent Sprite but with deformed colors.

public override void Update() {
    sprite.SetAdditiveTint(0f ,0f, 0f, -0.1 * Game.DeltaTime);
}

For the Multiply instead I used the following code. The sprite disappeared immediately.

public override void Update() {
    if(Disappear) {
        sprite.SetMultiplyTint(0f ,0f, 0f, 0.9 * Game.DeltaTime);
    }
}
fdefelici commented 3 years ago

Additive and Multiply are 'storically' implemented this way:

frag_color *= mul_tint;
frag_color += vec4(add_tint.xyz * frag_color.a, add_tint.a);

This explain why Addictive distor color (by Alpha component)

Instead, Multiply should work as expected. It's normal that sprite disappear immediatly because you are multiply RGB by 0. This should work in this way:

public override void Update() {
    if(Disappear) {
        sprite.SetMultiplyTint(1f ,1f, 1f, 0.9 * Game.DeltaTime);
    }
}
DoctorWho406 commented 3 years ago

Thank you @fdefelici. The Multiply method works!

I did not understand why the Additive should distort the colors. In my case (I used Either Additive OR Multiplay, never both) the mul_tin was not there so I suppose it is replaced with a vector (1, 1, 1, 1)

frag_color *= mul_tint;

while add_tin was a vector with (0,0,0, -1 * Game.Deltatime)

frag_color + = vec4 (add_tint.xyz * frag_color.a, add_tint.a);

then the frag_color would be incremented by a vector ((0,0,0) frag_color.a , -1 Game.DeltaTime) = (0, 0, 0, -1 * Game.DeltaTime) which should do exactly what I wanted.