• Hey! Guest! The 40th (!!!) GMC Jam will take place between February 25th, 12:00 UTC to March 1st 12:00 UTC. Why not join in this very special anniversary jam! Click here to find out more!

GMS 2.3+ A nice smooth blob ?

DaveInDev

Member
Hi,

I try to design an object that we could call "blob" : some king of a fluid mass floating in space and randomly changing shape.

For the moment, I use a serie of sprite, drawn in Krita with a vector tool, that gives the smooth anti aliased drawing that I want, with a separate outline. (see the screencopy)

BUT to get a smooth animation, that's another problem... Sprite animation will always be "abrupt". I really wish to give a fluid animation.

So do you have an idea on how to get this dynamically ? I wish there was a way to distort a similar circular sprite in a complex manner ?

1609334965432.png
 

Kezarus

Member
If that was on GM 1.4 there was a pretty neat Morph functionality on the GM Drawing program. It was very easy to make what you are saying there.

Now I don't know how it's done. And I am interested on this too.
 

Bentley

Member
I know this does not deal with sprites, but one idea is to actually draw a circle with different and changing radii. I think you can get that blobby look you're going for.
 
Well, for starters I see your animation runs at 4 frames per second, that won't cut it for smoothness. Maybe insert more frames in-between your keyframes? If that still won't cut it, you can also try to check the Edge Filtering box, see if that makes any difference in your case.
But yeah, 4 frames per second for a full movement like that, that's going to be choppy for sure. I say AT LEAST double your subimages if you want it to really start to flow.
 

DaveInDev

Member
I know this does not deal with sprites, but one idea is to actually draw a circle with different and changing radii. I think you can get that blobby look you're going for.
What kind of GMS function should I use for this ? Note that I want a filled outlined form with a antialiased edge.


Well, for starters I see your animation runs at 4 frames per second, that won't cut it for smoothness. Maybe insert more frames in-between your keyframes? If that still won't cut it, you can also try to check the Edge Filtering box, see if that makes any difference in your case.
But yeah, 4 frames per second for a full movement like that, that's going to be choppy for sure. I say AT LEAST double your subimages if you want it to really start to flow.
The fact is that my blobs could be quite big. It will be too much work to create these subimages with a one-pixel diff. And I'd like them to be unique, not just replicated. Thats' a challenge ;)


---------------
I'm currently looking at vertex buffers. Maybe if I can put this round sprite in a vertex buffer like the red triangles, I could then create a shader that would rotate every vertex around its original position, giving such a bloby distorted fx ?...

Does anyone have a example of such a manipulation ? (sprite->vertex->shader)
Because I'm quite new to this subject...


1609339341193.png
 
The fact is that my blobs could be quite big. It will be too much work to create these subimages with a one-pixel diff. And I'd like them to be unique, not just replicated. Thats' a challenge ;)
In that case, if performance is an issue, you could probably use just a circle blob + a wavy-watery-shader on that sprite. To me, this would be the most efficient way performance-wise, you could reuse the shader for any situation, draw it the exact size you want, and only when needed. Won't clutter the IDE with sprites that are not used so often. Would require a bit more of an initial set-up, tho, but once you get it working, you'll even be able to reuse it to other projects easily. Plus, you avoid all the collision-box BS that may or may not happen from frame to frame, since you have just a single sprite being distorted.
 
Wouldn't using a shader compromise the collision event with the blob? Is that an issue?
It will follow the sprite's collision mask, so yeah, maybe if you stretch it wayyyyy out, and you have a collision on the edges, it won't trigger anything. But most likely it won't be a problem, unless you aim for super-precise collisions everywhere on the blob, on every frame, kind of like checking "precise per frame" collision box in the sprite editor.
 

DaveInDev

Member
I do not need precise collision : the spaceship is just supposed to come "somewhere" over/close to the blob, that will be sucked in a tank, so the size of the blob will just decreased and vanish. So a simple point_distance to the center will be enough.
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
Moderator
I found a nice tutorial here, but I need to adapt this to my special vertex distribution, and rewrite a shader...
You know you don't need a shader for this? You can simply create a textured primitive and then draw it each frame and move the points of the triangles yourself. :) Also, depending on what you want, you may find using metaballs a more interesting solution, or even a good compliment to using primitives to get your blobs to join up and stuff...
 

DaveInDev

Member
You know you don't need a shader for this? You can simply create a textured primitive and then draw it each frame and move the points of the triangles yourself. :) Also, depending on what you want, you may find using metaballs a more interesting solution, or even a good compliment to using primitives to get your blobs to join up and stuff...
waooo, nice ! that's exactly what I need : each of the blob could just been made of 3-5 of these meatballs, constrained in a small area and it will do the trick. I'll test this right now ! :)
 

DaveInDev

Member
So I tried programming something similar, and, even before playing with gpu blend mode, I have a problem with drawing sprites on surface.
Please look at the YYZ enclosed. Press SPACE to switch between normal mode, and "drawing thru a surface", and look at the difference into the obj_blob/draw event.

