B.L.O.O.M

BLOOM

During This project I mainly focused on improving systems created in Spite: Knight of Odin, our previous project. I worked on areas like engine programming, graphics/render programming, animation systems and visual effect systems. As this project was a first-person shooter in a more realistic art style/setting. I needed to work a lot on making sure lighting, shadows and transparent objects were rendered better/more realistically. I also worked a lot on culling and increasing performance/making optimizations.

Further information about some of these systems are listed below.

Project Details

  • Time: 15 weeks, half time

  • Team Size: 6 programmers, 3 artists, 3 level designers

  • Engine: Custom engine based on The Game

    Assembly’s in-house engine TGE

  • Libraries: DirectX 11, FMOD, Nlohmann Json, ImGui

  • Language: C++

Object Culling

Because of the game being in a first-person perspective, culling was a lot more important than before. To solve this issue and improve performance, I implemented 2 layers of culling.

The first being a grid-based frustum culling, roughly culling most objects out of view. The cells are selected based on the camera frustum in this method.

The second layer of culling removed objects that had a dot product less than a set angle, relative to the camera. This removed a lot of the objects missed by the previous rougher method.

These culling systems were applied to the shadow map rendering as well, for increased performance.

Video showcases culling with an extra narrow angle for visual purposes.

Sorting Transparent objects

Because of our many transparent objects in the game, I had to create a way of sorting them efficiently. The problem being the depth stencil when rendering transparent objects. For example, an object rendered behind an already rendered transparent object will not show. This because of the previous objects depth already being drawn in front of it.

I came up with this sorting and insert algorithm with inspiration from the quick sort algorithm to circumvent it. Although not perfect it worked quite well for what we needed. It was quite performant as well which can be seen in the screenshot below with over 4000 transparent objects being drawn, keeping over 130 FPS.

Screenshot showcasing my rendering of transparent/forward rendered objects. What you can see is a test scene with over 4200 forward rendered models, rendered in correct order.

Batched Rendering

To increase performance, especially when rendering shadow maps. I decided to batch render everything that wasn’t forward rendered. This reduced draw calls massively, as I could render up to 64 models at a time in a single draw call. Especially helping with drawing shadow maps, as they required a lot of models being drawn and all of the models were possible to batch render to the shadow maps.

The reason this has such a big performance impact is because a lot more data can be sent to the graphics card memory in one call instead of multiple smaller calls. This is because of the overhead associated with each transfer being quite heavy.