Interstellar
By Geyu Liu→“Interstellar” is an extended version of Assignment 6 (Shader Pipeline). It renders a small animated solar system inside a rich procedural night sky, with:
- a procedurally shaded Earth–Moon system,
- a glowing, noisy Sun,
- a glass/crystal planet with a thin icy ring,
- a UFO carrying a cartoon alien,
- a long white elliptic spaceship with a bright blue cockpit and a red, flickering rocket tail,
- and a background full of stars, Milky Way band, nebula clouds, and shooting stars.
All visual effects are implemented procedurally in the GLSL shaders. No external textures or 3D models are loaded.
The main shaders and logic live in:
src/planet.fs(fragment shading for all objects)src/snap_to_sphere.tes(tessellation evaluation: sphere deformation)src/model.glsl(per-object model matrices / orbits)src/bump_height.glsl(height field for Earth and Moon)src/bump_position.glsl(bump-mapped positions for terrain)src/tangent.glsl,src/improved_perlin_noise.glsl, etc. for helpers.
Explicit List of Features and Code Locations
1. Procedural night sky with Milky Way and shooting stars
I replaced the plain background with a fully procedural night sky:
- A vertical color gradient from dark blue near the horizon to deeper space tones at the top.
- A Milky Way band created by projecting the direction vector onto a fixed
axis and modulating with FBM noise (
fbm()). - Twinkling stars created from high-frequency noise and thresholding, with a time-dependent sine term to make them flicker.
- Multiple warm-colored shooting stars that appear, move along arcs in texture space, have tapered cores and glows, and fade out over time.
- Slow-moving nebula clouds that drift using FBM and animation time.
All of this logic lives under the branch:
if(object_id == 4) { ... }
in planet.fs.
2. Enhanced Earth and Moon shading
Earth:
- Uses
bump_height(false, s)+ FBM noise to create a continuous height field over the unit sphere. - Thresholds height into ocean, beach, land, and ice regions with smooth transitions.
- Applies different colors for deep ocean, shallow water, grasslands, and mountains.
- Adds polar ice caps via a smoothstep over |y|.
- Clouds are animated using FBM with a time offset, creating moving cloud patterns that partially overlay the base color.
- On the night side (where the dot product with the light is small), a land-only mask is combined with high-frequency noise to produce “city lights” in warm yellow tones.
Moon:
- Uses
bump_height(true, s)together with a customridge()function and FBM to simulate craters and rough terrain. - Colors are mixed between dark and light grey to mimic lunar albedo.
The main logic is under:
if(object_id == 0 || object_id == 1) { ... }
in planet.fs.
3. Glowing animated Sun
The Sun is implemented with:
- A custom sun normal function
sun_bumped_normal(vec3 s)based on improved Perlin noise, creating boiling, moving surface normals. - A color mix between “cooler” orange regions and “hotter” bright yellow regions depending on two layers of noise.
- Standard Blinn–Phong lighting with strong emissive core: the lit regions near the light direction become very bright.
- A rim glow based on the view–normal dot product to give a halo around the edge of the Sun.
This logic is in the if(object_id == 3) block in planet.fs.
4. Glass / crystal planet with thin icy ring
Glass planet (object_id 2):
- Uses a simple Fresnel-style effect (
fresnel_schlick) based on the view–normal angle:- “Reflection” of a space color vs. a sun color.
- “Transmission” through a tinted interior giving a glass/crystal feel.
- Combined with Blinn–Phong shading to add more specular highlights.
Icy ring (object_id 6):
- Built in object space using radius in the xz-plane and a tight y-range.
- A very narrow radial band (
innerandouterradius) gives a thin ring. - High-frequency FBM creates subtle stripes around the ring.
- The ring is semi-transparent (reduced intensity) with softened vertical edges, so it looks like an icy ring rather than a solid disk.
The orbit and model transforms for the glass planet and its ring are in
the “Glass planet base orbit” section of model.glsl.
5. Procedural UFO with cartoon alien
Geometry (TES):
- Starts from a unit sphere.
- Flattens it along y and stretches in xz to form a saucer.
- Adds a central dome and outer rim via radial functions.
- Clamps the maximum radius to keep the shape nice and compact.
Shading:
- Dark metallic base color with a brighter rim band around the saucer.
- A ring of pulsating windows around the equator, driven by time-based sine and cell indexing along u.
- A glowing blue dome on top and bright engine glow on the bottom.
Alien:
- Inside the saucer, the local (x, y) coordinates are used to paint a
bright green alien using circles and ellipses:
- A large head circle and a body ellipse.
- Two big white eyes with cyan glowing pupils that pulse over time.
- A small antenna drawn as a line segment plus a circular tip.
- All of this is done procedurally in the
object_id == 5branch inplanet.fs.
The UFO’s position, bobbing motion, and gentle rotation are defined in
the if(id == 5) branch of model.glsl.
6. Elliptic white spaceship with blue cockpit and red flickering tail
Geometry (TES):
- The original sphere is stretched into a long, thin ellipsoid, more like a
“pill” than a sphere:
- x scaled up for length.
- y and z scaled down to make the ship thin and sleek.
Shading (fragment shader, object_id == 7):
- Base hull:
- Main color is white–grey.
- Top is slightly brighter, bottom slightly darker.
- A darker rim band near the sides to emphasize the shell shape.
- Nose:
- A “nose region” based on x is remapped toward a pure white color so the front tip does not look dirty or shaded too dark.
- Cockpit window:
- Local (x, y) coordinates are normalized and used to define a large top-side elliptical cockpit.
- The cockpit area has a dark frame around the edge and bright blue glass inside, with a subtle breathing animation driven by a sine function of time.
- Rocket tail:
- The rear side (negative x direction) is used as tail region.
- The tail color blends from yellowish white near the engine to red/orange further away.
- The intensity flickers using sine of time plus position-based offsets.
- A radial falloff in the yz-plane keeps the tail bright in the center and faint near the edges.
- The tail contribution is added as emissive light so it glows.
All of this logic is in the if(object_id == 7) block of planet.fs.
The orbit of the spaceship is defined in the if(id == 7) block in
model.glsl, where the ship flies on a large loop around the whole system
so it does not collide with other planets.
7. Custom orbits and animation for all bodies
The model(bool is_moon, float time) function controls the transform of
each object:
- Sun (id 3): Rotates in place at the origin with a larger uniform scale.
- Earth (id 0): Orbits the Sun and also rotates on its own axis.
- Moon (id 1): Orbits around the Earth with its own spin.
- Glass planet + ring (id 2 and 6): Orbits further out in the system with a different angular velocity; the ring shares the same orbital transform but has a larger scale.
- UFO (id 5): Placed off to the side, hovering with vertical bobbing and sideways sway; rotates slowly to show the saucer.
- Elliptic spaceship (id 7): Flies on a wide orbit around the entire scene, with an extra rotation so its long axis faces roughly along its motion direction, emphasizing its silhouette.
Acknowledgements
- CSC317 Assignment 6 “Shader Pipeline” starter code and framework provided by the course instructional team.
- OpenGL, GLFW, Eigen, and other support libraries that were already included in the course environment.
- All planets, sky, UFO, spaceship, and special effects in this Piece are created procedurally in GLSL shaders. I did not use any external textures or 3D models.