Smoke Simulation banner

Smoke Simulation

56 devlogs
171h 24m 5s

3D & 2D Realistic Smoke Simulation in C & OpenGL4.6 running entirely on the GPU.
Solving poisson’s equation with a multigrid V cycle solver

This project uses AI

AI was mainly used to understand physics formulas and to better understand how nuklear.h works. Towards the end of the project it also helped with README grammar & readability.

Demo Repository

Loading README...

blob blobbing

Last readme fixes, worked on showcase video. Finally shipping! Loved this project. Even if I spent 170h on it, I feel like I can still add many features and I’ll work on them probably during stardance. I learned OpenGL from zero, how navier stoke’s equation works, the various ways of solving large systems of linear equations, discovered nuklear.h, had to revise structs alignments, memory padding, learned how to use git and how releases work, and for the first time ever made something that can be run and compiled on Linux! Really sad that flavortown already came to an end. Farewell friends

Attachment
0
blob blobbing

Added simulation loading / exporting. Made some presets too, for who will test the app.

Attachment
0
blob blobbing

No way, no way I spent all this time trying to find the issue that made my 2D smoke simulation behave weird when the issue was under my eyes all this time. I did not bind the damn textures before calling init_solid_map. 2 days looking at shaders, changing values trying to figure out whats wrong, to figure out the same exact issue that sent me tripping when I was just starting 3d implementation came back when I reimplemented 2d grid. What an overlook.. Proper vortex shedding in a wind tunnel in the attached picture

Attachment
0
blob blobbing

Can finally be compiled on linux! Got build instructions written

Attachment
0
blob blobbing

Worked on the readme, logo, fixed a few more issues with UBOs / SSBOs (data to gpu upload).

Attachment
0
blob blobbing

Worked on nk styles! I would say the new style is way clearer, can finally understand when checkbox is on or off

Attachment
Attachment
Attachment
Attachment
0
blob blobbing

General bug fixes (grid creation screen using menu grid smoke buffer leading to menu’s smoke being shown in the creation grid, grid size data not being uploaded while being changed in creation screen, wind on the y axis being applied twice) + added quit button as it was missing before.

0
blob blobbing

2d grid can now have grid lines drawn. Found a strange bug where smoke manages to escape the grid even if its enclosed on big enough grids. Probably some restriction shader issue I will investigate tomorrow (too late today gotta sleep)

Attachment
0
blob blobbing

Took less than expected to fix. Still seeing some strange upwards drift in my smoke tho. Gotta figure that one out. Also fixed emitter delete button creating new emitters, reduced MAX_GRID_SIZE to 2^16 before someone kills his pc using this when it will be done, and added some more explicit casts in my shaders.

Attached images show vortex shedding with: only smoke drawn, velocities drawn, vorticity drawn.
Will now write the grid lines shader and at that point I should be done with 2D related code and go back to general fixes + nuklear.h styling

Attachment
Attachment
Attachment
0
blob blobbing

2D vorticity shader made! I think I spotted an issue with all shaders by coding it, but I do not really know. And I have no idea on how to find out if it’s actually an issue but I guess i’ll fix it everywhere

Pretty much every advection shader has something on the lines of:

ivec2 var;

vec2 result = vec2(var + 0.5f)

but I only now noticed that var + 0.5f might result in var as I do not know if glsl promotes var to vec2. And I am pretty sure it doesn’t. Well.. good thing I noticed now I guess

Attachment
0
blob blobbing

Started working on draw velocities shader and damn does it look goofy. I should add an option to draw the velocities every x cells otherwise it’s a mess, specially on high risolution grids where at best cases every pixel is a cell

Attachment
0
blob blobbing

Thats better. Man is coding with the refractored and rewritten files so much easier now, all the mess i had before is gone and adding new code requires way less changes through all the codebase.

Removed Z direction in emitter, obstacles settings when 2D grid is being simulated.
Fixed 2d grid smoke drawing

Attachment
0
blob blobbing

Started working again on 2D grid. Damn is it not going well.
Smoke drawing shader is not working at all. But the physics look kinda right so that gives me hope…
Will have to fix GUI so it doesn’t show Z options in 2d grids.

Attachment
0
blob blobbing

