2048 Point Lights @ 60 FPS

Today I released an update to my engine. The most prominent feature
is Forward+ aka Tiled Forward rendering. To my knowledge, no other
open source engine implements it.

Forward+ dates back to 2012 and is used in several AAA games like DiRT Showdown, Ryse (partially) and The Order: 1886. Its main advantages are support for MSAA, transparency and multiple BRDFs. The algorithm works by culling lights against a screen-space grid where cells are for example 16x16 pixels. It stores a per-tile list of light indices that are then used in shading. Culling is done with a compute shader and it uses depth texture to get each tile's extents. My engine does a depth-pass in any case, because it's needed for SSAO etc.

The implementation I did is based on AMD's ForwardPlus11 sample. However, the sample is D3D11 and uses deprecated D3DX libs, but my implementation also supports OpenGL 4.3. I was able to render 2048 point lights at 60 FPS in Sponza scene on my year-old MacBook Pro (GeForce 750M). All the surfaces use Cook-Torrance with normal maps.

If you want to implement it yourself or just test it, you can download my engine. Here's some API mappings from HLSL to GLSL:
gl_WorkGroupID: SV_GroupID
gl_LocalInvocationID: SV_GroupThreadID
gl_GlobalInvocationID: SV_DispatchThreadID
uintBitsToFloat(): asfloat()
floatBitsToUint(): asuint()

Here's some useful links:

So, what's next for Aether3D? I'll add spot lights soon and for the next release my focus will be in fixing open bugs and adding unit tests and support for CMake. I'm also planning to dogfood my engine this year by making a simple first-person game. Also, I'm working on an editor in Qt and C++. I'll blog more about them when they are more mature.


6 Steps to Better Commits

While working on my multi-platform game engine, here's some things I have learned:

1. Run all unit tests or functionality tests before submitting.
Should be a no-brainer, but laziness can lead to less testing and more bugs. Especially bad if you make many submits without testing because by then your search-space has grown needlessly. If you don't have any tests, stop reading this and write them now.

2. Submit only related changes.
For example, if you are hunting down a bug and inspect a changelist with a message "Fixed texture loading" and the changelist also contains modifications to Audio.cpp, finding the bug takes more time.

3. Fix bugs before adding new features.
Worst-case scenario would be when a new feature depends on a bug in an older feature and when the bug is finally fixed, the new feature stops working.

4. Describe all the changes you did in the commit message.
If you browse through a commit log of a source file and find a commit with a message that has nothing to do with that file, you have not documented your commit well and it could be hard to reason about why the file was changed.

5. Diff all the changes to be submitted for sanity-check.
Sometimes you have been making ad-hoc changes to test/debug a feature but forgot to revert them before submitting.

6. Try to submit a whole, working new feature in one submit instead of many non-working submits.
If the feature is really big, you can split it into smaller submits if each of the smaller submits represents a logical unit that can work without other submits.