diff --git a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanRenderDelegate.cpp b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanRenderDelegate.cpp
index b039bbfd4747bbde071a2688c2dc6d1aa70a43fa..f2c01dae800e1a74201303ed1a9c5bf4b5739be0 100644
--- a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanRenderDelegate.cpp
+++ b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanRenderDelegate.cpp
@@ -142,23 +142,35 @@ VulkanRenderDelegate::initializeData(VulkanMemoryManager& memoryManager,
     m_vertexUniformBuffer = std::make_shared<VulkanUniformBuffer>(memoryManager, (uint32_t)sizeof(VulkanLocalVertexUniforms));
     m_fragmentUniformBuffer = std::make_shared<VulkanUniformBuffer>(memoryManager, (uint32_t)sizeof(VulkanLocalFragmentUniforms));
 
-    m_material = std::make_shared<VulkanMaterialDelegate>(m_vertexUniformBuffer,
-        m_fragmentUniformBuffer,
-        material,
-        memoryManager);
+    if (material->getDisplayMode() == RenderMaterial::DisplayMode::SURFACE
+        || material->getDisplayMode() == RenderMaterial::DisplayMode::WIREFRAME_SURFACE)
+    {
+        m_material = std::make_shared<VulkanMaterialDelegate>(m_vertexUniformBuffer,
+            m_fragmentUniformBuffer,
+            material,
+            memoryManager);
+    }
 
     m_shadowMaterial = std::make_shared<VulkanMaterialDelegate>(m_vertexUniformBuffer,
         m_fragmentUniformBuffer,
         material,
         memoryManager,
-        true);
+        VulkanMaterialType::Shadow);
 
     m_depthMaterial = std::make_shared<VulkanMaterialDelegate>(m_vertexUniformBuffer,
         m_fragmentUniformBuffer,
         material,
         memoryManager,
-        false,
-        true);
+        VulkanMaterialType::Depth);
+
+    if (material->getDisplayMode() != RenderMaterial::DisplayMode::SURFACE)
+    {
+        m_wireframeMaterial = std::make_shared<VulkanMaterialDelegate>(m_vertexUniformBuffer,
+            m_fragmentUniformBuffer,
+            material,
+            memoryManager,
+            VulkanMaterialType::Wireframe);
+    }
 
     m_vertexBuffer = std::make_shared<VulkanVertexBuffer>(memoryManager,
         m_numVertices,
diff --git a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanRenderDelegate.h b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanRenderDelegate.h
index e238020e9c209b58102bf4b96c9fb4cf02a4653e..399def7d8c109f1b61e1dc0aac19ae35e62c685a 100644
--- a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanRenderDelegate.h
+++ b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanRenderDelegate.h
@@ -113,6 +113,7 @@ protected:
     std::shared_ptr<VulkanUniformBuffer> m_fragmentUniformBuffer;
 
     std::shared_ptr<VulkanMaterialDelegate> m_material = nullptr;
+    std::shared_ptr<VulkanMaterialDelegate> m_wireframeMaterial = nullptr;
     std::shared_ptr<VulkanMaterialDelegate> m_shadowMaterial = nullptr;
     std::shared_ptr<VulkanMaterialDelegate> m_depthMaterial = nullptr;
 
diff --git a/Source/Rendering/VulkanRenderer/imstkVulkanMaterialDelegate.cpp b/Source/Rendering/VulkanRenderer/imstkVulkanMaterialDelegate.cpp
index a4d402264df1127c07bfa2c4165d9aeaea2460e8..5f2a99641ba1d4612dfebd8ebedbc080bfd19c58 100644
--- a/Source/Rendering/VulkanRenderer/imstkVulkanMaterialDelegate.cpp
+++ b/Source/Rendering/VulkanRenderer/imstkVulkanMaterialDelegate.cpp
@@ -30,14 +30,14 @@ VulkanMaterialDelegate::VulkanMaterialDelegate(
     std::shared_ptr<VulkanUniformBuffer> fragmentUniformBuffer,
     std::shared_ptr<RenderMaterial> material,
     VulkanMemoryManager& memoryManager,
-    bool shadowPass,
-    bool depthPrePass)
+    VulkanMaterialType type)
 {
     m_vertexUniformBuffer = vertexUniformBuffer;
     m_fragmentUniformBuffer = fragmentUniformBuffer;
 
-    m_shadowPass = shadowPass;
-    m_depthPrePass = depthPrePass;
+    m_shadowPass = (type == VulkanMaterialType::Shadow);
+    m_depthPrePass = (type == VulkanMaterialType::Depth);
+    m_wireframe = (type == VulkanMaterialType::Wireframe);
     m_depthOnlyPass = m_shadowPass || m_depthPrePass;
     m_memoryManager = &memoryManager;
 
@@ -148,7 +148,7 @@ VulkanMaterialDelegate::buildMaterial(VulkanRenderer * renderer)
 
     m_constants.numLights = renderer->m_constants.numLights;
     m_constants.tessellation = m_material->getTessellated();
-    m_constants.shaded = m_material->getDisplayMode() == RenderMaterial::DisplayMode::SURFACE
+    m_constants.shaded = !m_wireframe
                          && !m_material->isLineMesh()
                          && !m_depthPrePass
                          && !m_material->isParticle();
@@ -358,17 +358,21 @@ VulkanMaterialDelegate::buildMaterial(VulkanRenderer * renderer)
     m_pipelineComponents.rasterizationInfo.depthClampEnable = VK_FALSE;
     m_pipelineComponents.rasterizationInfo.rasterizerDiscardEnable = VK_FALSE; // Might be enabled later
 
-    if (m_material->getDisplayMode() == RenderMaterial::DisplayMode::WIREFRAME)
+    m_pipelineComponents.rasterizationInfo.polygonMode = VK_POLYGON_MODE_FILL;
+    switch (m_material->getDisplayMode())
     {
+    case RenderMaterial::DisplayMode::WIREFRAME:
         m_pipelineComponents.rasterizationInfo.polygonMode = VK_POLYGON_MODE_LINE;
-    }
-    else if (m_material->getDisplayMode() == RenderMaterial::DisplayMode::POINTS)
-    {
+        break;
+    case RenderMaterial::DisplayMode::POINTS:
         m_pipelineComponents.rasterizationInfo.polygonMode = VK_POLYGON_MODE_POINT;
-    }
-    else
-    {
-        m_pipelineComponents.rasterizationInfo.polygonMode = VK_POLYGON_MODE_FILL;
+        break;
+    case RenderMaterial::DisplayMode::WIREFRAME_SURFACE:
+        if (m_wireframe)
+        {
+            m_pipelineComponents.rasterizationInfo.polygonMode = VK_POLYGON_MODE_LINE;
+        }
+        break;
     }
 
     m_pipelineComponents.rasterizationInfo.cullMode =
diff --git a/Source/Rendering/VulkanRenderer/imstkVulkanMaterialDelegate.h b/Source/Rendering/VulkanRenderer/imstkVulkanMaterialDelegate.h
index f8c602cd0a90bd2b68bc180a91612f2ca153acbf..c27dd839ece41d38291e21f5107c6902821d57a2 100644
--- a/Source/Rendering/VulkanRenderer/imstkVulkanMaterialDelegate.h
+++ b/Source/Rendering/VulkanRenderer/imstkVulkanMaterialDelegate.h
@@ -34,6 +34,14 @@
 
 namespace imstk
 {
+enum class VulkanMaterialType
+{
+    Material = 0,
+    Shadow,
+    Depth,
+    Wireframe
+};
+
 class VulkanRenderer;
 
 // Large struct to contain pipeline components for later pipeline creation
@@ -91,8 +99,7 @@ public:
         std::shared_ptr<VulkanUniformBuffer> fragmentUniformBuffer,
         std::shared_ptr<RenderMaterial> material,
         VulkanMemoryManager& memoryManager,
-        bool shadowPass = false,
-        bool depthPass = false);
+        VulkanMaterialType type = VulkanMaterialType::Material);
 
     ///
     /// \brief Clears the material
