Planetary atmospheres on Roblox

Introducing AtmosphereService

Hello my fellow Roblox developers, today I’m glad to announce that celestial atmospheres are no longer an issue on creating realistic planets or gas giants. On this guide we’ll walk you trough how AtmosphereService works and how you can implement this into your next game.


What is AtmosphereService?

As said AtmosphereService is a helpful tool when making atmospheres outside of the skybox, what that means is that you can apply atmospheres into other spherical objects.


The core system behind AtmosphereService

To modify and change the core of atmosphere its important to understand how it all works and the design choices made with the code, so lets go through it “all” together.

We know that on Roblox you can’t really have gradient spheres, so to make this easy we’ll jump down a dimension. Let’s imagine an intersecting slice of a sphere on a plane, that’s just a circle isn’t it? Well if we think about that this means instead of having a physical object representing the gradient sphere we have many layers of 2 dimensional circles that build up a sphere.

But we are missing a very important detail, the shadows. Basically the most important aspect of creating a good looking atmosphere is the shadows (not including the refraction of light). We’ll have to dig into some math and reconsider how shadows will work since it’s not plausible to add a 3D shadow to a 2D object, but what’s there to expect than just math math math! To darken a ImageLable or any GUI what we would normally do is change the RGB values for the ImageLable, but what we need is to darken a portion of the ImageLable. What we need is a UIGradient. If we apply a UI gradient to the gradient circles the resulting output is an atmosphere with half of it covered in shadow.

We could call that a day but what we need is a dynamic shadow system. To make a “3D” shadow from UIGradients, we’ll utilise the index variable for the for z = -detail/2, detail/2 do. If we apply an offset to the UIGradient there the z variable is the offset, we get a 45° degree shadow. And if we where to multiply that by a tan function we get an amazing shadow for the rotation of the Y axis, now its just to solve what rotation offset we need the UIGradient to have. It’s simple math really, just use atan2 to calculate on which direction it should look at.

So that’s how the core of AtmosphereService works, now for the looks.


How does AtmosphereService look

:eyes: pretty good I would say, could be better.


Implementing AtmosphereService into your game

To implement this groundbreaking feature to your game follow these two steps, if you can:

  1. add this model into your game and place everything where needed.
  2. make a new script or local script and try adding an atmosphere. Its important to know what all variables do
  3. if any problems arise you can just message down below! I’ll answer some day.

And remember, the fog is coming…

14 Likes


I get this when I click the link

1 Like

oh no. looks like I forgot to do something. l’ll fix this as fast as possible

1 Like

I think I fixed it, thank you for telling me about that!

2 Likes

Got me interested so decided to give it a try


For me, the atmosphere looks nothing like the screenshots you provided, am I doing something wrong?
Code:

local replicatedStorage = game:GetService("ReplicatedStorage")
local atmosphereService = require(replicatedStorage.AtmosphereService)

local thisAtmos = atmosphereService.NewAtmosphere(workspace.Earth, 18, 500, 500, Color3.fromRGB(116, 211, 255), Color3.fromRGB(0, 0, 0))

while task.wait() do
	atmosphereService.UpdateAtmosphere(thisAtmos)
end
1 Like

hmmm, it looks correct but lets try with this code:

local AtmosphereService = require(game:GetService("ReplicatedStorage").AtmosphereService) -- Gets module script responsible for AtmosphereService

local Atmosphere = AtmosphereService.NewAtmosphere(game.Workspace:WaitForChild("Earth"), 40, 400, .4, Color3.fromRGB(182, 194, 249), Color3.fromRGB(185, 255, 233)) -- Instances a new atmosphere

game:GetService("RunService").RenderStepped:Connect(function()
	AtmosphereService.UpdateAtmosphere(Atmosphere) -- Crutial for generating the shadows
end)

If this doesn’t work there must have been a problem when implementing the AtmosphereService, hope this helps

2 Likes

That did the trick, thanks! I’m definitely using this in a space game I’m making

Keep up the great work!

2 Likes

can you supply a .rbxl with a working planet? I added the code at the bottom of this post to a local script and a model called Earth… and I do not see any change…

Hello! Looking from the provided code and image I suspect that your atmosphere is scaled to small, setting the right variables are crucial for this to work. Try to peek into the planet to see if you get a gradient ball. If so and it’s to small, you’ll have to change some values when adding the atmosphere.

Now I would like to explain what these values represent since it seems like this has been the root of most problems when implementing atmospheres.

The first variable requires the parent for the atmosphere
The second variable explains the size of the atmosphere
The third variable explains the amount of 2D layers should represent the gradient sphere
The fourth sets the transparency of the atmosphere
The fifth variable explains the color and the last variable explains what color the transition from bright to dark there shall be.

Hope this helps :+1:

1 Like