 All right. The final talk in this session is Flux to Animation Boundary Method by Alexis Tomahin and Andrew Selle. Alexei will be giving the talk. All right. Thanks for the intro. My name is Alexei, and I'll be presenting this paper about Flux to Animated Boundary Method, which we wrote with Andy Selle at World D's Animation Studios. So I want to start with saying that, you know, that method kind of went, I guess, closely related to the movie production of the movie Moana, we used it to create full shots such as this one. All right. So when we started on this movie, we knew we were going to have a lot of water. So we started with writing our own physical-based water simulator. It's really similar to what Houdini Flip does with some advanced models on top of that, but basically the idea is the same. We have the Navi Stokes equation, which we discretized using particles. We'll get this physical-based solver, and as long as the input is physical, we can guarantee some realistic physical high-quality output. Now the problem is that directors oftentimes don't care about real life. The term we like to use the studio's believability. Sometimes that's borderline with magical kind of stuff you see on the left. And there's quite a big gap between physical-based simulation and our directed result. There are multiple methods you could use to control a simulation. I roughly classed five and three categories. There are obviously more methods. But the main criterion to distinguish the bias is basically how aggressive they are. So the most aggressive one is velocity override. We basically take a simulation of a frame and try to override the velocities with some predefined ones. Animators like to do that a lot because they have full control of fluid simulation, but it kind of defeats the purpose of the simulation itself because it pretty much end up animating the whole thing. Then we can take a little bit of software approach. We can use volumetric forces, meaning instead of enforcing velocities on particles, exactly we introduce some force fields which have some lag defect. Basically, you know, through inertia, you have a little bit more believable behavior. So it's more on the physics side, less in our direction. And finally, the approach we're actually interested in is using boundary conditions. So the previous two methods are really volume based. So you control the particle volume. Boundary conditions are more sparse, more sparse control mechanism. We just use the boundary to facilitate, you know, certain behavior that we want. And we believe that instead of controlling, kind of post-fixing the simulation that you see, so imagine you ran the same, you're not happy with the results, you try to fix it. We think that's probably not the best way to do it. Better ways to understand what went wrong and try to fix the boundary conditions so that the simulation works fine out of the box. And I just want to say, really, we're inspired by this paper by Nielsen Brisson from 2011 because they use boundary condition approach to oppress simulation, use low resolution, simulation to drive high resolution simulation. So that was really inspiring for us. And I also want to give a shout out to the talk that happened this morning. Bifrost team gave an overview of their boat wake pipeline. And it was interesting to hear some ideas of how they came from this paper and the development they did. All right, so back to the problem we want to solve. So we had to do a lot of boats or canoes traveling throughout the Pacific Ocean. And the ocean's big. There is no hope of simulating the whole thing. And also we wanted to have certain character of the ocean. We want to be able to control the shape of the waves. It makes an art direction problem. Basically, we have the whole big ocean that's specified by, say, layout department. And then we would like to simulate, to run the simulation next to the boats and the vicinity of the boats and make sure the simulation matches the character of the ocean. That is a sort of a particular case over a more general problem where we have, say, the whole world filled with some substance, something that kind of moves around, maybe obeying some physical laws or maybe has some procedural character to it. And then there's a character traveling through that world. And you'd like to have a localized simulation just around the character. So to run the same on the vicinity of the character and then impose the boundary conditions in such a way that the simulation matches the outside procedural specified world. So getting back to the boat, let's consider a simple example of a boat traveling on a flat ocean, flat, let's say, lake surface. So the boat moves. The lake is big. We don't want to simulate the whole thing. So we try to localize the simulation to some area just around the boat. So how would we do that? A sort of a simple naive approach would be to say, well, let's put a collision object in there. So sort of create this bathtub around the boat that would be traveling with it through the ocean and the water will be splashing inside of it. But if you think about it, so the boat moves, the collision object moves and that collision object would push in the fluid creating a moving water that would be going in the direction left. And that's not what we want. We want the water to be static and the boat actually be moving through that water creating a boatwake. So this is really what we want. So instead of a collision object, we would like to introduce this primitive called fluid boundary. So the idea here is the following. We would really like to decouple the two concepts that are involved in the setup. We would like to be able to distinguish between the moving shape of the window or the window similar to run to run and kind of realize that there is a separate entity, the static material that's in those two separate things and they're not necessarily should be mixed. So to kind of better explain what I mean here, let's consider the following example. So if we have the velocity of the wind or the velocity of the material matching, so the shape allows to measure the material velocity, we'll get that example I just talked about. We have a bathtub moving and the whole fluid moves with it. But you don't necessarily have to have them the same. So the shape velocity can be non-zero with material velocity being zero. And you get an example in the middle where the window moves through the static water. Where it can go more crazy and have them perpendicular to each other or have some different combination. To give examples of that, say here we have shape velocity matching the material velocity so we have a pure collision object moving through the scene. You can have shape being static and material moving which gives you a source. Then the shape could move and material can be static but that's not the kind of source where the fluid gets left behind with zero velocity. Or you can combine a combination of those. So one thing I want to point out here is that concept is not really new. Back in the day where particle level sets and Eulerian techniques were more popular, there was a natural way to impose boundary condition to create sinks and sources. But with more, say modern, I guess, flat approaches with particle-based solutions, that technique sort of got forgotten in favor of more particle-based ways of controlling simulations. So R is a more, prefer particle-based control mechanism. So in order to create a source, for example, they would throw a particle in the system. If you want to delete the fluid, they would just delete the particles. So that's a really simple control mechanism but that sort of downplays the effect of the boundary condition. So that got lost and we're looking forward to bringing that back into a flip simulation. So in order to do that, let's look at the flip solver. So in flip solver, particle is a primary representation. And then a simulation step consists of the following stages. The particles get rasterized to the grid. Then we perform a boundary value solve on the velocity field. We fix the velocity with a projection or if it's not a fluid, it could be an MPM or any other, you know, hybrid or larynal grunge and kind of solver. We perform the boundary solve as well. And we interpolate the result back on the particles. And then the particles get affected. Now, if you want to introduce some collision objects in the scene, you typically will start with some mesh. And then you would rasterize that mesh onto something volumetric that's understandable by the volumetric part of the solver. And that goes into the boundary value solve. So the way it affects the boundary value solve is the following. So typically we have some re-enoccupy with the fluid. Then the shape of the collision object would dictate whether the boundary condition can get enforced. And the boundary conditions themselves are determined by the velocity of that collision object. Finally, if you want to insert particles and remove them, you would perform a material set update step. So what, how do we, how do we integrate the flux-animated boundaries in our solver? Basically it happens right here. So instead of collision object, you would, you would put the flux-animated boundary in there. And the only difference is that instead of having one velocity field, you would have two velocity fields, you would have separate mesh shape and a material velocity. The only, there are two steps of the solver that gets affected. One is the boundary value solve, where instead of, I'm sorry, so you would use the shape of the, of the collision of the fab to still like, to still determine where the, where the boundary condition needs to get enforced. But instead of the velocity of, of that shape, you would use a material velocity. And also, the, the fab affects the material set update. We don't just want to throw particles and assist, we want to make sure that happens in the volumetric flux. So let me explain how that's done. So imagine here we have a container, the purple, in purple I'm showing the, the flux-animated boundary, which is a window moving through presumably the ocean that's showing blue, and we have the simulation particles. Now, assume we already did the whole projection step, so the flow is divergent free, now we need to move everything, we want to advect the flux-animated boundary, we want to advect the particles. And we also want to perform the necessary seeding. So what we do is, is perform the seeding in a thin layer of the, of the flux-animated boundary. We use VDBs to represent it, we don't have to see the whole volum, we just see the thin, in the boundary. That, that's good for performance reasons, and typically, you know, the CFL condition helps with, with determining the thickness of that layer. Then the shape of the object gets moved, and also we advect the particles. And finally, we will look at which particles are inside the object outside, and we'll leave all the ones that are inside. So that's how the seeding is performed. It was, it was interesting, so once we, once we implemented that technique, artists immediately put it to good use, they never cease to surprise us. There was this character in the, in the movie, the, the ocean. It was, it was actually a living creature. It kind of had a shape looking like that. And one of the artists took that shape as the, as the shape for the, for the simulator, and he painted those curves on top of the, on top of the shape, and rasterized it to a volume, creating the material velocity field. And that's the kind of same he was able to achieve for straight out of the box. So that was, that was pretty impressive. And also the same, same, but matched. And by the way, that image that I showed you at the beginning of the presentation was done with exactly the same technique. So now let's get back to the window simulation, and creating wigs for the canoes. So what we, what we started with is we hand drawn a procedural wave, which is shown in red here. So red line is the procedural, uh, wave train on the ocean surface, which would go all the way out of the horizon. And then we'd use this gray box to specify the window where we'd like to perform a simulation and actually try to recreate, uh, the, that, we, we would like to get a perfect match between our simulation and that red line. Because the boss is not there, so as long as the waves enter the simulated domain, we hope that they will stay, that they will keep the shape. But that didn't happen. And the reason it didn't happen is because, well, first of all, the shape of the procedural ocean was picked pretty randomly. There was some variation in the sine curve, and the material velocity would paint it, uh, I would say pretty randomly. It was kind of based on some intuition, but it was not physically exact. And, you know, with a physically based solvers, if you're not feeding in the physically correct input, you can't expect a physically, uh, plausible output. And of course we could have probably, uh, uh, had, uh, have our artists working on some more, try to, try to fix those velocities to, to make them more, more plausible, so the meshing is better. But it was not practical because we had nearly 400 shots, uh, in the movie with, with canoes on water, so we had to look for a more, um, more principal solution, uh, to that problem. So we went ahead and did some research. Uh, we found that actually an equation describing a motion of a, of a wave train on the ocean, uh, Stokes, uh, figured it out long time ago. Uh, so we basically took that, uh, took that equation, called Stokes wave, uh, Stokes wave train, it has a closed form, uh, expression for it. And if we use that to enforce the, uh, the boundary condition, we get a perfect match between simulation and, uh, procedural animation. Uh, now of course a single Stokes wave is not that interesting. Uh, typically you would like to see something like a deep water spectrum like Tessledorf waves. And, um, all those techniques look really fancy on the, on the outside, there are free transforms involved, but if you look closer, all of those are really just the sum of Stokes waves. So, right out of the box, who are able to get a perfect match between a procedural, uh, deep water spectrum and a simulated result. Uh, one thing I'd like to point out is that if you do want to use a, say, Tessledorf spectrum to, uh, to create a simulation such as that, you need to do extra work for, uh, for computing the velocities and the volume of the fluid. So like I said, um, there is a Fourier transform involved, uh, but you don't want to keep doing the Fourier transform on every single level, um, of your grid because it gets too expensive. Uh, and, uh, you know, the velocity actually decays, uh, downward into the volume of the fluid and has different exponential decal or for different harmonics. So you do have to do Fourier transform multiple times. But it turns out you can do it, you can, uh, take a discrete approach. You can compute, do the Fourier transform and compute those velocities on a few discrete levels, like a zero level and minus one meter and maybe minus two meters, and linear interplay between them. That's not an exact solution, but we found work pretty good in practice. Now, let's see how the whole boat wake pipeline works. We start with the canoe on, on the water which we get from layout department. So the water here is procedural, it's not interacting with the boat and the goal is to create a, a wake. We erode the surface around the boat creating that pool and also I'd like to point out that we actually filter out the high frequency detail because there is no hope of representing those in a simulation if your grid resolution is not really high. And later on we will apply those high frequencies of displacement at final render. Then we compute the material velocity field just like I described before for, for some of Stokes waves. And finally we get results. So if you look closely you can see there's a pretty perfect match between the simulation and the procedural waves on the right, uh, from the boat. On the left you get a little bit of scrappancy and that's related to the boat actually being present in the sim because you know we, we constructed the whole method in the assumption the boat is not there and Tesla north waves are also constructing this option that are no collision objects. So as long as, as soon as you put something in there it's gonna disrupt the surface. So you don't, you can't expect a perfect match but still it's, it's pretty close and we could use a simple, simple blending technique to get rid of that mismatch at, uh, at the mashing stage. Then we would run a white water pass and produce the final render. And here is, uh, just a couple more shots from the movie. Showing how the method works. Alright, so sort of like an extra thing I want to talk about, since we kind of got on the whole, uh, Stokes wave, uh, topic, we were actually really curious to know what happens when the, when the Stokes waves actually reach the, uh, shallow waters and how exactly, and can we actually simulate a breaking wave? Can we simulate a breaking, uh, uh, breaking barrel? So like I said before, uh, if you, uh, if you specify the, the material velocity correctly, uh, you can produce a traveling Stokes wave here in particular, we actually are sitting in the frame of reference of a Stokes wave. And the boundary conditions are specified exactly as why we're able to recreate the Stokes wave exactly. Now, there is a, uh, a parameter, uh, of a Stokes wave called steepness, uh, which sort of determines the character of the wave. It's, it's pretty kind of self-explanatory if you look at this. Uh, the steeper you make the wave, the more PQ it becomes. Uh, the dots here represent just a particle we had vector, uh, using the exact form for the Stokes wave expression. And you can see that beyond certain steepness, uh, the particles go crazy. And what happens there is the actual mathematical solution is not well defined. Uh, it blows up, becomes unstable. Uh, so that's, that's the limit on the plausible waves that you can have. Basically if the wave goes beyond that limit, it's gonna, it's gonna, so we utilize that to create breaking waves. So we'll start with a traveling wave as I showed before, uh, with an, with an infinite amount of water below it. Uh, so that would, that was, that's what was defined the boundary conditions. And we swap those boundary conditions for the ones that correspond to the shallow water. And if you do that, uh, the steepness of the wave has actually, that's the steepness constraint. So that kind of wave is not allowed in the shallow water. It's too high to, to keep traveling. So if you're on the same with that boundary condition, it's actually gonna overturn and break. So that's a 2D illustration. We can do the same thing in 3D. And we can actually vary the parameters. We can vary the boundary condition along the wave. So we can make it break from one side. Integrated into one of the shots in the movie. Alright, so to summarize, we introduced this flux-animated boundary method, uh, which we found to be really artist-friendly, artist-found really intuitive. Uh, on one hand, we didn't really, uh, invent the concept because it was present in allarian solvers before, but we did figure out a way how to integrate into existing flip solvers, uh, including efficient particle receding. And we also provided, um, several practical flux-animated boundaries, such as the Stokes waves, including breaking waves. And that's it. Thank you. Thank you for the talk. Please come up to the microphones if you have any questions. I will start. So for the, uh, the work behind the boats, uh, you talked about how there might be some reflections coming, going out. Uh, I imagine if, if it's far enough away, it's not a big deal. You can handle it all with blending and damping. Uh, but if it gets too close, uh, you might get these impossible to ignore reflections. Uh, what did, when your opinion, what, what is like the right heuristic for how much, based on the simulation and how much space you need and things like this? That's a good question. So I think like for, uh, for our Sims, we kind of eyeballed it. We looked at how, uh, how far the really weight plane goes and try to be, to make the domain big enough so that, uh, uh, so discrepancy is not, is not too big. Also the other thing that we did, we actually, um, uh, so that, that cavity in the water, it had shallower depth on the boundaries and we used extra damping to, uh, to facilitate that blending, even at the simulation stage. So we would actually dampen velocities to the ones with the procedural water to get rid of the mismatch. Drawing those curves around it. Are those curves controlling the, uh, the, uh, FAB or are they controlling the, uh, material velocity field? So the, uh, flux animated boundary is a combination of two things, right? It's, uh, it's, um, it's a shape and the, the real flow field. So the shape was that shape that was, that we got from the animation department, that wave kind of sticking out of the water, right? And then the flow curves represent the material velocity. So they would describe how the material would move with respect to the shape. They were mostly tangential, so, you know, the water would not splash outside the object too much, but, uh, the curves represented the material flow. I have a follow-up question. I, I know at the game presentation you said it was different from a velocity field, but in that particular example, how are those curves different from a velocity field, uh, uh, control? I think what was done, uh, the, the artist who did it, he actually, uh, took tangents of those curves and then rasterized them into like a VDB volume, and, and that was a material velocity field. Thank you. Okay. Uh, thank you again for the talk. This is the end of the session. The authors should be up front.