@@ -140,6 +147,7 @@ protected:
     uint32_t m_numTextures = 0;
     bool m_shadowPass = false;
     bool m_depthPrePass = false;
+    bool m_wireframe = true;
     bool m_depthOnlyPass = false;
 
     void createDescriptors(VulkanRenderer * renderer);
diff --git a/Source/Rendering/VulkanRenderer/imstkVulkanRenderer.cpp b/Source/Rendering/VulkanRenderer/imstkVulkanRenderer.cpp
index 32f43bd3d2564fc8ae15d8f23acd627b423348d6..abd17f865d7374e202461fd8761751310d4512f0 100644
--- a/Source/Rendering/VulkanRenderer/imstkVulkanRenderer.cpp
+++ b/Source/Rendering/VulkanRenderer/imstkVulkanRenderer.cpp
@@ -1019,19 +1019,35 @@ VulkanRenderer::renderFrame()
             continue;
         }
 
-        auto material = m_renderDelegates[renderDelegateIndex]->m_material;
-        vkCmdBindPipeline(m_renderCommandBuffer[nextImageIndex], VK_PIPELINE_BIND_POINT_GRAPHICS, material->m_pipeline);
+        auto buffers = m_renderDelegates[renderDelegateIndex]->getBuffer().get();
+        buffers->bindBuffers(&m_renderCommandBuffer[nextImageIndex], nextImageIndex);
         this->setCommandBufferState(&m_renderCommandBuffer[nextImageIndex], m_width, m_height);
 
