I’ve yet again made pretty significant changes, some of these are demonstrable but as per usual much is infrastructure, design and refactor.
The stuff you can’t see that takes time, but lets things progress, move and scale freely… until it doesn’t and I need to rinse-and-repeat.
Line Renderer Take-Two
I have refactored the LineSegmentRenderer to fit the new renderer/engine design.
This renderer broke when I was working on the deferred rendering pipeline and it further diverged when I implemented the entity component system.
A subtle but significant architectural change is that there is only a need for a single LineSegmentRenderer.
In the previous design, the DebugLocatorRenderer was a subclass of LineSegmentRenderer that didn’t really add much value and by design meant more subclasses for other line related rendering.
With the ECS in place, I can now create an entity with a new LineGeometryComponent, give it some general properties like thickness, color etc. attach a ScriptComponent that then creates LineSegments and the RenderSystem bundles them all together per frame to be rendered.
Blooming Fantastic
Bloom is one of those things that when done well can make a scene more grounded and atmospheric. It can also be extremely distracting and expensive. It’s often one of the settings gamers just disable.
For the unindoctrinated, bloom is the soft glow around bright things and is typically a ‘post-process’ shader.
It’s a fairly simple technique in computer graphics. You extract (or render if you can) the bright pixels into its own texture, blur that texture, then composite the result back onto the final frame.
I tried two approaches for this, the first was a simple full resolution texture which produced OK results. I found that you really needed high blur values to achieve the soft glow you’d expect from bloom, and that makes it comptuationally expensive on a full resolution texture.
The second and current approach is a multi-pass method, multiple textures but at progressively smaller dimensions that are then composited ontop of each other. It sounds like this would be more expensive, but this ends up being quite a bit cheaper. I had a page I was referencing that had some interesting stats on this, but now I cannot find it anywhere. Guess you’ll have to take my word for it.
From a Distance
Similar to bloom, distance fog is a technique that add atmosphere… or a tool to help hide limited draw distance.
It’s quite a cheap pass to do, we already have the G-Buffer’s depth pass so we use that. The shader then maps the depth into the cameras view space and with some other shader settings like colour, min/max distance etc. and pretty simple math bada-bing bada-boom we get distance fog.
It does help give the scene a sense of depth that is missing without it. With some artistic direction and engine capabilities it could be enough in many cases without going more expensive routes.
Resolution Scaling and Quality
Nothing to do with atmosphere, but I’ve added resolution scaling so you can change the resolution of the final image for performance vs quality/fidelity.
I noticed a while ago that things look crisper on my MacBook. The difference is that the pc/monitor has a ‘device pixel ratio’ of 1, which is 1 CSS pixel == 1 physical device pixel. The MacBook has a device pixel ratio of 2, so four times as many pixels for the same canvas size.
The final resolution is the starting point that some passes then downsample (as described in the multi-pass bloom approach) so lower quality settings can start to look pretty muddy. If the final render target size is low enough resolution then I probably don’t need to be downsampling as often, or even at all. Something I need to balance.
All Together Now
Scifi-City is looking a bit better, the bloom really does work well for this type of stylized scene and the distance fog helps with the scene depth, even if it’s not very realistic. Still mostly lit by IBL, the only direct light is the flickering point lights I added to the powerstation. That flicker is another ScriptComponent.
Final Words
You’ll notice the Overlay, I had much of this tucked away but as I’m to think a bit about optimisations, it made sense to spend some time on it. I won’t speak to much about this yet, I’ll save that for another post.
Last thing worth mentioning, now that I’m hosting Static Rectangle from my own website I can make use of URL parameters. I’m using them on this post right now, all three examples today are the same the exact same engine build, but I’m using URL parameters to select the scene, and enable/disable the Settings/Overlay.
You can test this out for yourself by launching this
https://leonwoud.com/StaticRectangle/0_0_15/index.html?scene=trail&overlay=true&settings=true
Change Log
- Added post-processing bloom
- Added distance fog
- Added Resolution quality setting for over/under sampling
- Added WorldBounds sytem for frustum culling
- Refactored renderer settings/options
- Refactored scene management/loading
- Added overlay stats
- Render stats/reporting changes across passes
- Expanded scene/script system
- Script registry changes
- Added fixed update/time changes
- Added URL params support
- Reworked line render pipeline
- SSGI optimizations, now supports quality setting
- SSAO now supports general quality setting
- TAA bug fixes