diff --git a/Examples/Rendering/RenderingExample.cpp b/Examples/Rendering/RenderingExample.cpp
index 2b3b89f4ef5e7047122ab0c7db8b1de1640d40cb..80cd9088d6c3f8ad88d3bc0431fb1d9712e86ed6 100644
--- a/Examples/Rendering/RenderingExample.cpp
+++ b/Examples/Rendering/RenderingExample.cpp
@@ -94,9 +94,9 @@ int main()
 
 #ifdef iMSTK_USE_Vulkan
     auto viewer = std::dynamic_pointer_cast<VulkanViewer>(sdk->getViewer());
-    viewer->setResolution(1920, 1080);
+    viewer->setResolution(800, 600);
     viewer->disableVSync();
-    viewer->enableFullscreen();
+    //viewer->enableFullscreen();
 #endif
 
     sdk->startSimulation(SimulationStatus::PAUSED);
diff --git a/Examples/RenderingBenchmark/CMakeLists.txt b/Examples/RenderingBenchmark/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..b11f6bc47e3bcdd345b387b25921df6ebe4c854e
--- /dev/null
+++ b/Examples/RenderingBenchmark/CMakeLists.txt
@@ -0,0 +1,35 @@
+###########################################################################
+#
+# Copyright (c) Kitware, Inc.
+#
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0.txt
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+###########################################################################
+
+project(Example-RenderingBenchmark)
+
+#-----------------------------------------------------------------------------
+# Create executable
+#-----------------------------------------------------------------------------
+add_executable(${PROJECT_NAME} RenderingBenchmark.cpp)
+
+#-----------------------------------------------------------------------------
+# Add shaders
+#-----------------------------------------------------------------------------
+include(imstkCopyAndCompileShaders)
+CopyAndCompileShaders()
+
+#-----------------------------------------------------------------------------
+# Link libraries to executable
+#-----------------------------------------------------------------------------
+target_link_libraries(${PROJECT_NAME} SimulationManager)
\ No newline at end of file
diff --git a/Examples/RenderingBenchmark/RenderingBenchmark.cpp b/Examples/RenderingBenchmark/RenderingBenchmark.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cfff4b781061b53edfc68a59dac263071676a4e9
--- /dev/null
+++ b/Examples/RenderingBenchmark/RenderingBenchmark.cpp
@@ -0,0 +1,146 @@
+/*=========================================================================
+
+   Library: iMSTK
+
+   Copyright (c) Kitware, Inc. & Center for Modeling, Simulation,
+   & Imaging in Medicine, Rensselaer Polytechnic Institute.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0.txt
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+=========================================================================*/
+
+#include "imstkSimulationManager.h"
+#include "imstkMeshIO.h"
+#include "imstkPbdObject.h"
+#include "imstkPbdSolver.h"
+#include "imstkOneToOneMap.h"
+#include "imstkAPIUtilities.h"
+#include "imstkLineMesh.h"
+
+using namespace imstk;
+
+///
+/// \brief This benchmark is to test the speed of various rendering operations
+///
+int main()
+{
+    // SDK and Scene
+    auto sdk = std::make_shared<SimulationManager>();
+    auto scene = sdk->createNewScene("RenderingBenchmarkTest");
+
+    auto camera = scene->getCamera();
+    camera->setPosition(0, 0, 1);
+    camera->setFocalPoint(0, 0, -1);
+
+    int numMeshes = 2000;
+    std::cout << "Enter number of meshes: ";
+    std::cin >> numMeshes;
+
+    size_t numLines = 100;
+    std::cout << "Enter number of triangles: ";
+    std::cin >> numLines;
+
+    bool dynamicMesh = true;
+    std::cout << "Enter dynamic mesh: ";
+    std::cin >> dynamicMesh;
+
+    std::vector<LineMesh::LineArray> lines;
+    StdVectorOfVec3d vertices;
+
+    vertices.resize(numLines * 2);
+    lines.resize(numLines);
+
+    for (int i = 0; i < numLines; i++)
+    {
+        vertices[i * 2] = Vec3d(0, 0, 0);
+        vertices[i * 2 + 1] = Vec3d(0, 0, 0.1);
+        lines[i][0] = i * 2;
+        lines[i][1] = i * 2 + 1;
+    }
+
+    for (int j = 0; j < numMeshes; j++)
+    {
+        // Construct surface mesh
+        auto mesh = std::make_shared<LineMesh>();
+
+        mesh->initialize(vertices, lines);
+
+        if (dynamicMesh)
+        {
+            auto object = std::make_shared<PbdObject>(std::string("mesh") + std::to_string(j));
+            object->setVisualGeometry(mesh);
+
+            auto model = std::make_shared<PbdModel>();
+            model->setModelGeometry(mesh);
+            object->setDynamicalModel(model);
+            scene->addSceneObject(object);
+        }
+        else
+        {
+            auto object = std::make_shared<VisualObject>(std::string("mesh") + std::to_string(j));
+            object->setVisualGeometry(mesh);
+            scene->addSceneObject(object);
+        }
+
+    }
+
+    int frame = 0;
+    auto watch = std::make_shared<StopWatch>();
+    auto startWatch = std::make_shared<StopWatch>();
+    double endTime = 0;
+    int startFrame = -1;
+    int startupFrame = -1;
+
+    sdk->getViewer()->setOnTimerFunction([&](InteractorStyle* c) -> bool
+        {
+            if (dynamicMesh)
+            {
+                for (int j = 0; j < numMeshes; j++)
+                {
+                    auto object = scene->getSceneObject(std::string("mesh") + std::to_string(j));
+                    auto mesh = std::dynamic_pointer_cast<LineMesh>(object->getVisualGeometry());
+
+                    mesh->setVertexPositions(vertices);
+                    mesh->setLinesVertices(lines);
+                }
+            }
+
+            if (scene->getSceneObject("mesh" + std::to_string(numMeshes - 1)) && startupFrame == -1)
+            {
+                startupFrame = frame;
+                LOG(INFO) << "Start time: " << startWatch->getTimeElapsed();
+            }
+            if (frame == startupFrame + 100)
+            {
+                startFrame = frame;
+                watch->start();
+                watch->reset();
+                LOG(INFO) << "Starting time";
+            }
+            else if (frame == startFrame + 100 && startFrame != -1)
+            {
+                endTime = watch->getTimeElapsed();
+                LOG(INFO) << "Total time: " << endTime;
+                LOG(INFO) << "Frame time: " << endTime / (frame - startFrame);
+            }
+            frame++;
+            return true;
+        }
+    );
+
+    // Start simulation
+    startWatch->start();
+    startWatch->reset();
+    sdk->setActiveScene(scene);
+    sdk->startSimulation();
+}
diff --git a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanCapsuleRenderDelegate.cpp b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanCapsuleRenderDelegate.cpp
index 1b67406082e849ad2c356c6035320d14e864b6cb..9b333b02988af45ce1b5008d2424ce6f4091b5fd 100644
--- a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanCapsuleRenderDelegate.cpp
+++ b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanCapsuleRenderDelegate.cpp
@@ -23,7 +23,9 @@
 
 namespace imstk
 {
-VulkanCapsuleRenderDelegate::VulkanCapsuleRenderDelegate(std::shared_ptr<Capsule> capsule, VulkanMemoryManager& memoryManager)
+VulkanCapsuleRenderDelegate::VulkanCapsuleRenderDelegate(std::shared_ptr<Capsule> capsule,
+    SceneObject::Type type,
+    VulkanMemoryManager& memoryManager)
     : m_geometry(capsule)
 {
     auto source = vtkSmartPointer<vtkCapsuleSource>::New();
diff --git a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanCapsuleRenderDelegate.h b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanCapsuleRenderDelegate.h
index 7c88c6202b2f8e148224ba0a2288e3ff35d98ae9..677fa2b1b0f466c201e70bc6ce265be75ffb2021 100644
--- a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanCapsuleRenderDelegate.h
+++ b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanCapsuleRenderDelegate.h
@@ -44,7 +44,9 @@ public:
     ///
     /// \brief Default constructor
     ///
-    VulkanCapsuleRenderDelegate(std::shared_ptr<Capsule> capsule, VulkanMemoryManager& memoryManager);
+    VulkanCapsuleRenderDelegate(std::shared_ptr<Capsule> capsule,
+        SceneObject::Type type,
+        VulkanMemoryManager& memoryManager);
 
     ///
     /// \brief Update render geometry
diff --git a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanCubeRenderDelegate.cpp b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanCubeRenderDelegate.cpp
index 1dada7e293851a7e463e1bfa5e4394b4573dc5a6..df778cb95a56d275b20185f76b1a0bc54048eaab 100644
--- a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanCubeRenderDelegate.cpp
+++ b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanCubeRenderDelegate.cpp
@@ -23,7 +23,9 @@
 
 namespace imstk
 {
-VulkanCubeRenderDelegate::VulkanCubeRenderDelegate(std::shared_ptr<Cube> cube, VulkanMemoryManager& memoryManager)
+VulkanCubeRenderDelegate::VulkanCubeRenderDelegate(std::shared_ptr<Cube> cube,
+    SceneObject::Type type,
+    VulkanMemoryManager& memoryManager)
     : m_geometry(cube)
 {
     auto width = m_geometry->getWidth();
diff --git a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanCubeRenderDelegate.h b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanCubeRenderDelegate.h
index 8753e4488b0354572b86bdf4cc3d2b79584625e3..136e7f22b16c17b1c20270fa733ad5e4e651ac76 100644
--- a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanCubeRenderDelegate.h
+++ b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanCubeRenderDelegate.h
@@ -44,7 +44,9 @@ public:
     ///
     /// \brief Default constructor
     ///
-    VulkanCubeRenderDelegate(std::shared_ptr<Cube> cube, VulkanMemoryManager& memoryManager);
+    VulkanCubeRenderDelegate(std::shared_ptr<Cube> cube,
+        SceneObject::Type type,
+        VulkanMemoryManager& memoryManager);
 
     ///
     /// \brief Update render geometry
diff --git a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanDecalRenderDelegate.cpp b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanDecalRenderDelegate.cpp
index 947c1c3bb9e9903496e693218093d67cfd60b12c..223ce39ae6840de9426f76b0750fee190e2f2db8 100644
--- a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanDecalRenderDelegate.cpp
+++ b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanDecalRenderDelegate.cpp
@@ -23,7 +23,9 @@
 
 namespace imstk
 {
-VulkanDecalRenderDelegate::VulkanDecalRenderDelegate(std::shared_ptr<DecalPool> decalPool, VulkanMemoryManager& memoryManager)
+VulkanDecalRenderDelegate::VulkanDecalRenderDelegate(std::shared_ptr<DecalPool> decalPool,
+    SceneObject::Type type,
+    VulkanMemoryManager& memoryManager)
     : m_geometry(decalPool)
 {
     m_numVertices = 8;
diff --git a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanDecalRenderDelegate.h b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanDecalRenderDelegate.h
index 1959327aaa3929bffc17d6cef11433d6b8bbf4a7..0b85dd79ed5505e133d6f169cab0c710003d914e 100644
--- a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanDecalRenderDelegate.h
+++ b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanDecalRenderDelegate.h
@@ -39,7 +39,9 @@ public:
     ///
     /// \brief Default constructor
     ///
-    VulkanDecalRenderDelegate(std::shared_ptr<DecalPool> decalPool, VulkanMemoryManager& memoryManager);
+    VulkanDecalRenderDelegate(std::shared_ptr<DecalPool> decalPool,
+        SceneObject::Type type,
+        VulkanMemoryManager& memoryManager);
 
     ///
     /// \brief Update render geometry
diff --git a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanLineMeshRenderDelegate.cpp b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanLineMeshRenderDelegate.cpp
index e8fa3f8a2d39a3d04fa1d49bc2d01b982ee0d7f2..13705671eef01ee11588a4e313bb684fbb6e0548 100644
--- a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanLineMeshRenderDelegate.cpp
+++ b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanLineMeshRenderDelegate.cpp
@@ -23,7 +23,9 @@
 
 namespace imstk
 {
-VulkanLineMeshRenderDelegate::VulkanLineMeshRenderDelegate(std::shared_ptr<LineMesh> lineMesh, VulkanMemoryManager& memoryManager)
+VulkanLineMeshRenderDelegate::VulkanLineMeshRenderDelegate(std::shared_ptr<LineMesh> lineMesh,
+    SceneObject::Type type,
+    VulkanMemoryManager& memoryManager)
     : m_geometry(lineMesh)
 {
     m_numVertices = (uint32_t)m_geometry->getNumVertices();
@@ -38,17 +40,35 @@ VulkanLineMeshRenderDelegate::VulkanLineMeshRenderDelegate(std::shared_ptr<LineM
 
     m_geometry->getRenderMaterial()->m_isLineMesh = true;
 
-    this->initializeData(memoryManager, m_geometry->getRenderMaterial());
+    if (type == SceneObject::Type::FEMDeformable || type == SceneObject::Type::Pbd)
+    {
+        this->initializeData(memoryManager, m_geometry->getRenderMaterial(), VulkanVertexBufferMode::VERTEX_BUFFER_DYNAMIC);
 
-    this->updateVertexBuffer();
+        for (uint32_t i = 0; i < memoryManager.m_buffering; i++)
+        {
+            this->updateVertexBuffer(i);
+            this->update(i);
+        }
+    }
+    else
+    {
+        this->initializeData(memoryManager, m_geometry->getRenderMaterial(), VulkanVertexBufferMode::VERTEX_BUFFER_STATIC);
 
-    this->update(0);
+        this->updateVertexBuffer(0);
+        this->update(0);
+    }
 }
 
 void
-VulkanLineMeshRenderDelegate::updateVertexBuffer()
+VulkanLineMeshRenderDelegate::updateVertexBuffer(const uint32_t frameIndex)
 {
-    auto vertices = (VulkanBasicVertex *)m_vertexBuffer->getVertexMemory();
+    int frame = 0;
+    if (m_vertexBuffer->getMode() != VERTEX_BUFFER_STATIC)
+    {
+        frame = frameIndex;
+    }
+
+    auto vertices = (VulkanBasicVertex *)m_vertexBuffer->getVertexMemory(frame);
 
     auto colors = m_geometry->getVertexColors();
 
@@ -73,7 +93,7 @@ VulkanLineMeshRenderDelegate::updateVertexBuffer()
         }
     }
 
-    auto lines = (std::array<uint32_t, 2> *)m_vertexBuffer->getIndexMemory();
+    auto lines = (std::array<uint32_t, 2> *)m_vertexBuffer->getIndexMemory(frame);
 
     m_vertexBuffer->setNumIndices((uint32_t)m_geometry->getNumLines() * 2);
 
@@ -92,7 +112,7 @@ VulkanLineMeshRenderDelegate::update(const uint32_t frameIndex)
 
     if (m_geometry->m_dataModified)
     {
-        this->updateVertexBuffer();
+        this->updateVertexBuffer(frameIndex);
     }
 }
 
diff --git a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanLineMeshRenderDelegate.h b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanLineMeshRenderDelegate.h
index 35d9a556ac6f3a9b0436ba7af0a5b99194606444..da752f7bd2ef50150b851dcbee9c27ba714dd870 100644
--- a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanLineMeshRenderDelegate.h
+++ b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanLineMeshRenderDelegate.h
@@ -42,7 +42,9 @@ public:
     ///
     /// \brief Default constructor
     ///
-    VulkanLineMeshRenderDelegate(std::shared_ptr<LineMesh> LineMesh, VulkanMemoryManager& memoryManager);
+    VulkanLineMeshRenderDelegate(std::shared_ptr<LineMesh> LineMesh,
+        SceneObject::Type type,
+        VulkanMemoryManager& memoryManager);
 
     ///
     /// \brief Update render geometry
@@ -58,7 +60,7 @@ public:
     ///
     /// \brief Fill vertex buffer
     ///
-    void updateVertexBuffer();
+    void updateVertexBuffer(const uint32_t frameIndex);
 
 protected:
     std::shared_ptr<LineMesh> m_geometry;
diff --git a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanPlaneRenderDelegate.cpp b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanPlaneRenderDelegate.cpp
index a2aede3fb41864c337888621f4ad4f9733b733ef..2afede163ed338496835770fa9fead7e46e5cf8f 100644
--- a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanPlaneRenderDelegate.cpp
+++ b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanPlaneRenderDelegate.cpp
@@ -23,7 +23,9 @@
 
 namespace imstk
 {
-VulkanPlaneRenderDelegate::VulkanPlaneRenderDelegate(std::shared_ptr<Plane> plane, VulkanMemoryManager& memoryManager)
+VulkanPlaneRenderDelegate::VulkanPlaneRenderDelegate(std::shared_ptr<Plane> plane,
+    SceneObject::Type type,
+    VulkanMemoryManager& memoryManager)
     : m_geometry(plane)
 {
     auto width = m_geometry->getWidth();
diff --git a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanPlaneRenderDelegate.h b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanPlaneRenderDelegate.h
index 1bf6abd7536e7d99c0118c20c6ce18afd8287654..77be0d644497771c200fc978d9892c3dc5998b53 100644
--- a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanPlaneRenderDelegate.h
+++ b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanPlaneRenderDelegate.h
@@ -45,7 +45,9 @@ public:
     ///
     /// \brief Default constructor
     ///
-    VulkanPlaneRenderDelegate(std::shared_ptr<Plane> plane, VulkanMemoryManager& memoryManager);
+    VulkanPlaneRenderDelegate(std::shared_ptr<Plane> plane,
+        SceneObject::Type type,
+        VulkanMemoryManager& memoryManager);
 
     ///
     /// \brief Update render geometry
diff --git a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanRenderDelegate.cpp b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanRenderDelegate.cpp
index 4ba1fc635bb2c2710206a49593ba3f59d480a3c1..ee9f73e2bf9104b5846bf8f626ec5e9f1a74600b 100644
--- a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanRenderDelegate.cpp
+++ b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanRenderDelegate.cpp
@@ -43,7 +43,9 @@
 namespace imstk
 {
 std::shared_ptr<VulkanRenderDelegate>
-VulkanRenderDelegate::make_delegate(std::shared_ptr<Geometry> geom, VulkanMemoryManager& memoryManager)
+VulkanRenderDelegate::make_delegate(std::shared_ptr<Geometry> geom,
+    SceneObject::Type type,
+    VulkanMemoryManager& memoryManager)
 {
     geom->m_renderDelegateCreated = true;
     switch (geom->getType())
@@ -51,27 +53,27 @@ VulkanRenderDelegate::make_delegate(std::shared_ptr<Geometry> geom, VulkanMemory
     case Geometry::Type::Plane:
     {
         auto plane = std::dynamic_pointer_cast<Plane>(geom);
-        return std::make_shared<VulkanPlaneRenderDelegate>(plane, memoryManager);
+        return std::make_shared<VulkanPlaneRenderDelegate>(plane, type, memoryManager);
     }
     case Geometry::Type::Sphere:
     {
         auto sphere = std::dynamic_pointer_cast<Sphere>(geom);
-        return std::make_shared<VulkanSphereRenderDelegate>(sphere, memoryManager);
+        return std::make_shared<VulkanSphereRenderDelegate>(sphere, type, memoryManager);
     }
     case Geometry::Type::Cube:
     {
         auto cube = std::dynamic_pointer_cast<Cube>(geom);
-        return std::make_shared<VulkanCubeRenderDelegate>(cube, memoryManager);
+        return std::make_shared<VulkanCubeRenderDelegate>(cube, type, memoryManager);
     }
     case Geometry::Type::Capsule:
     {
         auto capsule = std::dynamic_pointer_cast<Capsule>(geom);
-        return std::make_shared<VulkanCapsuleRenderDelegate>(capsule, memoryManager);
+        return std::make_shared<VulkanCapsuleRenderDelegate>(capsule, type, memoryManager);
     }
     case Geometry::Type::SurfaceMesh:
     {
         auto surfaceMesh = std::dynamic_pointer_cast<SurfaceMesh>(geom);
-        return std::make_shared<VulkanSurfaceMeshRenderDelegate>(surfaceMesh, memoryManager);
+        return std::make_shared<VulkanSurfaceMeshRenderDelegate>(surfaceMesh, type, memoryManager);
     }
     /*case Geometry::Type::TetrahedralMesh:
     {
@@ -81,7 +83,7 @@ VulkanRenderDelegate::make_delegate(std::shared_ptr<Geometry> geom, VulkanMemory
     case Geometry::Type::LineMesh:
     {
         auto lineMesh = std::dynamic_pointer_cast<LineMesh>(geom);
-        return std::make_shared<VulkanLineMeshRenderDelegate>(lineMesh, memoryManager);
+        return std::make_shared<VulkanLineMeshRenderDelegate>(lineMesh, type, memoryManager);
     }
     /*case Geometry::Type::HexahedralMesh:
     {
@@ -91,7 +93,7 @@ VulkanRenderDelegate::make_delegate(std::shared_ptr<Geometry> geom, VulkanMemory
     case Geometry::Type::DecalPool:
     {
         auto decalPool = std::dynamic_pointer_cast<DecalPool>(geom);
-        return std::make_shared<VulkanDecalRenderDelegate>(decalPool, memoryManager);
+        return std::make_shared<VulkanDecalRenderDelegate>(decalPool, type, memoryManager);
     }
     default:
     {
diff --git a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanRenderDelegate.h b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanRenderDelegate.h
index 9d0bcd2c6b12d17d38ef67232912181a380776f2..c19aeb0ad458b8247f95d950e29a04696379c62d 100644
--- a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanRenderDelegate.h
+++ b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanRenderDelegate.h
@@ -30,6 +30,7 @@
 #include <array>
 
 #include "imstkGeometry.h"
+#include "imstkSceneObject.h"
 #include "imstkVulkanVertexBuffer.h"
 #include "imstkVulkanUniformBuffer.h"
 #include "imstkVulkanMaterialDelegate.h"
@@ -52,6 +53,7 @@ public:
     ///
     static std::shared_ptr<VulkanRenderDelegate> make_delegate(
         std::shared_ptr<Geometry> geom,
+        SceneObject::Type type,
         VulkanMemoryManager& details);
 
     ///
diff --git a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanSphereRenderDelegate.cpp b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanSphereRenderDelegate.cpp
index 94c8db416cdd54d0fa8b67a50ea02b29df99a844..22ac28b370aeafd85db74005e55ad28a48f0df9c 100644
--- a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanSphereRenderDelegate.cpp
+++ b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanSphereRenderDelegate.cpp
@@ -23,7 +23,9 @@
 
 namespace imstk
 {
-VulkanSphereRenderDelegate::VulkanSphereRenderDelegate(std::shared_ptr<Sphere> sphere, VulkanMemoryManager& memoryManager)
+VulkanSphereRenderDelegate::VulkanSphereRenderDelegate(std::shared_ptr<Sphere> sphere,
+    SceneObject::Type type,
+    VulkanMemoryManager& memoryManager)
     : m_geometry(sphere)
 {
     auto radius = m_geometry->getRadius();
diff --git a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanSphereRenderDelegate.h b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanSphereRenderDelegate.h
index 0e1ef8039171a9641f004ae7a600ec21569f6831..fa5a8023620f2182236cb57c51732e34a150e0d5 100644
--- a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanSphereRenderDelegate.h
+++ b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanSphereRenderDelegate.h
@@ -44,7 +44,9 @@ public:
     ///
     /// \brief Default constructor
     ///
-    VulkanSphereRenderDelegate(std::shared_ptr<Sphere> sphere, VulkanMemoryManager& memoryManager);
+    VulkanSphereRenderDelegate(std::shared_ptr<Sphere> sphere,
+        SceneObject::Type type,
+        VulkanMemoryManager& memoryManager);
 
     ///
     /// \brief Update render geometry
diff --git a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanSurfaceMeshRenderDelegate.cpp b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanSurfaceMeshRenderDelegate.cpp
index 649344868a8d48dab6f153bfb99e707321c6f34f..73295c9a89f10f422d5e524c26afa818f179f8af 100644
--- a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanSurfaceMeshRenderDelegate.cpp
+++ b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanSurfaceMeshRenderDelegate.cpp
@@ -23,7 +23,9 @@
 
 namespace imstk
 {
-VulkanSurfaceMeshRenderDelegate::VulkanSurfaceMeshRenderDelegate(std::shared_ptr<SurfaceMesh> surfaceMesh, VulkanMemoryManager& memoryManager)
+VulkanSurfaceMeshRenderDelegate::VulkanSurfaceMeshRenderDelegate(std::shared_ptr<SurfaceMesh> surfaceMesh,
+    SceneObject::Type type,
+    VulkanMemoryManager& memoryManager)
     : m_geometry(surfaceMesh)
 {
     m_numVertices = (uint32_t)m_geometry->getNumVertices();
@@ -37,19 +39,35 @@ VulkanSurfaceMeshRenderDelegate::VulkanSurfaceMeshRenderDelegate(std::shared_ptr
         m_geometry->setRenderMaterial(std::make_shared<RenderMaterial>());
     }
 
-    this->initializeData(memoryManager, m_geometry->getRenderMaterial(), VulkanVertexBufferMode::VERTEX_BUFFER_DYNAMIC);
+    if (type == SceneObject::Type::FEMDeformable || type == SceneObject::Type::Pbd)
+    {
+        this->initializeData(memoryManager, m_geometry->getRenderMaterial(), VulkanVertexBufferMode::VERTEX_BUFFER_DYNAMIC);
 
-    for (uint32_t i = 0; i < memoryManager.m_buffering; i++)
+        for (uint32_t i = 0; i < memoryManager.m_buffering; i++)
+        {
+            this->updateVertexBuffer(i);
+            this->update(i);
+        }
+    }
+    else
     {
-        this->updateVertexBuffer(i);
-        this->update(i);
+        this->initializeData(memoryManager, m_geometry->getRenderMaterial(), VulkanVertexBufferMode::VERTEX_BUFFER_STATIC);
+
+        this->updateVertexBuffer(0);
+        this->update(0);
     }
 }
 
 void
 VulkanSurfaceMeshRenderDelegate::updateVertexBuffer(uint32_t frameIndex)
 {
-    auto vertices = (VulkanBasicVertex *)m_vertexBuffer->getVertexMemory(frameIndex);
+    int frame = 0;
+    if (m_vertexBuffer->getMode() != VERTEX_BUFFER_STATIC)
+    {
+        frame = frameIndex;
+    }
+
+    auto vertices = (VulkanBasicVertex *)m_vertexBuffer->getVertexMemory(frame);
 
     auto normals = m_geometry->getVertexNormals();
     auto tangents = m_geometry->getVertexTangents();
@@ -80,23 +98,23 @@ VulkanSurfaceMeshRenderDelegate::updateVertexBuffer(uint32_t frameIndex)
                 normals[i][2]);
         }
 
-        if (tangents.size() == m_geometry->getNumVertices())
-        {
-            vertices[i].tangent = glm::vec3(
-                tangents[i][0],
-                tangents[i][1],
-                tangents[i][2]);
-        }
-
         if (UVs && UVs->size() == m_geometry->getNumVertices())
         {
+            if (tangents.size() == m_geometry->getNumVertices())
+            {
+                vertices[i].tangent = glm::vec3(
+                    tangents[i][0],
+                    tangents[i][1],
+                    tangents[i][2]);
+            }
+
             vertices[i].uv = glm::vec2(
                 (*UVs)[i][0],
                 (*UVs)[i][1]);
         }
     }
 
-    auto triangles = (std::array<uint32_t, 3> *)m_vertexBuffer->getIndexMemory(frameIndex);
+    auto triangles = (std::array<uint32_t, 3> *)m_vertexBuffer->getIndexMemory(frame);
 
     m_vertexBuffer->setNumIndices((uint32_t)m_geometry->getNumTriangles() * 3);
     for (unsigned i = 0; i < m_geometry->getNumTriangles(); i++)
diff --git a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanSurfaceMeshRenderDelegate.h b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanSurfaceMeshRenderDelegate.h
index 8d8a3c91d6498d235a20efecbcdb2abde4cf92c7..658b8186d6da1ccb6afaa7abbc6b404bc91de3d3 100644
--- a/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanSurfaceMeshRenderDelegate.h
+++ b/Source/Rendering/VulkanRenderer/RenderDelegate/imstkVulkanSurfaceMeshRenderDelegate.h
@@ -39,7 +39,9 @@ public:
     ///
     /// \brief Default constructor
     ///
-    VulkanSurfaceMeshRenderDelegate(std::shared_ptr<SurfaceMesh> surfaceMesh, VulkanMemoryManager& memoryManager);
+    VulkanSurfaceMeshRenderDelegate(std::shared_ptr<SurfaceMesh> surfaceMesh,
+        SceneObject::Type type,
+        VulkanMemoryManager& memoryManager);
 
     ///
     /// \brief Update render geometry
diff --git a/Source/Rendering/VulkanRenderer/imstkVulkanMemoryManager.cpp b/Source/Rendering/VulkanRenderer/imstkVulkanMemoryManager.cpp
index dc029366dbe55571c08dc9cd2ae0be6c1a33e82d..3b003cd53865ab75ed41210acbc551fbf6a65707 100644
--- a/Source/Rendering/VulkanRenderer/imstkVulkanMemoryManager.cpp
+++ b/Source/Rendering/VulkanRenderer/imstkVulkanMemoryManager.cpp
@@ -115,7 +115,7 @@ VulkanMemoryManager::requestMemoryAllocation(
 
     if (vkAllocateMemory(m_device, &memoryInfo, nullptr, internalMemory->m_memory) != VK_SUCCESS)
     {
-        LOG(INFO) << "test";
+        LOG(INFO) << "Cannot allocate memory";
     }
 
     m_memoryAllocations[type].push_back(internalMemory);
diff --git a/Source/Rendering/VulkanRenderer/imstkVulkanRenderer.cpp b/Source/Rendering/VulkanRenderer/imstkVulkanRenderer.cpp
index 56836b04d781eaf99fff4e9ef3bbb9ea20d755e1..814ddbd19cfcd18c872e9e289d578d63c35082b4 100644
--- a/Source/Rendering/VulkanRenderer/imstkVulkanRenderer.cpp
+++ b/Source/Rendering/VulkanRenderer/imstkVulkanRenderer.cpp
@@ -153,7 +153,7 @@ VulkanRenderer::setupGPUs()
     queueInfo.pNext = nullptr;
     queueInfo.flags = 0;
     queueInfo.queueFamilyIndex = m_renderQueueFamily;
-    queueInfo.queueCount = m_queueFamilyProperties[m_renderQueueFamily].queueCount;
+    queueInfo.queueCount = 1;// m_queueFamilyProperties[m_renderQueueFamily].queueCount;
     queueInfo.pQueuePriorities = &priorities[0];
 
     // The display system isn't part of the Vulkan core
@@ -687,6 +687,22 @@ VulkanRenderer::renderFrame()
         auto buffers = m_renderDelegates[renderDelegateIndex]->getBuffer().get();
         buffers->uploadBuffers(m_renderCommandBuffer[nextImageIndex]);
     }
+    VkMemoryBarrier barrier;
+    barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
+    barrier.pNext = nullptr;
+    barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
+    barrier.dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_INDEX_READ_BIT;
+
+    vkCmdPipelineBarrier(m_renderCommandBuffer[nextImageIndex],
+        VK_PIPELINE_STAGE_TRANSFER_BIT,
+        VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+        0,
+        1,
+        &barrier,
+        0,
+        nullptr,
+        0,
+        nullptr);
 
     VkDeviceSize deviceSize = { 0 };
 
@@ -1026,19 +1042,20 @@ VulkanRenderer::loadAllGeometry()
     // Add new objects
     for (auto sceneObject : m_scene->getSceneObjects())
     {
+        auto type = sceneObject->getType();
         auto geometry = sceneObject->getVisualGeometry();
 
         if (geometry && !geometry->m_renderDelegateCreated)
         {
-            auto renderDelegate = this->loadGeometry(geometry);
+            auto renderDelegate = this->loadGeometry(geometry, type);
         }
     }
 }
 
 std::shared_ptr<VulkanRenderDelegate>
-VulkanRenderer::loadGeometry(std::shared_ptr<Geometry> geometry)
+VulkanRenderer::loadGeometry(std::shared_ptr<Geometry> geometry, SceneObject::Type type)
 {
-    auto renderDelegate = VulkanRenderDelegate::make_delegate(geometry, m_memoryManager);
+    auto renderDelegate = VulkanRenderDelegate::make_delegate(geometry, type, m_memoryManager);
     if (renderDelegate != nullptr)
     {
         m_renderDelegates.push_back(renderDelegate);
diff --git a/Source/Rendering/VulkanRenderer/imstkVulkanRenderer.h b/Source/Rendering/VulkanRenderer/imstkVulkanRenderer.h
index dcb5fe97f2c14926e5fd82e26f661673eb9d4882..218a97d7f91e1a39b6817f8104db061a0a3ebc29 100644
--- a/Source/Rendering/VulkanRenderer/imstkVulkanRenderer.h
+++ b/Source/Rendering/VulkanRenderer/imstkVulkanRenderer.h
@@ -173,7 +173,7 @@ protected:
 
     void initialize(unsigned int width, unsigned int height);
     void loadAllGeometry();
-    std::shared_ptr<VulkanRenderDelegate> loadGeometry(std::shared_ptr<Geometry> geometry);
+    std::shared_ptr<VulkanRenderDelegate> loadGeometry(std::shared_ptr<Geometry> geometry, SceneObject::Type type);
 
     ///
     /// \brief Sets some command buffer state
diff --git a/Source/Rendering/VulkanRenderer/imstkVulkanVertexBuffer.cpp b/Source/Rendering/VulkanRenderer/imstkVulkanVertexBuffer.cpp
index e0289c2762a1ab759ec8a7b6a9ac81fb071f3597..afcc4bfe7a736d9f55074f5fb40fe17d12cd9261 100644
--- a/Source/Rendering/VulkanRenderer/imstkVulkanVertexBuffer.cpp
+++ b/Source/Rendering/VulkanRenderer/imstkVulkanVertexBuffer.cpp
@@ -52,13 +52,21 @@ VulkanVertexBuffer::VulkanVertexBuffer(VulkanMemoryManager& memoryManager,
         auto vertexStagingBufferInfo = vertexBufferInfo;
         vertexStagingBufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
 
-        m_vertexBuffer = memoryManager.requestBuffer(m_renderDevice,
-                        vertexBufferInfo,
-                        VulkanMemoryType::VERTEX);
-
         m_vertexStagingBuffer = memoryManager.requestBuffer(m_renderDevice,
                         vertexStagingBufferInfo,
                         VulkanMemoryType::STAGING_VERTEX);
+
+        if (m_mode == VERTEX_BUFFER_STATIC)
+        {
+            m_vertexBuffer = memoryManager.requestBuffer(m_renderDevice,
+                            vertexBufferInfo,
+                            VulkanMemoryType::VERTEX);
+        }
+        else
+        {
+            m_vertexBuffer = m_vertexStagingBuffer;
+        }
+
     }
 
     // Index buffer
@@ -76,13 +84,21 @@ VulkanVertexBuffer::VulkanVertexBuffer(VulkanMemoryManager& memoryManager,
         auto indexStagingBufferInfo = indexBufferInfo;
         indexStagingBufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
 
-        m_indexBuffer = memoryManager.requestBuffer(m_renderDevice,
-                        indexBufferInfo,
-                        VulkanMemoryType::INDEX);
-
         m_indexStagingBuffer = memoryManager.requestBuffer(m_renderDevice,
                         indexStagingBufferInfo,
                         VulkanMemoryType::STAGING_INDEX);
+
+        if (m_mode == VERTEX_BUFFER_STATIC)
+        {
+            m_indexBuffer = memoryManager.requestBuffer(m_renderDevice,
+                            indexBufferInfo,
+                            VulkanMemoryType::INDEX);
+        }
+        else
+        {
+            m_indexBuffer = m_indexStagingBuffer;
+        }
+
     }
 }
 
@@ -108,7 +124,7 @@ VulkanVertexBuffer::updateVertexBuffer(std::vector<VulkanBasicVertex> * vertices
 {
     auto local_vertices = (VulkanBasicVertex *)this->getVertexMemory();
 
-    for (unsigned i = 0; i < vertices->size(); i++)
+    for (unsigned int i = 0; i < vertices->size(); i++)
     {
         local_vertices[i].position = glm::vec3(
             (*vertices)[i].position.x,
@@ -125,7 +141,7 @@ VulkanVertexBuffer::updateVertexBuffer(std::vector<VulkanBasicVertex> * vertices
     {
         auto local_triangles = (std::array<uint32_t, 3> *) this->getIndexMemory();
 
-        for (unsigned i = 0; i < triangles->size(); i++)
+        for (unsigned int i = 0; i < triangles->size(); i++)
         {
             local_triangles[i][0] = (*triangles)[i][0];
             local_triangles[i][1] = (*triangles)[i][1];
@@ -137,6 +153,11 @@ VulkanVertexBuffer::updateVertexBuffer(std::vector<VulkanBasicVertex> * vertices
 void
 VulkanVertexBuffer::uploadBuffers(VkCommandBuffer& commandBuffer)
 {
+    if (m_mode != VERTEX_BUFFER_STATIC)
+    {
+        return;
+    }
+
     if (m_vertexBufferModified)
     {
         VkBufferCopy copyInfo;
@@ -212,4 +233,11 @@ VulkanVertexBuffer::bindBuffers(VkCommandBuffer * commandBuffer, uint32_t frameI
     vkCmdBindVertexBuffers(*commandBuffer, 0, 1, m_vertexBuffer->getBuffer(), &vertexOffset);
     vkCmdBindIndexBuffer(*commandBuffer, *m_indexBuffer->getBuffer(), indexOffset, VK_INDEX_TYPE_UINT32);
 }
+
+VulkanVertexBufferMode
+VulkanVertexBuffer::getMode()
+{
+    return m_mode;
+}
+
 }
\ No newline at end of file
diff --git a/Source/Rendering/VulkanRenderer/imstkVulkanVertexBuffer.h b/Source/Rendering/VulkanRenderer/imstkVulkanVertexBuffer.h
index d42d28ab14122785eed83347fd8289cb0742c148..020d7055fe4d172116c4ec6de6b4fd1f354d1fd0 100644
--- a/Source/Rendering/VulkanRenderer/imstkVulkanVertexBuffer.h
+++ b/Source/Rendering/VulkanRenderer/imstkVulkanVertexBuffer.h
@@ -77,6 +77,8 @@ public:
 
     void bindBuffers(VkCommandBuffer * commandBuffer, uint32_t frameIndex);
 
+    VulkanVertexBufferMode getMode();
+
 private:
     friend class VulkanRenderer;