-        vkCmdBindDescriptorSets(m_renderCommandBuffer[nextImageIndex],
-            VK_PIPELINE_BIND_POINT_GRAPHICS,
-            material->m_pipelineLayout, 0, (uint32_t)material->m_descriptorSets.size(),
-            &material->m_descriptorSets[0], 0, &m_dynamicOffsets);
+        // Render opaque
+        auto material = m_renderDelegates[renderDelegateIndex]->m_material;
+        if (material)
+        {
+            vkCmdBindPipeline(m_renderCommandBuffer[nextImageIndex], VK_PIPELINE_BIND_POINT_GRAPHICS, material->m_pipeline);
+            vkCmdBindDescriptorSets(m_renderCommandBuffer[nextImageIndex],
+                VK_PIPELINE_BIND_POINT_GRAPHICS,
+                material->m_pipelineLayout, 0, (uint32_t)material->m_descriptorSets.size(),
+                &material->m_descriptorSets[0], 0, &m_dynamicOffsets);
 
-        auto buffers = m_renderDelegates[renderDelegateIndex]->getBuffer().get();
+            vkCmdDrawIndexed(m_renderCommandBuffer[nextImageIndex], buffers->m_numIndices, 1, 0, 0, 0);
+        }
 
-        buffers->bindBuffers(&m_renderCommandBuffer[nextImageIndex], nextImageIndex);
-        vkCmdDrawIndexed(m_renderCommandBuffer[nextImageIndex], buffers->m_numIndices, 1, 0, 0, 0);
+        // Render wireframe
+        auto wireframeMaterial = m_renderDelegates[renderDelegateIndex]->m_wireframeMaterial;
+        if (wireframeMaterial)
+        {
+            vkCmdBindPipeline(m_renderCommandBuffer[nextImageIndex], VK_PIPELINE_BIND_POINT_GRAPHICS, wireframeMaterial->m_pipeline);
+            vkCmdBindDescriptorSets(m_renderCommandBuffer[nextImageIndex],
+                VK_PIPELINE_BIND_POINT_GRAPHICS,
+                wireframeMaterial->m_pipelineLayout, 0, (uint32_t)wireframeMaterial->m_descriptorSets.size(),
+                &wireframeMaterial->m_descriptorSets[0], 0, &m_dynamicOffsets);
+
+            vkCmdDrawIndexed(m_renderCommandBuffer[nextImageIndex], buffers->m_numIndices, 1, 0, 0, 0);
+        }
     }
     vkCmdEndRenderPass(m_renderCommandBuffer[nextImageIndex]);
 
@@ -1400,7 +1416,16 @@ VulkanRenderer::loadVisualModel(std::shared_ptr<VisualModel> visualModel, SceneO
     {
         m_renderDelegates.push_back(renderDelegate);
         renderDelegate->getBuffer()->initializeBuffers(m_memoryManager);
-        renderDelegate->m_material->initialize(this);
+
+        if (renderDelegate->m_material)
+        {
+            renderDelegate->m_material->initialize(this);
+        }
+
+        if (renderDelegate->m_wireframeMaterial)
+        {
+            renderDelegate->m_wireframeMaterial->initialize(this);
+        }
 
         if (!renderDelegate->getVisualModel()->getRenderMaterial()->isDecal()
             && !renderDelegate->getVisualModel()->getRenderMaterial()->isParticle())