There seems to be a difference in alpha treatment when you draw to a separate surface ???
How can I correctthis, so that it looks the same in both mode ?
(then, I'll be able to uncomment the gpu commands)

 
So I tried programming something similar, and, even before playing with gpu blend mode, I have a problem with drawing sprites on surface.
Please look at the YYZ enclosed. Press SPACE to switch between normal mode, and "drawing thru a surface", and look at the difference into the obj_blob/draw event.

There seems to be a difference in alpha treatment when you draw to a separate surface ???
How can I correctthis, so that it looks the same in both mode ?
(then, I'll be able to uncomment the gpu commands)

I took a look at it in the Render window in the debugger, where you have all your GPU values.
I noticed when your game start, alpharef is set at 0, and as soon as you press space, it will jump to 192 and never be set back to 0 after that, even when toggling states with spacebar. It looks like it's the only value changing at all.
If you set
GML:
gpu_set_alphatestenable(true);
gpu_set_alphatestref(192);
from the start of the game, it will probably do what you want. Now it's only triggered and set when you press spacebar for the first time.
That Render window in the debugger tab will get you out of the woods eventually with those things, if it was not the problem!
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
Moderator
There seems to be a difference in alpha treatment when you draw to a separate surface ???
Yup, there is... Have a good read at these articles I wrote some time back:


:)
 

DaveInDev

Member
I took a look at it in the Render window in the debugger, where you have all your GPU values.
I noticed when your game start, alpharef is set at 0, and as soon as you press space, it will jump to 192 and never be set back to 0 after that, even when toggling states with spacebar. It looks like it's the only value changing at all.
If you set
GML:
gpu_set_alphatestenable(true);
gpu_set_alphatestref(192);
from the start of the game, it will probably do what you want. Now it's only triggered and set when you press spacebar for the first time.
That Render window in the debugger tab will get you out of the woods eventually with those things, if it was not the problem!
I do not understand : did you uncomment the GPU lines that were originally commented ?
With the comments ON, I do not understand how alpharef can be 192.
Please run the original YYZ, with the comments ON.
My original interrogations were about the differences between rendering thru or without a surface, with no GPU blend/alpha operations,
so with the comments ON. Don't you see a difference when you press spacebar ? Here is what I see :
without surface : 1609425801693.png
with surface : 1609425824965.png (balls seems really smaller or dimmed).

I did not try to tweak the GPU comments for the moment ;)

Yup, there is... Have a good read at these articles I wrote some time back:

:)
So there is. That's what I suspected, but did not find infos on this.... I will check these articles !
 

Yal

🍋 *lemon noises*
GMC Elder
Surfaces and alpha is a pretty messy subject because of some maths quirks, I'd avoid mixing those two elements unless absolutely necessary. Just having an array of positions/sizes for each ball that you loop over each draw event would be good enough. You want every blob to move around individually every step anyway, right? You're actually making the drawing slower if you use a surface since you can't reuse it between steps anyway and clearing/redrawing it adds overhead!
 
I do not understand : did you uncomment the GPU lines that were originally commented ?
With the comments ON, I do not understand how alpharef can be 192.
Please run the original YYZ, with the comments ON.
My original interrogations were about the differences between rendering thru or without a surface, with no GPU blend/alpha operations,
so with the comments ON. Don't you see a difference when you press spacebar ? Here is what I see :
I think it has something to do with the default blend mode, but not quite sure under the hood how or why. But why would you need it to work both with and without the commented code? I can't really see a situation where you would need to work both on the distorted surface, and on the application surface...maybe I don't see the endgame clearly, but anyway!
 

DaveInDev

Member
Surfaces and alpha is a pretty messy subject because of some maths quirks, I'd avoid mixing those two elements unless absolutely necessary. Just having an array of positions/sizes for each ball that you loop over each draw event would be good enough. You want every blob to move around individually every step anyway, right? You're actually making the drawing slower if you use a surface since you can't reuse it between steps anyway and clearing/redrawing it adds overhead!
Sure they are messy. But I'd like to understand this stuff. ;)

I need to draw to a surface, in order to use gpu_set_blendmode, gpu_set_alphatestenable and gpu_set_alphatestref like in this tutorial that @Nocturne pointed out. This gives a nice uniform blob fx. If you just mix balls , you still see individual balls overlapping each others, not the feeling of one single object with a progressive changing shape... :confused:

 

DaveInDev

Member
for those interested here is the final result.
I'm quite happy with it. I tried to add a little shadow fx on the borders using gpu_set_blendmode_ext_sepalpha to separate alpha addition and color mixing.

You can press SPACE to circulate between other simpler versions. And B to show border.

Thanks to @Nocturne for these tutos. Very helpfull.
A few weeks on GMS now, and really having fun ! :p

 
Last edited:
Top