General Ideas
Some general ideas:
A bit of warning here - there will be some mathematics (albeit, I'd hope reasonably basic, high school level). I will also use some tex-like notation in the below.
The plasma effect, fairly popular back in the heydays of the demoscene, was obtained as a combination of various wave functions on each screen pixel. This means on every pixel (x,y) of the screen we assign a value as the sum of 2d functions:
P(x,y,t) = num_colors / n_waves * \Sum_{n = 1 to n_waves} f_n(x,y,t)
n_waves is the total number of waves in the plasma, and num_colors represents the total number of colors we want to consider in the plasma (the meaning of this parameter will become more explicit later).
The functions f_n(x,y,t) can really be anything, but personally I find that trigonometric functions give the best results (there is also a neat trick with those I will be discussing later). So I will be using exclusively functions of the type:
f_n(x,y,t) = (1 + sin(x*u_n + y*v_n + p_n*t + q_n))/2
Each function will have its own set of parameters: u_n, v_n, q_n and p_n. The functions f_n, by design, can only take values between 0 and 1.
One thing I haven't mentioned so far is that there is another parameter --> time t. Plasma is not static. It can't only depend on the pixel position (x,y). We therefore add a time dependent parameter p_n*t so to generate the desired animation.
Practical considerations
- Each sets of parameter (u_n, v_n, p_n, q_n) is drawn randomly for each wave within a specified range.
- The range for each parameters is rather arbitrary - remember the functions will still be bounded between 0 and 1 no matter what the parameters are. However, for the smoothness of the effect, I found that u_n, v_n are best between between -1/100 and 1/100. Feel free to test any value and let me know if there are interesting. For q_n, given this is just a constant within a sine function, I simply draw it from a range [0, 2*pi].
- The parameter p_n is essentially the speed at which the wave. Since we work with a trigonometric function, the wave is periodic and will return to its original shape when p_n*t is a multiple of 2*pi. Therefore if you are looking to work with a period of N seconds, use p_n = 2*pi / N. For this parameter in fact, I do not use a random parameter but rather the same for all waves (which I will justify later), that is p_n = p for all. In my implementation, I use p = 0.5.
Since we work with a tileset, the position (x,y) corresponds to the position of each tile (which you can arbitrarily take as the center of the top left corner... as long as you are consistent, it does not really matter). For each tile, we calculate therefore the value of the plasma P(x,y,t) at a point in time t. The function can take any value between 0 and num_color. We then round this value to the nearest integer and map it to a given color (each of them having been defined as a tile within the tilemap):
Ideally pick a gradient like above, i.e. with a smooth transition between colors which will be consistent with the smooth changes of the plasma function.
This is in a nutshell the overall logic of my code. Now we can notice that this for a tilemap containing N tiles (simply calculated as width * height / (tile size * tile size) with height and width being the size of your game window) with n_waves functions, it takes N * n_waves calculations per frames. For a regular sized window and a decent number of waves - I'd say you need about 10 to get a good effect - this can be very calculation intensive. In the next devlog, I will show a simply trick to minimize significantly this number and make it scale very nicely with the number of waves.
Files
Plasma Godot4
Plasma Effect With Godot4
Status | In development |
Category | Assets |
Author | MidnattOel |
Tags | demoscene, Godot, Pixel Art, plasma, Prototype, sourcecode |
More posts
- ExamplesMay 11, 2024
- ImprovementsMay 11, 2024
Leave a comment
Log in with itch.io to leave a comment.