字幕表 動画を再生する 英語字幕をプリント (whistle whistles) - Hello and welcome to a Coding Challenge, a calm, soothing, although somewhat turbulent, Coding Challenge, called Fluid Simulation. Now I have something to admit to you. I don't really understand how any of this stuff works. I did make this at one point, and so I'm hoping this Coding Challenge to recreate exactly this, which will be a basis on which hopefully a lot of other interesting ideas will come about. This idea came into mind when I recently saw Smarter Every Day's video on laminar flow. You know, I love laminar flow and all, but Team Turbulence for life, muah. Alright, so there's a wonderful 3Blue1Brown, do I just reference the same other YouTube channels every single time? Yes, I do. But there's also an excellent 3Blue1Brown video on turbulence, which I would also recommend. So, let me give you some background here. So first of all, there is a GitHub issue thread which started by deardanielxd, from 2016. Lattice Boltzmann methods for fluid simulations. So this is one method. But what I want to highlight here is that this, people have, oh, what I want to highlight here are these three links. So these seminal kind of canonical standard, or the origins of doing fluid dynamics in computer graphics in my research comes from this article by Jos Stam. Real-Time Fluid Dynamics for Games. I believe this was a Siggraph paper, 2003. Somebody fact check me on that. And it's built on top of this idea of these Navier-Stokes Equations, which are partial differential equations that describe fluid dynamics and there was actually a $1 million challenge for proving that this can or cannot be solved in three dimensions. None of this is anything I'm capable of doing. But this paper includes some of the formulas, includes a lot of the code, and you can see one thing that's sort of key concept here is a fluid simulation can be done by thinking about fluid as kind of particles that live in a grid. And obviously it might be like an infinitely small grid (laughs) in real life, but we can make that discrete. Think about the grid of pixels and what the sort of density or the velocity of the fluid is at every one of these spots on the grid, that's ultimately what I'm going to do. And there's some nice C code and descriptions of some of these algorithms. So, this article I believe serves as the basis for Memo Atken's processing library, called MSAFluid, and is also an open frameworks library, which is a C++ engine. And you can see here the way that this ends up looking by sort of distorting this vector field, ah, this is awesome. Oh, I'm sure the YouTube compression is totally ruining this. But it's beautiful, check out that library. You should also check out Gabriel Weymouth's, I hope I pronounced that correctly, LilyPad project, which was actually I believe used in the 3Blue1Brown video on turbulence. Gabriel writes here at the end a bunch of things about Stan's approach, and what LilyPad does and a paper. So this is a giant rabbit hole you could go down. And I have spent some time poking around in this rabbit hole in the last week. The article that I found that I kind of enjoyed the most in terms of style was Mike Ash's article called Fluid Simulation for Dummies, which is actually a port, not a port, but a version of Jos Stam's paper, but actually turning it into 3-D and how to render that 3-D with paralyzing computing power is all here in his master's thesis. That's another rabbit hole you could go down. So what I would like to do is use this article, and I try to make sure that I don't repurpose somebody else's content without permission, even if it's sort of on the web in an open-source way. What I try to do, what I want to do, I asked Mike Ash for permission on Twitter. I think it's @MikeAsh, but I'll include a link in this video's description, if I could go through this in a video. So what I'm going to do is I'm going to go through this in the video and mostly just kind of like copy-paste this code, which is written, I believe, C++ or C. Something like that, some object-oriented C-flavor language. And I'm going to copy-paste it into Processing, which is a Java-based programming environment. And kind of like adjust the code to work in the way that I know and see if I can get the result and play with the result. So I don't feel obligated to understand or explain all of the maths involved throughout all this. And I would definitely encourage you to read this, I would entirely stop and read this whole article before you continue watching this. And then, this is going to be in three parts at a minimum. So this first part, I hope you just like get it working. Just want to copy-paste the code, change the syntax around, get it rendering, and play with it. Number two is I want to kind of refactor the code, this'll be in another video. I'm actually going to refactor it in a more kind of modern approach, I think modern's the wrong word, I mean this was done over 10 years ago. But I want to use like object-oriented programming, vector, like the PVector class in processing, I think there're some ways that I can redo the code to make it a little bit more readable than this particular style that uses a lot of esoteric variable meaning. So that's number two, and then number three, I want to then apply this logic to my, my flow field example from the Nature of Code book. So if I could take the fluid simulation, turn it into a vector field, I can just toss particles in that fly around. I think some visual opportunities will come of that. So that's three part. Just get the thing working, that's what I'm about to attempt to do right now, I'm sure it will go wrong. (laughs) But I will try my best. Number two, refactor the code to make it sort of fit with how I think about coding and processing in P5GS today. And then also, try to do some more stuff with it visually. And I would say one of the things is, there's going to be some performance issues, I'm going to keep things low-resolution. But you'll see a lot of the implementations of this, use shaders or webGL, all sorts of fancy tricks that I'm not going to get into, but if you know about that stuff and can build on top of whatever I'm doing, then fantastic. Alright, so I'm about to get started coding, but before I do that, I've written in advance a bunch of the concepts that are involved in this implementation that I want to make sure that I don't forget to mention. The first one that I think is really important is this idea of an incompressible fluid. An incompressible fluid is a fluid that density must remain constant throughout, like water. So for example if you have water in a balloon, and you squeeze that balloon, the water's got to like come out, it's not compressible, whereas air is actually compressible, its density can change. So this, apparently, from the little research that I've done, simplifies a lot of the stuff. So this fluid simulation is going to work only for this idea of an incompressible fluid. I should also mention that the goal here is not necessarily to with scientific accuracy simulate true fluid mechanics, but rather to create the illusion and feeling of that through some remote connection to that actual scientific accuracy. And I'm sure whatever I do will be less accurate than what people before, based on how I know the way I make things. Alright, but that's an important thing. So the first thing that we need to consider is that the fluid is going to live inside of a box. And I think, the way the math is sort of tuned in these examples I believe is so that this box should really be a square. And sometimes, I don't know why, like a power of two is maybe a nice thing. So maybe I'll start with 512 by 512 or maybe 256 by 256 just to make it low resolution. So you can think of this as a grid of pixels. And there is going to be inside of this grid a velocity vector. A velocity vector that points in a given direction. So if the velocity vector in every spot in the grid is zero, it's like completely still water. If I put a velocity vector moving to the right, it's like the water, that would be like Laminar Flow, by the way. Because the velocity, everything is smooth and perfect and all moving in exactly the same direction, as opposed to turbulence where everything's kind of going crazy. So that's one thing that's going to exist in here. So that is something I should say, there is this idea of the velocity field, or the vector field. And that's going to have Xs and Ys. In Mike Ash's blog post, it's actually all done in 3-D (laughs) with X, Ys, and Zs, and I'm going to take out that third dimension while I'm doing it. But you should add it back in and see what happens there. Now, the other thing is there's going to be this idea of dye. Oh, I wrote this over here already, 'cause I wanted to explain that. There's this idea of dye. And we're going to talk about the density of the dye, which is, in other words, this vector field, we wouldn't be able to see anything moving, we wouldn't be able to under see the flow through the fluid without like putting something in it. So you could imagine sprinkling a little dye in it and having it diffuse, maybe advect, diffuse, advect, project, all around the fluid. But what I want to make clear is when we start talking about density in this code example, and this Mike Ash makes very specific, makes a very specific point about. When we're talking about the density of this dye, which is like an extra thing we're adding, just so we can visualize it. We're also able to visualize it just as a vector field, which I will do at some point, but the dye is what's going to give it more this like smoky-like quality by visualizing the amount of dye as it moves throughout the fluid. So this is the basic idea. So the first thing I need to do is get an array to store all of the Xs and Ys of the vector field and the amount of dye, for every single one of these spots. And in the example, it's done with three separate arrays, an array of Xs, an arrays of Ys, an arrays of densities, and it kind of works like a cellular automata simulation, where I need the previous state and the next state, all the velocity of the previous and the next velocity, all the density and the next density. So I'm actually going to need two. So this is why the code gets really confusing, because I need x, Y, and density, then I need what's named as x zero, Y zero, and density zero. I forget, this might be called like S or something in the code, but I need the sort of previous of all of these. So there's a whole bunch of arrays. And this is what I want to later refactor it and see if I can just use Pvector, an object that stores a PVector and a density value in the previous, all that stuff. Alright, let's go back to Mike Ash's page. And I'm going to start with this. This is what I was talking about. So this C++ structure, I'm going to take it into processing. I'm going to add setup.