It’s been a really productive week!
It’s a huge changelog for the week, so I’ve sorted it by heading.
- Re-enabled some missing options in Architecture mode – stairs (up/down/both), ramps, and bridges. They mostly work, but fixing them is on next week’s board. In particular, selection needs to be a bit smarter to handle pre-planning 3D structures and placing future floors/stairs.
- Fixed the Mining hotkey (D-M), it was firing up Harvest mode due to a copy-paste error.
- Finished single layer designation mode. This is mostly for mining, but can be useful elsewhere. Rather than render a glorious 3D chunk (super optimized and with hidden cells taken out), it renders a single z-layer with hidden tiles rendered as “unknown” tiles. That lets you designate a large mining job, including areas that you have yet to reveal.
- Mining cursors are working in 3D. You can designate a large mining job and still have a frame of reference for the placement of stairs and similar. The tooltips are too forgiving right now, telling you all about areas that you haven’t revealed yet (fixing that is on next week’s list).
- Mining AI is functional, but buggy (it tends to have problems with getting stuck when it finishes). Despite this, you can mine out an area and see what’s going on.
- Added initial voxel models for oil, powder, ore, boulders, etc. These aren’t colored in yet, but they are sufficient to let me test that they are spawning correctly from mining.
- Added stonecutter and smelter models.
- Created initial voxel models for deer, badger, armadillo (looks awful!) and horses. Ensured that they are spawning properly in the Wildlife Management system.
- Added a texture for plasteel floors; the bottom of the ship had turned pink (my “you forgot a texture!” graphic is neon pink).
- Added some normal adjustments to plasteel girders, to make them less boring.
- I managed to squeeze out voxel models for loom, glass furnace, distillery, kiln and charcoal burner workshops.
- Refactor spree, removing unused variables this time.
- Fixed an entertaining bug that wildlife would never move, it would just drop poop. I truly have no recollection of adding pooping animals to the game, but it’s there. It even has some initial systems for gathering dung, extracting ammonia/fertilizer and making bombs.
- Fixed an issue that settlers wouldn’t fire their pistols, preferring instead to hit creatures with them. Lost several settlers to charging at a horse and attempting to beat it to death because they were hungry. It turns out that non-moving critters weren’t resetting their initiative properly either, and would insta-kill anyone who approached in a flurry of stomping.
- Did some memory management cleanup. In particular, terrain chunks weren’t clearing an intermediate buffer after use (and weren’t shrinking the buffer after clearing). Memory usage is now a stable 2 Gb throughout play in my testing, although it can grow as you make the world more complicated.
- Moved the lighting pass shader to a class, and cached uniform IDs for a small speed-up (and a surprisingly big speedup on Intel graphics).
- Distance maps (basically Dijkstra maps, but with varied heuristics for some map types) now use the in-built thread-pool to update in the background. This gave a surprisingly big performance improvement, since it no longer creates/detaches/destroys threads during play.
- Did some heavy profiling, and found that my use of
vector<bool>was biting me in the bum. In particular, calls to
std::fillwere performing terribly; clearing the visibile tile list (prior to rebuilding it) was eating nearly 5% of my frame cycle time! The assembly showed that instead of a
memsetit was doing it the hard way on Visual Studio (Clang/GCC didn’t have this problem). I first tried moving to a sparse map/unordered_map/flat_map structure, but performance actually worsened. Replaced them with a
vector<char>(and accepted the additional memory usage with a sigh), and suddenly it’s down to 0.01% of frame CPU time – and a single
memsetis taking care of it. This broke save compatibility, which isn’t really a big deal at this stage.
- Distance maps now pre-allocate some space in the open node list prior to running, which shaved off a bunch of CPU time being wasted on allocation.
- The shadow buffer now includes voxels models.
- Fixed a crash bug that occasionally hit when building the instance-render VBO for voxel models. It turns out that I’m bad at arithmetic, and my size was off.
- Found a problem with my normals; they were going into an RGB8 buffer in the gbuffer (deferred render stage), and weren’t being consistently transformed into positive numbers before storage (and then converted back). Switched to an RGB16F buffer, which handles negatives just fine and everything looked better.
- Screen Space Ambient Occlusion. I was a little skeptical of the value of SSAO, having seen some of the “SSAO abominations” pages people have put up. I was also worried about my framerate. Despite this, I had exactly the problem that SSAO is meant to fix: muddy pictures with poor differentiation between edges. After a bunch of trying different things, I realized I could simplify the process quite a bit. It takes 64 random triplets in as a uniform (I only set them once), and then for each pixel it takes the SCREEN position and randomly hits a neighbor offset by the random numbers (scaled so as to keep it local). I then read the depth texture for each hit, and if it is closer than the depth of the current pixel – it adds an occlusion. The occlusion weight is total occlusions divided by kernel size (and then inverted, so unoccluded is white). The results are spectacular – see the screenshots below. Now it’s in, I can’t believe I didn’t have it before.
- Environmental ambient lighting. A lot of PBR toolchains calculate the ambient component by sampling an environment map for each pixel. These are typically pre-calculated, which I can’t do in a dynamic environment (the map can completely change). Since I was already running a sampling kernel, I simply sample the color of neighboring ocluders as well – and average it into the ambient light color.
I also did a bunch of optimizing of my regular game loop per-frame. It’s too big to list here, so here is a graphic showing the flow
. Hopefully, this can be of some use to someone else crazy enough to build their own engine… this is mostly for my use, but it may be useful to someone.
- Before SSAO which features terrible blurriness, the SSAO layer, and after applying it – which is lovely and crisp.
- A zoomed out, heavily forested area – with SSAO and color enhancements. For reference, here is a similar area before SSAO
- . Notice that the colors are more uniform, there’s less stippling and the edges of trees are more clearly defined so it’s a lot easier to see what’s going on.
- Where SSAO really shines is when you zoom in
- . The detail on the Cordex and Replicator models is really visible now. It’s also highlighting a geometry bug I have to fix on rear-facing walls (they are missing a triangle!). You can also see the effects of ambient light on the floor – the subtle grey reflection around Cordex.
- Designating some trees for chopping. Again, SSAO has really brought out the detail of the selection, it’s much crisper/clearer and less muddy.
- We’ve built a lumber camp, consisting of 3 tents, a nuclear camp fire (it’s a nuclear-powered fire for camping trips with an automated marshmallow replicator), and a sawmill. The sawmill has a particle effect firing as it finishes cutting some wood. Note that auto-beamdown is in a deliberately crazy mode (new settlers every 24 hours of game time!), I wanted to stress-test the render engine.
- We go into Architecture mode, and designate some wallsfor construction. The game crashed so I did it again and construction of walls began
- . Notice how there’s a TON of settlers now – the stress test is working! (FPS is now in the 20-30 range, slowing down when a wall is completed and the chunk is rebuilt).
- The flattened mining view. We’ve designated a down stair for construction. Next layer down; the red is “unknown” since we haven’t explored it. We’ve designated an “up” staircase to match the down on the layer above.t area](http://bfnightly.bracketproductions.com/mining_3.png). The layer below also shows our progress. The grey blobs are boulders; I’ll fixup that graphic later. Finally, we designate some more exploratory mining.