Drawing Multiple Collisions

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
Leole
Prole
Posts: 2
Joined: Wed Mar 05, 2025 4:24 pm

Drawing Multiple Collisions

Post by Leole »

Hello! I've been hard at work on my game, 2 months now, and I've run into an issue that I don't seem to be able to solve by myself.

Without getting bogged down by the specific mechanics of my game, I have 2 physics objects colliding with each other, a Dynamic one and a Static one. When they collide, I would like to paint part of the Static one with a Red Circular Gradient where they collided, probably using a Shader. Simple.

What I've done so far:
  • I've set the world callbacks to get the collision information
  • I've sent this collision information to the corresponding object in my game that is in charge of drawing the Static object
The problem lies with the fact that, at any given moment, there's going to be several collisions per frame. Not only that, I would like for the Gradient to fade away with time, easily achievable with a tween (I'm using hump.Timer). All I would really need to do is update the information I send to the shader per frame and bob's your uncle.

I don't know how to send all the information to the shader so it knows where to draw the Gradient if the information is several collision coordinates. AFAIK and searched, you can't pass lua tables to GLSL Shaders through Shader:send().

I thought about drawing a canvas that draws where the collisions happen and then sending that, but I don't know if this is the right approach and I should keep exploring this angle (if it is, I would a small example if possible). I'm very new to shaders (Just the other week I managed to get some text to change color whenever a rectangle was drawn over it and I was ecstatic about it) so any help is welcome. Maybe I shouldn't even be using a shader for all I know!
RNavega
Party member
Posts: 456
Joined: Sun Aug 16, 2020 1:28 pm

Re: Drawing Multiple Collisions

Post by RNavega »

Leole wrote: Wed Mar 05, 2025 4:43 pm I would like to paint part of the Static one with a Red Circular Gradient where they collided
(...)
there's going to be several collisions per frame.
(...)
I would like for the Gradient to fade away with time
Hi, I'd do some tests with using some kind of stencil or masking mechanism.

Each collision instances a new "gradient sprite" -- that's a quad or custom mesh that can be filled with either a texture gradient or shader gradient. With time, each gradient sprite fades (you individually control the transparency of each sprite, like from the base color in love.graphics.setColor).
Then you need to mask those sprites to the silhouettes of the static objects.
_.png
_.png (100.36 KiB) Viewed 541 times
You can do this in two ways: if the static objects are not antialiased (meaning, they have hard pixels at their borders), then you can go ahead with a stencil buffer to mask the gradient sprites to only be drawn on top of the regions occupied by static objects.
If the static objects are antialiased however, then the stencil buffer won't work well with those semitransparent pixels. In such a case you can try a custom solution using a canvas: you draw all static object to that canvas so it holds those graphics + empty space (transparent black), then reference the canvas texture in the shader for the gradient sprites, using it as a mask. You need to account for the difference in image sizes, UV coordinates and that sort of thing, but it should work. There's an example of doing something like that in here, referencing an image as a secondary transparency mask: viewtopic.php?p=260985#p260985

Edit: a small correction... you don't have to actually "instance" thousands of gradient sprites. You can use a single sprite and repeatedly draw it on thousands of different positions. So you just have to keep track of the collision positions.
Leole
Prole
Posts: 2
Joined: Wed Mar 05, 2025 4:24 pm

Re: Drawing Multiple Collisions

Post by Leole »

RNavega wrote: Thu Mar 06, 2025 7:33 am If the static objects are antialiased however, then the stencil buffer won't work well with those semitransparent pixels. In such a case you can try a custom solution using a canvas: you draw all static object to that canvas so it holds those graphics + empty space (transparent black), then reference the canvas texture in the shader for the gradient sprites, using it as a mask. You need to account for the difference in image sizes, UV coordinates and that sort of thing, but it should work. There's an example of doing something like that in here, referencing an image as a secondary transparency mask: viewtopic.php?p=260985#p260985

Edit: a small correction... you don't have to actually "instance" thousands of gradient sprites. You can use a single sprite and repeatedly draw it on thousands of different positions. So you just have to keep track of the collision positions.
Thank you so much for your answer, I ended up doing something very similar to what you described in the previous quote. The only difference, I'm not using a sprite, rather, I'm drawing with love.graphics.circle() 3 circles overlapping with an alpha of 10%, so that when they overlap, they form a gradient. I don't necessarily need the whole sprite to be a perfect gradient. However, in your opinion, what's better for performance? Loading a sprite with the gradient, or drawing it inhouse with love.graphics? The performance difference is probably negligible but I would rather know how to do it proper :awesome:

I really appreciate the help! It reassured me that my first instinct of drawing a Canvas to act as a Mask wasn't super off base, I just didn't have the words to describe it as a Mask.
User avatar
dusoft
Party member
Posts: 765
Joined: Fri Nov 08, 2013 12:07 am
Location: Europe usually
Contact:

Re: Drawing Multiple Collisions

Post by dusoft »

Sprite+shader will be likely more performant. But if you are drawing literally just three circles colliding using graphics, you won't have any issues. If you plan on having a large number of circles drawn, then consider sprites/quads.
RNavega
Party member
Posts: 456
Joined: Sun Aug 16, 2020 1:28 pm

Re: Drawing Multiple Collisions

Post by RNavega »

I agree with dusoft that using a shader will be way faster than drawing multiple circles per gradient position. You can achieve the same stepped effect with some shader math. That said, if there aren't that many gradient spots in your game then ultimately it won't make a perceptible difference what method you're using to draw them, LÖVE is very fast and the game will be performant anyway.
It's not clear from your description how many gradient spots there'll usually be at any point in the game, it may be very few or it may be hundreds -- if it's the latter, you could try using a custom mesh that's a quad, to be drawn with love.graphics.drawInstanced.

PS there's an example of a shader-based gradient in here, but it's just in the alpha channel: viewtopic.php?t=89470
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Amazon [Bot], Bing [Bot], Google [Bot] and 2 guests