How can I make water like this?

I saw this water system in Nitefal’s The Labyrinth, which the when your camera is above the water, it’s normal.


But when you move you camera under the water, it’s blurred.

Also when you dive deeper, it gets darker and more blurred.

How can I make water like this?

5 Likes

I think this would go in #help-and-feedback:scripting-support

but I’ll help anyway, a really hacky way I guess you could do it is have different layers for each part of the water and then use :GetTouchingParts() and then do everything you want to do

like so
image

or however many layers you want

2 Likes

To stay with #help-and-feedback:building-support , though, you could use water terrain and then put a glass part over the water. (This will turn the water invisable)

1 Like

You’re right. I could change the brightness and blur effects. But how would I make the camer thing, in which it’s blurry if your camera goes underwater?

The camer thing what is that could you be more precise

When you move your camera with right click. When your veiwpoint is above the water, it’s not blurred. When it’s below the water, it’s blurred. See the images for refrence.

You just talked about how when its above water its normal, and then when you go into water its bit more blurry, and then deeper than that is even more blurry

You have 2 options
1st - Have the water level constant in your game and never have any open air under your water level, W.

On heartbeat, you would check if the camera.CFrame.Position.Y is less than or equal to W. If so blur the camera and set the UI opacity based on the difference.

2nd - Have invisible parts covering the mass of the water all underneath a group. This will allow you to have more water systems and is the better, more complex option.

Check if camera is inside any part by using CFrames and detect the difference in Y level then do the same in option 1.

If you need help with the math and CFrames, ask.

2 Likes

That’s when you’re swimming deeper. It gets blurrier and darker when you are swimming deeper. When your veiwpoint is underwater, it is affected by the blur and darkness. When your viewpoint is not underwater, it is not affected by the blur and darkness.

I think I just solved my own question.

The problem with this option is that you are not looking from the character’s perspective, this may need to some camera positions that should be affected.

I know this is offtopic but
@Ehonix Could you tutor me some maths

Please be more specific and you can directly message me.

Is there a tutorial on how to do all this?

I could make one and then let you know once it is finished.

If you make a tutorial about this, thanks so much!

It’s a relatively trivial thing to script. Put this as a LocalScript in the StarterCharacter and put a part named “water” in the Workspace. The script will account for rotation as well.

local camera = workspace.CurrentCamera
local waterPart = workspace:WaitForChild("water")
local rs = game:GetService("RunService")

local blur = Instance.new("BlurEffect")
local colorCorrection = Instance.new("ColorCorrectionEffect")
blur.Enabled = false
colorCorrection.Enabled = false
colorCorrection.TintColor = Color3.fromRGB(108,135,255)
blur.Parent = game.Lighting
colorCorrection.Parent = game.Lighting

rs:BindToRenderStep("underwaterCamera", 201, function()
	local objectSpaceCameraPosition = waterPart.CFrame:PointToObjectSpace(camera.CFrame.Position)
	local waterDepth = math.abs(objectSpaceCameraPosition.Y - waterPart.Size.Y/2) -- How far the player is below the water level
	local inWater = true;

	if (math.abs(objectSpaceCameraPosition.X) > waterPart.Size.X/2) then
		-- Out of bounds on the X axis
		inWater = false;
	end

	if (math.abs(objectSpaceCameraPosition.Y) > waterPart.Size.Y/2) then
		-- Out of bounds on the Y axis
		inWater = false;
	end

	if (math.abs(objectSpaceCameraPosition.Z) > waterPart.Size.Z/2) then
		-- Out of bounds on the Z axis
		inWater = false;
	end


	blur.Enabled = inWater;
	colorCorrection.Enabled = inWater;

end)
9 Likes

How does this script work? I’m interested.

It converts the camera’s position to the local-space (object-space) of the water part. This allows it to not care if anything is rotated.

So, in the end, the camera’s object space position will read something like this

Where the yellow line represents the object-space (basically the distance) the camera is from the center of the part. The red line is the size of that part’s particular axis.

The camera is 4 units away and the total water length (just for screenshot example) is 5 on that axis. So I check if the camera is Length / 2 units away (2.5 because 5/2 is 2.5) from the center of that axis. I do this for all 3 axes. That will tell me if the camera is inside the part or not.

5 Likes

Im realy realy sorry since i have to bump this but how would i implement the water if it was in for loop with Ipairs since i want it to be kind of modular so i can use the collection service which return a table full of instances? so i loop the table and do this procedure in each one since i tried 2 hours ago and it was a failure?

1 Like