nstgeorge / VEKTA

A space exploration game created in Processing 3 with orbital mechanics
MIT License
1 stars 1 forks source link

Add lighting system #89

Open nstgeorge opened 3 years ago

nstgeorge commented 3 years ago

Short Description

For stars (and in the future, cities), we should add a lighting system with somewhat realistic interactions with planets and objects.

More Details

This would be an extremely simplified ray tracing implementation. Every object only needs two rays for each light source in the scene (capped to a certain number). This will have to be done with shaders.

Related Ideas

While working on this, we could also add sunset/sunrise shaders to planets. This will likely require an entirely separate system and should be done as a separate issue.

nstgeorge commented 3 years ago

As for implementation, I've been thinking about it and I think the best way to do it might be this:

  1. For each light-emitting object in the scene within certain boundaries based on brightness and distance, run a shader pass. (Alternatively, we pass all these objects to one shader pass and it runs them sequentially, but I'm not sure how much performance benefit that offers.)

  2. When passing the light emitting objects, we also pass in the player, objects on screen, and every object between the player and light emitting object that is off screen.

  3. Within the shader, for each non-illuminating object, cast a ray from the outer edges of the object to the light emitting object, creating a cone. If a pixel lays within the bounds of this cone beyond the object from the point of reference of the light emitting object, mark it as "in shadow" or something like that. Ignore these pixels for future objects. (Probably a more efficient way to do this - experiment.)

  4. For each pixel not in shadow, increase its lightness based on distance from the light emitter and brightness of the emitter. This should be done on a log scale - darker pixels will increase in brightness more than light ones.

  5. Repeat for each light emitter gathered.

nstgeorge commented 3 years ago

For step 3, it might be better run this per pixel to take better advantage of the GPU parallelism:

For each pixel, cast a ray to each light emitting object. If the ray intersects with an object, mark it as in shadow.

This brings the implementation more in line with traditional per-pixel raycasting. It results in many more rays being cast than in the option I presented before (which is more specialized to a 2D environment with simple geometry), but the better parallelism might result in better runtimes. Will likely need to compare both methods, depending on performance results.