Performant, Procedural, Physics Based Skinned Mesh Ocean and Buoyancy Simulation!

Since the introduction of skinned mesh deformation and having further been inspired by tyridge77 's post I started working on my own skinned mesh ocean system.

Over the course of 2 years, on and off, I have continued to improve and refine this system, hoping to turn it into a passion project.

Today, I am excited to share with you the various physics-based interactions with Wind, Sea, and Sail that I’ve developed!

(Sails facing against the wind while raining)

Of the entire system I have a few things I want to showcase specifically here!

  • Procedural Skinned Mesh Ocean System :ocean:
  • “ShipAlign” Character Handling :person_standing:
  • Real-Time Physics Wind Based Sails :wind_face:
  • Ship Buoyancy Simulation :sailboat:
  • The Endless Horizon! :sunrise:
  • NPC Handling :person_cartwheeling:

There are a lot of attachments so I separated them into categories for your convenience.

More Attachments

Procedural Skinned Mesh Ocean System!

Real-Time Physics Wind Based Sails

Sails are also skinned meshes! By using parabolic equations, we can offset these bones based on the wind. We can also use these bones to raise and lower the sails!

Note: Both the waves and the sail displacements are computed in parallel to maintain under 1ms a frame in total :slightly_smiling_face:

"ShipAlign" Character Handling

Something I hated experiencing was not standing correctly on the deck of the ship. It took some time but with a lot of CFrame operations I was able to correct the stance of characters and their cameras accordingly.

(Before ShipAlign)

(After ShipAlign)

NPC Handling on ships

Using the same system above, ShipAlign, I was able to let NPCs pathfind onboard a dynamic ship in order to perform tasks for the player!

Ship Buoyancy Simulation

You might have seen the spheres and blocks inside the featured galleon; these are actually used to calculate the displaced volume and apply an equal force to raise the volume upwards!

It’s a little hard to showcase the buoyancy exactly, but look at it go up that wave! (Also, weight distribution is a pain, don’t judge me!)

The Endless Horizon!

Utilizing a combination of atmospheric effects, and multiple levels of detail for the water, the water smoothly transitions into the atmosphere!

Atmosphere and sun movement
Screen Rain
Wind Lines
I could not find the original creator for the galleon model I used, if you know the original creator please let me know!


Hey! This simulation is impressive and I don’t have words to express my fascination, I can’t make myself with physics haha. Keep up the good work and wish you luck!

1 Like

Yo, im trying to make something similair using vectorforces.
Firstly, is that similair to your strategy? could you give some insight on your bouyancy mechanics?
secondly, are you replicated the waves clientside? Im doing the tiling method for infinite oceans that causes no lag, but i feel like it make a slight disconnect between server and client which bothers me :frowning:

wait, second question. you are using bones to deform the mesh right??? cuz if roblox added vertex manipulation that would be AMAZING but i havent seen it

There actually IS vertex manipulation. Though im unsure if it useable in a live game or not. I plan to switch over to that so I can add dynamic level of detail to the wave resolutions.

Currently, yes, I am using bones to deform the mesh ocean.

The server doesn’t know where the waves are, but instead uses a planar equation and the position of bones (which are always arranged in a predictable grid) in order to find the height of the waves at any position in the worl.d.

First, with buoyancy, the entire ship is made massless except for a large yellow box who’s density is modified in order to achieve a certain weight for the ship. Secondly, the ship uses vector forces located at the cylindrical spheres to apply force equal to the amount of displaced volume of water (who’s density can be modified).

Also as for disconnect versus client and server, Ive never had this issue. Ive always used workspace:GetServerTimeNow().

(Old Picture)

I do recommend though, making sure your height lookup functions take into account the spacing between bones. As unless you have an ocean of infinite bone resolution, the spacing between them is a straight line unlike what is seen in a Gerstner wave, though you could also modify the equation itself to take this into account. This could be the reasoning behind the slight disconnect between client and server (X,Z displacement not being taken into account in height lookups)

Hope this helps!

I see that you put a lot of Effort in this game and the Details are great.