Realistic Oceans Using Mesh Deformation!

To make that work, you will need to call your gerstnertransform() function like my computeDisplacement() function. (see my previous reply)

You only need to return the height.

1 Like

I donā€™t think Iā€™m implementing that function correctly at all. I donā€™t know what Iā€™m supposed to do with it.


These are the functions:

function GerstnerWave(SamplePosition,Wavelength,Direction,Steepness,Gravity,SampleTick)
	local k = (2 * math.pi) / Wavelength
	local a = Steepness/k
	local d = Direction.Unit
	local c = math.sqrt(Gravity / k)
	local f = k * d:Dot(Vector2.new(SamplePosition.X,SamplePosition.Z)) - c * SampleTick
	local cosF = math.cos(f)

	--Displacement Vectors
	local dX = (d.X * (a * cosF))
	local dY = a * math.sin(f)
	local dZ = ( d.Y * (a * cosF))
	return Vector3.new(dX,dY,dZ)
end

function wavefunction(v) -- This is used for the bones, and it works correctly
	local WorldPos = v.WorldPosition - Vector3.new(root.Position.X,0,root.Position.Y)
	local Wave1 = GerstnerWave(WorldPos,90,Vector2.new(.5,.5),.4,4,SyncModule:Time()*timemodifier*1.2)
	local Wave2 = GerstnerWave(WorldPos,120,Vector2.new(.8,.2),.1,15,SyncModule:Time()*timemodifier*1)
	local Wave3 = GerstnerWave(WorldPos,400,Vector2.new(.7,0),.015,1000,SyncModule:Time()*timemodifier*0.02)
	local Wave4 = GerstnerWave(WorldPos,400,Vector2.new(0,1),.01,1000,SyncModule:Time()*timemodifier*0.026)
	local TotalDisplacement = Wave1+Wave2+Wave3+Wave4
	v.Transform = CFrame.new(TotalDisplacement)
end

function gerstnertransform(v)
	local WorldPos = v
	local Wave1 = GerstnerWave(WorldPos,90,Vector2.new(.5,.5),.4,4,SyncModule:Time()*timemodifier*1.2)
	local Wave2 = GerstnerWave(WorldPos,120,Vector2.new(.8,.2),.1,15,SyncModule:Time()*timemodifier*1)
	local Wave3 = GerstnerWave(WorldPos,300,Vector2.new(.7,0),.015,1000,SyncModule:Time()*timemodifier*0.02)
	local Wave4 = GerstnerWave(WorldPos,300,Vector2.new(0,1),.01,1000,SyncModule:Time()*timemodifier*0.026)
	local TotalDisplacement = Wave1+Wave2+Wave3+Wave4
	return Vector2.new(TotalDisplacement.X,TotalDisplacement.Z)
end

Here is the swimming height offset detector

rs:Connect(function()
	plane.Caustics.OffsetStudsU = -root.Position.X * 0.75
	plane.Caustics.OffsetStudsV = -root.Position.Z * 0.75
	plane.WaterTexture.OffsetStudsU = -root.Position.X * 1.2
	plane.WaterTexture.OffsetStudsV = -root.Position.Z * 1.2
	
	plane.Position = Vector3.new(root.Position.X,plane.Position.Y,root.Position.Z)
	
	for _,v in pairs(bones) do -- this whole loop works the way its expected to, albeit its really performance heavy.
		wavefunction(v)
	end
	
	if root.Position.Y < getHeight(gerstnertransform(Vector3.new(root.Position.X,plane.Position.Y,root.Position.Z))) then
		print('underwater')
	end
	
end)

First of all, without editing it, thereā€™s an error because Vector3 and Vector2 are not the same, and I donā€™t know how the two vectors are supposed to relate when it comes to the formulae you guys provided.
Secondly, I donā€™t really know if Iā€™m implementing it correctly ā€“ Iā€™m 99.9% certain that Iā€™m extremely off.
Edit: Thirdly, it seems like Iā€™m not even anchoring the plane to my character correctly about half the time. My movement displaces the waves sometimes.

Do you have a working example of this? I am doing something similar with scenery elements on land, only rendering ones within a certain distance from the camera, but I think your method would be more efficient and allow me more density of objects.

1 Like

Hi! Sorry if this counts as necroposting but, how do I make the ocean bigger? Iā€™m trying to make a fairly big map but itā€™s bigger than the ocean.

Check out my example of an ocean with 4 ocean planes in the original post.

So I did the ocean and it worked fine for a while, but recently itā€™s caused an IMMENSE amount of lag out of nowhereā€¦ deleted it and the lag was gone. Any reason this could be happeningā€¦? Any fixes?

Thatā€™s the nature of it. Skinned meshes with this amount of bones and movement arenā€™t always perfectly performant.

I suppose, I only ask because it wasnā€™t nearly this awful before, the performance was barely even affected on account of my friends experiencesā€¦ but now itā€™s unreasonably laggy unfortunately

is there any method to get the cframe at a specific point? its extremely important for making objects float

this yields an error
image
even after fixing the bug (the order of the transform and point), it wont give me accurate results

you have to understand that the gernster wave formula returns x and z offsets in addition to y, so getting the y level at a certain point is going to be really difficult as the wave not only rises and lowers, but moves side to side.

Iā€™ve managed to narrow down the problem but Iā€™m absolutely stumped where to go here:

i have the exact position of the 3 xā€™s, i have the x and z of the red X, how can i calculate the red Xā€™s y position so that it will be on the plane created by the black circles (the plane is the blue polygon)

Image

1 Like

If anyone is interested in making water float on the mesh heres what worked for me:

Find 4 points to make your point fit inside of them, narrow it down to 3 (so that your on the same side of the triangle), use interpolation between those 3 points to get the exact y value

4 Likes

can u make soo the wave follows the player with bone offset and uv texture offset

How are you able to place planes next to each other? When i do it the whole script does not work. But if there is only one plane it works fine. How do i fix this?

You just duplicate the entire plane model (all of it) and move it, shouldnā€™t be any issues. Check my WaveExample-4Plane.rbxl model out in the post for an example

1 Like

By the way, refresh is broken.

Any waves I duplicate are out-of sync. Whereas yours are fine. Solution?

https://gyazo.com/9c130880c9575423a712fce8af2d78ee

P.S I followed the layout of your 4 wave and just added 2 of my own, 5 and 6 (which are both out of sync from the rest)

Hello! This hasnā€™t seemed to work, the ocean does not move on the duplicated one, it only moves on the original ocean. How do I fix this?

You have to use the module I coded in order for it to work. There is a script in StarterPlayer that initializes the model as a wave, you would have to do the same for other wave models for it to work