• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Problem with bm_add and red channel

F

Forestherd

Guest
Hello!

I'm creating a lighting system that supports multiple colours and it uses the build in bm_add blend mode to merge lights together that I later posterize to get a layered, almost gel like light system. Everything seems to work fine, but there is this one oddity that is driving me insane. Namely, for whatever reason, bm_add does not want to blend the red channels. I've attached some pictures of the problem to this post. Here is the code that draws each individual circle of light:
Code:
surface_set_target(sf_light)
draw_clear_alpha(c_black,1)
shader_set(shd_value_to_opacity)
draw_set_blend_mode(bm_add)
with(obj_light) {
        draw_circle_colour(x-view_xview[0],y-view_yview[0],light_radius,light_color,c_black,false)
    }
draw_set_blend_mode(bm_normal)
shader_reset()
surface_reset_target();
The shader used is a simple fragment shader that removes the outer dark color of each circle (since I use draw_circle_colour):
Code:
//
// Simple passthrough fragment shader
//
varying vec2 v_vTexcoord;
varying vec4 v_vColour;

uniform float shadowMax;

void main()
{
    vec4 originalColor = v_vColour * texture2D( gm_BaseTexture, v_vTexcoord );
    float Cmax = max(originalColor.r,max(originalColor.g,originalColor.b));
    originalColor.a = Cmax-0.1;
   
    gl_FragColor = originalColor;
}
The weirdest part is that it only happens when red tries to mix with either green or blue. Every other color seems to work just fine as far as I can tell. I'm pretty sure that I have the red channel updating (otherwise the red light wouldn't even appear to begin it) so I honestly have no idea whats messing it up. It worked perfectly this morning!
Any help or feedback is really appreciated.

PS: Two of the screenshots have the posterization shader active so that it is a lot more apparent that the colors arent blending correctly.
 

Attachments

Ido-f

Member
Your shader seems to me to be the problem.
Setting the fragment's alpha to be 0.1 below its highest color channel maybe works as intended for darker colors,
but I'm not surprised it gets funky results.
It's a pretty arbitrary method that doesn't take all of the relevant elements into account.
So, for example, (0.8, 0.1, 0.2) and (0.8, 0.7, 0.6) colors would both get 0.7 alpha, while (0.6, 0.6, 0.6) would get 0.5 alpha.
Is that a desired result? I don't know, doesn't seem like one.
So what I think is happening is that the pure red, green and blue colors get the highest alpha from your shader, as they have a color channel in 1.0, which somehow cause the problem you described.

it's just a thought.
I don't feel I understand your lighting system, or what's wrong with it in the screenshots, really.
 

samspade

Member
I also am not sure I see the problem as everything appears to be blending well. One thing I will say though is that on some level this system simply can't do exactly what I think you want it to do. The reason for this is that each draw is handled 'separately' and what I mean by that is color values are added, and most importantly, clamped successively. This means that you won't get true averages if you have multiple circles. For example, take just the blue channel. Let's say there are 10 blue circles and one 'non blue' circle. You would expect blue to be dominate in a true average. However, because values are clamped after each draw, the final circle will have an equal weight to all preceding circles. For example, assuming 10 is the max the number can be: 10 + 10 + 10 + 10 + 0 should equal 8. However, if you clamp the value to 10 after each addition then the answer will actually be 5 or 9.375 depending upon the order the values are added in (e.g. 10 + 10 = 10, 10 + 10 = 10, 10 + 10 = 10, 10 + 0 = 5 or 0 + 10 = 5, 5 + 10 = 7.5, 7.5 + 10 = 8.75, 8.75 + 10 = 9.375).
 
F

Forestherd

Guest
Hey!

I got the system working okay-ish! Due to a lack of time I'll probably roll with this version of it - it get's the job done and while not perfect, it definitely adds more to the scene than it takes away. What I did in the end was I used 2 surfaces, one with no color for the layered lighting effect and then another with just the colors an no posterization, then I just added them together with the multiply blend mode. Thank you guys for the help! Here's a screenshot for the curious:
 

Attachments

Top