diff --git a/CMake/External/External_VTK.cmake b/CMake/External/External_VTK.cmake
index d664264ff024cfbae4703d69d2d1ce98509ffa6d..c9a55f7313cb6cf38f7d3ad8a1e96ce77450e552 100644
--- a/CMake/External/External_VTK.cmake
+++ b/CMake/External/External_VTK.cmake
@@ -10,78 +10,47 @@ endif()
 
 
 set(${PROJECT_NAME}_VTK_REPO_SOURCE "9.0" CACHE STRING "Select VTK Source Branch/Tag")
-set(VTK_SOURCES "8.2;8.9;9.0;master;release;nightly-master" CACHE INTERNAL "List of available VTK branch,tags to get")
+set(VTK_SOURCES "9.0;master;release;nightly-master" CACHE INTERNAL "List of available VTK branch,tags to get")
 set_property(CACHE ${PROJECT_NAME}_VTK_REPO_SOURCE PROPERTY STRINGS ${VTK_SOURCES})
+  
+if (${${PROJECT_NAME}_ENABLE_OPENVR})
+  set(VTK_OPENVR "WANT")
+else()
+  set(VTK_OPENVR "DONT_WANT")
+endif()
 
+set(VTK_MODULE_SETTINGS
+  -DVTK_MODULE_ENABLE_VTK_ChartsCore:STRING=YES
+  -DVTK_MODULE_ENABLE_VTK_RenderingOpenGL2:STRING=YES
+  -DVTK_MODULE_ENABLE_VTK_IOExport:STRING=YES
+  -DVTK_MODULE_ENABLE_VTK_IOImport:STRING=YES
+  -DVTK_MODULE_ENABLE_VTK_IOParallel:STRING=YES
+  -DVTK_MODULE_ENABLE_VTK_IOParallelXML:STRING=YES
+  -DVTK_MODULE_ENABLE_VTK_IOXML:STRING=YES
+  -DVTK_MODULE_ENABLE_VTK_IOLegacy:STRING=YES
+  -DVTK_MODULE_ENABLE_VTK_IOPLY:STRING=YES
+  -DVTK_MODULE_ENABLE_VTK_IOGeometry:STRING=YES
+  -DVTK_MODULE_ENABLE_VTK_InteractionStyle:STRING=YES
+  -DVTK_MODULE_ENABLE_VTK_RenderingAnnotation:STRING=YES
+  -DVTK_MODULE_ENABLE_VTK_RenderingOpenVR:STRING=${VTK_OPENVR}
+  -DVTK_MODULE_ENABLE_VTK_InteractionWidgets:STRING=YES
+  -DVTK_MODULE_ENABLE_VTK_glew:STRING=YES
+  -DVTK_MODULE_ENABLE_VTK_RenderingContext2D:STRING=YES
+  -DVTK_MODULE_ENABLE_VTK_RenderingVolumeOpenGL2:STRING=YES
+  -DVTK_MODULE_ENABLE_VTK_ViewsContext2D:STRING=YES
+  -DVTK_BUILD_EXAMPLES:STRING=DONT_WANT
+  -DVTK_BUILD_TESTING:STRING=OFF
+  -DVTK_GROUP_ENABLE_StandAlone:STRING=DONT_WANT
+  -DVTK_GROUP_ENABLE_Rendering:STRING=DONT_WANT
+-DVTK_MODULE_ENABLE_MODULE_FiltersModeling:STRING=YES
+-DVTK_MODULE_ENABLE_MODULE_FiltersExtraction:STRING=YES
+    )
+set(${PROJECT_NAME}_VTK_SOURCE GIT_REPOSITORY https://gitlab.kitware.com/vtk/vtk.git)
 
-if(${PROJECT_NAME}_VTK_REPO_SOURCE EQUAL "8.2")
-  set(VTK_MODULE_SETTINGS
-    -DModule_vtkChartsCore:BOOL=ON
-    -DModule_vtkRenderingOpenGL2:BOOL=ON
-    -DModule_vtkIOXML:BOOL=ON
-    -DModule_vtkIOLegacy:BOOL=ON
-    -DModule_vtkIOPLY:BOOL=ON
-    -DModule_vtkIOGeometry:BOOL=ON
-    -DModule_vtkInteractionStyle:BOOL=ON
-    -DModule_vtkRenderingAnnotation:BOOL=ON
-    -DModule_vtkRenderingOpenVR:BOOL=${${PROJECT_NAME}_ENABLE_VR}
-    -DModule_vtkInteractionWidgets:BOOL=ON
-    -DModule_vtkglew:BOOL=ON
-    -DModule_vtkRenderingContext2D:BOOL=ON
-    -DModule_vtkRenderingVolumeOpenGL2:BOOL=ON
-    -DModule_vtkViewsContext2D:BOOL=ON
-    -DBUILD_EXAMPLES:BOOL=OFF
-    -DBUILD_TESTING:BOOL=OFF
-    -DVTK_Group_StandAlone:BOOL=OFF
-    -DVTK_Group_Rendering:BOOL=OFF
-  )
-  set(${PROJECT_NAME}_VTK_SOURCE URL https://gitlab.kitware.com/vtk/vtk/-/archive/v8.2.0/vtk-v8.2.0.tar.gz)
-  set(${PROJECT_NAME}_VTK_HASH URL_HASH MD5=4115fb396f99466fe444472f412118cd)
+if(${PROJECT_NAME}_VTK_REPO_SOURCE EQUAL "9.0")
+  set(${PROJECT_NAME}_VTK_HASH GIT_TAG ab278e87b181e3a02082bea7361fbaa3ddafb3ad)
 else()
-  
-  if (${${PROJECT_NAME}_ENABLE_OPENVR})
-    set(VTK_OPENVR "WANT")
-  else()
-    set(VTK_OPENVR "DONT_WANT")
-  endif()
-  
-  set(VTK_MODULE_SETTINGS
-    -DVTK_MODULE_ENABLE_VTK_ChartsCore:STRING=YES
-    -DVTK_MODULE_ENABLE_VTK_RenderingOpenGL2:STRING=YES
-    -DVTK_MODULE_ENABLE_VTK_IOExport:STRING=YES
-    -DVTK_MODULE_ENABLE_VTK_IOImport:STRING=YES
-    -DVTK_MODULE_ENABLE_VTK_IOParallel:STRING=YES
-    -DVTK_MODULE_ENABLE_VTK_IOParallelXML:STRING=YES
-    -DVTK_MODULE_ENABLE_VTK_IOXML:STRING=YES
-    -DVTK_MODULE_ENABLE_VTK_IOLegacy:STRING=YES
-    -DVTK_MODULE_ENABLE_VTK_IOPLY:STRING=YES
-    -DVTK_MODULE_ENABLE_VTK_IOGeometry:STRING=YES
-    -DVTK_MODULE_ENABLE_VTK_InteractionStyle:STRING=YES
-    -DVTK_MODULE_ENABLE_VTK_RenderingAnnotation:STRING=YES
-    -DVTK_MODULE_ENABLE_VTK_RenderingOpenVR:STRING=${VTK_OPENVR}
-    -DVTK_MODULE_ENABLE_VTK_InteractionWidgets:STRING=YES
-    -DVTK_MODULE_ENABLE_VTK_glew:STRING=YES
-    -DVTK_MODULE_ENABLE_VTK_RenderingContext2D:STRING=YES
-    -DVTK_MODULE_ENABLE_VTK_RenderingVolumeOpenGL2:STRING=YES
-    -DVTK_MODULE_ENABLE_VTK_ViewsContext2D:STRING=YES
-    -DVTK_BUILD_EXAMPLES:STRING=DONT_WANT
-    -DVTK_BUILD_TESTING:STRING=OFF
-    -DVTK_GROUP_ENABLE_StandAlone:STRING=DONT_WANT
-    -DVTK_GROUP_ENABLE_Rendering:STRING=DONT_WANT
-	-DVTK_MODULE_ENABLE_MODULE_FiltersModeling:STRING=YES
-	-DVTK_MODULE_ENABLE_MODULE_FiltersExtraction:STRING=YES
-     )
-  set(${PROJECT_NAME}_VTK_SOURCE GIT_REPOSITORY https://gitlab.kitware.com/vtk/vtk.git)
- 
-  # TODO Update to a zip download when there is a new version after 8.2
-  if(${PROJECT_NAME}_VTK_REPO_SOURCE EQUAL "8.9")    
-    set(${PROJECT_NAME}_VTK_HASH GIT_TAG 9b6a039f43404053a0653f742148d123f6ada7d6)
-  elseif(${PROJECT_NAME}_VTK_REPO_SOURCE EQUAL "9.0")    
-    set(${PROJECT_NAME}_VTK_HASH GIT_TAG ab278e87b181e3a02082bea7361fbaa3ddafb3ad)
-  else()    
-    set(${PROJECT_NAME}_VTK_HASH GIT_TAG origin/${${PROJECT_NAME}_VTK_REPO_SOURCE})
-  endif()
-  
+  set(${PROJECT_NAME}_VTK_HASH GIT_TAG origin/${${PROJECT_NAME}_VTK_REPO_SOURCE})
 endif()
 
 #-----------------------------------------------------------------------------
@@ -100,6 +69,6 @@ imstk_add_external_project( VTK
   #VERBOSE
 )
 if(NOT USE_SYSTEM_VTK)
-  set(VTK_DIR ${CMAKE_INSTALL_PREFIX}/lib/cmake/vtk-8.2)
+  set(VTK_DIR ${CMAKE_INSTALL_PREFIX}/lib/cmake/vtk-9.0)
   #message(STATUS "VTK_DIR : ${VTK_DIR}")
 endif()
diff --git a/CMake/External/Patches/vtk-8.2.cmake b/CMake/External/Patches/vtk-8.2.cmake
deleted file mode 100644
index 3992e6d06e1a088b1ed83591765de6cc45ea3d02..0000000000000000000000000000000000000000
--- a/CMake/External/Patches/vtk-8.2.cmake
+++ /dev/null
@@ -1,6 +0,0 @@
-message(STATUS "Patching VTK")
-
-file(COPY  ${VTK_SOURCE_DIR}/Common/Core/vtkEventData.h
-     DESTINATION ${CMAKE_INSTALL_PREFIX}/include/vtk-8.2/)
-file(COPY  ${VTK_SOURCE_DIR}/Rendering/OpenVR/vtkOpenVROverlayInternal.h
-     DESTINATION ${CMAKE_INSTALL_PREFIX}/include/vtk-8.2/)
\ No newline at end of file
diff --git a/CMake/Utilities/imstkAddUncrustifyCustomTarget.cmake b/CMake/Utilities/imstkAddUncrustifyCustomTarget.cmake
index 5a41b26618ddc06cd2e5b67ab6e525651fb0b253..504864a5411a8fbd2bbea424e23a3a1f122a3f1c 100644
--- a/CMake/Utilities/imstkAddUncrustifyCustomTarget.cmake
+++ b/CMake/Utilities/imstkAddUncrustifyCustomTarget.cmake
@@ -1,5 +1,5 @@
 # Add target to run uncrustify
-  add_custom_target(CodeFormatter
+  add_custom_target(CodeFormatEnforcer
     COMMAND ${Uncrustify_EXECUTABLE}
       -c ${CMAKE_CURRENT_LIST_DIR}/../../Utilities/Uncrustify/iMSTKUncrustify.cfg
       -F ${CMAKE_CURRENT_BINARY_DIR}/Uncrustify.list
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 910e18c653d311e7d775b6f9f022fae04af8e7ff..c1f28d9cf750c655f7e9068e9d423071bfabc46c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,5 +1,5 @@
 cmake_minimum_required(VERSION 3.9)
-project(iMSTK VERSION 2.0.0 LANGUAGES C CXX)
+project(iMSTK VERSION 3.0.0 LANGUAGES C CXX)
 
 if(UNIX AND NOT APPLE)
   set(LINUX TRUE)
@@ -21,7 +21,7 @@ if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
   set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install CACHE PATH "Install location" FORCE)
 endif()
 set(CMAKE_PREFIX_PATH ${CMAKE_INSTALL_PREFIX})
-
+ 
 #-----------------------------------------------------------------------------
 # Project install directories
 #-----------------------------------------------------------------------------
@@ -32,7 +32,7 @@ set(CMAKE_PREFIX_PATH ${CMAKE_INSTALL_PREFIX})
 # Let's go ahead and make these directories
 file(MAKE_DIRECTORY ${CMAKE_INSTALL_PREFIX}/bin)
 file(MAKE_DIRECTORY ${CMAKE_INSTALL_PREFIX}/include)
-file(MAKE_DIRECTORY ${CMAKE_INSTALL_PREFIX}/lib)
+file(MAKE_DIRECTORY ${CMAKE_INSTALL_PREFIX}/lib) 
 
 #-----------------------------------------------------------------------------
 # Update CMake module path & cmake dir
@@ -274,37 +274,30 @@ endif()
 
 # VTK
 find_package(VTK CONFIG)
-if (VTK_VERSION VERSION_LESS "8.90")
-  # Modules are linked via `vtkCommonCore`
-  # VTK_DEFINITIONS has autoinit information
-  find_package(VTK REQUIRED)
-  include(${VTK_USE_FILE})
-else()
-  # modules are linked via `VTK::CommonCore`
-  # vtk_module_autoinit is needed
-  find_package(VTK COMPONENTS
-    ChartsCore
-    CommonCore
-    CommonDataModel
-    FiltersGeneral
-    FiltersSources
-	FiltersModeling
-	FiltersExtraction
-    IOExport
-    IOImport
-    IOPLY
-    IOParallel
-    IOParallelXML
-    ImagingCore
-    InteractionStyle
-    RenderingAnnotation
-    RenderingCore
-    RenderingOpenGL2
-    RenderingVolume
-    RenderingVolumeOpenGL2
-    ViewsContext2D
-  )
-endif()
+# modules are linked via `VTK::CommonCore`
+# vtk_module_autoinit is needed
+find_package(VTK COMPONENTS
+  ChartsCore
+  CommonCore
+  CommonDataModel
+  FiltersGeneral
+  FiltersSources
+FiltersModeling
+FiltersExtraction
+  IOExport
+  IOImport
+  IOPLY
+  IOParallel
+  IOParallelXML
+  ImagingCore
+  InteractionStyle
+  RenderingAnnotation
+  RenderingCore
+  RenderingOpenGL2
+  RenderingVolume
+  RenderingVolumeOpenGL2
+  ViewsContext2D
+)
 
 # Vulkan
 set(Vulkan_Dependency)
@@ -355,10 +348,12 @@ if(${PROJECT_NAME}_BUILD_TESTING OR ${PROJECT_NAME}_BUILD_EXAMPLES)
   imstk_add_data(${PROJECT_NAME} ${FILE_LIST})
 
   #-----------------------------------------------------------------------------
-  # Add shaders
+  # Add shaders (vulkan only)
   #-----------------------------------------------------------------------------
-  include(imstkCopyAndCompileShaders)
-  CopyAndCompileShaders() 
+  if(${PROJECT_NAME}_USE_Vulkan)    
+      include(imstkCopyAndCompileShaders)
+      CopyAndCompileShaders() 
+  endif()
 endif()
 
 # Folder name to put our headers/cmake config files under
diff --git a/Data/armadillo/armadillo_volume.vtk.sha512 b/Data/armadillo/armadillo_volume.vtk.sha512
new file mode 100644
index 0000000000000000000000000000000000000000..67c4809c3b251ea7a3f613f3b7518ae3d6f60e20
--- /dev/null
+++ b/Data/armadillo/armadillo_volume.vtk.sha512
@@ -0,0 +1 @@
+8e9f278002a3a17b2bb3471523672947034de0ed87d07dd6a422e2b9157bd6f91e4be5df4b3e820ab3f722b599b10d0a77c68ac0d320d1a2ecc94515aefb11fe
\ No newline at end of file
diff --git a/Data/textured_organs/heart_volume.vtk.sha512 b/Data/textured_organs/heart_volume.vtk.sha512
new file mode 100644
index 0000000000000000000000000000000000000000..6aad13a1eddd08c93756ce38c08d09c1603558b9
--- /dev/null
+++ b/Data/textured_organs/heart_volume.vtk.sha512
@@ -0,0 +1 @@
+30c084333b758578905445e55918095b12979fc50bebe4d23f7903f6aae50c1bc4e9aceec22ea1c62491f64db509835d3c0e8310ecbdb2ee4f4fd6af401f5e85
\ No newline at end of file
diff --git a/Examples/CreateEnclosingMesh/CreateEnclosingMesh.cpp b/Examples/CreateEnclosingMesh/CreateEnclosingMesh.cpp
index 8de2f05cc81f7a9c11aefef1af8d042a19c78777..0fe78bb592a44389ceb61cab79e045de1cb73c01 100644
--- a/Examples/CreateEnclosingMesh/CreateEnclosingMesh.cpp
+++ b/Examples/CreateEnclosingMesh/CreateEnclosingMesh.cpp
@@ -20,6 +20,7 @@
 =========================================================================*/
 
 #include "imstkSimulationManager.h"
+#include "imstkSceneManager.h"
 #include "imstkLight.h"
 #include "imstkCamera.h"
 #include "imstkAPIUtilities.h"
@@ -52,7 +53,7 @@ main()
     // configure and add the render model to the scene object
     auto material = std::make_shared<RenderMaterial>();
     material->setDisplayMode(RenderMaterial::DisplayMode::Surface);
-    material->setColor(Color::Red);
+    material->setColor(Color::LightGray);
     auto surfMeshModel = std::make_shared<VisualModel>(surfMesh);
     surfMeshModel->setRenderMaterial(material);
     surfaceObject->addVisualModel(surfMeshModel);
@@ -66,12 +67,12 @@ main()
     auto volObject   = std::make_shared<VisualObject>("VolObj");
     auto tetMaterial = std::make_shared<RenderMaterial>();
     tetMaterial->setDisplayMode(RenderMaterial::DisplayMode::Wireframe);
+    tetMaterial->setEdgeColor(Color::Teal);
     tetMaterial->setPointSize(7.);
     tetMaterial->setLineWidth(3.);
     auto tetVizModel = std::make_shared<VisualModel>(tetMesh, tetMaterial);
     volObject->addVisualModel(tetVizModel);
 
-    // add the scene object to the scene
     scene->addSceneObject(volObject);
 
     // Light
diff --git a/Examples/DeformableBody/DeformableBodyExample.cpp b/Examples/DeformableBody/DeformableBodyExample.cpp
index 63d3e634e886d96088840529e59886f053290e7c..f6367107bef7acf2a86adbeee6218be9ae8e3952 100644
--- a/Examples/DeformableBody/DeformableBodyExample.cpp
+++ b/Examples/DeformableBody/DeformableBodyExample.cpp
@@ -21,7 +21,7 @@
 
 #include "imstkTimer.h"
 #include "imstkSimulationManager.h"
-#include "imstkDeformableObject.h"
+#include "imstkFeDeformableObject.h"
 #include "imstkBackwardEuler.h"
 #include "imstkNonLinearSystem.h"
 #include "imstkNewtonSolver.h"
@@ -112,10 +112,10 @@ createAndAddFEDeformable(std::shared_ptr<Scene>    scene,
     dynaModel->setTimeIntegrator(timeIntegrator);
 
     auto material = std::make_shared<RenderMaterial>();
-    material->setDisplayMode(RenderMaterial::DisplayMode::Wireframe);
-    material->setPointSize(6.);
-    material->setEdgeColor(Color::Marigold);
+    material->setDisplayMode(RenderMaterial::DisplayMode::WireframeSurface);
+    material->setPointSize(10.);
     material->setLineWidth(4.);
+    material->setEdgeColor(Color::Color::Orange);
     auto surfMeshModel = std::make_shared<VisualModel>(surfMesh);
     surfMeshModel->setRenderMaterial(material);
 
diff --git a/Examples/PBD/PBDCloth/pbdClothExample.cpp b/Examples/PBD/PBDCloth/pbdClothExample.cpp
index e642d54f549cdc51f0b6a68e3bc295a7813aa30f..559dbe895d112603de365affedfcbf2546e54c2d 100644
--- a/Examples/PBD/PBDCloth/pbdClothExample.cpp
+++ b/Examples/PBD/PBDCloth/pbdClothExample.cpp
@@ -40,13 +40,15 @@ const int    nCols  = 16;
 /// \brief Creates cloth geometry
 ///
 static std::unique_ptr<SurfaceMesh>
-makeClothGeometry(
-    const double width, const double height, const int nRows, const int nCols)
+makeClothGeometry(const double width,
+                  const double height,
+                  const int    nRows,
+                  const int    nCols)
 {
     // Create surface mesh
-    std::unique_ptr<SurfaceMesh> clothMesh = std::make_unique<SurfaceMesh>();
-    StdVectorOfVec3d             vertList;
+    auto clothMesh = std::make_unique<SurfaceMesh>();
 
+    StdVectorOfVec3d vertList;
     vertList.resize(nRows * nCols);
     const double dy = width / (double)(nCols - 1);
     const double dx = height / (double)(nRows - 1);
@@ -97,7 +99,11 @@ makeClothGeometry(
 /// \brief Creates cloth object
 ///
 static std::shared_ptr<PbdObject>
-makeClothObj(const std::string& name, double width, double height, int nRows, int nCols)
+makeClothObj(const std::string& name,
+             const double       width,
+             const double       height,
+             const int          nRows,
+             const int          nCols)
 {
     auto clothObj = std::make_shared<PbdObject>(name);
 
@@ -109,7 +115,7 @@ makeClothObj(const std::string& name, double width, double height, int nRows, in
     pbdParams->enableConstraint(PbdConstraint::Type::Distance, 1e2);
     pbdParams->enableConstraint(PbdConstraint::Type::Dihedral, 1e1);
     pbdParams->m_fixedNodeIds     = { 0, static_cast<size_t>(nCols) - 1 };
-    pbdParams->m_uniformMassValue = width * height / (nRows * nCols);
+    pbdParams->m_uniformMassValue = width * height / ((double)nRows * (double)nCols);
     pbdParams->m_gravity    = Vec3d(0, -9.8, 0);
     pbdParams->m_defaultDt  = 0.005;
     pbdParams->m_iterations = 5;
@@ -156,16 +162,16 @@ main()
 
     // Light (red)
     auto colorLight = std::make_shared<SpotLight>("colorLight");
-    colorLight->setPosition(Vec3d(-5, -3, 5));
-    colorLight->setFocalPoint(Vec3d(0, -5, 5));
-    colorLight->setIntensity(100);
+    colorLight->setPosition(Vec3d(-5., -3., 5.));
+    colorLight->setFocalPoint(Vec3d(0., -5., 5.));
+    colorLight->setIntensity(100.);
     colorLight->setColor(Color::Red);
     colorLight->setSpotAngle(30);
     scene->addLight(colorLight);
 
     // Adjust camera
-    scene->getCamera()->setFocalPoint(0, -5, 5);
-    scene->getCamera()->setPosition(-15., -5.0, 15.0);
+    scene->getCamera()->setFocalPoint(0., -5., 5.);
+    scene->getCamera()->setPosition(-15., -5., 15.);
 
     // Start
     simManager->setActiveScene(scene);
diff --git a/Examples/PBD/PBDCollisionOneObject/PBDCollisionOneObjectExample.cpp b/Examples/PBD/PBDCollisionOneObject/PBDCollisionOneObjectExample.cpp
index d41458514a75c2b38318811cc5f24e44fdc5fc30..65a5343f8684602417e06675247e9ff405f11daa 100644
--- a/Examples/PBD/PBDCollisionOneObject/PBDCollisionOneObjectExample.cpp
+++ b/Examples/PBD/PBDCollisionOneObject/PBDCollisionOneObjectExample.cpp
@@ -79,7 +79,7 @@ main()
     material->setDisplayMode(RenderMaterial::DisplayMode::Surface);
     material->setLineWidth(0.5);
     material->setEdgeColor(Color::Blue);
-    material->setShadingModel(RenderMaterial::ShadingModel::Flat);
+    material->setShadingModel(RenderMaterial::ShadingModel::Phong);
     auto surfMeshModel = std::make_shared<VisualModel>(highResSurfMesh);
     surfMeshModel->setRenderMaterial(material);
 
diff --git a/Examples/PBD/PBDCollisionStairs/PBDCollisionStairsExample.cpp b/Examples/PBD/PBDCollisionStairs/PBDCollisionStairsExample.cpp
index a88d0e31303a06d79fe6f767371ea597f7a474be..4da0b8f5cf78a2602b038c2ef88df03ecfdd3e26 100644
--- a/Examples/PBD/PBDCollisionStairs/PBDCollisionStairsExample.cpp
+++ b/Examples/PBD/PBDCollisionStairs/PBDCollisionStairsExample.cpp
@@ -96,17 +96,17 @@ buildStairs(int nSteps, double width, double height, double depth)
 }
 
 static std::shared_ptr<PbdObject>
-makeDragonPbdObject(const std::string& name)
+makeArmadilloPbdObject(const std::string& name)
 {
     auto pbdObj = std::make_shared<PbdObject>(name);
 
-    // Read in the dragon mesh
-    auto highResSurfMesh = std::dynamic_pointer_cast<SurfaceMesh>(MeshIO::read(iMSTK_DATA_ROOT "/asianDragon/asianDragon.obj"));
-    auto coarseTetMesh   = std::dynamic_pointer_cast<TetrahedralMesh>(MeshIO::read(iMSTK_DATA_ROOT "/asianDragon/asianDragon.veg"));
-    highResSurfMesh->translate(Vec3d(0.0f, 10.0f, 0.0f), Geometry::TransformType::ApplyToData);
-    coarseTetMesh->translate(Vec3d(0.0f, 10.0f, 0.0f), Geometry::TransformType::ApplyToData);
-    auto coarseSurfMesh = std::make_shared<SurfaceMesh>();
-    coarseTetMesh->extractSurfaceMesh(coarseSurfMesh, true);
+    // Read in the armadillo mesh
+    auto tetMesh = std::dynamic_pointer_cast<TetrahedralMesh>(MeshIO::read(iMSTK_DATA_ROOT "armadillo/armadillo_volume.vtk"));
+    tetMesh->scale(0.07, Geometry::TransformType::ApplyToData);
+    tetMesh->rotate(Vec3d(1.0, 0.0, 0.0), 1.3, Geometry::TransformType::ApplyToData);
+    tetMesh->translate(Vec3d(0.0f, 10.0f, 0.0f), Geometry::TransformType::ApplyToData);
+    auto surfMesh = std::make_shared<SurfaceMesh>();
+    tetMesh->extractSurfaceMesh(surfMesh, true);
 
     // Setup the Parameters
     auto pbdParams = std::make_shared<PBDModelConfig>();
@@ -117,27 +117,26 @@ makeDragonPbdObject(const std::string& name)
     pbdParams->m_uniformMassValue = 1.0;
     pbdParams->m_gravity    = Vec3d(0, -10.0, 0);
     pbdParams->m_defaultDt  = 0.01;
-    pbdParams->m_iterations = 10;
+    pbdParams->m_iterations = 5;
     pbdParams->collisionParams->m_proximity = 0.3;
     pbdParams->collisionParams->m_stiffness = 0.1;
 
     // Setup the Model
     auto pbdModel = std::make_shared<PbdModel>();
-    pbdModel->setModelGeometry(coarseTetMesh);
+    pbdModel->setModelGeometry(tetMesh);
     pbdModel->configure(pbdParams);
 
     // Setup the VisualModel
     auto material = std::make_shared<RenderMaterial>();
     material->setDisplayMode(RenderMaterial::DisplayMode::WireframeSurface);
-    auto surfMeshModel = std::make_shared<VisualModel>(highResSurfMesh);
+    auto surfMeshModel = std::make_shared<VisualModel>(surfMesh);
     surfMeshModel->setRenderMaterial(material);
 
     // Setup the Object
     pbdObj->addVisualModel(surfMeshModel);
-    pbdObj->setCollidingGeometry(coarseSurfMesh);
-    pbdObj->setPhysicsGeometry(coarseTetMesh);
-    pbdObj->setPhysicsToCollidingMap(std::make_shared<OneToOneMap>(coarseTetMesh, coarseSurfMesh));
-    pbdObj->setPhysicsToVisualMap(std::make_shared<TetraTriangleMap>(coarseTetMesh, highResSurfMesh));
+    pbdObj->setCollidingGeometry(surfMesh);
+    pbdObj->setPhysicsGeometry(tetMesh);
+    pbdObj->setPhysicsToVisualMap(std::make_shared<TetraTriangleMap>(tetMesh, surfMesh));
     pbdObj->setDynamicalModel(pbdModel);
 
     return pbdObj;
@@ -189,7 +188,7 @@ main()
     scene->getCamera()->setFocalPoint(0.0, 0.0, 0.0);
 
     // Create and add the dragon to the scene
-    auto pbdDragon1 = makeDragonPbdObject("PbdDragon1");
+    auto pbdDragon1 = makeArmadilloPbdObject("PbdArmadillo1");
     scene->addSceneObject(pbdDragon1);
 
     auto stairObj = makeStairsPbdObject("PbdStairs", 12, 20.0, 10.0, 20.0);
diff --git a/Examples/PBD/PBDDeformableObject/PBD3DDeformableObject.cpp b/Examples/PBD/PBDDeformableObject/PBD3DDeformableObject.cpp
index 2d411318e30509d6480df164ba8c1352e820e3c7..f309e978d20afc58bda4f09c26d13a7736df1a6a 100644
--- a/Examples/PBD/PBDDeformableObject/PBD3DDeformableObject.cpp
+++ b/Examples/PBD/PBDDeformableObject/PBD3DDeformableObject.cpp
@@ -41,12 +41,10 @@ using namespace imstk;
 /// \brief Create a PbdObject and add it to a \p scene
 ///
 std::shared_ptr<PbdObject> createAndAddPbdObject(std::shared_ptr<Scene> scene,
-                                                 const std::string&     surfMeshName,
                                                  const std::string&     tetMeshName);
 
 // mesh file names
-const std::string& surfMeshFileName = iMSTK_DATA_ROOT "/asianDragon/asianDragon.obj";
-const std::string& tetMeshFileName  = iMSTK_DATA_ROOT "/asianDragon/asianDragon.veg";
+const std::string& tetMeshFileName = iMSTK_DATA_ROOT "textured_organs/heart_volume.vtk";
 
 ///
 /// \brief This example demonstrates the soft body simulation
@@ -60,21 +58,12 @@ main()
     scene->getCamera()->setPosition(0, 2.0, 15.0);
 
     // create and add a PBD object
-    createAndAddPbdObject(scene, surfMeshFileName, tetMeshFileName);
-
-    // Setup plane
-    auto planeGeom = std::make_shared<Plane>();
-    planeGeom->setWidth(40);
-    planeGeom->setTranslation(0, -6, 0);
-    auto planeObj = std::make_shared<CollidingObject>("Plane");
-    planeObj->setVisualGeometry(planeGeom);
-    planeObj->setCollidingGeometry(planeGeom);
-    scene->addSceneObject(planeObj);
+    createAndAddPbdObject(scene, tetMeshFileName);
 
     // Light
     auto light = std::make_shared<DirectionalLight>("light");
     light->setFocalPoint(Vec3d(5, -8, -5));
-    light->setIntensity(1);
+    light->setIntensity(1.1);
     scene->addLight(light);
 
     simManager->setActiveScene(scene);
@@ -86,17 +75,24 @@ main()
 
 std::shared_ptr<PbdObject>
 createAndAddPbdObject(std::shared_ptr<Scene> scene,
-                      const std::string&     surfMeshName,
                       const std::string&     tetMeshName)
 {
-    auto surfMesh = std::dynamic_pointer_cast<SurfaceMesh>(MeshIO::read(surfMeshName));
-    auto tetMesh  = std::dynamic_pointer_cast<TetrahedralMesh>(MeshIO::read(tetMeshName));
-    //auto tetMesh  = TetrahedralMesh::createTetrahedralMeshCover(surfMesh, 10, 6, 6);
+    auto tetMesh = std::dynamic_pointer_cast<TetrahedralMesh>(MeshIO::read(tetMeshName));
+    tetMesh->rotate(Vec3d(1.0, 0.0, 0.0), -1.3, Geometry::TransformType::ApplyToData);
+    auto surfMesh = std::make_shared<SurfaceMesh>();
+    tetMesh->extractSurfaceMesh(surfMesh, true);
 
     auto map = std::make_shared<TetraTriangleMap>(tetMesh, surfMesh);
 
     auto material = std::make_shared<RenderMaterial>();
     material->setDisplayMode(RenderMaterial::DisplayMode::Surface);
+    material->setColor(Color(220. / 255.0, 100. / 255.0, 70. / 255.0));
+    material->setMetalness(100.9f);
+    material->setRoughness(0.5);
+    material->setEdgeColor(Color::Teal);
+    material->setAmbientLightCoeff(50.);
+    material->setShadingModel(RenderMaterial::ShadingModel::Phong);
+    material->setDisplayMode(RenderMaterial::DisplayMode::WireframeSurface);
     auto surfMeshModel = std::make_shared<VisualModel>(surfMesh);
     surfMeshModel->setRenderMaterial(material);
 
@@ -108,16 +104,15 @@ createAndAddPbdObject(std::shared_ptr<Scene> scene,
     auto pbdParams = std::make_shared<PBDModelConfig>();
 
     // FEM constraint
-    pbdParams->m_femParams->m_YoungModulus = 1000.0;
+    pbdParams->m_femParams->m_YoungModulus = 500.0;
     pbdParams->m_femParams->m_PoissonRatio = 0.3;
-    pbdParams->m_fixedNodeIds = { 50, 126, 177 };
+    pbdParams->m_fixedNodeIds = { 75, 82, 84, 94, 95, 105, 110, 124, 139, 150, 161, 171, 350 };
     pbdParams->enableFEMConstraint(PbdConstraint::Type::FEMTet, PbdFEMConstraint::MaterialType::StVK);
 
     // Other parameters
     pbdParams->m_uniformMassValue = 1.0;
     pbdParams->m_gravity    = Vec3d(0, -9.8, 0);
-    pbdParams->m_iterations = 15;
-    // pbdParams->m_solverType = PbdConstraint::SolverType::PBD;
+    pbdParams->m_iterations = 6;
 
     // Set the parameters
     pbdModel->configure(pbdParams);
diff --git a/Examples/PBD/PBDString/pbdStringExample.cpp b/Examples/PBD/PBDString/pbdStringExample.cpp
index 655e95df4e43e82b61e37bf27f790022b8c9eeb7..d59f975374963f11c0d44569947846b1e78d5a9d 100644
--- a/Examples/PBD/PBDString/pbdStringExample.cpp
+++ b/Examples/PBD/PBDString/pbdStringExample.cpp
@@ -95,9 +95,10 @@ makePbdString(
     // Setup the VisualModel
     std::shared_ptr<RenderMaterial> material = std::make_shared<RenderMaterial>();
     material->setBackFaceCulling(false);
-    material->setColor(color);
+    material->setEdgeColor(color);
     material->setLineWidth(2.0f);
-    material->setDisplayMode(RenderMaterial::DisplayMode::Wireframe);
+    material->setPointSize(6.0f);
+    material->setDisplayMode(RenderMaterial::DisplayMode::WireframeSurface);
 
     std::shared_ptr<VisualModel> visualModel = std::make_shared<VisualModel>(stringMesh);
     visualModel->setRenderMaterial(material);
diff --git a/Examples/Rendering/RenderingExample.cpp b/Examples/Rendering/RenderingExample.cpp
index 26368907c3d5ae3d380fb3e61b150af405dad69f..cf9dcf2a0d03bde879b8a8ffbb74805c562ded8d 100644
--- a/Examples/Rendering/RenderingExample.cpp
+++ b/Examples/Rendering/RenderingExample.cpp
@@ -93,41 +93,39 @@ main()
 
     // Position camera
     auto cam = scene->getCamera();
-    cam->setPosition(0, 0.25, 1);
+    cam->setPosition(0, 0.25, 0.6);
     cam->setFocalPoint(0, 0.25, 0);
 
     // Lights
     auto directionalLight = std::make_shared<DirectionalLight>("DirectionalLight");
-    directionalLight->setIntensity(1);
+    directionalLight->setIntensity(4);
     directionalLight->setColor(Color(1.0, 0.95, 0.8));
     directionalLight->setCastsShadow(true);
     directionalLight->setShadowRange(1.5);
     scene->addLight(directionalLight);
 
-    /* auto pointLight = std::make_shared<PointLight>("PointLight");
-     pointLight->setIntensity(0.1);
-     pointLight->setPosition(0.1, 0.2, 0.5);
-     scene->addLight(pointLight);*/
+    auto pointLight = std::make_shared<PointLight>("PointLight");
+    pointLight->setIntensity(0.1);
+    pointLight->setPosition(0.1, 0.2, 0.5);
+    scene->addLight(pointLight);
 
+#ifdef iMSTK_USE_Vulkan
     // Sphere
     auto sphereObj      = apiutils::createVisualAnalyticalSceneObject(Geometry::Type::Sphere, scene, "VisualSphere", 0.025);
     auto sphereMaterial = std::make_shared<RenderMaterial>();
     auto sphereMesh     = sphereObj->getVisualGeometry();
     sphereMesh->translate(0.1, 0.2, 0.5);
-    sphereMaterial->setEmissivity(1);
+    sphereMaterial->setEmissivity(2);
     sphereMaterial->setCastsShadows(false);
     sphereObj->getVisualModel(0)->setRenderMaterial(sphereMaterial);
+#endif
 
     // Plane
     auto planeObj      = apiutils::createVisualAnalyticalSceneObject(Geometry::Type::Plane, scene, "VisualPlane", 10);
     auto planeMaterial = std::make_shared<RenderMaterial>();
-    planeMaterial->setColor(Color::DarkGray);
+    planeMaterial->setColor(Color::LightGray);
     planeObj->getVisualModel(0)->setRenderMaterial(planeMaterial);
 
-    // Run
-    simManager->setActiveScene(scene);
-    //simManager->getViewer()->setBackgroundColors(Vec3d(0, 0, 0));
-
 #ifdef iMSTK_USE_Vulkan
     auto viewer = std::dynamic_pointer_cast<VulkanViewer>(simManager->getViewer());
     viewer->setResolution(1000, 800);
@@ -135,6 +133,8 @@ main()
     //viewer->enableFullscreen();
 #endif
 
+    // Run
+    simManager->setActiveScene(scene);
     simManager->start(SimulationStatus::Paused);
 
     return 0;
diff --git a/Examples/TaskGraph/Timing/taskGraphTimingExample.cpp b/Examples/TaskGraph/Timing/taskGraphTimingExample.cpp
index c438c94549a04b57a805af7c4a541b16578d3597..e5f8032c118763301345c8f40e51c6e77f82bc4a 100644
--- a/Examples/TaskGraph/Timing/taskGraphTimingExample.cpp
+++ b/Examples/TaskGraph/Timing/taskGraphTimingExample.cpp
@@ -97,7 +97,7 @@ makePbdString(
     // Setup the VisualModel
     std::shared_ptr<RenderMaterial> material = std::make_shared<RenderMaterial>();
     material->setBackFaceCulling(false);
-    material->setColor(color);
+    material->setEdgeColor(color);
     material->setLineWidth(2.0f);
     material->setDisplayMode(RenderMaterial::DisplayMode::Wireframe);
 
@@ -165,6 +165,7 @@ main()
     // Setup N separate strings with varying bend stiffnesses
     std::vector<std::shared_ptr<PbdObject>> pbdStringObjs =
         makePbdStrings(numStrings, numVerts, stringSpacing, stringLength, startColor, endColor);
+    // Add them to the scene
     for (std::shared_ptr<PbdObject> obj : pbdStringObjs)
     {
         scene->addSceneObject(obj);
@@ -176,8 +177,7 @@ main()
 
     // Move the points every frame
     double t = 0.0;
-
-    auto movePoints =
+    auto   movePoints =
         [&pbdStringObjs, &t](Module* module)
         {
             for (unsigned int i = 0; i < pbdStringObjs.size(); i++)
diff --git a/README.md b/README.md
index 8e842f48756b0204a1bb636048b0d3d0c42d2d46..e2bc6473fe8d703593d6213b6b023c31095adbde 100644
--- a/README.md
+++ b/README.md
@@ -22,9 +22,10 @@
 - [CeMSIM-Rensselaer Polytechnic Institute](http://cemsim.rpi.edu/)
 - [University of Central Arkansas](http://sun0.cs.uca.edu/~thalic/virasim.html)
 
-Funding support:
-- [NIH-OD] SBIR award [9R44OD018334](https://www.sbir.gov/sbirsearch/detail/1032259)
-- [NIH-NIBIB] SBIR award [1R44EB019802-01A1](https://www.sbir.gov/sbirsearch/detail/1047037)
+####Funding support:
+This project is supported in part by the following grants [9R44OD018334](https://www.sbir.gov/sbirsearch/detail/1032259), [1R44EB019802](https://www.sbir.gov/sbirsearch/detail/1047037), [1R44AR075481](https://projectreporter.nih.gov/project_info_details.cfm?aid=9777225&icde=50531419) , [1R01EB025247](https://projectreporter.nih.gov/project_info_details.cfm?aid=9738646&icde=50531433), [2R44DK115332](https://projectreporter.nih.gov/project_info_details.cfm?aid=9843084&icde=50531443)
+
+Disclaimer: The content is solely the responsibility of the authors and does not necessarily represent the official views of the NIH and its institutes.
 
 ### Licensing
 iMSTK is licensed under [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt)
@@ -46,7 +47,7 @@ Designed more specifically for developers, the issue tracker allows developers t
 
 ## Prerequisites
 * Git
-* CMake 3.9 or higher
+* CMake 3.15 or higher
 
 ##### On Linux:
 
@@ -82,7 +83,7 @@ ninja
 This will checkout, build and link all iMSTK dependencies. When making changes to iMSTK [base source code](/Base), you can then build from the `Innerbuild` directory.
 
 * ##### On Windows
-Run CMake-GUI and follow the directions described [HERE](https://cmake.org/runningcmake/). You will have to choose which version of Visual Studio you'd like to use when configuring the project, make sure to select **Microsoft Visual Studio C++ 15 2017**. CMake will generate a `iMSTK.sln` solution file for Visual Studio at the top level. Open this file and build all targets, which will checkout, build and link all iMSTK dependencies. When making changes to iMSTK [base source code](/Base), you can then build from the `iMSTK.sln` solution file located in the `Innerbuild` directory.
+Run CMake-GUI and follow the directions described [HERE](https://cmake.org/runningcmake/). You will have to choose which version of Visual Studio you'd like to use when configuring the project, make sure to select **Microsoft Visual Studio C++ 15 2017 or 2019**. CMake will generate a `iMSTK.sln` solution file for Visual Studio at the top level. Open this file and build all targets, which will checkout, build and link all iMSTK dependencies. When making changes to iMSTK [base source code](/Base), you can then build from the `iMSTK.sln` solution file located in the `Innerbuild` directory.
 If you would like to build on multiple cores add /MP[N] to CMAKE_CXX_FLAGS in CMake-GUI, where N is optional representing the number of cores (without N supplied, the build will use as many cores as available on the device).
 
 * ##### PhysX Support
diff --git a/Source/CollisionHandling/imstkPenaltyCH.cpp b/Source/CollisionHandling/imstkPenaltyCH.cpp
index b3a482040a49f1323be2fd7876eb9ac0e05a8b03..1e59fa12cbc584a16712229a5f7ccadb757da249 100644
--- a/Source/CollisionHandling/imstkPenaltyCH.cpp
+++ b/Source/CollisionHandling/imstkPenaltyCH.cpp
@@ -22,7 +22,7 @@
 #include "imstkPenaltyCH.h"
 #include "imstkCollidingObject.h"
 #include "imstkCollisionData.h"
-#include "imstkDeformableObject.h"
+#include "imstkFeDeformableObject.h"
 #include "imstkFEMDeformableBodyModel.h"
 #include "imstkLogger.h"
 #include "imstkParallelUtils.h"
diff --git a/Source/CollisionHandling/imstkPickingCH.cpp b/Source/CollisionHandling/imstkPickingCH.cpp
index ac70bb54389fc2dd923b6be4e8be87c827db9739..92f35e96a0543d4402b602db7208c97f6ababfc1 100644
--- a/Source/CollisionHandling/imstkPickingCH.cpp
+++ b/Source/CollisionHandling/imstkPickingCH.cpp
@@ -20,7 +20,7 @@ limitations under the License.
 =========================================================================*/
 
 #include "imstkPickingCH.h"
-#include "imstkDeformableObject.h"
+#include "imstkFeDeformableObject.h"
 #include "imstkParallelUtils.h"
 #include "imstkPointSet.h"
 #include "imstkFEMDeformableBodyModel.h"
diff --git a/Source/Geometry/imstkGeometry.cpp b/Source/Geometry/imstkGeometry.cpp
index abca330a03cb9322b88f2fb9a0dd56b47383cb85..3d56ecfde0073d3ff0e6595053ef4994330ff866 100644
--- a/Source/Geometry/imstkGeometry.cpp
+++ b/Source/Geometry/imstkGeometry.cpp
@@ -124,9 +124,9 @@ Geometry::rotate(const Quatd& q, TransformType type)
 }
 
 void
-Geometry::rotate(const Vec3d& axis, double angle, TransformType type)
+Geometry::rotate(const Vec3d& axis, double radians, TransformType type)
 {
-    this->rotate(Rotd(angle, axis).toRotationMatrix(), type);
+    this->rotate(Rotd(radians, axis).toRotationMatrix(), type);
 }
 
 void
diff --git a/Source/Geometry/imstkGeometry.h b/Source/Geometry/imstkGeometry.h
index 4f20faceae37cf412f7e6a4fbed0e20065b98b2a..038dc8bffa68e05b9b26b1272379b0a803153bb7 100644
--- a/Source/Geometry/imstkGeometry.h
+++ b/Source/Geometry/imstkGeometry.h
@@ -118,7 +118,7 @@ public:
     ///
     void rotate(const Quatd& q, TransformType type = TransformType::ConcatenateToTransform);
     void rotate(const Mat3d& m, TransformType type = TransformType::ConcatenateToTransform);
-    void rotate(const Vec3d& axis, double angle, TransformType type = TransformType::ConcatenateToTransform);
+    void rotate(const Vec3d& axis, double radians, TransformType type = TransformType::ConcatenateToTransform);
 
     ///
     /// \brief Scale in Cartesian directions
diff --git a/Source/Rendering/Materials/imstkRenderMaterial.cpp b/Source/Rendering/Materials/imstkRenderMaterial.cpp
index 4802127a1c533c67fc4402a24d407101a6612b81..63bedfd6292b7d239b2b06534a35f4b5c32a43a8 100644
--- a/Source/Rendering/Materials/imstkRenderMaterial.cpp
+++ b/Source/Rendering/Materials/imstkRenderMaterial.cpp
@@ -136,16 +136,54 @@ RenderMaterial::backfaceCullingOff()
 }
 
 const Color&
-RenderMaterial::getColor() const
+RenderMaterial::getDiffuseColor() const
 {
-    return m_color;
+    return m_diffuseColor;
 }
 
+void
+RenderMaterial::setDiffuseColor(const Color& color)
+{
+    m_diffuseColor = color;
+    m_modified     = true;
+}
+
+const Color&
+RenderMaterial::getColor() const
+{
+    return this->getDiffuseColor();
+};
+
 void
 RenderMaterial::setColor(const Color& color)
 {
-    m_color    = color;
-    m_modified = true;
+    this->setDiffuseColor(color);
+};
+
+const Color&
+RenderMaterial::getSpecularColor() const
+{
+    return m_specularColor;
+}
+
+void
+RenderMaterial::setSpecularColor(const Color& color)
+{
+    m_specularColor = color;
+    m_modified      = true;
+}
+
+const Color&
+RenderMaterial::getAmbientColor() const
+{
+    return m_ambientColor;
+}
+
+void
+RenderMaterial::setAmbientColor(const Color& color)
+{
+    m_ambientColor = color;
+    m_modified     = true;
 }
 
 const float&
diff --git a/Source/Rendering/Materials/imstkRenderMaterial.h b/Source/Rendering/Materials/imstkRenderMaterial.h
index 9f3364a447d2a644d99da57742a98f970522e171..58ce51cb63136897e184b9997893e7d99e1ba523 100644
--- a/Source/Rendering/Materials/imstkRenderMaterial.h
+++ b/Source/Rendering/Materials/imstkRenderMaterial.h
@@ -105,15 +105,41 @@ public:
     /// \brief Get/Set the color. This affects the diffuse color directly, but
     /// it affects the specular color in the case of metals.
     ///
+    const Color& getDiffuseColor() const;
+    void setDiffuseColor(const Color& color);
     const Color& getColor() const;
     void setColor(const Color& color);
 
+    ///
+    /// \brief Get/Set the specular color
+    ///
+    const Color& getSpecularColor() const;
+    void setSpecularColor(const Color& color);
+
+    ///
+    /// \brief Get/Set the ambient color
+    ///
+    const Color& getAmbientColor() const;
+    void setAmbientColor(const Color& color);
+
     ///
     /// \brief Get/Set the metalness
     ///
     const float& getMetalness() const;
     void setMetalness(const float metalness);
 
+    ///
+    /// \brief Get/Set ambient light coefficient
+    ///
+    const float& getAmbientLightCoeff() const { return m_ambientLightCoeff; };
+    void setAmbientLightCoeff(const float a) { m_ambientLightCoeff = a; };
+
+    ///
+    /// \brief Get/Set ambient light coefficient
+    ///
+    const float& getSpecularPower() const { return m_specularPower; };
+    void setSpecularPower(const float p) { m_specularPower = p; };
+
     ///
     /// \brief Get/Set the roughness
     ///
@@ -205,8 +231,13 @@ protected:
     BlendMode m_blendMode = BlendMode::Alpha;
 
     ///-------------------Common properties---------------------
-    Color m_color   = Color::LightGray;
-    float m_opacity = 1.0;
+    Color m_diffuseColor  = Color::LightGray;
+    Color m_specularColor = Color::Red;
+    Color m_ambientColor  = Color::White;
+
+    float m_ambientLightCoeff = 0.1f;
+    float m_specularPower     = 100.f;
+    float m_opacity = 1.f;
 
     ///-------------Wireframe specific properties----------------
     float m_lineWidth        = 1.f;
diff --git a/Source/Rendering/VTKRenderer/RenderDelegate/imstkVTKRenderDelegate.cpp b/Source/Rendering/VTKRenderer/RenderDelegate/imstkVTKRenderDelegate.cpp
index e2f74f2ecd5529435eaab1168a6b0a14b1b5370b..e0119202fbb71ea09e8ae2c69ca112a6b6ce15d6 100644
--- a/Source/Rendering/VTKRenderer/RenderDelegate/imstkVTKRenderDelegate.cpp
+++ b/Source/Rendering/VTKRenderer/RenderDelegate/imstkVTKRenderDelegate.cpp
@@ -293,8 +293,11 @@ VTKRenderDelegate::updateActorProperties()
     auto actorProperty = m_actor->GetProperty();
 
     // Colors & Light
-    auto diffuseColor = material->m_color;
-    actorProperty->SetDiffuseColor(diffuseColor.r, diffuseColor.g, diffuseColor.b);
+    actorProperty->SetDiffuseColor(material->m_diffuseColor.r, material->m_diffuseColor.g, material->m_diffuseColor.b);
+    actorProperty->SetAmbientColor(material->m_ambientColor.r, material->m_ambientColor.g, material->m_ambientColor.b);
+    actorProperty->SetAmbient(material->m_ambientLightCoeff);
+    actorProperty->SetSpecularColor(material->m_specularColor.r, material->m_specularColor.g, material->m_specularColor.b);
+    actorProperty->SetSpecularPower(material->m_specularPower);
 
     // Material state is now up to date
     material->m_modified = false;
@@ -437,12 +440,19 @@ VTKRenderDelegate::updateActorPropertiesMesh()
     }
     else
     {
-        if (material->getDisplayMode() != RenderMaterial::DisplayMode::Fluid)// surface
+        if (material->getDisplayMode() != RenderMaterial::DisplayMode::Fluid)// = surface
         {
             actorProperty->SetRepresentationToSurface();
             actorProperty->SetEdgeVisibility(false);
             actorProperty->SetVertexVisibility(false);
-            actorProperty->SetColor(surfaceColor.r, surfaceColor.g, surfaceColor.b);
+
+            // Colors & Light
+            actorProperty->SetDiffuseColor(material->m_diffuseColor.r, material->m_diffuseColor.g, material->m_diffuseColor.b);
+            actorProperty->SetAmbientColor(material->m_ambientColor.r, material->m_ambientColor.g, material->m_ambientColor.b);
+            actorProperty->SetAmbient(material->m_ambientLightCoeff);
+            actorProperty->SetSpecularColor(material->m_specularColor.r, material->m_specularColor.g, material->m_specularColor.b);
+            actorProperty->SetSpecularPower(material->m_specularPower);
+
             if (material->getShadingModel() == RenderMaterial::ShadingModel::PBR)
             {
                 /*actorProperty->UseImageBasedLightingOn();
diff --git a/Source/Rendering/VTKRenderer/imstkVTKRenderer.cpp b/Source/Rendering/VTKRenderer/imstkVTKRenderer.cpp
index f2606e9e083bb2fea8e19fc84bf8b8b3ce627464..60a92b28d55a506065484e52917880b4fe17fe07 100644
--- a/Source/Rendering/VTKRenderer/imstkVTKRenderer.cpp
+++ b/Source/Rendering/VTKRenderer/imstkVTKRenderer.cpp
@@ -419,76 +419,76 @@ VTKRenderer::getAxesVisibility() const
     return m_AxesActor->GetVisibility();
 }
 
-void
-VTKRenderer::setTimeTable(const std::unordered_map<std::string, double>& timeTable)
-{
-    // Sort by elapsed times
-    std::vector<std::pair<std::string, double>> nameToTimesVec(timeTable.begin(), timeTable.end());
-    std::sort(nameToTimesVec.begin(), nameToTimesVec.end(),
-        [](const std::pair<std::string, double>& a, const std::pair<std::string, double>& b) { return a.second < b.second; });
-
-    // Construct vtkTable from provided data
-    vtkSmartPointer<vtkDoubleArray> xIndices      = vtkDoubleArray::SafeDownCast(m_timeTable->GetColumn(0));
-    vtkSmartPointer<vtkDoubleArray> yElapsedTimes = vtkDoubleArray::SafeDownCast(m_timeTable->GetColumn(1));
-    vtkSmartPointer<vtkStringArray> labels = vtkStringArray::SafeDownCast(m_timeTable->GetColumn(2));
-
-    labels->SetNumberOfValues(nameToTimesVec.size());
-    xIndices->SetNumberOfValues(nameToTimesVec.size());
-    yElapsedTimes->SetNumberOfValues(nameToTimesVec.size());
-    for (size_t i = 0; i < nameToTimesVec.size(); i++)
-    {
-        labels->SetValue(i, nameToTimesVec[i].first.c_str());
-        xIndices->SetValue(i, i + 1);
-        yElapsedTimes->SetValue(i, nameToTimesVec[i].second);
-    }
-
-    // The range for the x axis is based on history of the elapsed times
-    vtkAxis* botAxis = m_timeTableChart->GetAxis(vtkAxis::BOTTOM);
-
-    // Get the previous and current range
-    double newMaxElapsed = yElapsedTimes->GetRange()[1];
-    yElapsedTimes->Modified();
-    double currMaxElapsed = botAxis->GetMaximum();
-
-    // Always respect the max as all information should be shown
-    if (newMaxElapsed > currMaxElapsed)
-    {
-        botAxis->SetRange(0.0, newMaxElapsed);
-    }
-    // But if current elapsed is less than the existing one we can lag
-    else
-    {
-        // Lag downscaling by 400 iterations
-        if (m_timeTableIter % 400 == 0)
-        {
-            botAxis->SetRange(0.0, newMaxElapsed);
-        }
-        else
-        {
-            botAxis->SetRange(0.0, currMaxElapsed);
-        }
-        m_timeTableIter++;
-    }
-    botAxis->Modified();
-
-    vtkAxis* leftAxis = m_timeTableChart->GetAxis(vtkAxis::LEFT);
-    leftAxis->SetRange(xIndices->GetRange());
-    leftAxis->SetCustomTickPositions(xIndices, labels);
-
-    m_timeTable->Modified();
-}
-
-void
-VTKRenderer::setTimeTableVisibility(const bool visible)
-{
-    m_timeTableChartActor->SetVisibility(visible);
-}
-
-bool
-VTKRenderer::getTimeTableVisibility() const
-{
-    return m_timeTableChartActor->GetVisibility();
-}
+//void
+//VTKRenderer::setTimeTable(const std::unordered_map<std::string, double>& timeTable)
+//{
+//    // Sort by elapsed times
+//    std::vector<std::pair<std::string, double>> nameToTimesVec(timeTable.begin(), timeTable.end());
+//    std::sort(nameToTimesVec.begin(), nameToTimesVec.end(),
+//        [](const std::pair<std::string, double>& a, const std::pair<std::string, double>& b) { return a.second < b.second; });
+//
+//    // Construct vtkTable from provided data
+//    vtkSmartPointer<vtkDoubleArray> xIndices      = vtkDoubleArray::SafeDownCast(m_timeTable->GetColumn(0));
+//    vtkSmartPointer<vtkDoubleArray> yElapsedTimes = vtkDoubleArray::SafeDownCast(m_timeTable->GetColumn(1));
+//    vtkSmartPointer<vtkStringArray> labels = vtkStringArray::SafeDownCast(m_timeTable->GetColumn(2));
+//
+//    labels->SetNumberOfValues(nameToTimesVec.size());
+//    xIndices->SetNumberOfValues(nameToTimesVec.size());
+//    yElapsedTimes->SetNumberOfValues(nameToTimesVec.size());
+//    for (size_t i = 0; i < nameToTimesVec.size(); i++)
+//    {
+//        labels->SetValue(i, nameToTimesVec[i].first.c_str());
+//        xIndices->SetValue(i, i + 1);
+//        yElapsedTimes->SetValue(i, nameToTimesVec[i].second);
+//    }
+//
+//    // The range for the x axis is based on history of the elapsed times
+//    vtkAxis* botAxis = m_timeTableChart->GetAxis(vtkAxis::BOTTOM);
+//
+//    // Get the previous and current range
+//    double newMaxElapsed = yElapsedTimes->GetRange()[1];
+//    yElapsedTimes->Modified();
+//    double currMaxElapsed = botAxis->GetMaximum();
+//
+//    // Always respect the max as all information should be shown
+//    if (newMaxElapsed > currMaxElapsed)
+//    {
+//        botAxis->SetRange(0.0, newMaxElapsed);
+//    }
+//    // But if current elapsed is less than the existing one we can lag
+//    else
+//    {
+//        // Lag downscaling by 400 iterations
+//        if (m_timeTableIter % 400 == 0)
+//        {
+//            botAxis->SetRange(0.0, newMaxElapsed);
+//        }
+//        else
+//        {
+//            botAxis->SetRange(0.0, currMaxElapsed);
+//        }
+//        m_timeTableIter++;
+//    }
+//    botAxis->Modified();
+//
+//    vtkAxis* leftAxis = m_timeTableChart->GetAxis(vtkAxis::LEFT);
+//    leftAxis->SetRange(xIndices->GetRange());
+//    leftAxis->SetCustomTickPositions(xIndices, labels);
+//
+//    m_timeTable->Modified();
+//}
+//
+//void
+//VTKRenderer::setTimeTableVisibility(const bool visible)
+//{
+//    m_timeTableChartActor->SetVisibility(visible);
+//}
+//
+//bool
+//VTKRenderer::getTimeTableVisibility() const
+//{
+//    return m_timeTableChartActor->GetVisibility();
+//}
 
 void
 VTKRenderer::updateSceneCamera(std::shared_ptr<Camera> imstkCam)
diff --git a/Source/Rendering/VTKRenderer/imstkVTKRenderer.h b/Source/Rendering/VTKRenderer/imstkVTKRenderer.h
index 22e13ea70d9067b8c6234cdad61bba07251450b7..fca9a81520cdc09d76844786d3480b34732e0499 100644
--- a/Source/Rendering/VTKRenderer/imstkVTKRenderer.h
+++ b/Source/Rendering/VTKRenderer/imstkVTKRenderer.h
@@ -102,17 +102,17 @@ public:
     ///
     /// \brief Sets the benchmarking table using unordered_map
     ///
-    void setTimeTable(const std::unordered_map<std::string, double>& timeTable);
+    //void setTimeTable(const std::unordered_map<std::string, double>& timeTable);
 
     ///
     /// \brief Set the visibility of the benchmark graph
     ///
-    void setTimeTableVisibility(const bool visible);
+    //void setTimeTableVisibility(const bool visible);
 
     ///
     /// \brief Get the visibility of the benchmark graph
     ///
-    bool getTimeTableVisibility() const;
+    //bool getTimeTableVisibility() const;
 
     ///
     /// \brief Updates the scene camera's position and orientation
@@ -177,10 +177,10 @@ protected:
     std::vector<vtkOpenVRCameraPose> m_camPos;
 #endif
 
-    vtkSmartPointer<vtkChartXY>      m_timeTableChart      = nullptr;
-    vtkSmartPointer<vtkContextActor> m_timeTableChartActor = nullptr;
-    vtkSmartPointer<vtkTable> m_timeTable = nullptr;
-    vtkPlotBar* m_timeTablePlot = nullptr;
+    vtkSmartPointer<vtkChartXY>      m_timeTableChart;
+    vtkSmartPointer<vtkContextActor> m_timeTableChartActor;
+    vtkSmartPointer<vtkTable> m_timeTable;
+    vtkPlotBar* m_timeTablePlot;
     int m_timeTableIter = 0;
 };
 }
diff --git a/Source/Scene/imstkObjectInteractionFactory.cpp b/Source/Scene/imstkObjectInteractionFactory.cpp
index eaba788f7d8d03002a21f191d9e6d3d32c89133b..0541f7448cf2c45a0df711427f2ffe55c8a857d3 100644
--- a/Source/Scene/imstkObjectInteractionFactory.cpp
+++ b/Source/Scene/imstkObjectInteractionFactory.cpp
@@ -25,7 +25,7 @@ limitations under the License.
 #include "imstkCollidingObject.h"
 #include "imstkCollisionData.h"
 #include "imstkCollisionDetection.h"
-#include "imstkDeformableObject.h"
+#include "imstkFeDeformableObject.h"
 #include "imstkLogger.h"
 #include "imstkPbdObject.h"
 #include "imstkPbdObjectCollisionPair.h"
diff --git a/Source/Scene/imstkScene.cpp b/Source/Scene/imstkScene.cpp
index 888b64ac509e9f0675357a2f46b79f8853c320ba..b7c06707d772bc16a32a57038f702ccef30960da 100644
--- a/Source/Scene/imstkScene.cpp
+++ b/Source/Scene/imstkScene.cpp
@@ -26,7 +26,7 @@
 #include "imstkCollisionGraph.h"
 #include "imstkCollisionPair.h"
 #include "imstkDebugRenderGeometry.h"
-#include "imstkDeformableObject.h"
+#include "imstkFeDeformableObject.h"
 #include "imstkDynamicObject.h"
 #include "imstkFEMDeformableBodyModel.h"
 #include "imstkInteractionPair.h"
diff --git a/Source/SceneEntities/Objects/imstkDeformableObject.cpp b/Source/SceneEntities/Objects/imstkDeformableObject.cpp
index e4d1fb73f7da0a3df888484e3fa1bc0ce7d4ed8b..d49510a0a844bf161759b65d0e48874f1c08a1db 100644
--- a/Source/SceneEntities/Objects/imstkDeformableObject.cpp
+++ b/Source/SceneEntities/Objects/imstkDeformableObject.cpp
@@ -19,7 +19,7 @@
 
 =========================================================================*/
 
-#include "imstkDeformableObject.h"
+#include "imstkFeDeformableObject.h"
 #include "imstkFEMDeformableBodyModel.h"
 #include "imstkLogger.h"
 
diff --git a/Source/SceneEntities/Objects/imstkFeDeformableObject.cpp b/Source/SceneEntities/Objects/imstkFeDeformableObject.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d49510a0a844bf161759b65d0e48874f1c08a1db
--- /dev/null
+++ b/Source/SceneEntities/Objects/imstkFeDeformableObject.cpp
@@ -0,0 +1,43 @@
+/*=========================================================================
+
+   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 "imstkFeDeformableObject.h"
+#include "imstkFEMDeformableBodyModel.h"
+#include "imstkLogger.h"
+
+namespace imstk
+{
+bool
+FeDeformableObject::initialize()
+{
+    m_femModel = std::dynamic_pointer_cast<FEMDeformableBodyModel>(m_dynamicalModel);
+    if (m_femModel == nullptr)
+    {
+        LOG(FATAL) << "Dynamics pointer cast failure in DeformableObject::initialize()";
+        return false;
+    }
+
+    DynamicObject::initialize();
+    m_femModel->initialize();
+
+    return true;
+}
+} // imstk
diff --git a/Source/SceneEntities/Objects/imstkDeformableObject.h b/Source/SceneEntities/Objects/imstkFeDeformableObject.h
similarity index 100%
rename from Source/SceneEntities/Objects/imstkDeformableObject.h
rename to Source/SceneEntities/Objects/imstkFeDeformableObject.h
diff --git a/Source/SimulationManager/VTKRenderer/imstkVTKViewer.cpp b/Source/SimulationManager/VTKRenderer/imstkVTKViewer.cpp
index e53ca868bf6ea18f80a3479c8f6749eae1ae272e..d5ab9f6b983c4d52c82ff1f0134a3b480bfacf23 100644
--- a/Source/SimulationManager/VTKRenderer/imstkVTKViewer.cpp
+++ b/Source/SimulationManager/VTKRenderer/imstkVTKViewer.cpp
@@ -80,9 +80,9 @@ VTKViewer::VTKViewer(SimulationManager* manager /*= nullptr*/, bool enableVR /*=
 #endif
 
     // Setup callback for timer on the interactor
-    timerCallbackCommand = vtkSmartPointer<vtkCallbackCommand>::New();
+    /*timerCallbackCommand = vtkSmartPointer<vtkCallbackCommand>::New();
     timerCallbackCommand->SetCallback(timerCallback);
-    timerCallbackCommand->SetClientData(this);
+    timerCallbackCommand->SetClientData(this);*/
 }
 
 void
@@ -190,13 +190,13 @@ VTKViewer::startRenderingLoop()
         m_vtkRenderWindow->GetInteractor()->CreateOneShotTimer(0);
 
         // If the Scene wants benchmarking hookup timer to update the table
-        auto vtkRen = std::dynamic_pointer_cast<VTKRenderer>(getActiveRenderer());
+        /*auto vtkRen = std::dynamic_pointer_cast<VTKRenderer>(getActiveRenderer());
         vtkRen->setTimeTableVisibility(m_activeScene->getConfig()->taskTimingEnabled);
         if (m_activeScene->getConfig()->taskTimingEnabled)
         {
             m_vtkRenderWindow->GetInteractor()->AddObserver(vtkCommand::TimerEvent, timerCallbackCommand);
             m_vtkRenderWindow->GetInteractor()->CreateRepeatingTimer(500);
-        }
+        }*/
 
         m_vtkRenderWindow->SetWindowName(m_config->m_windowName.c_str());
         m_vtkRenderWindow->GetInteractor()->Start();
@@ -254,17 +254,17 @@ VTKViewer::getTextStatusManager()
     return m_vtkInteractorStyle->getTextStatusManager();
 }
 
-void
-VTKViewer::timerCallback(vtkObject* caller, long unsigned int vtkNotUsed(eventId), void* clientData, void* vtkNotUsed(callData))
-{
-    VTKViewer* self = static_cast<VTKViewer*>(clientData);
-
-    if (self->getActiveScene()->getConfig()->taskTimingEnabled)
-    {
-        auto vtkRen = std::dynamic_pointer_cast<VTKRenderer>(self->getActiveRenderer());
-        self->getActiveScene()->lockComputeTimes();
-        vtkRen->setTimeTable(self->getActiveScene()->getTaskComputeTimes());
-        self->getActiveScene()->unlockComputeTimes();
-    }
-}
+//void
+//VTKViewer::timerCallback(vtkObject* caller, long unsigned int vtkNotUsed(eventId), void* clientData, void* vtkNotUsed(callData))
+//{
+//    VTKViewer* self = static_cast<VTKViewer*>(clientData);
+//
+//    if (self->getActiveScene()->getConfig()->taskTimingEnabled)
+//    {
+//        auto vtkRen = std::dynamic_pointer_cast<VTKRenderer>(self->getActiveRenderer());
+//        self->getActiveScene()->lockComputeTimes();
+//        vtkRen->setTimeTable(self->getActiveScene()->getTaskComputeTimes());
+//        self->getActiveScene()->unlockComputeTimes();
+//    }
+//}
 } // imstk
diff --git a/Source/SimulationManager/VTKRenderer/imstkVTKViewer.h b/Source/SimulationManager/VTKRenderer/imstkVTKViewer.h
index 5280057247dc4684ddddba2b2681000f43f7aed3..2cc0c11031e4f73775d04d3e31c919adbc423eef 100644
--- a/Source/SimulationManager/VTKRenderer/imstkVTKViewer.h
+++ b/Source/SimulationManager/VTKRenderer/imstkVTKViewer.h
@@ -111,13 +111,13 @@ public:
 
 protected:
     /// \brief TODO
-    static void timerCallback(vtkObject* caller, long unsigned int eventId, void* clientData, void* callData);
+    //static void timerCallback(vtkObject* caller, long unsigned int eventId, void* clientData, void* callData);
 
     vtkSmartPointer<vtkRenderWindow>    m_vtkRenderWindow;
     std::shared_ptr<VTKInteractorStyle> m_vtkInteractorStyle;
     bool m_enableVR;
 
-    vtkSmartPointer<vtkCallbackCommand> timerCallbackCommand;
+    //vtkSmartPointer<vtkCallbackCommand> timerCallbackCommand;
 
 #ifdef iMSTK_ENABLE_VR
     vtkSmartPointer<OpenVRCommand> m_openVRCommand;