• 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!

Legacy GM Particle trails on a surface

M

Mann_mit_Hut

Guest
Hey fellows,

i have some particles flowing around in a velocityfield, now i' working on a visual representation.
To make it look nice they should draw trails, that fade out.

The effect i got by drawing them on a surface goes in the right direction, but i'm not doing it right i think.
In the screenshot you can see, that the particles dont fade out to 0, they still leave slight trails that will stay forever.

Maybe someone has done something like that and could give me a hint?

Here is my code so far:
Code:
surface_set_target(particlesurf);

// let the fadeout happen
draw_set_alpha(0.1)
draw_set_colour(c_white)
draw_rectangle(0,0,room_width,room_height,false)
draw_set_alpha(1)

// draw particles on surface
for(var i=0; i<100; i++){
  draw_sprite_ext(spr_particle,0,particlex[i],particley[i],1,1,0,c_white,1)
}

// draw the particlesurface on screen
surface_reset_target();
draw_surface(particlesurf,0,0)
 

Attachments

obscene

Member
With the regular blend mode layering on 10% opacity each time is just going to keep blending the existing image and you'll never get it completely washed out. You may do better using bm_subtract and either drawing a black or white rectangle (can't remember which).
 
M

Mann_mit_Hut

Guest
Hey fellows,

i had draw_clear_alpha(c_black, 0); after creating the surface, sorry for not telling.

The substraction makes absolutely sense - but there are still trails left.
When i substract a c_white rectangle the trails get black, with a c_black substraction they stay white, but still leave a slight trail.
I also tried colors like make_colour_rgb(10,10,10), but its nearly the same as c_black
 
S

seanm

Guest
you have to clear the surface every time you draw to it, not just when you create it.
 
M

Mann_mit_Hut

Guest
Hmm but when i do draw_clear_alpha(1,0) every time there are no particle trails at all...
 
S

seanm

Guest
oh i see. try clearing with more alpha then.

draw_clear_alpha(1,0.1)
 
M

Mann_mit_Hut

Guest
Also doesn't work, it just resets the surface and there are no trail. The manual said, draw_clear_alpha doesn't do any blending, so it just sets every value on the surface, including alpha and color...
 
S

seanm

Guest
Well Im sure there is some way to do it the way you want to right now.

But what about just creating the trail yourself? store the previous positions of the particles in a data structure and draw them.
 

obscene

Member
Judging by the image you posted it looks like you could just skip the whole issue by having a single long trailing sprite. You could also use a particle (the actual particle system) to create particles that emit a stationary fading particle every step though that's the least efficient methoid.
 
M

Mann_mit_Hut

Guest
Drawing the trail every time is to expensive for mobile i think, because i draw 100 particles with a trail that is again maybe 100 draws long, that might be a bit much for mobile...

I came up with a solution, but i don't know why it works.
The constants like alpha and the colour are very sensitive. But it seems to leave no trail now...

Code:
  draw_set_alpha(0.05)
  draw_set_colour(make_colour_rgb(10,10,10))

   draw_set_blend_mode(bm_subtract)
  draw_rectangle(0,0,room_width,room_height,false)
  draw_set_blend_mode(bm_normal)
A single trail-sprite is not feasible, because it's a fluid simulation, as you can see in the attachment
 

Attachments

Last edited by a moderator:
S

seanm

Guest
Ahhhhhhhhhhh right.

So surfaces behave differently. You have to premultiply alpha for it to work properly, but you can't do that because of your use of bm_subtract. If you have something that works now, then don't worry about it.
 
S

seanm

Guest
sh_premultiply
Code:
//vertex
//
// Simple passthrough vertex shader
//
attribute vec3 in_Position;                  // (x,y,z)
//attribute vec3 in_Normal;                  // (x,y,z)     unused in this shader.
attribute vec4 in_Colour;                    // (r,g,b,a)
attribute vec2 in_TextureCoord;              // (u,v)

varying vec2 v_vTexcoord;
varying vec4 v_vColour;

void main()
{
    vec4 object_space_pos = vec4( in_Position.x, in_Position.y, in_Position.z, 1.0);
    gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos;

    v_vColour = in_Colour;
    v_vTexcoord = in_TextureCoord;
}
Code:
//fragment
varying vec2 v_vTexcoord;
varying vec4 v_vColour;

void main()
{
    gl_FragColor = v_vColour * texture2D(gm_BaseTexture, v_vTexcoord);
    gl_FragColor.rgb *= gl_FragColor.a;
}

surface code
Code:
surface_set_target(surf)
draw_set_blend_mode_ext(bm_one, bm_inv_src_alpha);
shader_set(sh_premultiply);

draw_sprite_ext(sprite_index,image_index,x,y,1,1,0,-1,0.5)

shader_reset()
draw_set_blend_mode(bm_normal)
surface_reset_target()

draw_set_blend_mode_ext(bm_one, bm_inv_src_alpha);
draw_surface_ext(surf,x,y,1,1,0,c_white,1)
draw_set_blend_mode(bm_normal)

I believe that is all you need to premultiply alpha. I just ripped this from an old project file; unfortunately I can't find the gmc post that I got the info/shader from.

@Lonewolff


I had to do this for transparent bloodsplats that I drew onto surfaces.
 
M

Mann_mit_Hut

Guest
Thank you, so the 'right' solution contains shaders :D

Are the blend modes part of the solution or part of your particular drawing Code?
From what i understand, the shader itself could solve my problem, i could remove the bm_subtract and just premultipy in normalmode with the shader.
 
M

Mann_mit_Hut

Guest
I tried your code, i also tried it with the extended blend modes, but it still leaves behind these slight trails or the trails stay all the time.
Nevermind, my hacked solution where i subtract a slightly grey quad from the surface values works for me.

Thanks for your help guys!
 
S

seanm

Guest
The blend mode is important, so you cant use bm_subtract if you are premultiplying. Which means you would probably have to use multiple surfaces, and it'll get weird. So like I said, and as you've realized, just go with what you know already works.
 
Top