What a rabbit hole of alignment issues I fell into.. My 3d simulation was not working anymore as I moved in the UBO cell_size as last member after struct physics_settings. Apparently, in C, when a variable is declared in a struct with explicit alignment like “attribute((aligned(16))) typedef…” (which cglm apparently does with vec4. or does something similar that messes up alignment) the compiler adds TAIL padding to the struct so it follows that alignment! My struct was previously 40 bytes, so the compiler was padding with 8 bytes to get into a multiple of 16. That, I did not know. I knew about padding / aligment in cases like char-char-float but not tail padding after explicit alignment. Obviously it completely messed up my data uploads to the GPU. thats now fixed and i learned something new about C!

Well grid rendering and simulation is now working again and my last 3 devblogs code refractors now allow for me to start coding 2d grid logic!

Attachment
0
blob blobbing

Finished rewriting the last mess files: window.c & window.h
Finally created a repository.
Fixed the damn grid not being drawn! Now it’s being drawn but pressure solve is having some very apparent issues as can be seen from the devblog image.. gotta find out why thats happening now. At least the code compiles. Not sure if I preferred some compiler error as that would have been more straightforward to fix than whatever I have to handle now

Attachment
0
blob blobbing

Rewrote the absolute mess that the 1000 lines grid.c file was into 11 smaller files to allow for 2d and 3d grid creation ( grid.c became physics.c & .h, grid.c & .h, grid2d.c & .h, grid3d.c & .h, obstacles.c & .h, emitters.c & .h, opengl_bindings.h). Now of course the grid is not being drawn as graphics3d code is the second absolute mess that has to be fixed and ported to allow both 2d and 3d grid drawing. The third absolute mess of a file I will fix for last will be window.c. It was fun to resolve the 400+ errors that arose by moving stuff around :(

Attachment
0
blob blobbing

Added the possibility to make emitters emit with a delay. Add two obstacles to shape your smoke some more, make your smoke purple and it looks beautiful!

0
blob blobbing

Could only free cam or auto orbit before. Now can freely orbit around grid. Wonder if I have the time to port it all back to 2d (kinda funny that it started as a 2d smoke sim and i now have to port to 2d..) as schoolwork is piling up and time is running out

0
blob blobbing

Of course it didn’t work! I completely forgot to update the textures after my grid size was changed.
Now works beautifully :)

Attachment
0
blob blobbing

main menu grid creation works! Looks awful, and smoke advection bugs out when grid size is not the same for all 3 axis (why???) but the rest works well. Will try to find out why that’s happening now.. thought I took care of that like 10 devblogs ago

0
blob blobbing

Well of course heap was getting corrupted i forgot to remove obstacles malloc after setting obstacles num to 0… thats fixed. And the grid was never getting rendered wrongly: it was me forgetting to upload multigrid constants so the solver had no data to work with. Found a new rendering issue tho, depth texture is probably being sampled wrong. Will work on fixing that now.

Attachment
0
blob blobbing

8 hour of work for: not so working smoke render (why does it render it so badly..), heap corruption at window close, sometimes heap corruption at window open and lastly heap corruption sometimes in the middle of the main menu screen.

But at least I’ve got animations down for the new / load sim buttons!
Will work on finding out whats causing heap corruption first, then I’ll fix whatever is causing the smoke render to be completely off and lastly I’ll work on getting my smoke sim logo or something in the topleft of the screen as that space is pretty empty right now

0
blob blobbing

Started working on the main menu using nuklear.h and quickly realised it’s limitations. Wrote custom text renderer and managed to get it to display some text. Can now go back to working on the main menu, this time from scratch without relying on nuklear and leaving nuklear for whatever follows main menu

Attachment
0
blob blobbing

Got wind working! Encountered way more issues than expected allowing the smoke to flow out of the grid. Next step is gonna be a main menu (even simple one) so I can start building out of that. Many variables in my code are currently hard coded values the user cannot change in the middle of the simulation, so they will go into the main menu

Attachment
0
blob blobbing

Can create and delete obstacles and emitters during the simulation now! While working on it I realised two things: I can make the gui way prettier if I play around with nk_styles and it would be cool to have a way to save / load emitter & obstacle positions. But for the second one, I think I will first have to work on the main menu etc.

Attachment
0
blob blobbing

Tried implementing a spatial hash map and realised how impractical it is with the variying obstacles sizes and other issues, so I decided to see how much performance I can squeeze out by optimizing my already existing shaders with shared memory. That worked out fantastically.

