Home

Awesome

Pumex library

The purpose of the Pumex library is to create an efficient and universal rendering engine using Vulkan API that has following properties :

Quick preview on Youtube :

Pumex preview

You can follow library development on Twitter .


Library architecture

This paragraph assumes that reader knows Vulkan specification.

Every Pumex application consists of three distinct layers of objects :

viewer/device/surface layer

render graph

Each node may have descriptor sets connected to it. Descriptor sets consist of images and buffers along with their GPU representation ( whether they should be treated as uniform buffers, storage buffers, sampled images, samplers, etc.).

By default the scene graph is included into primary command buffer building, but subgraphs may be moved to secondary buffers ( as long as secondary buffers include graphics pipeline / compute pipeline - this is Vulkan requirement ). Secondary command buffers may be built/rebuilt in parallel to each other.

Scene graph shown below is connected to the "lighting" operation from image above. First graphics pipeline to the left defines shaders that use gbuffers as input attachments. As a result, pumex::AssetNode draws a fullscreen triangle that uses gbuffers to render lighting. Second and third graphics pipelines render statistics GUI: pumex::DrawVerticesNode draws rectangles representing CPU timing of different rendering stages. pumex::Text nodes render FPS counter and names of rendering stages.

scene graph

Articles discussing various features of the library

Basic tutorial : rendering single 3D object

How does main render loop work

Multithreaded cooperation between render stage and update stage

Memory buffers and images in detail

Asset class and its components

Pumex examples

Pumex library comes with a set of examples implementing different aspects of it. Each of the examples accepts following options from command line :

-h, --help                        display this help menu
-d                                enable Vulkan debugging
-f                                create fullscreen window
-p [presentation_mode]            presentation mode (immediate, mailbox, fifo, fifo_relaxed)
-u [update_frequency]             number of update calls per second

Default value for presentation mode is mailbox ( = VK_PRESENT_MODE_MAILBOX_KHR ).

While each example is running , you are able to use following inputs :

pumexcrowd

Application that renders a crowd of 500 animated people on one or more windows.

Application presents :

pumexcrowd example rendered on 3 windows

Apart from standard command line parameters pumexcrowd example uses also following ones :

      -v                                create two halfscreen windows for VR
      -t                                render in three windows

Below is additional image showing pumexcrowd example working in VR mode ( 2 windows - each one covers half of the screen, window decorations disabled ) :

pumexcrowd in VR mode

pumexgpucull

Application that renders simple not textured static objects ( trees, buildings ) and dynamic objects ( cars, airplanes, blimps ) on one or more windows.

This application serves as performance test, because all main parameters may be modified ( LOD ranges, number of objects, triangle count on each mesh ). All meshes are generated procedurally. Each LOD for each mesh has different color, so you may see, when switches betwen LODs occur.

In OpeneSceneGraph library there is almost the same application called osggpucull, so you may compare performance of Vulkan API and OpenGL API.

pumexgpucull example

Command line parameters enable us to use one of predefined window configurations and also we are able to modify all parameters that affect performance:

  -v                                create two halfscreen windows for VR
  -t                                render in three windows
  --skip-static                     skip rendering of static objects
  --skip-dynamic                    skip rendering of dynamic objects
  --static-area-size=[static-area-size]
                                    size of the area for static rendering
  --dynamic-area-size=[dynamic-area-size]
                                    size of the area for dynamic rendering
  --lod-modifier=[lod-modifier]     LOD range [%]
  --density-modifier=[density-modifier]
                                    instance density [%]
  --triangle-modifier=[triangle-modifier]
                                    instance triangle quantity [%]
  --instances-per-cell=[instances-per-cell]
                                    how many static instances per cell

pumexdeferred

Application that implements deferred rendering with multisampling in one window. The number of samples per pixel may be configured from command line ( see parameters below ). Available values of samples per pixel include : 1, 2, 4, 8.

By default application uses depth prepass rendering, but you are able to switch it off using command line parameters ( see below ).

Application presents how to use attachment produced by one render operation as input attachment in a following render operation.

Famous Sponza Palace model is used as a render scene.

Shaders used in that example realize physically based rendering inspired by learnopengl.com

pumexdeferred example

Additional command line parameters :

    -n                                skip depth prepass
    -s[samples]                       samples per pixel (1,2,4,8). Default = 4

pumexmultiview

Application based on pumexdeferred example. It shows how to utilize VK_KHR_multiview extension to render two images at the same time ( without a need for a second render graph and scene graph traversal ) and how to apply barrel distortion.

Shaders used in that example realize physically based rendering inspired by learnopengl.com

pumexmultiview example

pumexibl

Application presenting image based lighting with models able to render using physically based rendering methods ( example model seen on a screenshot below was acquired from glTF Sample Models repository managed by Khronos ).

From technical standpoint - this example shows how to render to many cubemap layers and to texture mipmaps using render graph. Also shows how to generate texture mipmaps using transfer operations ( vkCmdBlitImage is called under the hood to generate missing mipmaps ).

pumexibl example

Additional command line parameters :

  -i [texture_name]                 provide equirectangular texture that will be
                                    transformed into cubemaps required to implement
                                    IBL.
  model                             3D model filename
  animation                         3D animation filename

pumexviewer

Minimal pumex application that renders single non-textured 3D model provided by the user in command line along with its bounding box. You may render any model as long as Assimp library is able to load it and sum of model's vertex and index size is less than 64 MB.

At the moment the pumexviewer example is only example working on Android.

Application presents simplest possible render graph with only one render operation.

pumexviewer example

Additional command line parameters :

  model                             3D model filename
  animation                         3D animation filename

Examples of use ( command line ) :

Show animated model of a man ( running animation ) :

pumexviewer people/wmale1_lod0.dae people/wmale1_run.dae

