2D Spinning Sphere
A simple shader that makes a 2D canvas item look like a spinning sphere. Make sure to set the “Repeat” import flag for your texture!
In the first example (the animation below), I used a sprite with a 2D image supplied by Solar System Scope to create a spinning Earth.
In the second example, I used two more sprites, both with a 2D cloud texture also provided by Solar System Scope. One has the as_shadow
shader param set to true, which creates dark, somewhat transparent shapes on the Earth. The non-shadow cloud sprite is scaled slightly larger than the other two sprites, so that the clouds float off the surface of the planet. As an aside, simply adding a radial gradient behind the planet to create an atmospheric glow can really sell the effect.
Note that the textures I used have an aspect ratio of 2:1. As such, the aspect_ratio
shader param is set to 2.0. Additionally, I had to set the sprite scales to match the aspect ratio (e.g. scale = Vector2(0.5, 1.0)
) to prevent an oval-like shape.
Shader code
shader_type canvas_item;
uniform float aspect_ratio = 2.0;
uniform float rotation_speed = 0.3;
uniform bool as_shadow = false;
const float PI = 3.141593;
void fragment() {
float px = 2.0 * (UV.x - 0.5);
float py = 2.0 * (UV.y - 0.5);
if (px * px + py * py > 1.0) {
// Outside of "sphere"
COLOR.a = 0.0;
} else {
px = asin(px / sqrt(1.0 - py * py)) * 2.0 / PI;
py = asin(py) * 2.0 / PI;
COLOR = texture(TEXTURE, vec2(
0.5 * (px + 1.0) / aspect_ratio - TIME * rotation_speed,
0.5 * (py + 1.0)));
if (as_shadow) {
COLOR.rgb = vec3(0.0, 0.0, 0.0);
COLOR.a *= 0.9;
}
}
}
Thank you for this!
I’m new to Godot and even newer to shaders so sorry if this is a stupid question. How can I make the planet rotate when I want it to? As rotating left when pressing left, right when pressing right and stop when not pressing anything.
I’ve managed to do it changing the rotation_speed variable but the texture “jumps” when changing direction, so I guess I should change something else but, as I said, I’m fairly new to this.
Thanks again!
Found the answer!
On line 21
that 1.0 is the “planet position” and changing it you rotate the planet left or right. So I created a variable for it and now can move the planet when I want.
On the shader:
And then in the GDScript whatever method you want to apply the movement and (I know this is not the best coding, it was just a fast test):
Hi!, I am trying to make it move vertically too, but the UV is distorted, like the image is distorted at the top and bottom of the sphere. Any suggestion how to do it?
Hi! I am still trying to do the same thing. Tried a lot of approaches, but none of them works. Still only able to rotate the sphere only in one direction. Since two years have passed, maybe now you have the answer? Any information would be extremely helpful for me
This is largely unavoidable due to the geometrical reality of mapping a rectangular or square texture to a sphere. This is why real-life Earth map projections all have weird quirks, for example.
In my opinion, if you want a 3D globe that can be arbitrarily panned to any point, then you should actually make a 3D object and UV unwrap it how you want it. If you’re just going for an effect that involves vertical spinning, then that can be faked fairly easily with this shader by simply rotating the sprite so that it spins on the angle you want, though this might require changing the texture to look the way you want it to.
very epik shader <3
Good shader!