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
"Shell Texturing"
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 begin we’ll think of the simples version of our problem.
If we would want to add a 2 dimensional atmosphere on a 2 dimensional globe the problem becomes much more simpler to solve, all we have to do is place a gradient circle behind the layer of the 2D globe. Now to step up in complexity let’s now imagine a 2D creature observing a sphere passing through their plane of existence. Since this creature can only see in 2D they see an infinitely small slice of the sphere, which for them is only a circle. This circle grows and shrinks as the ball rolls through their plane of existence.
Now how can this help in creating 3D gradient spheres? Well we could layer these observations from the creature, spacing each layer accordingly in the 3rd dimension. When a sufficient amount of layers have been added the result is a sphere. Since in Roblox this would not be a physical object but many GUI’s we can apply textures. Layering many textures to create a sense of 3D is often referred to “shell texturing”, a way many video games fake fur.
Generating 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 any GUI what we would normally do is change the RGB values, but what we need is to darken a portion of the GUI. 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.
But BillboardGUI’s (the 2D layers) always face towards the camera, which means that the shadows follow along. What we need is a dynamic shadow system.
To make a “3D” shadow from UIGradients, we’ll utilise the offset variable for the layers. If we apply an offset to the UIGradient there the z variable is the offset, we get a 45° degree shadow. And if we were to multiply that by a tan function we get an amazing shadow for the rotation of the Y axis.
now all that’s left is to solve what rotation offset we need the UIGradient to have. Compared to calculating the offset, the solution is relatively straight forward, just use atan2
to calculate on which direction it should look at.
How does AtmosphereService look
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:
- add this model into your game and place everything where needed.
- make a new script or local script and try adding an atmosphere. Its important to know what all variables do
- if any problems arise you can just message down below! I’ll answer some day.
Instancing Atmosphere
note: the provided code only works in the client
local AtmosphereService = require(game:GetService("ReplicatedStorage").AtmosphereService) -- Gets module script responsible for AtmosphereService
local Atmosphere = AtmosphereService.NewAtmosphere(
game.Workspace:WaitForChild("Earth"), -- Parent of the atmosphere
40, -- The radius of the atmosphere
500, -- The #Layers that represent the atmosphere (recommended value is 500)
.4, -- Transparency of the atmosphere
Color3.fromRGB(182, 194, 249), -- Color of the atmosphere
Color3.fromRGB(185, 255, 233) -- Transition color (from in light to shadow)
)
game:GetService("RunService").RenderStepped:Connect(function()
AtmosphereService.UpdateAtmosphere(Atmosphere) -- Crutial for generating the shadows
end)
I wish you the best of luck with your game. As said feel free to discuss ideas in the comments, maybe even show what cinematic masterpieces you created with it!