Lightmap baking on CPU using Embree and OpenImageDenoise

I wanted to have a portable lightmapper that is part of a custom map editor that I was building in C++. Thus I chose to build CPU powered lightmapper.

And to my amazement, it is really fast as OpenImageDenoise works like magic and the noisy CPU path tracer result gets smoothed out. The lightmapper is based on design described by the creator of Bakery-addon for Unity.

First, it creates the lightmap UV space GBuffer with multipass rendering to emulate conservative rasterization. Secondly, it offsets the sample position by raytracing from each sample position. It checks if the sample position resides inside geometry and offsets it to redure shadow leaks. Thirdly, using Embree it path traces from the sample positions and builds the lightmap. Finally, the lightmap is filtered using the OpenImageDenoiser.

The only downside is that the OpenImageDenoise is huge. The .dll takes around 45 megabytes (compared to my exe ~700KB). Anyway, I think it is worth having as it speeds up the path tracing result significantly. Here is a screenshot of preliminary result.

Denoised lightmap result in 20 seconds on Intel i7-5820k

Developing own custom game engine from scratch in 2021

Unreal Engine 5 is soon to be released with new groundbreaking features, Unity dark mode is finally free and Godot 4 plans to take over the indie gamedev community. Why as an indie dev, would you skip all of those (plus many other production-ready game engines) and build your own custom game engine in 2021?

Next, I go through some of the decision reasons of choosing between Unity / Unreal / Godot vs Custom Game Engine. Lastly, I go over the reasons why I did choose to build my own custom game engine for my game project.

When it is better to use Unity / Unreal / Godot?

  • The game will be a cross-platform game

Cross-platform is hard to get right even for seasoned developers as there are many moving blocks and undefined behavior. Most popular game engines are already tested and have built-in workaround for many issues.

  • You need proper content pipeline

If your game depends on or uses many imported 3D models and materials it is crucial to have working content pipeline. Content pipeline transform the imported 3D models and textures to game engine specific data format. If you want to import wide amount of different 3D model formats and have working texture compression, you might want to use off-the-shelf game engine.

  • You need to have realistic or next-gen graphics

As an indie, it would be hard to stay at the same levels or even bring a new game engine to the levels of current off-the-shelf game engines.

  • Game has to be build in the shortest time possible

It is hard to beat time-to-market with a custom engine. This doesn’t need any explanations.

  • You need to find people with existing skills to use the engine

When you bring new people to the team in the later stages of the game’s development, you will be better of when they would have experience from the game engine you are using.

  • Game is a mobile game that ships for Android

It’s pain in the ass to develop OpenGL ES for Android. Be prepared for graphics issues. There are so many different phones and OpenGL drivers with undefined or wrong behavior. I would chose proven game engine for mobile games (Unity / Defold).

  • You don’t have any specific or good reasoning for building a custom engine

Lastly, if you don’t find any good reasons business or game design wise to develop a game engine.

When it is viable to build a custom game engine?

  • You care about fine-tuning underlying technical side

You need to tinker the fine details to have the minimal possible game distribution size and achieve the best performance. When you have access to source code, you can customize or optimize the whole stack from raw input to rendering. This is also possible on off-the-self engine, if you have access to the engines source code.

  • Your needs are well known before building the game

You can estimate the features needed for the game engine to build the game. This way you can have rough estimate, how long it will take to build the engine. And how big of a job it is to build the game engine.

  • Your content pipeline is simple and limited

For example, if your game design allows you to stick with one 3D model format and exclude textures with alpha.

  • The game doesn’t require next-gen graphics

This is self-explanatory. Sometimes less is more.

  • You think the game development will take more than two years or you want to provide updates for the game many years after the game release

After starting to build with Unreal / Unity / Godot, those will receive updates and the upgrade process for your game can bring game breaking changes that would need reworking levels and/or game mechanics. I have seen this happen for AAA game.

Why I have chosen to build custom game engine for my gamedev project?

  • It has to achieve lowest possible network and input lag

I need to have full control over the rendering loop, present swapchain and also input polling to fine tune the input and network latency.

  • It has to be ultra-light and ultra-fast

I want the game to be small in distribution size, have ultra-fast start-up time and minimal loading times. Also the game performance should be excellent on low-end machines. I want the game to be non-intrusive, lightweight and accessible by people with low-end machines.

  • It has simple visuals

This is both a game design choice and it also enables us realistically to develop custom game engine. We believe that visuals are very important but highly-realistic or candy graphics distract the core gameplay. Simple visuals also means simple content pipeline and simple rendering engine for the game engine.

  • I want to provide the map editor for the community