Started working on the emitters and obstacles GUI. Very rudimentary for now, doesn’t allow for deleting / creating new emitters or obstacles. That’s what im gonna work on next.

Attachment
0
blob blobbing

Fixed a vorticity issue that has been bugging me for a while and fixed all the graphical issues that arised with allowing different grid sizes on different axis. With many objects the performance drops are pretty bad, I should implement a spatial grid for the solid objects, so thats what im probably gonna work on next!

Attachment
Attachment
0
blob blobbing

Cleaned up the multigrid implementation and it works wonderfully! Also had to rework a good amount of physics and graphics code due to it not allowing the user to set a non cubic non power of 2 grid (192x100x50 would not have been allowed before for example, only 128x128x128 or 256x256x256 etc)

In the image a 128x1024x128 grid!

Tried working on the ray marcher and investigating more of the pbr world but got only a boring and flattened smoke. Probably messed up formulas, will work on other issues now: velocities draw shader, grid lines shader and objects shader still expect an uniform grid, so they end up being squished. Biggest issue for now is the objects shader doing that: I want objects! and I cannot have them because it’s drawing them based on an uniform grid

Attachment
1

Comments

tunnor
tunnor about 1 month ago

Project looks awesome! I can’t even imagine the math required to simulate this…

blob blobbing

Quickly implemented multigrid (so as you can guess the code looks horrible) after uni entrance test with cooked mind (fixing code tomorrow will make me cry) (i am gonna have nightmares tonight) and a 256x256x256 grid runs as good as a 128x128x128 grid with old code.. which is surprising! Take into account that the 256^3 grid is not double the old one it’s way more than that! 16.777.216 (256^3) against 2.097.152 (128^3)!

Pretty surprising performance jump taking into consideration that it was badly implemented.

For now it only works with powers of 2 and with a grid of same size in all axis. Will work onto fixing that issue in the next week. Enjoy a 256x256x256 smoke in the attached image (that would have taken ages before)

Attachment
0
blob blobbing

Was distracted by school these days. Not much changed output wise: Settings got cleaned up, resizing the window actually works now (before it would break as framebuffer would not be updated) and objects can now be hidden.

The next additions should be:
a GUI to spawn / edit / move emitters
a GUI to spawn /edit / move objects
multigrid solver

I do not want, at all, to work on GUIs anymore for at least a week. Because it should not affect too much most of the code I’ll work on the multigrid solver (or at least start working on it) so I can double the current grid size without falling into horrible fps values (Right now a 64^3 grid can be displayed flawlessly at circa 180 fps, which is not bad at all. Move to 128^3 and it drops to 30 fps. 30 fps.. with a timestep of 1/120 thats 4 seconds for 1 in-simulation second. Thats not real time)

Attachment
0
blob blobbing

got it working and not breaking my ray marcher. Now gotta make it actually send the new data to the gpu whenever it updates, and gotta make the code more readable. Right now it’s just nuklear calls filling up my main.c

Attachment
0
blob blobbing

Not a lot of cooperation between smoke sim and nuklear :/
I gotta figure out what else is nuklear changing that is breaking my ray marcher

Attachment
0
blob blobbing

cleaned up code and smoke is now affected by the solid objects! In the picture balls fell into the center of emitters so they displaced the smoke around!

Attachment
0
blob blobbing

there’s solid objects and they move now. 2 main problems:

  1. the code looks horrible. I wanted to finish implementing them before going to sleep so you can guess how much “ill fix that later” pieces of code are sitting around the various code files.
  2. the smoke is not really affected by them. It doesn’t move into them but they dont displace the already present smoke with their movement.

I will first work on fixing the first issue as I dont want more confusion in my already confusion-full project and then work onto the second issue.

Attachment
0
blob blobbing

Came back from school trip. Added emitters, cleaned up a lot of code, made everything togglable (right now with keybinds, will later move to ImGUI).

Not many visual updates. Emitters with advect_smoke turned off in picture.

Attachment
0
blob blobbing

Smoke can now be colored! Should make creating emitters easier and should implement wind now

Attachment
0
blob blobbing

actually improved ray marching :) damn does it look good

Attachment
0
blob blobbing

Cleaned up the code, realised vorticity confinement has some bug that leads velocites to explode after a while :/ they don’t explode for the first 10 seconds or so tho so it kinda works there? That will be something I’ll fix after school trip.. it’s headache inducing…

