Skip to content

Aquel32/space-adventure

Repository files navigation

space-adventure

3D Planetary system simulation build with TypeGPU

During this project I have set my first steps into Graphic Programming world, learning some basic rendering concepts and visual effects.

Demo

You can check it out yourself here.

b a d c
mov.mp4

How it works

Geometry and Phong Lighting

Celestial Bodies are generated with cubesphere technique with a Perlin Noise offset applied to create uneven terrain. By varying surface colors, we get diffrent-looking planets.

Normal vectors are analytically calculated by sampling Perlin Noise around vertex. Then they are using to compute Phong lighting.

Bloom

Pixels that cross a brightness treshhold are simultaneously drawn onto emission texture.
That texture is blurred using 2 pass Gaussian Blur. To limit cost of many iterations, I use Mipmapping to apply blur on lower-resolution versions of texture.
To avoid unnecessary memory allocation, pipeline ping-pongs between two textures.

Shadows

Celestian bodies need to cast shodows on one another.
Shadows are generated using Omnidirectional Shadow Mapping.
A point light (the Sun) hosts six cameras pointing in all direction of a cube's faces, rendering the scene's depth into a depth cube. In main render pass, we sample that depth cube to determine if a pixel is in shadow (it's just multiplying final Phong lighting).

Currently, body index 0 is hardcoded as the only light emmiter. Additionally, default planet scales are quite small relative to the distances between them, making planetary shadows not that visible.
If you want to see the effect, it's better to increase up planet radiuses.

Atmosphere

The atmosphere effect uses raymarching.
At each sample point along camera ray, shader checks average atmospheric density from that point toward the sun. Summing and normalizing theese values results in beautiful light multiplier.
My implementation is heavily based on Sebastian Lague's video, rewritten to TypeGPU.

Right now, planet density pre-computation isn't implemented.
Also the atmosphere is currently simulated only for the closest body to the camera, which looks weird when you look at Body 3 while standing on Body 4.

Other optimization

Verticies and normal positions are stored in Half-Precision Float.
Theese compact vectors are fed directly into the main and shadow render pipelines via Vertex Layouts.
That way we cut vertex memory allocation by half.

Quick note on gravity

Gravity wasn't the primary focus of this project, so it's a bit clunky and can be unstable.
All simulation takes place on CPU using a simple gravitational acceleration formula.
Orbit prediction works by running the simulation hundreds of times on a cloned dataset (curently hardcoded to 10,000 steps ahead) and saving coordinates into a buffer.
Orbit render pipeline uses line-strip topology, meaning each vertex connects to the previous one to draw a path.

Known Issues

  • TODO: Render multiple atmospheres simultaneously
  • TODO: Implement a pre-computed density lookup texture for atmosphere performance.
  • TODO: Configure atmosphere settings for the rest of planets.
  • ISSUE: CPU Perlin Noise doesn't use same alogrithm as GPU (XOROSHIRO64**).
  • ISSUE: "Sliding" behaviour when standing on planet while Pull Camera option is enabled.

About

3D Planetary system simulation build with TypeGPU

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors