Porting (Vulkan)Quake to Android

Axel Gneiting from iD software recently ported Quake to Vulkan (based on the QuakeSpasm OpenGL port) and released the sources at github with support for windows and Linux. With Vulkan also being available on Android, I decided to use the knowledge gained while porting my Vulkan examples and Demos over to Android and add it to his Vulkan Quake port.

I have tested with the registered and full .pak files of the original Quake and both are fully playable. The Android port supports gamepads and all the gameplay elements are there, including working multiplayer. A few things are still missing, e.g. there is no sound yet as SDL audio doesn’t work on Android out-of-the box. I’m currently looking into implementing OpenSL but no ETA on that yet.

No binaries yet (as the .pak file has to be packed in the .apk and I don’t want to redistribute these), but if you want to try this, the code is available at https://github.com/SaschaWillems/vkQuake.

It includes all files necessary to build the APK using the Android NDK and should run on other Android devices too (but note that you’d need a gamepad).

Continue reading “Porting (Vulkan)Quake to Android”


New Vulkan example: Deferred shading and shadows

Based on the recently updated deferred shading example, I have added a new example to my open source C++ Vulkan samples. This example adds dynamic shadows from multiple light sources, showcasing a few technologies that can be used to make rendering of multiple shadows more efficient.

To achieve this, the example uses a layered depth attachment with one layer per light source that is sampled in the final scene composition. Traditionally one would do multiple passes to render the depth maps for the scene’s light source, and to avoid this the example also uses shader instancing by doing multiple invocations in the geometry shader. The geometry shader then uses the invocation index to output into the different layers of the depth attachment, with the matrices from the different point-of-views of the light sources getting passed as an array.

This is an approach that fits modern GPUs very well and allows for an arbitrary number of shadow casting light sources to be added without the need to add multiple render passes.