I have only one question - is there any correlation between buoyancy of the objects and successfulness of their distant relationships? Having trouble with my drowning simulation
My favorite fake bouyancy is in the original half life. All they did was put a trigger plane slightly under the surface of the water, every time an object touches the plane it just kinda punches the object up a little bit And that's all it does
Sometimes simple just works best. I think Acerola kinda touched on it here: at some point, the ocean becomes noise. The fact is that no one is really gonna notice if the object is tilting the correct way because the waves are such chaotic movement in the first place. You can really just fake things at this point.
"Did Archimedes ever take another bath?" Actually yes, IIRC there were historical records uncovered in 2011 stating that he once bathed in blood inside Heavy's ventral cavity
I have one question - is there any correlation between buoyancy of the objects and successfulness of their distant relationships? Having trouble with my drowning simulation
Great video! I had to create a relatively convincing buoyancy sim at work for VR interactable objects. You did a fantastic job with this break down! The difficulty I found, most of all, was creating an interface for designers to end up implementing the parameters, per object, to determine physical values. Lots of fun! Designers have such high standards but then want simple controls!
Both are vital to being able to craft a good experience. They need to be able to author and tweak huge amounts of content and slowing that process tangibly impacts their output and the quality of the final product.
Working on a buoyancy sim for my own ocean.. watching you go through the same thought processes as me was funny. To address the issues with the voxel approach (no control/ bad performance) i did a couple things instead of a plane fitting algorithm - Based the rotation of the object, if it aligned orthogonally with the oceans suface such that the cubes could same from ones "below" them, i could drastically cut down on the # of samples especially for ships which almost always maintain a similar equilibrium -To address control, i worked the buoyancy equation backwards to calculate the water density based on a desired height for the object to be at equilibrium for. This meant that for ships, all I had to do was set a specific y value to be the waterline and the program made it float there no matter what. It also meant the water density was different for each object, but that didn't have any effect so long as there weren't things that were Massively overweight and floating I have some questions about the gpu read back: What if you calculated, on the gpu, the lower frequency waves slightly ahead in the future such that when the packets arrived, they would be right on time instead of lagging behind (this would also help with noise). I'm not sure if its practical but I just thought of it now
@@Acerola_tIt's not GPU-expensive to do so and you're not bandwidth-starved, are you? Couldn't you just pass 2-5 (or however much it is) worth of forward frame calculations to the CPU? Can you tell, after receiving a "GPU Packet", how long it took to deliver, and then pick the correct data point? For that matter, can't you just keep a "future stream" of data going? Also since the GPU is going to need to calculate the future anyways, can't you just store the future results instead of calculating them again? In effect you're just delaying the simulation. I guess it would have an effect if objects could affect the water simulation, but they can't in your example, so it doesn't matter, right?
The problem is calculating. This data isn't reliable. It might give you the results for the current frame on that frame or it might give you the results for this frame in five frames. You're essentially just dealing with a race condition. @@fimbulvntr
Uh, thinking about the pressure on the surface of the object is actually way more applicable to how 3D objects in game engines are usually implemented. This can be done by using a displacement mesh, cutting it at the water surface and then calculating the pressure and area for each triangle to get the forces. Implementing things like slamming forces and surface friction also becomes possible. There is a great article by Jacques Kerner about the Just Cause 3 boat physics on the gamedeveloper website and a person called Habrador also has a Unity implementation with sample code based on it.
One thing that could also work is having the gpu return a grid of water normals around the origin of the buoy to the cpu where you calculate the difference in normals over time and apply that to the buoy. That way the cpu is interpolating the data in order to calculate while waiting on the gpu, so the buoys are always animating.
that's an interesting idea, it requires even more data to be read back though which sucks. i wonder if maybe you could estimate the normals from the read back height data and get a similar result
Your thumbnail made me realize where the word buoy comes from, so thanks for that random little insight :) (seems kinda obvious in hindsight, but then again I suppose most things do)
I kept thinking, wouldn't it be better to ask for the data in bulk? The time to make lots of little requests scales way faster than making few big requests. This is due to the individual overhead attached to each request. (Now imagine instead of talking to the GPU, you're sending data over the internet. Had to tackle that in my job.) Probably just shoving the heightmap into a render texture and reading that.
One thing I think could quite improve the simulation is drag. Objects in water experience significant drag which slows them down (tried running through a pool? Impossible). Moving objects, like ships, rely on there being far more drag sideways than forward/back in order to be able to turn properly. I made a game in 3rd year in high school where I implemented water simulation. The boats I used would sink noticably when jumping into the water, and would slide across when turned. Adding drag (high drag sideways, very high vertically) mostly fixed the issue. I don't remember much from his previous water sim video, but if the simulation isn't incredibly compute heavy, you can in fact just simulate it on the CPU for every point you need. I sampled 7 points on a boat's hull in order to determine the buoyancy.
It is rather heavy, but since each vertex is (IIRC) displaced in isolation, I'm thinking your idea of recalculating just the points we need for the interacting bodies will have basically negligible cost. Additionally, you probably don't need all of the sine waves to get it to look convincing, just the lower frequency ones, and if it's a big vessel, you can get away with sampling just the largest waves, because the small splashing will not have noticeable effect.
I made the water physics for Aqua Moto Racing Utopia. I used something similar to get a plain around the floating objects. If the object was deeper then a hardcoded value, I added a force in the water normal direction. If the object normal was not in the same direction as the water normal, I added a torque to push the object towards the water normal. A lot of movement friction removes jerkiness.
Great video. Presenting vastly different solutions is very important, if you need to decide which solution fits your project the best with a limited time budget. Thank you for providing this to everybody, Acerola. The voxel solution looked very promissing here. It could be something that might become feasible in future games. Almost then years ago I worked on a game with a large body of water and wrote a full height field sim on the GPU and a per-sample sim on the CPU. They were deterministic and ran synchronised and used artist-controlled wave patterns to improve control over visuals and gameplay. It was similar to sum of sinuses, it makes several things simpler, but less realistic, as was pointed out in this and an earlier video. You could perform multiple thousands of CPU side "samples" (they were pattern samples and computations instead of actual samples of a map, the height field did not exist as such on the CPU side) within a reasonable budget (a single / few ms out of 33 / 16 ms per frame) on then-current consoles (with very weak tablet-level CPUs), of which we only used a small fraction in the final game (probably low hundreds, it never came up in the profiler, so I don't know). To reduce the CPU side overhead, you could bundle multiple samples that were then computed in one go. That yielded some meaningful savings for scenarios like the one in the video. The approach in that game was otherwise quite similar to the last solution. I was a little worried for a while, that I had missed an obvious better solution. 😅 Seriously, there is always something new to learn in these videos, even if you've already got some experience in the topic. PS: This is one of a few select channels where I don't mind the in-video ads. I usually don't skip them anyway, but with these channels, I genuinely enjoy the presentation, as weird as that might be.
Since you mentioned the signal domain, the "noise" can be filtered with a simple damping filter (also known as Exponential Moving Average Infinite Impulse Response filter): o = lerp(i, o, t). This effectively removes high frequencies from your signal, simulating inertia and mass. Of course, you don't have to stop to just one filter (1st order), you can have up to 3 filters chained one after another for an even smoother frequency cutoff.
i remember doing this myself and following a bunch of tutorials and what we ended up doing is getting the bounding box and then at the 4 corners of the intersecting plane with the water use spring physics to pull the current “plane” into alignment. i by no means came up with his myself but it’s a neat solution that gave really nice results, especially since we had a full copy of the water shader living on the cpu and could then use this copy to interact with the rest of the cpu things
I love this video because the topic is one of the most obvious things that regular game players haven’t ever thought about. How I went my entire life without questioning how they make things float in games is wild
Isn't it possible to just stream a downscaled height texture of the water back to the CPU? That should be much faster than individual reads for each object. Also you can set a spring constraint in many physics engines, even the one unity uses. If you add an X/Z (or X/Y) lock to the body, you end up with a buoy that doesn't move and doesn't topple over (artist control) while still being physics based.
@@Acerola_t That's no joke. I find it genuinely impressive how fast you manage to make these videos at the high quality and the topic's depth, given that in production (albeit possibly with broader scope, more restrictions, artist requests and systems interacting etc.) these things can easily take up person months or years and then there's still a video that you need to writte and produced at the end.
@@Acerola_t what is a while in this context? With 60fps frametime is around 20 msecs and gpu and cpu frequencies are much faster than that? Where is the bottleneck?
no matter what there's going to be latency, I would consider anything >1 frame of latency to be 'awhile' because it's visible at that point already@@4crafters597
I think you might be able to optimize considerably the voxel technique by using different shapes. With that buoy example, 4 or 5 well positioned voxels might be sufficient to do both the height and the tilt, with one in the center and the rest in corners...
If you want to level up your ocean simulation even further, you can add in ripples and boat wakes with Cem Yuksel's Wave Particles whitepaper. This has nothing to do with particle systems, but instead is about creating a displacement map that looks pretty darn convincing. Cem Yuksel also has a really good paper on caustics for underwater light simulaiton.
Fantastic video as always! We need more of what you have to offer! Your work researching, explaining, and covering topics without just talking about what your code does and showing code allows us to learn to code it on our own in our own ways. Keep this up! I'll for sure be subscribing to your Patreon!
I'd love to see you take on some rudimentary water interaction physics pretty similar to how RDR2 detailed theirs in the GDC paper. I think that would be an extremely interesting thing to add to your ocean simulation. Plus it'll help as you add more objects to the world
My immediate thought in regards to the lag is that since it, gameplay-wise, doesn't matter what time the ocean simulation is at, if you could hold back the clock for the rendering time, you could have the wave visual sync up with the values you got from the gpu->cpu reads. I'm too lazy to go back to the previous vid to chek how the sim was stored, but given it's not just a simple function of time like a sum of sines would be, I suppose this might require a circular history buffer of wave maps or something
At 16:00 I would recommend a dashpot/damper rather than a spring, I don't wanna overexplain if you know what it is, but basically instead of resisting based off distance like a spring, it resist motion from its current point, this prevents it from being pulled to the normal and instead allows it to drift around without being erratic
15:40 If you measure and plot the normal vector angle fluctuations, and then tune the spring and damping constant so that the angular spring has a similar resonant frequency, the motion won't be quite as smoothed out. Alternatively, if you all you want is to keep the buoy upright, you could apply a similar angular spring to the physics-based system. That way you could keep the nice angular displacements, while having a tunable parameter that keeps it mostly upright.
But Acerola?? How do you make these informative and entertaining videos about an obscure topic that is very hard hard to learn?? On a serious note your channel just became my favorite, thanks for all the hard work!
You say bad game design, but I think it's perfect. I want large waters to be anti-player boarders in my dream game. Having rough seas that actively move the player is perfect! I want a 99% game over, but with a real possibility of survival. Like an irl rip tide. They don't automatically kill you, miracles can happen, but you're probably dead.
An interesting idea is to just combine them both! Have the cheaper method applied on buoys far away, where accuracy is not the greatest concern, and then when the buoys enter a close range of the player, switch it to physics mode.
Buoys are irrelevant background objects for the purpose of a game and literally noone cares if they're realistic or not except people who don't play games to actually have fun but to instead whine about things that don't matter. If I wanted to look at buoys floating I'd rent out a boat and go check them out.
I think adding a little blip noise when notes/corrections are put on screen would be helpful because I'm a listener not a watcher and wouldn't know what I heard was incorrect unless I saw the screen.
16:00 so my suggestion is to use a first order lowpass filter here (there's some similarity between ideal springs and lowpass filters), each frame setting the value to partway between the last value and the updated value. any changes too far above the filter's cutoff will be reduced and that smooths it out. it can completely remove changes if they happen too fast, so sometimes it requires scaling up the input or output to compensate, but a higher order filter could more easily allow changes you want while still smoothing it out. a higher order filter could have a higher Q and rock back and forth faster when the frequency is just right, as often happens. there's possibly some overlap between this and what you were doing but hopefully it gives you some ideas to explore.
Incredible. This is inspiring and really well done. As an audio guy looking to begin game dev, I wish there was a channel just like yours but for us audio nerds… but as you know in the industry, who gets their data compressed and cut first? Audio 🤣 thanks a million for the inspiration!
For the more realistic simulation a thing that came to mind that would give quite a bit of artistic control and shouldn't be that much heavier to compute, just have a buoyancy multiplier for the voxels/areas and then you can easily make different parts of the object more or less buoyant. With that just making the top more or the bottom less buoyant should make the buoy auto correct unless it's completely inverted.
TBH buoyancy feels so unpredictable IRL because of all inertia that I can imagine that this spring physics with some tuning will give believable effect. The fact that delay didn't affect subjective feeling only shows how much one can cheat on this.
My solution to all denoising for movement is recency-weighted exponential falloff. position and orientation = (alpha * previous) + ((1.0 - alpha) * newest values). When alpha is 0 you get the jittery one. When alpha is low you get slow movement. Tune it low for turbulent waves and heavy objects. High for light weight plastics and flags.
It amazes me how similar is sound/music field to video game/grogramming. All these algorythms pretty much work the same but with different data. It makes me optimistic that if i understand one i'll eventually undarstand another.
One idea is to do a bit of time smoothing so that the CPU snapshot has less intermittent effects. Sure, it'd make there be more latency between the water movement and the buoy movement, and you'd have to draw the water to a texture to do the time smoothing on the GPU side, but maybe it'd make up for it with the buoy being less noisy
Very entertaining. It seems that this is a case where the delay is not only helpful, but you want more of it. Because water is compressible, objects (especially heavy objects) don't react immediately to changes in height or direction. Thus you could send some portion of the changes into an "accumulator" that would release an average of the changes. I did this with a flight sim where I wanted to add a little lag into the time between inputs and results - to reflect that controls wires stretch and contract (like springs) and air is compressible. It worked like a charm. That might just be the tweak that you need.
@@AR-cy6uj You are absolutely correct. When I used the term, I was thinking about the ability of the water to flow around the object - the thing that allows me to dive into a pool of water and not go "splat". Perhaps the term I should have used is density. And perhaps the true explanation even more complex - having more to do with the weight of the object and how far the object is submerged in the water. In any case, this appears to be one situation where lag is not a bad thing - it is just a matter of making that lag look smooth and realistic.
You need to set your center of mass on the buoy to be lower to automatically correctly avoid the stuck on its side problem and apply the force at the voxel position not at center of mass. It will then naturally want to tip to an upright position.
What i would've done is position an oriented bounding box for the buoy, represented as a model matrix, at the rough location where it should be floating. This matrix is passed to the GPU in a buffer. After the computing the water surface, you run a separate compute shader pass, which modifies the model matrix to simulate buoy displacement. In the final pass, you render the buoy geometry with the modified model matrix. No need to pass things back to the CPU. The beauty of this technique is that you can probably render a hundred buoys this way via manipulating their corresponding matrices in the compute shaders, then apply instanced rendering.
yo i actually predicted where a video was going to go for once!!! i thought you were going to start off with the plane fitting algorithm thing and then was very disappointed but you CAME BACK TO IT
Running waves simulation on CPU is perfectly fine, until you calculate it only for some positions (where bounce objects are located). And you may avoid computing waves with length less than object size.
Making the simulation more "physically accurate" could actually make it easier to adjust, if you take the height and normal vector deltas between the ocean and the buoy you can use them as forces acting on the buoy, then you only need to adjust the vertical and rotational inertia (and friction) of the buoy to make it feel "right". You can even add an adjustable spring along the plane of the water so the buoy drifts around a spot. Directly sampling the normal vector of a particular detail level based on object size also allows you to skip the plane approximation.
Inertia (physics) and interpolation (simulation) would lend themselves well together. You can also use bounding boxes, coordinate systems, etc, as a performance optimization. Also, coarse grids progressively being refined into more granular grids only in small areas... Dividing the water into "chunks", etc.
I really like physics based buoyancy, it’s very satisfying to watch, but I understand how it’s not really realistic if you need a lot of buoyant objects. I’m honestly wondering how something like sea of thieves does buoyancy, since they need to have a lot of buoyant objects at once sometimes. I think for small objects they’re just setting the height position to the height of the water, but I’m not sure what’s being done for larger objects like ships, and I’m curious to know.
Probably just height queries at manually-placed spots around the ship, then apply an upward force at that spot scaled by the distance to the surface, fidget with drag / downward forces until it feels right. You can approximate a pretty convincing buoyancy with just 6 sample points for ships, everything else they just use 1 and the "swaying" is faked either procedurally or with an animation. What needs to stay upright is just facing the queried normal, and I guess you can also have a mix of fake swaying and facing the normal for even more convincing looks. What is interesting about SoT is that you can't use anything shown in this video to get the water height on the server. There's really no way around it, the math involved must be replicated for both the gpu and cpu, the trick to read the gpu data back is just impossible to do with a networked game like that. How exactly they went about it is a mystery that would make for a very interesting talk imho.
My grug-brained solution a while back was just to quiet down the waters around the buoyant object, sine wave the up/down axis cpu on the object and pass the full location to the gpu to do the water quieting and let it join in up/down
Of course the equation for the semi circle is represented by the equation -sqrt(1-x^2), or if you do want to go further, you can replace one with r^2, but it’s helpful to start with a base case
Beautifull! I loved the plot twist with reading data back from the GPU!, and seeing you go through a similar thinking process for bouyancy,, even though, i never went with the voxel approach for performance concerns, i did, stategically placed a number of "buoyant detectors" arround what i decided would be the bouyancy line of a given boat model,, theese detectoirs simply read a few data points for our ocean, and apply the bouyant force at a rigidbody at each detector location., if they are below the ocean water., they push up, and if not they fall, by gravity, wich ensures that the rotation of the bouyant object will match the waves outline arrount it, although that push up or down is running in cpu, is constantly in motion riding them with no lag. I love to see you took the simulation approach! Amazing!!
want some more fun? most buoys are chained to a weight on the ocean floor, it'll drift and set at a distance versus chain angle, then swivel toward vertical instead of lift straight up and down, then slowly move back toward the drift position, distance depending on wave speed. more applicable to tides really, a stuff in tides simulations could be fun.
You can cut your simplified cylinder with the water plane and find volume and center of mass of the submerged part. That gives you a bouyancy vector. You can do a series expansion on cpu to get the value in single point.
I always get such a happy feeling of excitement when this dude uploads I love the silly and random cool and interesting programming videos, it's so fun!
It would be interesting to see how the amount of voxels, (and maybe their shapes & distribution in the cube) changes the simulation. Great video as always !
Hey, i made something similar a year ago. I was inspired by a part of the sea of thieves documentation, were they talked about having a complex visual ocean (gerstener waves) based on a more simple combination of sine waves. So my solution was having a nice looking shader(back then only shdergraph, bc i just started on cg) and calculating the the hight of the water with the biggest waves represented as sine waves. it looked nice and was really easy on the pc(my plan is to redo that stuff at somepoint and make the vr sailing expierience or puking simulator).
Hey why you want use point upward force, basically I mean sample the ocean surface at some point divide by you then add upward force at point. Also gpu is better because it doing all vertex, but CPU can do that little times like 10 to 100 times with no problem. That mean no need to take data from gpu to CPU, just directly run the algorithm in CPU, also point that I mention is preferred by you, for me 4 to 6 point enough for your model
Feels like spring has "too tough" coefficient. It takes several guessing iterations to find a nice look. At least in cloth simulation from scratch it took for me.
cool the buoy interacts with the water. Now make the water interarct with the buoy - currently its just clipping into the water mesh. fr tho, great content
I feel like a better version of the amazon package analogy is having a frozen dinner already ready, sticking it in the microwave, and not being able to do anything but wait for the food to be done because tbh you have nothing else to do and you're hungry and maybe it'll cook faster if you stare at it (it wont)
For the problem where the bouy could wind up on its side, you could add ballast, like a real bouy has. Essentially add an extra rigidbody near the bottom of the bouyant volume and put a bunch of the bouy's weight there. If you want it usable by a designer, you could add some code in the inspector that calculates the correct weight for the desired bouyancy and puts some fraction of that weight in the ballast. And to stop it from wandering, you could have an anchor, again like a real bouy has. It could be simulated as just a spring attached to the bottom that pulls the bouy back towards a desired position. I prefer physics based solutions to things if I can manage it. It takes some insight into how to translate that physics into simple tools that a layperson can use, but I really enjoy that process anyway.
the long distance cpu and gpu relationship hit way too close to home and tells me that I'm still not really over my 7 year relationship... thank you for the happy new year video computer game png man
For the voxel aproach you dont need the volume displacement for them. if we have a dence enough voxel field we can approximate the displacement by just sampling the waterhight.
You could set a linear interval to sample the gpu requests to smooth out the raw data coming in. That could be a "sample rate" variable that you can set wherein a higher sample rate is more accurate but has more noise, whereas lower sample rates result in less accurate but smoother motion. You could also simply bake the motion if the object is static. Since the sin waves won't change at that exact position after a each cycle.
Get a free 30 day trial and 20% off an annual plan at brilliant.org/acerola ! #ad
Simple topic today thanks friends happy new year
happy new year, Acerola
I have only one question - is there any correlation between buoyancy of the objects and successfulness of their distant relationships?
Having trouble with my drowning simulation
You literally put cat videos beside the ad to keep people from not skipping?
and i'll do it again@@YHK_YT
@@Acerola_t I was so confused and shocked, does it work? Does it keep retention high?
I'm actually really glad the cat gag hasn't been removed because I find it genuinely fun to watch your cat
it unironically works to keep people watching the ads lol
@@Acerola_t lmao it works for me
@@Acerola_ti absolutely watch the ads for the cat
dont get me wrong i want to support the channel but the cat makes a billion timee better
No shit, this was probably the first time in month I've not skipped an ad read and I didn't even realize until I read these comments.
@@Acerola_t Whenever I'm about to skip the ad my brain goes "Just one more second of the cute cat plz" and suddenly the ad has ended
My favorite fake bouyancy is in the original half life.
All they did was put a trigger plane slightly under the surface of the water, every time an object touches the plane it just kinda punches the object up a little bit
And that's all it does
Sometimes simple just works best. I think Acerola kinda touched on it here: at some point, the ocean becomes noise. The fact is that no one is really gonna notice if the object is tilting the correct way because the waves are such chaotic movement in the first place. You can really just fake things at this point.
@@spell105this is how they did it in half life alix for the bottle shader "it's gonna look chaotic anyway, so the bad approximation is good enough"
"Did Archimedes ever take another bath?" Actually yes, IIRC there were historical records uncovered in 2011 stating that he once bathed in blood inside Heavy's ventral cavity
TF2 reference = like
Archimedes no!!
eh, birds
Now, most hearts couldn't withstand this voltage... but I'm fairly certain your heart-
@@makeandbreakgames1791tf2 = cringelord
I have one question - is there any correlation between buoyancy of the objects and successfulness of their distant relationships?
Having trouble with my drowning simulation
NO BATHS, NO MATHS
NO BATHS, NO MATHS
NO BALLS, NO MALLS.
NO CATHS, NO SYLVIA PLATHS
The funny PNG computing man is back! My day has improved drastically
Indeed
Oh I didn't realise he was that sophisticated, I assumed they were Jpegs
@@locinolacolino1302jpeg doesn’t have transparency so he couldn’t have done the green screen
Great video! I had to create a relatively convincing buoyancy sim at work for VR interactable objects. You did a fantastic job with this break down! The difficulty I found, most of all, was creating an interface for designers to end up implementing the parameters, per object, to determine physical values. Lots of fun! Designers have such high standards but then want simple controls!
Funny seeing you here, I used to watch your 1 2 Oatmeal remixes back in 2017
@@eightstunningangles Of course! Love Prof. Rola's videos lmao. Thanks for watching mine, eons ago!
Both are vital to being able to craft a good experience. They need to be able to author and tweak huge amounts of content and slowing that process tangibly impacts their output and the quality of the final product.
Working on a buoyancy sim for my own ocean.. watching you go through the same thought processes as me was funny. To address the issues with the voxel approach (no control/ bad performance) i did a couple things instead of a plane fitting algorithm
- Based the rotation of the object, if it aligned orthogonally with the oceans suface such that the cubes could same from ones "below" them, i could drastically cut down on the # of samples especially for ships which almost always maintain a similar equilibrium
-To address control, i worked the buoyancy equation backwards to calculate the water density based on a desired height for the object to be at equilibrium for. This meant that for ships, all I had to do was set a specific y value to be the waterline and the program made it float there no matter what. It also meant the water density was different for each object, but that didn't have any effect so long as there weren't things that were Massively overweight and floating
I have some questions about the gpu read back:
What if you calculated, on the gpu, the lower frequency waves slightly ahead in the future such that when the packets arrived, they would be right on time instead of lagging behind (this would also help with noise). I'm not sure if its practical but I just thought of it now
the latency is anywhere between 2-5 frames so calculating ahead of time, while it sounds cool, would probably have the same results visually lol
@@Acerola_t Ah, so I guess the stutter is more from the low density of updates from the gpu rather than a delay. Thanks for responding!
@@Acerola_tIt's not GPU-expensive to do so and you're not bandwidth-starved, are you?
Couldn't you just pass 2-5 (or however much it is) worth of forward frame calculations to the CPU?
Can you tell, after receiving a "GPU Packet", how long it took to deliver, and then pick the correct data point?
For that matter, can't you just keep a "future stream" of data going?
Also since the GPU is going to need to calculate the future anyways, can't you just store the future results instead of calculating them again? In effect you're just delaying the simulation.
I guess it would have an effect if objects could affect the water simulation, but they can't in your example, so it doesn't matter, right?
The problem is calculating. This data isn't reliable. It might give you the results for the current frame on that frame or it might give you the results for this frame in five frames. You're essentially just dealing with a race condition. @@fimbulvntr
Uh, thinking about the pressure on the surface of the object is actually way more applicable to how 3D objects in game engines are usually implemented.
This can be done by using a displacement mesh, cutting it at the water surface and then calculating the pressure and area for each triangle to get the forces. Implementing things like slamming forces and surface friction also becomes possible.
There is a great article by Jacques Kerner about the Just Cause 3 boat physics on the gamedeveloper website and a person called Habrador also has a Unity implementation with sample code based on it.
Yeah, would be interested to see how a pressure approach compares.
One thing that could also work is having the gpu return a grid of water normals around the origin of the buoy to the cpu where you calculate the difference in normals over time and apply that to the buoy. That way the cpu is interpolating the data in order to calculate while waiting on the gpu, so the buoys are always animating.
that's an interesting idea, it requires even more data to be read back though which sucks. i wonder if maybe you could estimate the normals from the read back height data and get a similar result
Your thumbnail made me realize where the word buoy comes from, so thanks for that random little insight :)
(seems kinda obvious in hindsight, but then again I suppose most things do)
I kept thinking, wouldn't it be better to ask for the data in bulk?
The time to make lots of little requests scales way faster than making few big requests. This is due to the individual overhead attached to each request. (Now imagine instead of talking to the GPU, you're sending data over the internet. Had to tackle that in my job.)
Probably just shoving the heightmap into a render texture and reading that.
yes you could do that, as I said, there are many ways to do the exact same thing
One thing I think could quite improve the simulation is drag. Objects in water experience significant drag which slows them down (tried running through a pool? Impossible). Moving objects, like ships, rely on there being far more drag sideways than forward/back in order to be able to turn properly.
I made a game in 3rd year in high school where I implemented water simulation. The boats I used would sink noticably when jumping into the water, and would slide across when turned. Adding drag (high drag sideways, very high vertically) mostly fixed the issue.
I don't remember much from his previous water sim video, but if the simulation isn't incredibly compute heavy, you can in fact just simulate it on the CPU for every point you need. I sampled 7 points on a boat's hull in order to determine the buoyancy.
It is rather heavy, but since each vertex is (IIRC) displaced in isolation, I'm thinking your idea of recalculating just the points we need for the interacting bodies will have basically negligible cost. Additionally, you probably don't need all of the sine waves to get it to look convincing, just the lower frequency ones, and if it's a big vessel, you can get away with sampling just the largest waves, because the small splashing will not have noticeable effect.
My first idea would be to sample the 4 corners, use a plane approximation, and filter that using a moving average window.
that's an interesting idea i wish i thought of that
I made the water physics for Aqua Moto Racing Utopia. I used something similar to get a plain around the floating objects. If the object was deeper then a hardcoded value, I added a force in the water normal direction. If the object normal was not in the same direction as the water normal, I added a torque to push the object towards the water normal. A lot of movement friction removes jerkiness.
Great video. Presenting vastly different solutions is very important, if you need to decide which solution fits your project the best with a limited time budget. Thank you for providing this to everybody, Acerola.
The voxel solution looked very promissing here. It could be something that might become feasible in future games.
Almost then years ago I worked on a game with a large body of water and wrote a full height field sim on the GPU and a per-sample sim on the CPU. They were deterministic and ran synchronised and used artist-controlled wave patterns to improve control over visuals and gameplay. It was similar to sum of sinuses, it makes several things simpler, but less realistic, as was pointed out in this and an earlier video. You could perform multiple thousands of CPU side "samples" (they were pattern samples and computations instead of actual samples of a map, the height field did not exist as such on the CPU side) within a reasonable budget (a single / few ms out of 33 / 16 ms per frame) on then-current consoles (with very weak tablet-level CPUs), of which we only used a small fraction in the final game (probably low hundreds, it never came up in the profiler, so I don't know). To reduce the CPU side overhead, you could bundle multiple samples that were then computed in one go. That yielded some meaningful savings for scenarios like the one in the video. The approach in that game was otherwise quite similar to the last solution. I was a little worried for a while, that I had missed an obvious better solution. 😅 Seriously, there is always something new to learn in these videos, even if you've already got some experience in the topic.
PS: This is one of a few select channels where I don't mind the in-video ads. I usually don't skip them anyway, but with these channels, I genuinely enjoy the presentation, as weird as that might be.
Yeah, I was thinking that since you can sample a single point out of the field, taking a handful of points on the CPU should work just fine.
Since you mentioned the signal domain, the "noise" can be filtered with a simple damping filter (also known as Exponential Moving Average Infinite Impulse Response filter): o = lerp(i, o, t). This effectively removes high frequencies from your signal, simulating inertia and mass. Of course, you don't have to stop to just one filter (1st order), you can have up to 3 filters chained one after another for an even smoother frequency cutoff.
i remember doing this myself and following a bunch of tutorials and what we ended up doing is getting the bounding box and then at the 4 corners of the intersecting plane with the water use spring physics to pull the current “plane” into alignment. i by no means came up with his myself but it’s a neat solution that gave really nice results, especially since we had a full copy of the water shader living on the cpu and could then use this copy to interact with the rest of the cpu things
Amazing video. Love your content.
yooooo
love your's too
I love this video because the topic is one of the most obvious things that regular game players haven’t ever thought about. How I went my entire life without questioning how they make things float in games is wild
Isn't it possible to just stream a downscaled height texture of the water back to the CPU? That should be much faster than individual reads for each object.
Also you can set a spring constraint in many physics engines, even the one unity uses. If you add an X/Z (or X/Y) lock to the body, you end up with a buoy that doesn't move and doesn't topple over (artist control) while still being physics based.
yeah that's one option, like I said there are many ways to go about it lol either way it's taking awhile
@@Acerola_t That's no joke. I find it genuinely impressive how fast you manage to make these videos at the high quality and the topic's depth, given that in production (albeit possibly with broader scope, more restrictions, artist requests and systems interacting etc.) these things can easily take up person months or years and then there's still a video that you need to writte and produced at the end.
@@Acerola_t what is a while in this context? With 60fps frametime is around 20 msecs and gpu and cpu frequencies are much faster than that? Where is the bottleneck?
no matter what there's going to be latency, I would consider anything >1 frame of latency to be 'awhile' because it's visible at that point already@@4crafters597
@@Acerola_t I wish PCs eventually got an unified memory bus, but its not happening. So the best possible case scenario is at least 1 frame of latency.
I think you might be able to optimize considerably the voxel technique by using different shapes. With that buoy example, 4 or 5 well positioned voxels might be sufficient to do both the height and the tilt, with one in the center and the rest in corners...
I like the part in the intro where it's just a color background with texts, reminds me of monogatari series, so nostalgic ahhh😊
If you want to level up your ocean simulation even further, you can add in ripples and boat wakes with Cem Yuksel's Wave Particles whitepaper. This has nothing to do with particle systems, but instead is about creating a displacement map that looks pretty darn convincing. Cem Yuksel also has a really good paper on caustics for underwater light simulaiton.
Yo Ace I’m loving binging your whole channel as I learn blender
Fantastic video as always! We need more of what you have to offer! Your work researching, explaining, and covering topics without just talking about what your code does and showing code allows us to learn to code it on our own in our own ways. Keep this up! I'll for sure be subscribing to your Patreon!
I hadn't noticed this. These videos have even better presentation than I thought.
I don’t know what it is about the way you make videos but don’t stop, your videos feel so casual while still being informative and it’s great.
I'd love to see you take on some rudimentary water interaction physics pretty similar to how RDR2 detailed theirs in the GDC paper. I think that would be an extremely interesting thing to add to your ocean simulation. Plus it'll help as you add more objects to the world
My immediate thought in regards to the lag is that since it, gameplay-wise, doesn't matter what time the ocean simulation is at, if you could hold back the clock for the rendering time, you could have the wave visual sync up with the values you got from the gpu->cpu reads.
I'm too lazy to go back to the previous vid to chek how the sim was stored, but given it's not just a simple function of time like a sum of sines would be, I suppose this might require a circular history buffer of wave maps or something
At 16:00 I would recommend a dashpot/damper rather than a spring, I don't wanna overexplain if you know what it is, but basically instead of resisting based off distance like a spring, it resist motion from its current point, this prevents it from being pulled to the normal and instead allows it to drift around without being erratic
Love that you named your cat Brilliant, and that they sponsored this video 💕
15:40 If you measure and plot the normal vector angle fluctuations, and then tune the spring and damping constant so that the angular spring has a similar resonant frequency, the motion won't be quite as smoothed out.
Alternatively, if you all you want is to keep the buoy upright, you could apply a similar angular spring to the physics-based system. That way you could keep the nice angular displacements, while having a tunable parameter that keeps it mostly upright.
I was just thinking multiplying the non-"up" coordinates and then smoothing out that data to exaggerate the buoyancy and then make it look smooth.
But Acerola?? How do you make these informative and entertaining videos about an obscure topic that is very hard hard to learn??
On a serious note your channel just became my favorite, thanks for all the hard work!
a monogatari and persona 3 ref in first few seconds, you have my sub
You say bad game design, but I think it's perfect. I want large waters to be anti-player boarders in my dream game. Having rough seas that actively move the player is perfect! I want a 99% game over, but with a real possibility of survival. Like an irl rip tide. They don't automatically kill you, miracles can happen, but you're probably dead.
A physics video starting with a monogatari reference? What kind of dreamscape did i just stumble upon
an acerola video a month keeps one feeling comf
Acerola must’ve tried a long distance relationship that went bad. Cause that was very accurate
An interesting idea is to just combine them both!
Have the cheaper method applied on buoys far away, where accuracy is not the greatest concern, and then when the buoys enter a close range of the player, switch it to physics mode.
Buoys are irrelevant background objects for the purpose of a game and literally noone cares if they're realistic or not except people who don't play games to actually have fun but to instead whine about things that don't matter.
If I wanted to look at buoys floating I'd rent out a boat and go check them out.
I think adding a little blip noise when notes/corrections are put on screen would be helpful because I'm a listener not a watcher and wouldn't know what I heard was incorrect unless I saw the screen.
there was no need for the long distance relationship gag because that literally happened to me and now I'm crying
great video tho
16:00 so my suggestion is to use a first order lowpass filter here (there's some similarity between ideal springs and lowpass filters), each frame setting the value to partway between the last value and the updated value. any changes too far above the filter's cutoff will be reduced and that smooths it out. it can completely remove changes if they happen too fast, so sometimes it requires scaling up the input or output to compensate, but a higher order filter could more easily allow changes you want while still smoothing it out. a higher order filter could have a higher Q and rock back and forth faster when the frequency is just right, as often happens. there's possibly some overlap between this and what you were doing but hopefully it gives you some ideas to explore.
Incredible. This is inspiring and really well done. As an audio guy looking to begin game dev, I wish there was a channel just like yours but for us audio nerds… but as you know in the industry, who gets their data compressed and cut first? Audio 🤣 thanks a million for the inspiration!
For the more realistic simulation a thing that came to mind that would give quite a bit of artistic control and shouldn't be that much heavier to compute, just have a buoyancy multiplier for the voxels/areas and then you can easily make different parts of the object more or less buoyant. With that just making the top more or the bottom less buoyant should make the buoy auto correct unless it's completely inverted.
TBH buoyancy feels so unpredictable IRL because of all inertia that I can imagine that this spring physics with some tuning will give believable effect. The fact that delay didn't affect subjective feeling only shows how much one can cheat on this.
Why did acerola have to go so far with the longterm situationship? Definitely hit a bit too close to home for me😂
My solution to all denoising for movement is recency-weighted exponential falloff. position and orientation = (alpha * previous) + ((1.0 - alpha) * newest values). When alpha is 0 you get the jittery one. When alpha is low you get slow movement. Tune it low for turbulent waves and heavy objects. High for light weight plastics and flags.
That intro of flashing text reminds me of monogatari
It’s a bad game if the developers don’t take into consideration Quantum Entanglement.
It amazes me how similar is sound/music field to video game/grogramming. All these algorythms pretty much work the same but with different data. It makes me optimistic that if i understand one i'll eventually undarstand another.
Me, small brain: *Lerp it for smoothness*
One idea is to do a bit of time smoothing so that the CPU snapshot has less intermittent effects. Sure, it'd make there be more latency between the water movement and the buoy movement, and you'd have to draw the water to a texture to do the time smoothing on the GPU side, but maybe it'd make up for it with the buoy being less noisy
My favorite math daddy
the monogatari editing is so peak
Very entertaining. It seems that this is a case where the delay is not only helpful, but you want more of it. Because water is compressible, objects (especially heavy objects) don't react immediately to changes in height or direction. Thus you could send some portion of the changes into an "accumulator" that would release an average of the changes. I did this with a flight sim where I wanted to add a little lag into the time between inputs and results - to reflect that controls wires stretch and contract (like springs) and air is compressible. It worked like a charm. That might just be the tweak that you need.
Air is compressible, but water is practically incompressible. It takes a ridiculous amount of force to compress water by a non trivial amount.
@@AR-cy6uj You are absolutely correct. When I used the term, I was thinking about the ability of the water to flow around the object - the thing that allows me to dive into a pool of water and not go "splat". Perhaps the term I should have used is density. And perhaps the true explanation even more complex - having more to do with the weight of the object and how far the object is submerged in the water. In any case, this appears to be one situation where lag is not a bad thing - it is just a matter of making that lag look smooth and realistic.
You need to set your center of mass on the buoy to be lower to automatically correctly avoid the stuck on its side problem and apply the force at the voxel position not at center of mass. It will then naturally want to tip to an upright position.
stuck on its side wasnt a problem i was just using the same model to demo how it would look if it did topple over
cant wait to see you fully simulate the wind forces and buoyancy of a pirate ship having the sails and rudder actually work
Very nice. I imagine that if the object wasn't interactive you could simulate it all in a shader.
What i would've done is position an oriented bounding box for the buoy, represented as a model matrix, at the rough location where it should be floating. This matrix is passed to the GPU in a buffer. After the computing the water surface, you run a separate compute shader pass, which modifies the model matrix to simulate buoy displacement. In the final pass, you render the buoy geometry with the modified model matrix. No need to pass things back to the CPU. The beauty of this technique is that you can probably render a hundred buoys this way via manipulating their corresponding matrices in the compute shaders, then apply instanced rendering.
9:06 Tony the Tiger... ❤️
Dude your videos are so good. Your timing between images is impeccable
yo i actually predicted where a video was going to go for once!!! i thought you were going to start off with the plane fitting algorithm thing and then was very disappointed but you CAME BACK TO IT
Running waves simulation on CPU is perfectly fine, until you calculate it only for some positions (where bounce objects are located). And you may avoid computing waves with length less than object size.
what a nice way to end the year with another acerola graphics adventures
Making the simulation more "physically accurate" could actually make it easier to adjust, if you take the height and normal vector deltas between the ocean and the buoy you can use them as forces acting on the buoy, then you only need to adjust the vertical and rotational inertia (and friction) of the buoy to make it feel "right". You can even add an adjustable spring along the plane of the water so the buoy drifts around a spot.
Directly sampling the normal vector of a particular detail level based on object size also allows you to skip the plane approximation.
Acerola uploads, we watch.
that's so cool, acerola. happy new year.
edit: i just watched an entire ad read because cat videos were playing off on the side. genius?
"It's at this point that our problem space moves from physics to signal processing, as all things do."
this line goes insanely hard
make the water go splish splash when the thing falla
Inertia (physics) and interpolation (simulation) would lend themselves well together.
You can also use bounding boxes, coordinate systems, etc, as a performance optimization.
Also, coarse grids progressively being refined into more granular grids only in small areas... Dividing the water into "chunks", etc.
i like how this video has floated to the top of my youtube suggestions. I hope it has the staying power to remain afloat and garner many views!
I learned something new, the video is enjoyable, and there is variety of options presented!
🎉 10/10 video
I can't believe you changed the thumbnail. The original one was SO GOOD!
I really like physics based buoyancy, it’s very satisfying to watch, but I understand how it’s not really realistic if you need a lot of buoyant objects. I’m honestly wondering how something like sea of thieves does buoyancy, since they need to have a lot of buoyant objects at once sometimes. I think for small objects they’re just setting the height position to the height of the water, but I’m not sure what’s being done for larger objects like ships, and I’m curious to know.
Probably just height queries at manually-placed spots around the ship, then apply an upward force at that spot scaled by the distance to the surface, fidget with drag / downward forces until it feels right. You can approximate a pretty convincing buoyancy with just 6 sample points for ships, everything else they just use 1 and the "swaying" is faked either procedurally or with an animation. What needs to stay upright is just facing the queried normal, and I guess you can also have a mix of fake swaying and facing the normal for even more convincing looks.
What is interesting about SoT is that you can't use anything shown in this video to get the water height on the server. There's really no way around it, the math involved must be replicated for both the gpu and cpu, the trick to read the gpu data back is just impossible to do with a networked game like that. How exactly they went about it is a mystery that would make for a very interesting talk imho.
My grug-brained solution a while back was just to quiet down the waters around the buoyant object, sine wave the up/down axis cpu on the object and pass the full location to the gpu to do the water quieting and let it join in up/down
Of course the equation for the semi circle is represented by the equation -sqrt(1-x^2), or if you do want to go further, you can replace one with r^2, but it’s helpful to start with a base case
Beautifull! I loved the plot twist with reading data back from the GPU!, and seeing you go through a similar thinking process for bouyancy,, even though, i never went with the voxel approach for performance concerns, i did, stategically placed a number of "buoyant detectors" arround what i decided would be the bouyancy line of a given boat model,, theese detectoirs simply read a few data points for our ocean, and apply the bouyant force at a rigidbody at each detector location., if they are below the ocean water., they push up, and if not they fall, by gravity, wich ensures that the rotation of the bouyant object will match the waves outline arrount it, although that push up or down is running in cpu, is constantly in motion riding them with no lag. I love to see you took the simulation approach! Amazing!!
6:50 godot does in fact now have async read backs. man i love being one of the maybe 4 people using godot for this sort of task.
want some more fun? most buoys are chained to a weight on the ocean floor, it'll drift and set at a distance versus chain angle, then swivel toward vertical instead of lift straight up and down, then slowly move back toward the drift position, distance depending on wave speed. more applicable to tides really, a stuff in tides simulations could be fun.
You can cut your simplified cylinder with the water plane and find volume and center of mass of the submerged part. That gives you a bouyancy vector. You can do a series expansion on cpu to get the value in single point.
TH-cam RELENTLESSLY recommended this video to me since its release. I have high expectations now
This was my final project for my computer animation class in my last semester of college
I always get such a happy feeling of excitement when this dude uploads
I love the silly and random cool and interesting programming videos, it's so fun!
Great video. You have one of the best and most informative channels on the internet! Love to watch your stuff!
It would be interesting to see how the amount of voxels, (and maybe their shapes & distribution in the cube) changes the simulation. Great video as always !
Hey, i made something similar a year ago. I was inspired by a part of the sea of thieves documentation, were they talked about having a complex visual ocean (gerstener waves) based on a more simple combination of sine waves. So my solution was having a nice looking shader(back then only shdergraph, bc i just started on cg) and calculating the the hight of the water with the biggest waves represented as sine waves. it looked nice and was really easy on the pc(my plan is to redo that stuff at somepoint and make the vr sailing expierience or puking simulator).
Hey why you want use point upward force, basically I mean sample the ocean surface at some point divide by you then add upward force at point. Also gpu is better because it doing all vertex, but CPU can do that little times like 10 to 100 times with no problem. That mean no need to take data from gpu to CPU, just directly run the algorithm in CPU, also point that I mention is preferred by you, for me 4 to 6 point enough for your model
Feels like spring has "too tough" coefficient. It takes several guessing iterations to find a nice look. At least in cloth simulation from scratch it took for me.
cool the buoy interacts with the water.
Now make the water interarct with the buoy - currently its just clipping into the water mesh.
fr tho, great content
I feel like a better version of the amazon package analogy is having a frozen dinner already ready, sticking it in the microwave, and not being able to do anything but wait for the food to be done because tbh you have nothing else to do and you're hungry and maybe it'll cook faster if you stare at it (it wont)
I didnt remember why i was subbed to you until i saw that tony the tiger thumbs up image. THAT of all things is what reminded me of who you were
For the problem where the bouy could wind up on its side, you could add ballast, like a real bouy has. Essentially add an extra rigidbody near the bottom of the bouyant volume and put a bunch of the bouy's weight there. If you want it usable by a designer, you could add some code in the inspector that calculates the correct weight for the desired bouyancy and puts some fraction of that weight in the ballast.
And to stop it from wandering, you could have an anchor, again like a real bouy has. It could be simulated as just a spring attached to the bottom that pulls the bouy back towards a desired position.
I prefer physics based solutions to things if I can manage it. It takes some insight into how to translate that physics into simple tools that a layperson can use, but I really enjoy that process anyway.
I just want to say Acerola’s cat + advertisement segment is the smartest thing ever.
the long distance cpu and gpu relationship hit way too close to home and tells me that I'm still not really over my 7 year relationship...
thank you for the happy new year video computer game png man
Ayy new Acerola video! Happy New Year
Happy new year Acerola! Great vid as always)
For the voxel aproach you dont need the volume displacement for them. if we have a dence enough voxel field we can approximate the displacement by just sampling the waterhight.
You could set a linear interval to sample the gpu requests to smooth out the raw data coming in. That could be a "sample rate" variable that you can set wherein a higher sample rate is more accurate but has more noise, whereas lower sample rates result in less accurate but smoother motion.
You could also simply bake the motion if the object is static. Since the sin waves won't change at that exact position after a each cycle.
i love your vids SO MUCH! thanks, Acerola.
Watching your videos with the sound off is like solving a rebus puzzle