EXAMPLES_BASIC.md

March 11, 2018 ยท View on GitHub

Intermediate Examples

Gears

Vulkan interpretation of glxgears. Procedurally generates separate meshes for each gear, with every mesh having it's own uniform buffer object for animation. Also demonstrates how to use different descriptor sets.

Texture mapping

Loads a single texture and displays it on a simple quad. Shows how to upload a texture including mip maps to the gpu in an optimal (tiling) format. Also demonstrates how to display the texture using a combined image sampler with anisotropic filtering enabled.

Cubemaps

Building on the basic texture loading example a cubemap is loaded into host visible memory and then transformed into an optimal format for the GPU.

The demo uses two different pipelines (and shader sets) to display the cubemap as a skybox (background) and as a source for reflections.

Texture array

Texture arrays allow storing of multiple images in different layers without any interpolation between the layers. This example demonstrates the use of a 2D texture array with instanced rendering. Each instance samples from a different layer of the texture array.

Particle system

Point sprite based particle system simulating a fire. Particles and their attributes are stored in a host visible vertex buffer that's updated on the CPU on each frame. Also makes use of pre-multiplied alpha for rendering particles with different blending modes (smoke and fire) in one single pass.

Pipelines

Pipeline state objects replace the biggest part of the dynamic state machine from OpenGL, baking state information for culling, blending, rasterization, etc. and shaders into a fixed stat that can be optimized much easier by the implementation.

This example uses three different PSOs for rendering the same scene with different visuals and shaders and also demonstrates the use pipeline derivatives.

Mesh loading and rendering

Uses assimp to load a mesh from a common 3D format including a color map. The mesh data is then converted to a fixed vertex layout matching the shader vertex attribute bindings.

Multi sampling

Demonstrates the use of resolve attachments for doing multisampling. Instead of doing an explicit resolve from a multisampled image this example creates multisampled attachments for the color and depth buffer and sets up the render pass to use these as resolve attachments that will get resolved to the visible frame buffer at the end of this render pass. To highlight MSAA the example renders a mesh with fine details against a bright background. Here is a screenshot without MSAA to compare.

Mesh instancing

Shows the use of instancing for rendering many copies of the same mesh using different attributes and textures. A secondary vertex buffer containing instanced data, stored in device local memory, is used to pass instance data to the shader via vertex attributes with a per-instance step rate. The instance data also contains a texture layer index for having different textures for the instanced meshes.

Indirect rendering

Shows the use of a shared vertex buffer containing multiple shapes to rendering numerous instances of each shape with only one draw call.

Push constants

Demonstrates the use of push constants for updating small blocks of shader data with high speed (and without having to use a uniform buffer). Displays several light sources with position updates through a push constant block in a separate command buffer.

Skeletal animation

Based on the mesh loading example, this example loads and displays a rigged COLLADA model including animations. Bone weights are extracted for each vertex and are passed to the vertex shader together with the final bone transformation matrices for vertex position calculations.

(Tessellation shader) PN-Triangles

Generating curved PN-Triangles on the GPU using tessellation shaders to add details to low-polygon meshes, based on this paper, with shaders from this tutorial.

Spherical environment mapping

Uses a (spherical) material capture texture containing environment lighting and reflection information to fake complex lighting. The example also uses a texture array to store (and select) several material caps that can be toggled at runtime.

The technique is based on this article.

(Geometry shader) Normal debugging

Renders the vertex normals of a complex mesh with the use of a geometry shader. The mesh is rendered solid first and the a geometry shader that generates lines from the face normals is used in the second pass.

Distance field fonts

Instead of just sampling a bitmap font texture, a texture with per-character signed distance fields is used to generate high quality glyphs in the fragment shader. This results in a much higher quality than common bitmap fonts, even if heavily zoomed.

Distance field font textures can be generated with tools like Hiero.

Vulkan demo scene

More of a playground than an actual example. Renders multiple meshes with different shaders (and pipelines) including a background.

(Tessellation shader) Displacement mapping

Uses tessellation shaders to generate additional details and displace geometry based on a displacement map (heightmap).

Parallax mapping

Like normal mapping, parallax mapping simulates geometry on a flat surface. In addition to normal mapping a heightmap is used to offset texture coordinates depending on the viewing angle giving the illusion of added depth.

(Extension) VK_EXT_debug_marker

Example application to be used along with this tutorial for demonstrating the use of the new VK_EXT_debug_marker extension. Introduced with Vulkan 1.0.12, it adds functionality to set debug markers, regions and name objects for advanced debugging in an offline graphics debugger like RenderDoc.

Multi threaded command buffer generation

This example demonstrates multi threaded command buffer generation. All available hardware threads are used to generated n secondary command buffers concurrent, with each thread also checking object visibility against the current viewing frustum. Command buffers are rebuilt on each frame.

Once all threads have finished (and all secondary command buffers have been constructed), the secondary command buffers are executed inside the primary command buffer and submitted to the queue.

Occlusion queries

FIXME the queies seem to work, but generate validation errors every frame

Shows how to use occlusion queries to determine object visibility depending on the number of passed samples for a given object. Does an occlusion pass first, drawing all objects (and the occluder) with basic shaders, then reads the query results to conditionally color the objects during the final pass depending on their visibility.