It’s been two-weeks of Christmas, traveling the length of the country to visit in-laws, and working as much as I can inbetween everything else. We even had an unexpected house-guest, which I expected to slow me down – but instead she thought the game project was awesome, so I plugged away. 🙂
I just woke up after spending 16 hours driving yesterday (from Florida to Missouri, in a single go…), so this is late and shorter than I’d like!
The new engine now meets all of its big-ticket design goals, so I’ve begun the slightly tedious process of getting it building on other platforms. This is mostly CMake editing, and some inevitable linker fighting that always seems to accompany it (GCC in particular is really picky on this front). The project builds/runs on VS and MSYS2 so far, and the other platforms shouldn’t be too far behind.
The major engine works are:
- I re-implimented the loading screen using the C++20/TS Coroutines system. It’s awesome, but I haven’t got it working properly on anything other than the latest Visual Studio – so I’ve shelved this for now. I may revisit using Boost’s equivalent, since this made the job a LOT easier. Coroutines let you write your loader as a serial/synchronous process, but with careful yielding you can still release control to the main loop to avoid locking up (some platforms are particularly strict about how often you have to receive messages to avoid a “this application has crashed” message).
- Sped up the voxel model loader by a LARGE amount by adding a
breakto a loop!
- Lighting, part 1 – light volumes. Previously, lighting worked by calculating which tiles were illuminated as a CPU-based system, and then sending this to the renderer via a 3D texture. It worked, but tiles could only have one lightsource – and shadows were pretty much impossible. This was changed to a render pass per light (only for visible lights, and after the GBuffer is populated – so the hard work has already happened). A shader discards pixels that aren’t in a light’s 3D radius, and lighting is additive. This gives spherical lights at a low cost, and removes the CPU drain of changing a light’s color. The system is smart about adding/removing lights from the games ECS. The result is a good start.
- Lighting, part 2 – depth cubes. Part two creates a small cube-map per light, and renders the scene to it – from the point of view of the light. Depths are stored as the distance to the light. A cube-map test in the lighting pass then determines if a pixel is both inside the sphere AND not shadowed. To keep performance up, it only updates these shadow maps from time to time (every 20 frames or so). Lights are then added and blended in the same way as part 1. Here’s a view of one depth-face for a light.
- Lighting, part 3 – PCF. This gave a lot of “acne” on the view, so I implemented PCF. This basically samples the depth cube multiple times, with a small adjustment made to the coordinates each time and averages the samples. Samples below a certain threshold are discarded, and lighting is scaled based on shadowed-percentage. This gives softer shadows, and gets rid of the acne. This looks pretty good
- Lighting, part 4 – the sun. Still in progress, but the sun is now a game object like any other and orbits the planet. It casts shadows. I’m still tweaking this, so no screenshots this week.
- Laser blasts now shoot a particle line that fades. Combat looks much better. Still in progress, I’ll screenshot it next time.
I’m going to sleep!