Show Sponza palace model :

pumexviewer sponza/sponza.dae

pumexviewerqt

If Pumex was built withQT support enabled ( CMake flag PUMEX_BUILD_QT set to ON - see: Building and installation section ), then there is additional example showing how to create a window using QT library and how to cooperate with it. pumexviewerqt example performs rendering the same way as pumexviewer example.

Difference is that models and animations are not loaded from command line, but when user presses appropriate buttons to do so ( code presents how to use QFileDialog to load a 3D model and send data to pumex application using QT signals ). Additionally user may change model color ( code shows how to use QColorDialog ).

pumexviewerqt example

pumexvoxelizer

Application that performs realtime voxelization of a 3D model provided by the user in command line. After producing 3D texture raymarching algorithm is used to render it on screen.

Application presents

pumexvoxelizer example

Additional command line parameters :

  model                             3D model filename
  animation                         3D animation filename

Examples of use ( command line ) :

Voxelize and render animated model of a man ( running animation ) :

pumexvoxelizer people/wmale1_lod0.dae people/wmale1_run.dae

Voxelize and render Sponza palace model :

pumexvoxelizer sponza/sponza.dae

Windows installer

If you want to see examples in action - there's a Windows installer on Github releases page.

Besides installer you also need Vulkan SDK to be able to run examples.

Installer contains libraries, example applications, header files, data files and compiled shaders, but does not contain source code. In other words - installer has everything you need to run examples and use library as a dependency.

Installer puts all these elements in C:\Program Files\Pumex directory by default ( you may choose different target directory during installation process ).

Installer does not have QT support at the moment.

Building and installation on Windows

Elements that are required to build and install Pumex on Windows :

Steps required to build and install library :

  1. download Pumex Library from here

  2. create solution files for MS Visual Studio using CMake

    1. to build Pumex with support for QT5 library - you need to set the flag PUMEX_BUILD_QT manually in CMake GUI. This flag is switched off by default. Also remember, that you have to recompile QT5 library yourself, because Vulkan support is switched off in QT by default.
  3. build Release version for 64 bit. All external dependencies will be downloaded during first build. Now you are able to run examples from within Visual Studio

  4. (optional step) install library and applications by building INSTALL project ( you need to run Visual Studio in administrator mode to be able to perform this step ). WARNING: due to recent CMake modifications installation is not possible at the moment.

  5. if example programs have problem with opening shader files, or 3D models - set the PUMEX_DATA_DIR environment variable so that it points to a directory with data files, for example :

    set PUMEX_DATA_DIR=C:\Dev\pumex\data
    

Building and installation on Linux

Elements that are required to build and install Pumex on Linux :

You can install above mentioned libraries using this command ( excluding QT ) :

sudo apt-get install libassimp-dev libtbb-dev libfreetype6-dev libjpeg-dev libpng-dev

Other libraries will be downloaded during first build ( glm, gli and args )

Steps required to build and install library :

  1. download Pumex Library from here

  2. create solution files for gcc using CMake, choose "Release" configuration type for maximum performance.

    1. to build Pumex with support for QT5 library - you need to set the flag PUMEX_BUILD_QT manually in CMake GUI. This flag is switched off by default. Also remember, that you have to compile and install QT5 library yourself, because Vulkan support is switched off in QT by default.
  3. perform make -j4

  4. ( optional step ) perform sudo make install if necessary. WARNING: due to recent CMake modifications installation is not possible at the moment.

    Pumex library instals itself in /usr/local/* directories. On some Linux distributions ( Ubuntu for example ) /usr/local/lib directory is not added to LD_LIBRARY_PATH environment variable. In that case you will see a following error while trying to run one of the example programs :

    pumexviewer: error while loading shared libraries: libpumex.so.1: cannot open shared object file: No such file or directory
    

    In that case you need to add /usr/local/lib directory to LD_LIBRARY_PATH to remove this error :

    export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
    
  5. if example programs have problem with opening shader files, or 3D models - set the PUMEX_DATA_DIR environment variable so that it points to a directory with data files, for example :

    export PUMEX_DATA_DIR=${HOME}/Dev/pumex/data
    

Building and installation on Android

Elements that are required to build Pumex on Windows and install it on Android device ( building on Linux has not been tested, but it should look the same )

Steps required to build and deploy pumexviewer example ( as it is only example working on Android at the moment ) :

  1. Import project into Android Studio from pumex/android directory.

  2. find local.properties file in pumex/android directory. This file is created by import and is not stored in git, because it contains local settings ). Newest CMake version bundled with Android Studio is 3.10 so it's below minimal Pumex requirements. As a result you have to add path to newer CMake to local.properties file ( CMake 3.11 at least. Newest version is 3.13). For example :

    cmake.dir=C\:\\Program Files\\CMake
    
  3. Build project by pressing Build -> Make Project. First project compilation may take some time, because external dependencies are downloaded, patched and built.

  4. Deploy to your device using Run -> Run 'pumexviewer'

  5. Write github issue describing what went wrong. There's no chance it worked on a first try. Murphy's laws are strong on Android.

You are also able to build project without Android Studio ( standalone build - using gradlew script ). But you still should have proper Android SDK, Android NDK and CMake installed.

Dependencies

Pumex renderer is dependent on a following set of libraries :

On Windows and Android all mandatory dependencies are downloaded and built on first Pumex library build. On Linux - some of the libraries may be installed using your local package manager ( see section about installation on Linux ). On both systems optional QT library must be downloaded manually and built with Vulkan support enabled.


Future plans

Remark : Pumex is a "work in progress" which means that some elements of Vulkan API are not implemented yet and some may not work properly on every combination of hardware / operating system ( especially on Android ). Pumex API is subject to change.