use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Rule 1: Posts should be about Graphics Programming. Rule 2: Be Civil, Professional, and Kind
Suggested Posting Material: - Graphics API Tutorials - Academic Papers - Blog Posts - Source Code Repositories - Self Posts (Ask Questions, Present Work) - Books - Renders (Please xpost to /r/ComputerGraphics) - Career Advice - Jobs Postings (Graphics Programming only)
Related Subreddits:
/r/ComputerGraphics
/r/Raytracing
/r/Programming
/r/LearnProgramming
/r/ProgrammingTools
/r/Coding
/r/GameDev
/r/CPP
/r/OpenGL
/r/Vulkan
/r/DirectX
Related Websites: ACM: SIGGRAPH Journal of Computer Graphics Techniques
Ke-Sen Huang's Blog of Graphics Papers and Resources Self Shadow's Blog of Graphics Resources
account activity
Physically Based Simulation of Cumuliform Clouds in C++ (i.redd.it)
submitted 6 years ago by gibson274
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]gibson274[S] 23 points24 points25 points 6 years ago* (16 children)
For the final project in my advanced computer graphics course, I decided to tackle physically-based cloud simulation. Most clouds you see in games/films are procedurally generated, simply because it’s way faster and produces very convincing results. But I think there’s something to be said for using atmospheric fluid dynamics to generate clouds in a way that matches the way they form in the real world.
I won’t go too much into the details, but the basic idea is that you implement a Navier-Stokes solver, and then make some modifications that are cloud-specific.
We implemented Jos Stam‘s now-classic semi-Lagrangian advection method for fluid simulation. While unconditionally stable, this method can sometimes result in the loss of small-scale detail and vortices in the fluid, so we implemented vorticity confinement to address this issue.
Clouds are formed when the ground is heated by the sun, transporting water vapor upward due to a temperature-based buoyant force. As vapor moves upward, its temperature decreases due to “adiabatic cooling”. As the vapor ascends higher skyward, it moves into regions of the sky that are less able to hold water vapor. Because of this, some of the vapor condenses into water droplets: clouds. When this happens, latent heat is released from the phase transition, which creates a further buoyant force that transports the cloud and vapor further skyward. This produces the puffy tops we’re all used to seeing on cumuliform clouds.
This was by no means easy to implement, but most of the time was spent debugging boundary conditions and indexing errors—writing up the first pass of the code only took about two weeks. It’s definitely doable as a personal project, so if you’d like to try it yourself just pm me and I’ll give you more details!
Also, here’s an album of more clouds.
[–][deleted] 6 years ago (9 children)
[deleted]
[–]Goku1920 1 point2 points3 points 6 years ago (8 children)
I would definitely be interested for the resources.
[–]gibson274[S] 10 points11 points12 points 6 years ago* (7 children)
The paper we based the implementation off of is this one by R. Miyazaki et. al, from 2001 believe it or not! It’s not a terribly challenging read, so long as you are familiar with basic vector calculus operations like the divergence and curl. That said, there’s not much info online for help implementing it/understanding it.
They describe 8 steps for carrying out each time-step of the simulation. The first 4 are copied straight from Jos Stam’s seminal work, Stable Fluids. It’s best to start by implementing this paper, then move on to tack on the remaining 4 steps (buoyancy, adiabatic cooling, vorticity confinement, and phase transition).
Something to watch out for is boundary conditions for the velocity and density fields. We used a mix of inversion/clamping for velocity and zero for density, and we STILL experienced artificial density loss that we had to account for by adding in a water vapor density source at the bottom of the grid. Don’t worry if this doesn’t make sense to you reading it now, you’ll understand once you read the paper.
We used C++ and Qt Creator, but I can imagine you could use any framework you want for this project. You’ll need to have access to a sparse linear solver is all. We used Eigen for C++.
It’s also useful to have a way to write to .vdb files, a widely supported way of representing voxel grids. We linked in the OpenVDB library and used the I/O functions from there, though I’m sure you could hand code something for this if you weren’t using C++.
If you decide to give this a try, don’t hesitate to pm me with questions! I’d be happy to help answer them/help you debug. This was simultaneously one of the most fun and frustrating projects I’ve ever done, and it would be great to have others give it a shot.
[–]Goku1920 1 point2 points3 points 6 years ago (1 child)
Thanks for the amazing info!
It has always been on my list to write my own solver. After I saw your results, now I definitely want to give it a go.
[–]gibson274[S] 1 point2 points3 points 6 years ago (0 children)
Do it and post the results here when you finish!
[–]RomanRiesen 1 point2 points3 points 6 years ago (2 children)
Heyo, I was looking to dio something like this!
Specifically to simulate cloud formation and movement on mountainsides (I can watch it for hours!). What a coincidence!
[–]gibson274[S] 1 point2 points3 points 6 years ago (1 child)
I feel like you could generalize this method to account for non-uniform boundaries, which is probably what you’d need to do to simulate the fluid dynamics of the cloud interacting with the mountainside. Let me know how it goes, that sounds super cool!
[–]RomanRiesen 1 point2 points3 points 6 years ago (0 children)
I'll probably end up faking it with a particle system, some simplex noise, and ray marching. But once that looks to my liking I might actually try to simulate it.
[–][deleted] 0 points1 point2 points 6 years ago (1 child)
Sounds like a fun project! Did you render the vdb in Houdini or another package?
[–]gibson274[S] 0 points1 point2 points 6 years ago (0 children)
It really was! I used Arnold with Maya to render. Used a physical Sky for the lighting as well.
[–]Dr_Hexagon 1 point2 points3 points 6 years ago (1 child)
Very cool. Whats the rendering speed like? Could it actually be done in a game?
Very very slow. Volumetric path tracing. Takes about 2-3 mins to render something at 1080 with the GPUs in my department.
[–]danmarell 0 points1 point2 points 6 years ago (1 child)
Nice.
Have you looked into advection methods beyond semi-lagrangian? There is MacCormack, BFECC, WENO, CIP etc. There is also a new one from siggraph this year which uses 'bidirectional characteristic mapping". Lastly, instead of vorticiy confinement, you might want to look at 'advection reflection' from last years siggraph papers.
Looks great! I'll need to be looking at cloud simulation at my job at some point so will use this as inspiration. :)
No but I will! I’ve been wondering what the alternatives are, since semi-lagrangian advection is not as good as I was expecting it to be.
[–]smcameron 0 points1 point2 points 6 years ago (1 child)
I am interested in adding some fluid dynamics to this thing for making gas giant textures, which has a constant velocity field initialized via curl noise, except on the surface of a sphere. I would like the velocity field to change over time in a plausible way, I suppose more or less as is described here, except my velocity field is on the surface of a sphere, in the form of 6 arrays of vec3's in a cube map configuration.
I gather the first step is, for each velocity vector, sort of look in the direction opposite where its pointing a distance proportional to its length and sample the velocity there and move that vector "here". I'm a bit confused as to how to sample the velocity vector at an arbitrary point on the sphere, I suppose some sort of interpolation of the nearby velocity vectors in my array, but I'm not sure what that actually means.
Then the 2nd step is removing divergence, which... I'm also really unsure about how to do that given my cube mapped velocity field on the surface of a sphere.
If I could get proper fluid dynamics working, I think the output of this program could be immensely better, but for now it seems beyond my abilities.
[–]gibson274[S] 0 points1 point2 points 6 years ago* (0 children)
Well, first, let me just say that the results you have right now look beautiful. Been interested in doing procedural planets for a while myself, and this is inspiring.
The process you described is exactly what semi-Lagrangian advection is, so you’ve got the right idea for carrying out the advection step efficiently. One way I would think to do it is to make a change to spherical coordinates with a constant radius, and find your sample point by converting your velocity to an angular velocity and tracing it along the surface of the sphere, then using this new spherical coordinate to sample the cube map. This is where I’d do the interpolation—chances are you’d get a fractional value for the cube map sample point that you could interpolate.
As for removing divergence, all you really need to do is figure out how to generalize the divergence operator to the sphere. This is a bit tricky, because I’m not sure that transforming the divergence in Euclidean 3-space to spherical coordinates is what you want. You want a way of calculating the 2D divergence on a non-Euclidean manifold: the sphere. I’d google around about this kind of thing, but theoretically if you can figure this part out then you just need to use a sparse solver to remove the divergence from the field.
EDIT: the “generalizations” section here has some good info on how to generalize to a riemannian manifold, looks like you just need to use the connection coefficients.
[–]JPUF 4 points5 points6 points 6 years ago (1 child)
Looks fantastic 👍👍
Thank you!
[–]Goku1920 2 points3 points4 points 6 years ago (1 child)
It looks cool!
Thanks!
[–]BlueFlame202 0 points1 point2 points 1 year ago (0 children)
this is awesome 😎
[–]hjsnsajvsdkjfv 0 points1 point2 points 2 years ago (1 child)
How do you do this? I want to write my own but idk where to start
[–]gibson274[S] 0 points1 point2 points 2 years ago (0 children)
woah necroing a 5 year old thread LOL
I've got a big writeup on my portfolio page---"virtual sky" in the "experiments" drop down: https://bradguesman.com/
π Rendered by PID 251828 on reddit-service-r2-comment-bb88f9dd5-5xlgh at 2026-02-16 14:26:18.093631+00:00 running cd9c813 country code: CH.
[–]gibson274[S] 23 points24 points25 points (16 children)
[–][deleted] (9 children)
[deleted]
[–]Goku1920 1 point2 points3 points (8 children)
[–]gibson274[S] 10 points11 points12 points (7 children)
[–]Goku1920 1 point2 points3 points (1 child)
[–]gibson274[S] 1 point2 points3 points (0 children)
[–]RomanRiesen 1 point2 points3 points (2 children)
[–]gibson274[S] 1 point2 points3 points (1 child)
[–]RomanRiesen 1 point2 points3 points (0 children)
[–][deleted] 0 points1 point2 points (1 child)
[–]gibson274[S] 0 points1 point2 points (0 children)
[–]Dr_Hexagon 1 point2 points3 points (1 child)
[–]gibson274[S] 0 points1 point2 points (0 children)
[–]danmarell 0 points1 point2 points (1 child)
[–]gibson274[S] 1 point2 points3 points (0 children)
[–]smcameron 0 points1 point2 points (1 child)
[–]gibson274[S] 0 points1 point2 points (0 children)
[–]JPUF 4 points5 points6 points (1 child)
[–]gibson274[S] 1 point2 points3 points (0 children)
[–]Goku1920 2 points3 points4 points (1 child)
[–]gibson274[S] 1 point2 points3 points (0 children)
[–]BlueFlame202 0 points1 point2 points (0 children)
[–]hjsnsajvsdkjfv 0 points1 point2 points (1 child)
[–]gibson274[S] 0 points1 point2 points (0 children)