Attachment
0
blob blobbing

No way I just spent an hour looking at all shaders code, trying to understand whats wrong ,double checking math just to realise I was not binding the damn buffers on the gpu before initializing solid map.. how did I not notice from the start.. in the pic velocities are finally properly contained in the grid.. wow what an overlook

Attachment
0
blob blobbing

Ugh.. while working on vorticity confinement i noticed my damn velocities are slipping into solid cells. no idea where this is happening but its making smoke escape..

Attachment
0
blob blobbing

Temperature introduced! now onto vorticity confinement, afterwards i can finally work on tidying code up, adding external forces and making my smoke more smokey

Attachment
0
blob blobbing

Implemented some rudimentary ray marching. I hate pretty much everything about it, how flat it looks, how SAD it looks, but its fine as for now I just need to be able to see what my smoke is doing.. Will work on buoyancy and then I should be done with most of 2d -> 3d port, allowing me to work on a more exciting way to visualize this smoke..

Attachment
0
blob blobbing

finally managed to draw some kind of arrows ( i hate them, but they do their job quite fantastically for debugging purpouses ). Without them i would not have been able to get advection working.. at all. In the attached photo, properly advected +10.0f velocity at P(2,4,4) (grid size: 9^3)

Attachment
1

Comments

YourLocalSatyrFlip
YourLocalSatyrFlip about 2 months ago

SO COOL!

blob blobbing

Well the grid looks good.. time to move into coding the smoke..

Attachment
0
blob blobbing

slowly transitioning to 3d.. got the axis drawn! well, more importantly, started implementing the camera system and everything that could be completely ignored in 2d.

Attachment
0
blob blobbing

Cleaned up some code. Kind of happy with how my smoke behaves. Will now move to 3D! this is gonna be painful and im gonna regret this.. will backup all files because I know many things will break :/
Don’t even know where to start with visualization

Attachment
0
blob blobbing

temperature introduced! cold smoke falls, hot smoke rises!
as always it initially broke everything! had some issues with buffer swapping functions

Attachment
0
blob blobbing

it finally works on the gpu… man did it make me lose my mind… I was sampling incorrectly as i didnt realise how opengl’s texture() works.

1000x1000 grid. Gpu starts getting hot..

Attachment
0
blob blobbing

10h in im losing my mind. It’s way smoother on the gpu, but my advection program was wrong: it was for whatever reason advecting diagonally (??!!??!!) so I tried to fix it, just to end up with velocities completely disappearing (?!?!?!). Because of that i can’t even show how smooth it was, so this devblog will just be a high resolution grid being drawn…
I liked cuda way more. way more.

Attachment
0
blob blobbing

With velocity advection figured out I finally implemented smoke which is the main point of the simulation. Looks good, and as expected FPS are horrible and we’re still in 2d with an extremerly small resolution. I will start learning about opengl compute shaders now and will port most of the code to those.

I hope they are similar to CUDA ones otherwise this is gonna be rough

Attachment
0
blob blobbing

Arrows are drawn properly and divergence is finally being resolved.. fixed the math issues

Attachment
0
blob blobbing

Working on some arrows, I understood my grid was being drawn incorrectly. It took me 5 whole hours for one of my dumbest mistakes ever.. this was a headache (10x10 grid was drawn as 8x8. Now its properly drawn)

Attachment
0
blob blobbing

Got a way to visualise divergence. Will work on 2d until math works, then Ill port to 3d.

Attachment
0
blob blobbing

Got to transformations, textures. So far enjoying the OpenGL learning experience. Should soon start working on the smoke sim!

Attachment
0
blob blobbing

Got to the rainbow triangle, implemented shader source parser

Attachment
0
blob blobbing

This will be a fun transition from my previous fluid sim project. Decided to drop WinGDI which I previously used as it proved to be painfully slow (I mean, part of the reason I chose wingdi was because I knew it was painfully slow) and CUDA as I want it to be usable on as many platforms as possible (Even if I really enjoyed CUDA programming!). I know NOTHING about openGL so my first project hours will probably be spent on learning opengl. So far? Set it up and got a window running! Good start. As soon as opengl clicks in I will start working on the smoke simulation math. First CPU; then slowly will transition it to GPU.

Attachment
0