Simulated Ocean with EditableMesh

Inspired by this post, I decided to try my own hand at creating a simulated ocean with Gerstner waves. After a few months of work, I managed to complete it with the help of colleagues, with the goal of releasing this publicly for anyone to use this in their games or to simply learn how it works.

Features:

  • Multithreaded (honestly have no idea if this is working properly)
  • Frustum culling
  • Vertex Lerping (distant vertices aren’t updated every frame)
  • Customizable settings (ocean size, detail, color, etc…)
  • ‘Infinite’ (the ocean plane will follow your camera)
  • Vertex coloring / depth coloring
  • Texture scrolling
  • Accurate & performant height lookups → Buoyancy system for boats included
  • Zone system, allowing you to create custom zone areas with different wave parameters (ex. rough sea areas)
  • Whirlpools
  • Ocean plane can be subdivided to have more vertex detail near the camera
  • Shorelines (vertices are slightly transparent and colored differently near shallow water)
  • Synced between the server and client (can do precise height lookups on the server/client)

There are definitely improvements that can be made to the ocean, which are mentioned in the main script.

Additionally, this isn’t a perfect system, and comes with some limitations due to performance or technical reasons:

Limitations:

  • Height Lookup: It can rarely ‘fail’ at certain times if the vertices of the ocean mesh are very deformed, an example being a whirlpool, since the vertices are displaced in it. There are some precautions to avoid this from happening.
  • Ocean texture near whirlpools: The UV’s of the ocean are rotated near a whirlpool in order to mimic a vortex effect, and this obviously leads to distortion / warping around the whirlpool due to the rotating texture.
  • Vertex popping: Because of the way the LOD for the ocean works, vertices can occasionally ‘pop’ when the ocean plane readjusts itself to follow the camera, depending on your wave parameters. This is specifically due to the LOD having no smooth transition between different levels.

There are also some issues with EditableMeshes in general, such as vertex transparency not functioning properly unless the entire mesh plane is slightly transparent, alongside some frustum culling issues Due to this, some features may not work correctly until these issues are fixed.

Videos:


Accessing the place:

You can access the ocean system here: Ocean Simulation - Roblox

There are two scripts inside StarterPlayerScripts for running the ocean, as well as multiple ModuleScripts in ReplicatedStorage. For editing the way the ocean looks, there’s a ‘Settings’ module where multiple properties of the ocean can be modified to suit your needs.

Additionally, there’s a boat, whirlpool, and rough sea area with scripts inside them to show how they’re set up.

Comments are also placed throughout most scripts / modules to help give an understanding of how it works.

How to use:

  • Main script is located in StarterPlayerScripts
  • Modules are in ReplicatedStorage (‘Gerstner’ module has a settings module nested inside)
  • 2 boats are under Workspace, one is a boat with buoyancy simulated on the server and one is a controllable boat simulated on the client
  • A whirlpool and rough sea area are included to demonstrate how they are spawned in
  • A single part with buoyancy is also included to demonstrate height lookups for a single point / part
  • Workspace.Ocean is a folder where the ocean plane(s) are stored
  • Workspace.Map is a folder for islands required for shorelines to function
50 Likes

This is very impressive. Well done!
I might use this for showcases and the such.
But I do have a question. When you say “infinite” do you mean that the ocean will always be visible and nothing else is?
Could you for example, place a part and tag it with ocean which, on run transforms it into one?

3 Likes

This looks fire as hell, awesome work

2 Likes

Very awesome work, glad to help on testing this with you.

2 Likes

Thank you!

The ocean is infinite in the sense that the entire mesh will follow your camera, making the ocean look infinite no matter how far you go.

Unfortunately, you can’t place ocean tagged parts to transform them, but it’s definitely possible with some heavy modifications to this system.

Now this is a cool thing for sure. Thanks for sharing!

1 Like

Something with the normals near the whirlpool?

You’ll need to set “DEPTH_ENABLED” to false in the settings module. This occurs because for vertex transparency to work, the entire ocean plane needs to be slightly transparent (some unintended issue that ROBLOX is working on).

1 Like

Your multithreading seems to be working correctly from my testing, I tested with the BrownianMotionWaves function and 200 waves (while removing the limitation you placed on it) and was getting around 120 FPS with only one worker thread, but with 4 worker threads I was getting 200 FPS.

1 Like

Imagine if a onepiece game uses this :fire::fire::fire:

Average one piece games user device will explode of such load

2 Likes

This is incredible. How could one create a character that could swim in it? Is it difficult as it is client-sided and won’t appear on the server?

Are there any benchmarks on how this compares in performance to other implementations like ones that use a skinned mesh instead?

Absolute CINEMA. This has so much potential it’s insane, thank you so much for sharing it!

1 Like

excuse me if im being ignorant; the client boat (haven’t tested the server one) seems to be kind of floating, how would you fix this?

also, is it possible to do a height lookup on the server?

image0

The client boat was programmed such that it only ‘activates’ once you sit in the VehicleSeat for it. You can easily change this to run on the client at all times, similar to how the server-sided boat works.

Yes, you can do the height lookup on the server, and it should be synced between the client and server as well.

1 Like

ah, i meant floating in the water, like, while driving it.
either way, one of the best open sources ever, thanks a lot!

Wouldn’t this look awful when moving around in the ocean? It would impact the buoyancy physics of boats etc.

There appears to be issues with the chunking and/or rendering priority? I notice the rough seas area for example sometimes won’t render for a while, or will influence the ocean unevenly, with some parts being effected, others having a hard cutoff, and other weird stretching issues.

Besides the rendering issues this looks great! If it was a little more polished I’d probably just straight up use this for future projects.

(It’s not letting me upload a video of it, but there’s a lot of jumping and popping in and out probably due to LOD’s, and theres noticable hard cutoffs that seem somewhat inconsistent with stuff like islands, rough sea part or the little vortex part. Like it genuinly forms a massive water wall between the rough seas area and the normal sea but based on your position will sometimes properly render and then go back to weirdness when moving your camera.)