Is there a better way to create realistic fog?

Are you sure the fog is at fault? My GTX 1050 TI can run it fine. No lag drops, nor any noticable lag.

It sounds like you are generating a lot of physics overhead for the Roblox engine based on your described behavior. I would try several things:

  1. Set CanCollide property of the ball to false.
  2. Change the collision group of the ball using PhysicsService.
  3. Use the Offset property of FileMeshes instead of CFraming the ball part.

Point #3 sounds compelling.

I already have collision off (Given that it’s a small, anchored part, the collision shouldn’t be a problem anyway as there’s no interactions it has to do, and there’s no unanchored parts anywhere nearby with the exception of my avatar).

I’ll tinker with #2 and #3 to see what I can get to happen. I’ll edit my post after testing.

Update: Neither of those two solutions were successful. Good insight nonetheless.

You could try and decrease how fast your fog updates. Since you are updating on RenderStepped, you are updating every frame. Try decreasing the amount of time your fog updates (probably using a while loop)

That may be the one solution I have to take.

Through more testing I found that it doesn’t lag if the ball has Transparency=1, and it doesn’t lag if I simply don’t CFrame the ball.

This likely confirms my speculation that the lag stems from the render workload.

Update: Unfortunately the workload seems to be so heavy that even delay times of 0.2 result in lag.

I’m going to try something else where I use a flat plane situated in front of the camera to see how that ends up working.

Transparent parts can be incredibly expensive.

The transparency of the part is only >0 and <1 when transitioning from one state to another. Any other fog state will have the transparency at 0 or 1, nothing in between.

A bit of an update, using a plane in front of the camera has notable performance increases though they could use to be perfected.

In order to determine the size of the plane, I use this function:

function GetPlaneSize(Distance)
	local VPSize = workspace.CurrentCamera.ViewportSize
	local Aspect = VPSize.X / VPSize.Y
	local vFOV = math.rad(workspace.CurrentCamera.FieldOfView)
	local Y = 2 * math.tan(vFOV / 2) * math.abs(Distance)
	local X = Y * Aspect
	return X, Y
end

I should be able to make use of this by giving it some extra size to compensate for the slight delay from moving when it’s not bound to RenderStepped

You don’t need the whole sphere. You should only use the section of the sphere that the user can see. Roblox could be trying to render shadows or lighting from all around the sphere every time it is updated which could be the cause of your increased frame times.

Edit: combing this with your GetPlaneSize function could look just as good as using a whole sphere, although you may have to tweak it slightly to accommodate for the different shape

A bit of an update, I have come up with probably one of the single hackiest solutions I’ve made to-date.

I was able to get around this lag by attaching a BillboardGui to Terrain. The BillboardGui’s size is set to UDim2.new(W, 0, H, 0) where W and H are the return values from GetPlaneSize(Distance) (See response #12).

There is a Frame in this BillboardGui that has its color set to the fog’s color. The BillboardGui’s StudsOffsetWorldSpace property is set to the position of where the part would normally be, and the rotation is handled automatically by the UI element.

This isn’t really the best way in the aspect of long-term support (for instance, Roblox may deem it a good idea to not have fog affect BillboardGui, although I doubt this will be the case given that there was an update to add this a while ago), but it is most certainly functional and lagless.

5 Likes

I haven’t got the foggiest why you aren’t just using Roblox fog at this point tbh

2 Likes

This is what I’m currently doing, except I’m adjusting the container part’s position on RenderStep, instead of StudsOffsetWorldSpace. I think your method is better performance wise, so I think ill use that instead :slight_smile:

1 Like

I am using roblox fog – Roblox fog just doesn’t block out the sky, and that’s not realistic.

2 Likes

The Billboard gui is used to make the fog affect the skybox. (fog affects BillboardGuis)

It makes the fog much more effective at setting a lighting mood, you dont want evil black fog with a clearly visible pink skybox that has hearts on it :stuck_out_tongue:

nice pun lol

1 Like

This is a bit of a necro bump, but scaling up meshes or parts in Roblox to very large sizes always causes a lot of lag, instead scale the mesh inside blender or some other 3d modelling software before importing it. You won’t have any frame drops with it. It’s weird.

Does importing it as a large model really have a notable performance improvement? I may tinker with that to see how it works out and what it can do.

What do you mean ‘StudsOffsetWorldSpace property is set to the position of where the part would normally be’ ; I’m setting StudsOffsetWorldSpace to game.Workspace.CurrentCamera.CFrame.Position . Is that correct? It isn’t working correctly for me

If I recall (I haven’t touched this in a while), I mean something like workspace.CurrentCamera.CFrame * Vector3.new(0, 0, -z)z needs to be set to Lighting.FogEnd.

Hey, I’ve been running into the same issue but I am using the new Atmosphere class.
Would anyone happen to have a solution for those using it?

I made something like this before except I had it so that the CFrame was set to the HumanoidRootPart’s CFrame instead of their camera’s CFrame. Also, I wasn’t ever going to change the look of the fog, so I only needed to apply the CFrame every step (I wouldn’t have to worry about the color or scale, in your case).

Since it was still kinda jittery, I just attached it to the character’s HumanoidRootPart using a WeldConstraint to solve it.