Realistic Water Simulation in Roblox: Custom Physics (No Terrain Water Used)

As some of you may know, the current water in Roblox looks… okay. A year ago, I embarked on creating a myth game. By my standards at the time, I did a good job, but I couldn’t help but notice that the blood water looked a bit lackluster, as I was using the default water terrain.

Recently, I took on the challenge of developing a more detailed water system than Roblox’s default, and I believe I’ve made a significant breakthrough. Here’s what I achieved:

With one simple change, I managed to improve the FPS from 1 to 48. This is very good with the limits on Roblox. For those familiar with how games store mesh information, there’s a folder that contains all vertex positions. These vertices build up 3D triangles, which in turn create a mesh. Realistic seas in games don’t usually create a new mesh from scratch; they use a displacement map. That’s exactly what I did, making the vision for generating realistic water a reality without insane lag spikes.

Additionally, here’s the same number of triangles for a smaller, much more detailed area:

And for those interested I will be posting updates sometimes : )

4 Likes

Update: Water Physics Development

I’m currently adding the water physics. Here’s a sneak peek into how the system works:

The physics code captures the character’s velocity—both its strength and direction. Using this data, the system determines the movement and force to apply to the water. This allows us to create realistic wave dynamics, deciding whether they should rise or fall based on the character’s interactions.

And yes I might release the code, I’m not that secretive, but I will make sure to post updates when I’m done with the physics.

3 Likes

Update: Water Physics - Velocity Transfer

After some experimentation and leveraging basic physics knowledge, I’ve discovered effective formulas for simulating energy transfer between neighboring quads.


Waves

Simulating waves can seem complex, but I found a straightforward approach during my testing.

VelocityY = VelocityY / (1 + EnergyLoss) + Position.Y / 50

This formula creates a dissipating sine wave effect, mimicking real wave behavior. However, issues with unstable speeds arose. Excessive speeds led to unrealistic compression and prolonged wave dissipation. To address this, I integrated the exponential function, which stabilized the velocities:

VelocityY = VelocityY / (math.exp(math.abs(Position.Y / 500) + EnergyLoss)) + Position.Y / 50

This adjustment produced more realistic and stable results, even at high velocities.


Velocity Transfer

Transferring velocity is quite simple. By using cosine and sine functions, we can add the velocity of a quad, multiplied by a velocity transfer strength variable, to neighboring quads.

This is the progress I’ve made so far!

3 Likes

Update: Water Physics - Velocity Transfer 2

As mentioned previously, I use the direction of the force to estimate where current force will be transferred. I have fixed most bugs except for one related to the energy transfer algorithm.

Currently, there are many issues with the system, but I will focus on one: the speed at which velocity gets transferred. Each vertex of the mesh plane is assigned a velocity array with three important variables: Velocity_Strength, Velocity_Direction, and VelocityAttraction_Direction.

The problem lies in the limited number of vertices. Since the velocity transfer direction for each axis can only be a float between 0 and 1, the speed of the energy transfer depends on the mesh’s Level of Detail (LOD). Increasing the LOD could solve this, but it would hurt performance.

Therefore, I am considering a fixed LOD specifically for the velocity grid. This should fix the problem, but it’s crucial not to compute too many values every frame and to have enough pixels/stud to not enter the problem of high LOD mesh’s looking the same.

I’ll update once I have implemented and tested this solution.

Update: Water Physics - Velocity Transfer 3

Well, no. That didn’t work, but I did mention that a big risk on attempting to implement my idea could be lag. So I’ll just have to find another way to slow down the transfer speed… As long as I can get this working I’ll be finished on the V.1 for the physics and I’ll post how others can implement my code into their game

Oof this is a hard one

1 Like