Yes, you can also build map editor with Unreal / Unity / Godot. But this comes as a bonus while building the map editor for the engine. It brings a bit more extra work to polish the editor for external users but I think it is worth it.

  • I’m in it for the long term!

It is much easier to support future Windows versions and fix upcoming issues related to new hardware when I have control over the whole stack. If I would have chosen Unity or Unreal I would be stuck with the version we started to design with. If they would, for example, change the ray casting engine, physics engine, AI navigation engine or any core part of the engine in future versions, it could potentially change the gameplay drastically and to unwanted directions!

  • It is PC-only game

It easy to focus developing the game engine to support only single platform. By focusing on single platform, I miss the headache of developing cross-platform abstractions and separate implementations.

  • I’m software engineer first, game designer second.

In the end, I just like to tinker, read and develop things around new techniques and possibilities.

Sound and audio in competitive FPS game

Lately, I have been thinking sound design in my a multiplayer FPS game prototype.

Audio is very important in games. Sounds gives clues and reference about the current game situation and environment the listener is in. Both silence and high volume sounds have their places, but is important that the audio volume levels are correct.

In competitive FPS game, 3D positional audio plays important role when locating opponents. Headphones are must have to be competitive in multiplayer FPS game.

When working on the audio and sound design for my multiplayer FPS game, I take account the importance of audio occlusion, clues, directivity, effects and more.

Audio occlusion

Occlusion happens when there is physical obstacle (medium) between listener and audio source. Often the sound doesn’t completely get blocked because the sound either reflects from nearby walls which bounce the sound waves to the listener. Also lower frequency sound waves are good at traveling through mediums.

In games, audio occlusion test is often implemented using raycasting. Most likely a good estimation of audio occlusion is done by raycasting multiple lines from the listener to points near by the audio source. Path tracing can also be used to compute better reflection and realistic audio directivity.

In multiplayer FPS games, I argue that realistic audio directivity will cause confusion for the player. For example, gun shots or footstep audio should be seemed to be coming directly from the true audio source and not reflected from walls. Although it isn’t realistic, it is important from gameplay perspective to avoid confusing the player.

In my FPS game prototype, the audio occlusion implementation is still work-in-progress. Currently I use multiple raycast testing to define audio occlusion. The audio is simply low-pass filtered and reduced by volume depending on the obstace medium size.

Improving audio directivity with HRTF

For audio, I leverage OpenAL Soft audio library. It comes with an excellent HRTF (Head Related Transfer Function) implementation. In short, HRTF simulates how ears will hear the sound from a certain point in 3D world. Headphones has to be used when HRTF is enabled. With HRTF player gets much better immersion of the sound direction, especially on the up/down axis.

Minimizing input latency for games

I feel that input latency should be as minimal as possible. Input latency affects the game feel and is especially important when the game requires fast reactions, such as fast-paced multiplayer FPS game or racing sim.

I’m currently working on a project with custom game engine where low input latency is important. I take input latency seriously and do my best to minimize it. One part of minimizing input latency is to make the frame rendering as fast as possible.

How to minimize input latency

In order to minimize input latency, the game needs to postpone the frame’s input processing as late as possible before frame present. Also the game should only have single buffered present.

Naively by default, games use triple buffering. Triple buffering is best choice when smoothness and larger frametime budget is required. For example, when using single buffered present with 60hz screen, both the CPU and GPU must have computed the frame under 16.6ms to be ready for the next vblank.

When using double or triple buffering, both GPU and CPU have 16.6ms of time to process the frame, giving the best throughput with cost of additional latency. Thus single buffered rendering reduces the system parallelization. CPU has to wait for GPU to complete the present and then GPU has to wait for CPU to start pushing rendering commands.

In my current project, I use single buffered rendering. The game waits for GPU to complete present before processing input for next frame. This achieves theoretical input latency between 16.6ms – 33.2ms on 60hz refresh rate.

Angle Level – a simple level tool for iOS

At some time ago, I was looking for a level / clinometer app for iOS that could present the result with six digits of precision, with four decimal places (e.g. 12.3456). I could not find any, so I decided to build one myself.

It was already some three years ago I did my last iOS dev work with Obj-C. Angle Level would be my first complete app to be released at the App Store using Swift. SwiftUI was on its infancy still and some basic UI features was missing, so I went with the goold old UIKit. I build the UI completely in Swift code and aimed to look like a native app. To test how viable App Store is for this kinds of apps, I also monetized the app with basic IAP. Full precision with four decimal places can be unlocked using the IAP.

The final angle measurement is computed using temporal filtering. The app gathers result from 100+ accelometer samples and ditches the samples that deviate with predefined amount from the gathered samples. The measurement is complete after predefined minimum deviation threshold is achieved.

More detailed info of about the Angle Level app can be found at App Store.