Volumetric lights/fog test

Short video of a test for volumetric lights. It is using the same information as the cluster deferred shading path. The shader iterates every cluster and samples at a random position inside the cluster. The result is too noisy at the moment, especially with shadows.

One decade working on AnKi. Uploaded the first snapshot I found in my archive

It’s almost 10 years of AnKi so I decided to to upload a very old snapshot of the engine I have lying in my hard drive. This early snapshot is a few years before I used any revision control. Browse the code here https://github.com/godlikepanos/anki-3d-engine-2007

Some interesting facts:

  • It started as a simple skeletal animation project and grow to what it is now.
  • Was featuring a blender 2.4 exporter for meshes, skeletons and skeletal animations.
  • It was running on OpenGL 1.1 with immediate mode.
  • The code is a weird mixture of (Microsoft-centric) C++ and C.
  • It was compiling only in ancient versions of VisualC++. Had to struggle to get it compile with GCC.
  • Different code style from what AnKi has now.
  • The first name of AnKi was Malice. Kept that name for a few months.

The journey of porting AnKi to Vulkan

Someone once said “make it work, make it fast, make it pretty” and I’m happy (and at the same time relieved) to say that the effort of porting AnKi to Vulkan just hit the first major milestone! It’s working! I think this is a good time to share a few thoughts on how this milestone was achieved, the pains and generally the overall experience. Disclaimer: Whatever you read in the following lines reflects my own views and not those of my current employer.

So let’s start from the beginning. Continue reading “The journey of porting AnKi to Vulkan”

Solving the Linux multi-monitor problem with SDL 2.0

A few days back I decided to upgrade my Ubuntu 14.04 LTS to Ubuntu 16.04 LTS and the first thing I did, after the upgrade, was to re-build and test AnKi. Everything seemed to work fine except the fullscreen mode. In my dual-monitor setup and with 14.04 SDL was creating a fullscreen SDL_Window in my primary monitor and the second monitor was left alone. In 16.04 though the fulscreen window covered both the monitors and it was placed in a very odd position. This is the code I’m using to create the SDL_Window:

U32 flags = SDL_WINDOW_OPENGL;

if(init.m_fullscreenDesktopRez)
{
	flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
}

m_impl->m_window = SDL_CreateWindow(&init.m_title[0],
	SDL_WINDOWPOS_UNDEFINED,
	SDL_WINDOWPOS_UNDEFINED,
	init.m_width,
	init.m_height,
	flags);

I spend quite a few hours trying to understand the issue and after some digging I found out that SDL was reporting only one display (SDL_GetNumVideoDisplays) with the resolution of my entire desktop. Obviously that was wrong. After trying different stuff I found out the culprit. Apparently SDL 2.0 is using libxinerama.so to query some information related to multi-monitor setups. Since my Ubuntu installation was brand new I didn’t have that library installed. That didn’t stop SDL from building but querying multiple monitors was not working properly.

Hopefully this sort post will help people that have similar problems. If you have multiple monitors and you are using SDL 2.0 install libxinerama-dev.

Game level video demonstration

A video demonstration of a character navigating a real game level. Actually this is a small part of a bigger level. The complete level may be released at some point. Until then, enjoy the video:

PS: Music by almighty Varathron.

Squashing bugs in AnKi

There are some universally accepted truths in software and one of those truths is that all software has bugs. Some people are more careful than others but nobody is perfect and nobody can write 100% bug free code. Another truth is that hunting bugs is rarely a fun job. It shifts the focus and sometimes it forces a mental context switch (graphics guys know that context switches can be slow). I always considered AnKi as a playground. A codebase where I can experiment, learn and have fun. Since the inception of AnKi I knew that bugs and debugging in general will spoil that fun so I had to find a way to have a robust codebase so I can focus on the fun parts. I think to some degree I’ve managed to avoid the endless pains of debugging by using the tricks I’ll describe in the following lines.

The first and, in my opinion, the most powerful tool against bugs is the almighty assertions. AnKi has a ton of assertions. To put it into perspective, there are 852 assertions throughout the code and it’s roughly 1 assertion every 84.8 lines of code. Some subsystems like util (AnKi’s equivalent of STL) have to be extremely robust so this particular subsystem has 1 assertion every 37 lines of code. In practice AnKi almost never segfaults when assertions are enabled. In the majority of cases an assertion is triggered and finding out what’s wrong is a mater of minutes.

Another thing I’ve tried early on and improved over the years is based on the idea that the commonly used subsystems have to be as robust as possible. One of these subsystems is util (contains a list, something like std::vector, hashmap, memory management, strings and other). Util is a widely used subsystem and it’s extremely important to be reliable. As I mentioned earlier, util is rigged with assertions. On top of that there are quite a few unit and performance tests. So unit tests is another weapon against bugs. In AnKi’s case unit testing is not that excessive but they cover some commonly used cases.

AnKi loves wrappers. To protect against common mistakes there are some wrappers that have debug capabilities. One example is anki::Array (something like std::array). anki::Array wraps constant size arrays and it asserts on out of bounds access (unlike std::array). Also, there is SArray that is constructed using a pointer to some memory and a size. SArray will also assert on out of bounds assess. These wrappers, and more, ensure that stupid mistakes will be caught.

The last weapon is the excellent valgrind and more precisely valgrind’s memcheck tool. Once and a white I run a demo on top of valgrind just to make sure that everything is in order. There were some occasions where all of the above methods failed but valgrind found the culprit. Unfortunately in complex workloads valgrind can be quite slow.

Of course C++ bugs are not the only source of bugs. Half of the bugs in AnKi are graphical glitches and rendering problems. Graphics related bugs heavily depend on the GPU and the driver and debugging those can be painful. Spending a whole week debugging can be kind of painful. There are some tools that help graphics related problems but those will not be covered by this article.

To sum up, what worked for AnKi is tons of assertions, robust core subsystems, some unit testing and quality code.

That’s all for now.

Status report: Demo, physically based rendering, cluster based deferred shading, preparing for Vulkan

It’s been a while. AnKi’s development is continuing with some slowdown (I am a dad now). Some of the new features that landed in the codebase since the last update:

  • Physical based rendering. Seems everyone is using it and now I can understand why.
  • Cluster based deferred shading. Changed the (CPU hybrid) tile based with a brand new one that divides the space into clusters. It’s CPU hybrid once again. Avalance is (was) using something similar.
  • Added tone mapping with eye adaptation.
  • The lighting is fully HDR now.
  • Added support for particles that react to lights. The new cluster based renderer allows me to do that which is pretty cool.
  • Reworked the graphics backend to make it Vulkan friendly. I’ll start with the Vulkan backend when the drivers become a bit more stable (now they are in early beta state).
  • Finally I worked with an artist for a few months to produce a game level. This level is helping me optimize the engine for real life scenarios. Ultimately I’ll produce a tech demo with it.

For the future:

  • Continue creating a UI library (boring).
  • Expand on a new idea for reflections.
  • Expand on a new idea for global illumination
  • Integrate Newton Game Dynamics even further (create joints and other stuff).
  • Start on the Vulkan backend.