Pumex
Vulkan library oriented on high speed rendering
Install / Use
/learn @pumexx/PumexREADME
Pumex library
The purpose of the Pumex library is to create an efficient and universal rendering engine using Vulkan API that has following properties :
- enables multithreaded rendering on many windows ( or many screens ) at once, may use many graphics cards in a single application
- uses render graph allowing for complete customization of a renderer. Pumex is not tied up to any particular rendering method, like deferred rendering, direct plus rendering, etc. In fact the user is able to implement any of these methods himself fairly quickly.
- decouples rendering stage from update stage and enables update step with constant time rate independent from rendering time rate
- uses modern C++ ( C++11 to C++17 ) but not overuses its features if it's not necessary
- works on many platforms: currently Windows, Linux and Android operating systems are supported. Optionally you may also render to QT windows on Linux and Windows.
- implements efficient rendering algorithms ( like instanced rendering with vkCmdDrawIndexedIndirect() to draw many objects of different types with one draw call )
Quick preview on Youtube :
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 :
- first layer is responsible for creation and configuration of Vulkan instance, logical devices, surfaces and windows. Let's call it a device layer. Below you may see an example of such layer.

-
second layer is called a render graph ( also known in literature as frame graph ). Each Vulkan surface rendered by the application may use one or more render graphs. Render graphs may be shared between surfaces ( see: image above ).
Render graph defines render operations and inputs/outputs between them. During application run abstract render graph is compiled into a set of Vulkan objects required to render a scene: graphics passes and subpasses ( with its attachments and dependencies ), compute passes, images, buffers, attachments and pipeline barriers. These objects are then used to build a primary command buffers.
Each render graph may use one or more Vulkan queues for its execution.
An example of render graph for a simple deferred renderer with depth prepass is shown below.

- third layer is called a scene graph. Every render operation ( graphics subpass from image above ) has its own scene graph. All nodes in a scene graph derive from pumex::Node class and can be categorized as follows :
- pipelines defining render state such as used shaders, culling, blending, depth test state, etc ( pumex::GraphicsPipeline, pumex::ComputePipeline )
- nodes that store vertex and index data ( pumex::AssetBufferNode, pumex::AssetNode, pumex::DrawVerticesNode )
- nodes that perform vkCmdDraw calls ( pumex::AssetBufferDrawNode, pumex::AssetBufferDrawIndirectObject, pumex::AssetNode, pumex::DrawVerticesNode, pumex::Text ) - these nodes are leafs in a scene graph
- node that performs vkCmdDispatch in compute operations ( pumex::DispatchNode )
- helper nodes ( pumex::Group, pumex::AssetBufferFilterNode )
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.

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 :
-
W, S, A, D, Q, Z - move camera : forward, backward, left, right, up, down
-
Left Shift - move camera faster
-
LMB - rotate camera around origin point
-
RMB - change distance to origin point
-
F4 - change application statistics mode. Available modes are : "no statistics", "FPS counter", "CPU stats"
-
F5, F6 - change time scale in "CPU stats" mode
-
F7, F8 - show less / more frames in "CPU stats" mode
pumexcrowd
Application that renders a crowd of 500 animated people on one or more windows.
Application presents :
-
how to utilize compute operation in a render graph.
-
how to use output storage buffer from compute operation as input indirect buffer in a following render operation
-
how to use instanced rendering nodes like pumex::AssetBufferFilterNode and pumex::AssetBuffer
-
how to store textures in texture array and use texture array during instanced rendering

- There are 3 different models of human body, each one has 3 LODs ( levels of detail ) :
- LOD0 has 26756 triangles
- LOD1 has 3140 triangles
- LOD2 has 1460 triangles
- Skeleton of each model has 53 bones
- Each body has 3 texture variants
- Each model has 3 different sets of clothes ( also 3D models ). Each cloth has only 1 LOD.
- Each model randomly chooses one of four provided animations.
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 ) :

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.

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
Related Skills
node-connect
346.8kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
107.6kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
346.8kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
346.8kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。

