2
\$\begingroup\$

I'm making a space game using Godot 4, and I need to capture the "hugeness" of planets. I figured I'd use spheres with textures on them for planets. The textures have identifiable landmasses on them, because that's consistent with what planets have. You should be able to recognize the same landmass when you see it again.

The planets all need to spin, as planets are wont to do. I figure I'd just rotate the mesh itself while the player space ship is still far enough away.

My difficulty begins with approaching the planet closely enough. I don't want to land on any planet, but I do want to be able to achieve a low enough orbit that gives the sense of a horizon. The little picture should illustrate it well enough. little picture I figure I could "squash" the sphere into basically a flat circle when the ship gets close enough to the planet, and you wouldn't notice. I'd point this flattened sphere at the player's position, so it would function like a billboard in that sense. This flattened sphere could then be scaled up in the right directions, to give the sense of a vast circular plane almost.

I figure I could do some kind of trickery with UV offset and scale to keep the texture "in the right place", but i don't have any idea where to start, especially because it would need to be scaled up when you get close to it AND it would need to be in the same place as it was when you were further away from it AND...the uv would need to be offset by the rotation of the planet constantly because when the mesh is squashed, you can't rotate the mesh itself anymore. truthfully, i don't have much experience with uv shenanigans, nor with optical perspective. This whole approach is just an intuitive attempt, but i have to do SOMETHING because just "really big spheres" doesn't give a good enough impression of the hugeness of planets and stars and moons, and I don't know any of that shader black magic that could do the sphere-imposter trick on a quad (especially one you could freely orbit around).

The textures don't need to be super sharp: maybe i could stylize them somehow to be acceptable, but they DO need to have those recognizable landmasses which you can revisit, hence the difficulty.

Does anyone have any pointers for how to do this? Alternatively, does anyone know of a better solution for giving that "vastness of planets" feeling that emerges seamlessly once you get close enough to a planet?

\$\endgroup\$
5
  • \$\begingroup\$ Working with a sphere can easily give that horizon feeling, especially if you're using a shader to draw an atmosphere. The trick is that your perspective needs to be close to the surface of the sphere (on the order of 1.02 * radius). As a data point, Earth's radius is 6,371 km, the ISS orbits at 400km and that's pushing the limit for a horizon. \$\endgroup\$
    – Basic
    Commented Feb 23 at 23:15
  • \$\begingroup\$ the difficulty with using a sphere (i've found in experimenting), is that once i make the radius of it large enough, it also necessitates that the center of the sphere be far away from the player...and this introduces a bunch of issues with flickering which i think comes from floating point truncation and z-buffer confusions...if i make it a squashed sphere (or a flat cylinder, for instance) then i can have the center of that sphere much closer to the player, and i can limit the radius to avoid issues. maybe i could use quad at this point too, but a circle seems to look better. \$\endgroup\$
    – w94n9
    Commented Feb 24 at 20:51
  • \$\begingroup\$ The way I've approached this before is to use two cameras, one for "large scale" objects, another for the ship/foreground. You can use different coordinate systems, scale movement, etc... This may break down for certain visual interactions between foreground and large-scale objects. You may also find issues with the number of verts you'd need for a smooth horizon at that scale. An alternative approach to a sphere is the CubeSphere demo'd by Sebastian Lague here: youtube.com/watch?v=lctXaT9pxA0 (and throughout that series) \$\endgroup\$
    – Basic
    Commented Feb 24 at 23:59
  • \$\begingroup\$ @Basic I wish i could do that! it looks so cool. Unfortunately, this project i'm working on is in VR, and it doesn't seem like you can do a double-camera trick with an XRcamera. might work for in-game video screens though (like ship computers), thanks for the tip! \$\endgroup\$
    – w94n9
    Commented Mar 3 at 16:46
  • \$\begingroup\$ It may still be possible. I'm not familiar with XRCamera but do you have the concept of rendering to texture? If so, render large-scale to a texture, clear the camera with it, (rather than a color/skybox) then render over it. That said, you'd need at least 3 cameras, possibly 4 (depends if large scale needs parallax), so possibly not viable for that reason alone. Different approach: Do you have specific images you want to use for continents? Or is an arbitrary (recognisable, repeatable) shape good enough? If the latter, you might be able to do the whole thing with shaders. \$\endgroup\$
    – Basic
    Commented Mar 3 at 20:08

1 Answer 1

0
\$\begingroup\$

One way to approach this would be to generate the surface of the planet procedurally, using weighted octaves of noise;

Start with a noise function like Perlin or Simplex that takes an x/y[/z] coordinate and returns a value (usually 0-1) for that position.

By scaling the sample coordinates, you can generate different "octaves" of noise.

enter image description here

Blending those together with different weights can give a texture that works very much like a height map, except it can be sampled at arbitrary levels of detail...

enter image description here

Pick a cutoff height as a water level and you now have randomly shaped, but deterministic/repeatable continents with mountainous features.

enter image description here

If you want to go a step farther, you can also calculate erosion and other effects. It'll give you a more realistic result, but it'll be a lot more compute intensive and may require pre-calculating.

For more info on the approach see:

You can either use a 2D noise function and map a 2D coordinate system to your sphere's surface (but you'll get the usual spherical wrapping quirks) OR use a 3D noise function and just sample the points in space for the surface of the sphere, then treat that as a surface height.

Add a random offset to the coordinates for each planet and you'll get unique (but deterministic) results.

\$\endgroup\$
5
  • \$\begingroup\$ smart, i like it. \$\endgroup\$
    – Pow
    Commented Mar 3 at 21:58
  • \$\begingroup\$ Noise is a great texturing solution once you have the projection math down. To add, I would indeed highly suggest using 3D noise, as you mentioned, rather than contorting a flat 2D function to fit a sphere. There is virtually no need to accept the mapping nonuniformities when 3D noise is so readily available. \$\endgroup\$
    – KdotJPG
    Commented Mar 5 at 21:16
  • \$\begingroup\$ @KdotJPG I agree with you most of the time (and especially in this use-case). The only issue with the 3D approach is if you want the surface to change over time. 4D uniform noise on the GPU has been a PITA in my experience (lots of artifacts and/or noticeable repetition) so you can "cheat" an extra dimension by wrapping 2D noise to a surface and using the 3rd for time. \$\endgroup\$
    – Basic
    Commented Mar 5 at 21:37
  • \$\begingroup\$ @Basic Have you been using the Ashima Arts Simplex function by chance? The vertex discovery logic is great but there is an issue with the 4D gradient selection there that causes the noise to look less clean than it should. Here is an improved version: shadertoy.com/view/4XlXRB \$\endgroup\$
    – KdotJPG
    Commented Mar 5 at 21:59
  • \$\begingroup\$ @KdotJPG Possibly, it's been years since I last had a delve. Thanks for the link, I'll give it a try next time I need 4D noise \$\endgroup\$
    – Basic
    Commented Mar 5 at 22:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .