Modern Vulkan-based 3D engine featuring procedural shape generation, scene management, and ImGui integration
Find a file
Sascha Willems feb939096f
Merge glTF branch (#747)
* Added helper function for easy pipeline vertex input state create info structure setup from glTF model vertex class

* Split glTF loader into header and implementation

* Updated sample to use glTF

* Removed collada files

Replaced assets are now part of the asset pack

* Return value for glTF model vertex input state create info helper

* Removed unused assets

* Use glTF assets

* Added default material for glTF node's without materials

* Use glTF assets

* Apply pre-transforms to normals

* Use glTF assets

* Use glTF assets

* Use vertex input state from glTF model class

* Scene setup

* Use glTF assets

* Use glTF assets

* Display error message and exit if glTF file could not be loaded

* Use glTF assets

* Use glTF assets

* Use glTF assets

* Remove unused buffer binds

* Use glTF assets

* Remove no longer used model files

* Remove no longer used model files

* Added support for rendering glTF models with images

* glTF model normal pre-transform ignores translation

* Use glTF assets

* Use glTF assets

* Use glTF assets

* Use glTF assets

* Use glTF assets

* Only add combined image samplers to pool if actually used in the scene

* Use global descriptor set layouts

* Use global descriptor set layouts

* Use glTF assets

* Use glTF assets

* Use glTF assets

Code cleanup
Updated GLSL and HLSL shaders

* Use glTF assets

Code cleanup

* Use glTF assets

Code cleanup
Updated GLSL and HLSL shaders

* Remove no-longer used model

* Use glTF assets

Code cleanup
Updated GLSL and HLSL shaders

* Use glTF assets

Code cleanup
Updated GLSL and HLSL shaders
Removed no-longer used model

* Use glTF assets

Code cleanup
Use RGBA texture instead of different compressed formats
Removed no-longer used assets

* Adnrdoid build file

* Use glTF assets

Code cleanup and refactoring
Updated GLSL and HLSL shaders

* Added vertex count and way of passing additional memory property type flags to glTF loader

* Use glTF assets

Updated GLSL and HLSL shaders
Removed no-longer used assets

* Use glTF assets

Updated GLSL and HLSL shaders

* Remove unfinished sample

* Completely reworked push constants sample

Use glTF assets
Updated GLSL and HLSL shaders
Removed no-longer used assets

* Android CMake build files

* Removed un-used asset

* Explicit buffer binding function

* Use glTF assets

Code cleanup
Updated GLSL and HLSL shaders

* Use glTF assets

Code cleanup

* Use glTF assets

Code cleanup
Removed no-longer used assets

* Use glTF assets

Code cleanup
Updated GLSL and HLSL shaders
Removed no-longer used assets

* Remove no-longer used asset

* Use glTF assets

Code cleanup and refactoring
Performance optimizations
Updated GLSL and HLSL shaders
Removed no-longer used assets

* Use glTF assets

Code cleanup and refactoring
Updated GLSL and HLSL shaders
Removed no-longer used assets

* Use glTF assets

Code cleanup and refactoring
Updated GLSL and HLSL shaders
Removed no-longer used assets

* Use glTF assets

Code cleanup and refactoring
Removed no-longer used assets

* Use glTF assets

Code cleanup and refactoring
Removed no-longer used assets

* Use glTF assets

Code cleanup and refactoring

* Use glTF assets

Code cleanup and refactoring

* Use glTF assets

Code cleanup and refactoring
Removed no-longer used assets

* Pass vertex size and calculate multiplier in shaders instead of hard-coding

With this, changes to the glTF vertex structure won't break the ray tracing samples

* Load tangents (if present)

* Use glTF assets

Code cleanup and heavy refactoring
Reworked debug display code

* Android build

* Normal mapping fixes

Udpated HLSL shaders

* Use glTF assets

Code cleanup and heavy refactoring
Reworked debug display code
Updated GLSL and HLSL shaders

* Code cleanup, comments

* Use glTF assets

Code cleanup and heavy refactoring
Reworked debug display code
Updated GLSL and HLSL shaders

* Added sample count to framebuffer create info

* Removed no-longer used assets

* Android build

Removed no-longer used assets

* Code cleanup and heavy refactoring

Updated GLSL and HLSL shaders
Use tangents stored in GLSL instead of calculating them in the fragment shader

* Renamed textured PBR sample main cpp file

* Use glTF assets

Code cleanup and refactoring
Updated GLSL and HLSL shaders
Removed no-longer used assets

* Use glTF assets

Removed no-longer used assets

* Android build files

* Android build files

* Use glTF assets

Removed no-longer used assets

* Fixed HLSL shaders

* Android build files

* Use glTF assets

Updated GLSL and HLSL shaders
Removed no-longer used assets

* Use glTF assets

Updated GLSL and HLSL shaders
Removed no-longer used assets

* Added flag to disable glTF image loading

Useful for samples that use their own textures or don't use textures at all to speed up loading

* Use glTF assets

Code cleanup
Use Sponza scene instead of Sibenik to better highlight the effect
Updated GLSL and HLSL shaders

* Updated Android build files

* Removed left-over comment

* Use Sponza scene for the SSAO sample

* Removed unused code

* Removed ASSIMP

No longer required as all samples now use the glTF file format

* Added missing vertex shader stage

* Removed old ASSIMP-based model loader

* Added support for loading external glTF images from ktx

Android fixes for loading external buffer files

* Scene setup

* Added missing shader stages

* Removed ASSIMP from build files

* Fixed compiler warning

* Removed ASSIMP from readmes

* Android build files cleanup

* Replaced ktx submodule with only the files required for this repo

The ktx submodule was a tad too big and contained lots of files not required for this repo

* Moved ktx build files into base project

* Use glTF assets

* Use glTF assets

* Removed license files, will be moved to asset pack

* Use RGBA textures

* Use RGBA cubemp texture with face assignment based on original images

Refs #679

* Android build files

* Removed textures

All textures will be moved to the asset pack

* Ignore asset folders

* Removed font

Fonts will be moved to the asset pack

* Link to gltf asset pack

* Updated gitignore

* Android build file
2020-07-28 20:20:38 +02:00
.github Create FUNDING.yml 2020-06-24 19:55:02 +02:00
android Merge glTF branch (#747) 2020-07-28 20:20:38 +02:00
base Merge glTF branch (#747) 2020-07-28 20:20:38 +02:00
bin Merge glTF branch (#747) 2020-07-28 20:20:38 +02:00
cmake Merge glTF branch (#747) 2020-07-28 20:20:38 +02:00
data Merge glTF branch (#747) 2020-07-28 20:20:38 +02:00
examples Merge glTF branch (#747) 2020-07-28 20:20:38 +02:00
external Merge glTF branch (#747) 2020-07-28 20:20:38 +02:00
images Updates to iOS and macOS functionality using MoltenVK. 2017-06-22 14:53:49 -04:00
libs/vulkan Merge glTF branch (#747) 2020-07-28 20:20:38 +02:00
screenshots Merge glTF scene rendering sample (#744) 2020-07-04 14:20:45 +02:00
xcode Merge glTF branch (#747) 2020-07-28 20:20:38 +02:00
.clang-format Add clang format setting 2020-06-06 14:43:11 +02:00
.gitattributes gitattributes 2016-02-18 12:03:13 +01:00
.gitignore Merge glTF branch (#747) 2020-07-28 20:20:38 +02:00
.gitmodules Merge glTF branch (#747) 2020-07-28 20:20:38 +02:00
.travis.yml Merge glTF branch (#747) 2020-07-28 20:20:38 +02:00
appveyor.yml Updated appveyor settings 2019-03-24 19:26:55 +01:00
BUILD.md Merge glTF branch (#747) 2020-07-28 20:20:38 +02:00
CMakeLists.txt Merge glTF branch (#747) 2020-07-28 20:20:38 +02:00
CREDITS.md Merge glTF branch (#747) 2020-07-28 20:20:38 +02:00
download_assets.py Merge glTF branch (#747) 2020-07-28 20:20:38 +02:00
LICENSE.md Added Vulkan examples sources! 2016-02-16 15:07:25 +01:00
README.md Added cube map array sample 2020-07-19 07:07:54 +02:00

Vulkan C++ examples and demos

A comprehensive collection of open source C++ examples for Vulkan®, the new generation graphics and compute API from Khronos.

Donate

Table of Contents

Official Khronos Vulkan Samples

Khronos recently made an official Vulkan Samples repository available to the public (press release).

You can find this repository at https://github.com/KhronosGroup/Vulkan-Samples

As I've been involved with getting the official repository up and running, I'll be mostly contributing to that repository from now, but may still add samples that don't fit there in here and I'll of course continue to maintain these samples.

Cloning

This repository contains submodules for external dependencies, so when doing a fresh clone you need to clone recursively:

git clone --recursive https://github.com/SaschaWillems/Vulkan.git

Existing repositories can be updated manually:

git submodule init
git submodule update

Assets

Many examples require assets from the asset pack that is not part of this repository due to file size. A python script is included to download the asset pack that. Run

python download_assets.py

from the root of the repository after cloning or see this for manual download.

Building

The repository contains everything required to compile and build the examples on Windows, Linux, Android, iOS and macOS (using MoltenVK) using a C++ compiler that supports C++11.

See BUILD.md for details on how to build for the different platforms.

Shaders

Vulkan consumes shaders in an intermediate representation called SPIR-V. This makes it possible to use different shader languages by compiling them to that bytecode format. The primary shader language used here is GLSL but thanks to an external contribution you'll also find HLSL shader sources.

Examples

Basics

01 - Triangle

Basic and verbose example for getting a colored triangle rendered to the screen using Vulkan. This is meant as a starting point for learning Vulkan from the ground up. A huge part of the code is boilerplate that is abstracted away in later examples.

02 - Pipelines

Using pipeline state objects (pso) that bake state information (rasterization states, culling modes, etc.) along with the shaders into a single object, making it easy for an implementation to optimize usage (compared to OpenGL's dynamic state machine). Also demonstrates the use of pipeline derivatives.

03 - Descriptor sets

Descriptors are used to pass data to shader binding points. Sets up descriptor sets, layouts, pools, creates a single pipeline based on the set layout and renders multiple objects with different descriptor sets.

04 - Dynamic uniform buffers

Dynamic uniform buffers are used for rendering multiple objects with multiple matrices stored in a single uniform buffer object. Individual matrices are dynamically addressed upon descriptor binding time, minimizing the number of required descriptor sets.

05 - Push constants

Uses push constants, small blocks of uniform data stored within a command buffer, to pass data to a shader without the need for uniform buffers.

06 - Specialization constants

Uses SPIR-V specialization constants to create multiple pipelines with different lighting paths from a single "uber" shader.

07 - Texture mapping

Loads a 2D texture from disk (including all mip levels), uses staging to upload it into video memory and samples from it using combined image samplers.

08 - Texture arrays

Loads a 2D texture array containing multiple 2D texture slices (each with its own mip chain) and renders multiple meshes each sampling from a different layer of the texture. 2D texture arrays don't do any interpolation between the slices.

09 - Cube map textures

Loads a cube map texture from disk containing six different faces. All faces and mip levels are uploaded into video memory, and the cubemap is displayed on a skybox as a backdrop and on a 3D model as a reflection.

10 - Cube map arrays

Loads an array of cube map textures from a single file. All cube maps are uploaded into video memory with their faces and mip levels, and the selected cubemap is displayed on a skybox as a backdrop and on a 3D model as a reflection.

11 - 3D textures

Generates a 3D texture on the cpu (using perlin noise), uploads it to the device and samples it to render an animation. 3D textures store volumetric data and interpolate in all three dimensions.

12 - Input attachments

Uses input attachments to read framebuffer contents from a previous sub pass at the same pixel position within a single render pass. This can be used for basic post processing or image composition (blog entry).

13 - Sub passes

Advanced example that uses sub passes and input attachments to write and read back data from framebuffer attachments (same location only) in single render pass. This is used to implement deferred render composition with added forward transparency in a single pass.

14 - Offscreen rendering

Basic offscreen rendering in two passes. First pass renders the mirrored scene to a separate framebuffer with color and depth attachments, second pass samples from that color attachment for rendering a mirror surface.

15 - CPU particle system

Implements a simple CPU based particle system. Particle data is stored in host memory, updated on the CPU per-frame and synchronized with the device before it's rendered using pre-multiplied alpha.

16 - Stencil buffer

Uses the stencil buffer and its compare functionality for rendering a 3D model with dynamic outlines.

glTF

These samples show how implement different features of the glTF 2.0 3D format 3D transmission file format in detail.

01 - glTF model loading and rendering

Shows how to load a complete scene from a glTF 2.0 file. The structure of the glTF 2.0 scene is converted into the data structures required to render the scene with Vulkan.

02 - glTF vertex skinning

Demonstrates how to do GPU vertex skinning from animation data stored in a glTF 2.0 model. Along with reading all the data structures required for doing vertex skinning, the sample also shows how to upload animation data to the GPU and how to render it using shaders.

03 - glTF scene rendering

Renders a complete scene loaded from an glTF 2.0 file. The sample is based on the glTF model loading sample, and adds data structures, functions and shaders required to render a more complex scene using Crytek's Sponza model with per-material pipelines and normal mapping.

Advanced

01 - Multi sampling

Implements multisample anti-aliasing (MSAA) using a renderpass with multisampled attachments and resolve attachments that get resolved into the visible frame buffer.

02 - High dynamic range

Implements a high dynamic range rendering pipeline using 16/32 bit floating point precision for all internal formats, textures and calculations, including a bloom pass, manual exposure and tone mapping.

03 - Shadow mapping

Rendering shadows for a directional light source. First pass stores depth values from the light's pov, second pass compares against these to check if a fragment is shadowed. Uses depth bias to avoid shadow artifacts and applies a PCF filter to smooth shadow edges.

04 - Cascaded shadow mapping

Uses multiple shadow maps (stored as a layered texture) to increase shadow resolution for larger scenes. The camera frustum is split up into multiple cascades with corresponding layers in the shadow map. Layer selection for shadowing depth compare is then done by comparing fragment depth with the cascades' depths ranges.

05 - Omnidirectional shadow mapping

Uses a dynamic floating point cube map to implement shadowing for a point light source that casts shadows in all directions. The cube map is updated every frame and stores distance to the light source for each fragment used to determine if a fragment is shadowed.

06 - Run-time mip-map generation

Generating a complete mip-chain at runtime instead of loading it from a file, by blitting from one mip level, starting with the actual texture image, down to the next smaller size until the lower 1x1 pixel end of the mip chain.

07 - Capturing screenshots

Capturing and saving an image after a scene has been rendered using blits to copy the last swapchain image from optimal device to host local linear memory, so that it can be stored into a ppm image.

Performance

01 - Multi threaded command buffer generation

Multi threaded parallel command buffer generation. Instead of prebuilding and reusing the same command buffers this sample uses multiple hardware threads to demonstrate parallel per-frame recreation of secondary command buffers that are executed and submitted in a primary buffer once all threads have finished.

02 - Instancing

Uses the instancing feature for rendering many instances of the same mesh from a single vertex buffer with variable parameters and textures (indexing a layered texture). Instanced data is passed using a secondary vertex buffer.

03 - Indirect drawing

Rendering thousands of instanced objects with different geometry using one single indirect draw call instead of issuing separate draws. All draw commands to be executed are stored in a dedicated indirect draw buffer object (storing index count, offset, instance count, etc.) that is uploaded to the device and sourced by the indirect draw command for rendering.

04 - Occlusion queries

Using query pool objects to get number of passed samples for rendered primitives got determining on-screen visibility.

05 - Pipeline statistics

Using query pool objects to gather statistics from different stages of the pipeline like vertex, fragment shader and tessellation evaluation shader invocations depending on payload.

Physically Based Rendering

Physical based rendering as a lighting technique that achieves a more realistic and dynamic look by applying approximations of bidirectional reflectance distribution functions based on measured real-world material parameters and environment lighting.

01 - PBR basics

Demonstrates a basic specular BRDF implementation with solid materials and fixed light sources on a grid of objects with varying material parameters, demonstrating how metallic reflectance and surface roughness affect the appearance of pbr lit objects.

02 - PBR image based lighting

Adds image based lighting from an hdr environment cubemap to the PBR equation, using the surrounding environment as the light source. This adds an even more realistic look the scene as the light contribution used by the materials is now controlled by the environment. Also shows how to generate the BRDF 2D-LUT and irradiance and filtered cube maps from the environment map.

03 - Textured PBR with IBL

Renders a model specially crafted for a metallic-roughness PBR workflow with textures defining material parameters for the PRB equation (albedo, metallic, roughness, baked ambient occlusion, normal maps) in an image based lighting environment.

Deferred

These examples use a deferred shading setup.

01 - Deferred shading basics

Uses multiple render targets to fill all attachments (albedo, normals, position, depth) required for a G-Buffer in a single pass. A deferred pass then uses these to calculate shading and lighting in screen space, so that calculations only have to be done for visible fragments independent of no. of lights.

02 - Deferred multi sampling

Adds multi sampling to a deferred renderer using manual resolve in the fragment shader.

03 - Deferred shading shadow mapping

Adds shadows from multiple spotlights to a deferred renderer using a layered depth attachment filled in one pass using multiple geometry shader invocations.

04 - Screen space ambient occlusion

Adds ambient occlusion in screen space to a 3D scene. Depth values from a previous deferred pass are used to generate an ambient occlusion texture that is blurred before being applied to the scene in a final composition path.

Compute Shader

01 - Image processing

Uses a compute shader along with a separate compute queue to apply different convolution kernels (and effects) on an input image in realtime.

02 - GPU particle system

Attraction based 2D GPU particle system using compute shaders. Particle data is stored in a shader storage buffer and only modified on the GPU using memory barriers for synchronizing compute particle updates with graphics pipeline vertex access.

03 - N-body simulation

N-body simulation based particle system with multiple attractors and particle-to-particle interaction using two passes separating particle movement calculation and final integration. Shared compute shader memory is used to speed up compute calculations.

04 - Ray tracing

Simple GPU ray tracer with shadows and reflections using a compute shader. No scene geometry is rendered in the graphics pass.

05 - Cloth simulation

Mass-spring based cloth system on the GPU using a compute shader to calculate and integrate spring forces, also implementing basic collision with a fixed scene object.

06 - Cull and LOD

Purely GPU based frustum visibility culling and level-of-detail system. A compute shader is used to modify draw commands stored in an indirect draw commands buffer to toggle model visibility and select its level-of-detail based on camera distance, no calculations have to be done on and synced with the CPU.

Geometry Shader

01 - Normal debugging

Visualizing per-vertex model normals (for debugging). First pass renders the plain model, second pass uses a geometry shader to generate colored lines based on per-vertex model normals,

02 - Viewport arrays

Renders a scene to multiple viewports in one pass using a geometry shader to apply different matrices per viewport to simulate stereoscopic rendering (left/right). Requires a device with support for multiViewport.

Tessellation Shader

01 - Displacement mapping

Uses a height map to dynamically generate and displace additional geometric detail for a low-poly mesh.

02 - Dynamic terrain tessellation

Renders a terrain using tessellation shaders for height displacement (based on a 16-bit height map), dynamic level-of-detail (based on triangle screen space size) and per-patch frustum culling.

03 - Model tessellation

Uses curved PN-triangles (paper) for adding details to a low-polygon model.

Headless

Examples that run one-time tasks and don't make use of visual output (no window system integration). These can be run in environments where no user interface is available (blog entry).

01 - Render

Renders a basic scene to a (non-visible) frame buffer attachment, reads it back to host memory and stores it to disk without any on-screen presentation, showing proper use of memory barriers required for device to host image synchronization.

02 - Compute

Only uses compute shader capabilities for running calculations on an input data set (passed via SSBO). A fibonacci row is calculated based on input data via the compute shader, stored back and displayed via command line.

User Interface

01 - Text rendering

Load and render a 2D text overlay created from the bitmap glyph data of a stb font file. This data is uploaded as a texture and used for displaying text on top of a 3D scene in a second pass.

02 - Distance field fonts

Uses a texture that stores signed distance field information per character along with a special fragment shader calculating output based on that distance data. This results in crisp high quality font rendering independent of font size and scale.

03 - ImGui overlay

Generates and renders a complex user interface with multiple windows, controls and user interaction on top of a 3D scene. The UI is generated using Dear ImGUI and updated each frame.

Effects

01 - Fullscreen radial blur

Demonstrates the basics of fullscreen shader effects. The scene is rendered into an offscreen framebuffer at lower resolution and rendered as a fullscreen quad atop the scene using a radial blur fragment shader.

02 - Bloom

Advanced fullscreen effect example adding a bloom effect to a scene. Glowing scene parts are rendered to a low res offscreen framebuffer that is applied atop the scene using a two pass separated gaussian blur.

03 - Parallax mapping

Implements multiple texture mapping methods to simulate depth based on texture information: Normal mapping, parallax mapping, steep parallax mapping and parallax occlusion mapping (best quality, worst performance).

04 - Spherical environment mapping

Uses a spherical material capture texture array defining environment lighting and reflection information to fake complex lighting.

Extensions

01 - Conservative rasterization (VK_EXT_conservative_rasterization)

Uses conservative rasterization to change the way fragments are generated by the gpu. The example enables overestimation to generate fragments for every pixel touched instead of only pixels that are fully covered (blog post).

02 - Push descriptors (VK_KHR_push_descriptor)

Uses push descriptors apply the push constants concept to descriptor sets. Instead of creating per-object descriptor sets for rendering multiple objects, this example passes descriptors at command buffer creation time.

03 - Inline uniform blocks (VK_EXT_inline_uniform_block)

Makes use of inline uniform blocks to pass uniform data directly at descriptor set creation time and also demonstrates how to update data for those descriptors at runtime.

04 - Multiview rendering (VK_KHR_multiview)

Renders a scene to to multiple views (layers) of a single framebuffer to simulate stereoscopic rendering in one pass. Broadcasting to the views is done in the vertex shader using gl_ViewIndex.

05 - Conditional rendering (VK_EXT_conditional_rendering)

Demonstrates the use of VK_EXT_conditional_rendering to conditionally dispatch render commands based on values from a dedicated buffer. This allows e.g. visibility toggles without having to rebuild command buffers (blog post).

06 - Debug markers (VK_EXT_debug_marker)

This sample is deprecated

An updated version using VK_EXT_debug_utils along with an in-depth tutorial is available in the Official Khronos Vulkan Samples repository.

07 - Negative viewport height (VK_KHR_Maintenance1 or Vulkan 1.1)

Shows how to render a scene using a negative viewport height, making the Vulkan render setup more similar to other APIs like OpenGL. Also has several options for changing relevant pipeline state, and displaying meshes with OpenGL or Vulkan style coordinates. Details can be found in this tutorial.

08 - Basic ray tracing with VK_NV_ray_tracing

Basic example for doing ray tracing using the new Nvidia RTX extensions. Shows how to setup acceleration structures, ray tracing pipelines and the shaders needed to do the actual ray tracing.

09 - Ray traced shadows with VK_NV_ray_tracing

Adds ray traced shadows casting using the new Nvidia RTX extensions to a more complex scene. Shows how to add multiple hit and miss shaders and how to modify existing shaders to add shadow calculations.

10 - Ray traced reflections with VK_NV_ray_tracing

Renders a complex scene with reflective surfaces using using the new Nvidia RTX extensions. Shows how to do recursion inside of the ray tracing shaders for implementing real time reflections.

Misc

01 - Vulkan Gears

Vulkan interpretation of glxgears. Procedurally generates and animates multiple gears.

02 - Vulkan demo scene

Renders a Vulkan demo scene with logos and mascots. Not an actual example but more of a playground and showcase.

Credits and Attributions

See CREDITS.md for additional credits and attributions.