GMS 2 How to draw particles not affected by the surfaces above them?

Sozidar

Member
I know its possible to just draw particle system above the lighting surfaces, but I really need to preserve depth order. Here's a screenshot of current situation:1.png
Particles on hand and sword are too dim, but the depth is ok.

And here's how they look when being drawn above everything:2.png
Bright and clear, except that the depth now is not ok.

So how do I preserve both luminosity and depth? Any help with solving this problem is greatly appreciated.
 

Sozidar

Member
So... after three days of pathetic attempts of fixing this issue I've settled down on using bm_subtract to cut holes in lighting surface, and although it is the closest I can get it to being perfect there are still some imperfections such as visible holes and pixelated particles, as seen here:3.png

And it's still not looking any better than previous variants, so I dunno...

Code:
var cam = view_get_camera(0);
var cx = camera_get_view_x(cam);
var cy = camera_get_view_y(cam);

//Cutting holes from final lighting surface
surface_set_target(_pl_lightmap);
gpu_set_blendmode(bm_subtract);
//Shader for transforming all colors to black without affecting alpha
shader_set(shd_black);
with HAND_PARENT {
    part_system_position(system_hand,-cx,-cy);
    part_system_drawit(system_hand);
}
shader_reset();
surface_reset_target();

if !surface_exists(_pl_final) _pl_final = surface_create(1440,900);
surface_set_target(_pl_final);

//Drawing application surface without lightmap, so we can
draw_surface(application_surface,0,0);
 
//Drawing lightmap with blendmode
gpu_set_blendmode_ext(bm_dest_color, bm_src_color);
draw_surface_ext(_pl_lightmap, 0, 0, 4, 4, 0, c_white, 1);
surface_reset_target();

//Drawing final surface (for some reason it's huge, so I scaled it down)
gpu_set_blendmode(bm_normal);
draw_surface_ext(_pl_final,cx,cy,0.25,0.25,0,c_white,1);

Any suggestions? C:

I'm exhausted fighting with this thing.
 
Last edited:

Phil Strahl

Member
I am by no means an expert, but theoretically, could you fake some of depth buffer, e.g. draw all the sprites in solid colors on a separate view and then sample those pixels when drawing particles? Should be halfway decent with shaders, I presume, but hacky af. Someone in here who knows how to do this?
 
If I understand you correctly, your issue is thst the lighting surface is darkening the particles. You solution would be to mask the particles and draw them atop.

Heres another solution, not perfect but probably fast: why not draw lights to the light surface where the particles are? Of course the light wont be masked but it might look good enough.
 
One solution could be to use multiple rendering targets. That would allow you to easily mask all the particles on your lighting surface.

But I think there are easier solutions. One is to not include the darkening portion of your ambient lighting in the actual light surface. If you moved that to a shader or to blending colors, then you can easily select not to have it affect your particles. In which case you can change your lighting surface to only have an additive effect.
 
Top