diff --git a/Source/Rendering/Testing/imstkAnalyticalGeometryRenderTest.cpp b/Source/Rendering/Testing/imstkAnalyticalGeometryRenderTest.cpp
deleted file mode 100644
index e9ca03055d299d5c0a1a9ff9947b8ee6a9cf07be..0000000000000000000000000000000000000000
--- a/Source/Rendering/Testing/imstkAnalyticalGeometryRenderTest.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/*=========================================================================
-
-   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 "imstkSetupRenderTest.h"
-
-#include "imstkCapsule.h"
-#include "imstkCylinder.h"
-#include "imstkDecal.h"
-#include "imstkOrientedBox.h"
-#include "imstkPlane.h"
-#include "imstkSphere.h"
-
-class AnalyticalGeometryRenderTest : public RenderTest { };
-
-TEST_F(AnalyticalGeometryRenderTest, createCapsule)
-{
-    ASSERT_TRUE(scene != nullptr) << "ERROR: Unable to create scene object";
-
-    auto geom = std::make_shared<Capsule>();
-
-    addGeometry(geom, Color::Pink);
-
-    run_for(driver.get(), 2);
-}
-
-TEST_F(AnalyticalGeometryRenderTest, createCylinder)
-{
-  ASSERT_TRUE(scene != nullptr) << "ERROR: Unable to create scene object";
-
-  auto geom = std::make_shared<Cylinder>();
-
-  addGeometry(geom, Color::Blue);
-
-  run_for(driver.get(), 2);
-}
-
-TEST_F(AnalyticalGeometryRenderTest, createOrientedBox)
-{
-  ASSERT_TRUE(scene != nullptr) << "ERROR: Unable to create scene object";
-
-  auto geom = std::make_shared<OrientedBox>();
-
-  addGeometry(geom, Color::Teal);
-
-  run_for(driver.get(), 2);
-}
-
-TEST_F(AnalyticalGeometryRenderTest, createPlane)
-{
-  ASSERT_TRUE(scene != nullptr) << "ERROR: Unable to create scene object";
-
-  auto geom = std::make_shared<Plane>();
-
-  addGeometry(geom, Color::Orange);
-
-  run_for(driver.get(), 2);
-}
-
-TEST_F(AnalyticalGeometryRenderTest, createSphere)
-{
-  ASSERT_TRUE(scene != nullptr) << "ERROR: Unable to create scene object";
-
-  auto geom = std::make_shared<Sphere>();
-
-  addGeometry(geom, Color::Red);
-
-  run_for(driver.get(), 2);
-}
\ No newline at end of file
diff --git a/Source/Rendering/Testing/imstkRenderAnalyticalGeometryTest.cpp b/Source/Rendering/Testing/imstkRenderAnalyticalGeometryTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e844808a6e02d522827b285e5078dc011311aff1
--- /dev/null
+++ b/Source/Rendering/Testing/imstkRenderAnalyticalGeometryTest.cpp
@@ -0,0 +1,89 @@
+/*=========================================================================
+
+   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 "imstkRenderTest.h"
+
+#include "imstkCapsule.h"
+#include "imstkCylinder.h"
+#include "imstkDecal.h"
+#include "imstkOrientedBox.h"
+#include "imstkPlane.h"
+#include "imstkSphere.h"
+
+class CapsuleRenderTest : public RenderTest
+{
+  void createGeometry() override
+  {
+    geom = std::make_shared<Capsule>();
+  }
+};
+TEST_F(CapsuleRenderTest, createCapsule)
+{
+    runAllMaterials();
+}
+
+class CylinderRenderTest : public RenderTest
+{
+  void createGeometry() override
+  {
+    geom = std::make_shared<Cylinder>();
+  }
+};
+TEST_F(CylinderRenderTest, createCylinder)
+{
+  runAllMaterials();
+}
+
+class OrientedBoxRenderTest : public RenderTest
+{
+  void createGeometry() override
+  {
+    geom = std::make_shared<OrientedBox>();
+  }
+};
+TEST_F(OrientedBoxRenderTest, createOrientedBox)
+{
+  runAllMaterials();
+}
+
+class PlaneRenderTest : public RenderTest
+{
+  void createGeometry() override
+  {
+    geom = std::make_shared<Plane>();
+  }
+};
+TEST_F(PlaneRenderTest, createPlane)
+{
+  runAllMaterials();
+}
+
+class SphereRenderTest : public RenderTest
+{
+  void createGeometry() override
+  {
+    geom = std::make_shared<Sphere>();
+  }
+};
+TEST_F(SphereRenderTest, createSphere)
+{
+  runAllMaterials();
+}
\ No newline at end of file
diff --git a/Source/Rendering/Testing/imstkRenderSurfaceMeshTest.cpp b/Source/Rendering/Testing/imstkRenderSurfaceMeshTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5467328a9a5eb5a744bb699014bfa28923bf5258
--- /dev/null
+++ b/Source/Rendering/Testing/imstkRenderSurfaceMeshTest.cpp
@@ -0,0 +1,220 @@
+/*=========================================================================
+
+   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 "imstkRenderTest.h"
+
+#include "imstkEventObject.h"
+#include "imstkLogger.h"
+#include "imstkMeshIO.h"
+#include "imstkSurfaceMesh.h"
+#include "imstkVecDataArray.h"
+
+class MeshFileRenderTest : public RenderTest
+{
+public:
+
+  void createGeometry() override
+  {
+      geom = MeshIO::read(iMSTK_DATA_ROOT "/textured_organs/heart.obj");
+      geom->scale(0.15, Geometry::TransformType::ConcatenateToTransform);
+  }
+};
+TEST_F(MeshFileRenderTest, meshFile)
+{
+  runAllMaterials();
+}
+
+class MeshColorFunctionVerticesRenderTest : public RenderTest
+{
+public:
+
+  void createGeometry() override
+  {
+    imstk::VecDataArray<double, 3> points;
+    auto scalars = std::make_shared<imstk::DataArray<float>>();
+
+    for (int i = 0; i < 6; ++i)
+    {
+      points.push_back({ 0, 0, static_cast<double>(i) });
+      scalars->push_back(i);
+      points.push_back({ 1, 0, static_cast<double>(i) });
+      scalars->push_back(i);
+    }
+
+    auto mesh = std::make_shared<imstk::SurfaceMesh>();
+    geom = mesh;
+
+    imstk::VecDataArray<int, 3> tris;
+    for (int i = 0; i < 5; ++i)
+    {
+      int j = i * 2;
+      tris.push_back({ j + 2, j + 1, j });
+      tris.push_back({ j + 3, j + 1, j + 2 });
+    }
+
+    mesh->initialize(std::make_shared<VecDataArray<double, 3>>(points), std::make_shared<VecDataArray<int, 3>>(tris));
+    mesh->setVertexAttribute("scalars", scalars);
+    mesh->setVertexScalars("scalars");
+
+    std::shared_ptr<imstk::AbstractDataArray> abstracScalars = scalars;
+
+    float val = 0.0;
+    auto  onPreUpdate = [scalars, abstracScalars, &val](Event*) 
+    {
+      if (val < 6.0)
+      {
+        val += 0.05;
+      }
+      else
+      {
+        val = 0.0;
+      }
+      (*scalars)[0] = val;
+      (*scalars)[1] = val;
+      (*scalars)[2] = val;
+      (*scalars)[3] = val;
+      abstracScalars->postModified();
+    };
+
+    connect<Event>(viewer, VTKViewer::preUpdate, onPreUpdate);
+    onPreUpdate(nullptr);
+    applyColorFunction();
+
+    scene->getActiveCamera()->setPosition(Vec3d(0, 12, 3));
+    scene->getActiveCamera()->setFocalPoint(Vec3d(0, 0, 3.01));
+  }
+};
+TEST_F(MeshColorFunctionVerticesRenderTest, meshColorFunctionVertices)
+{
+    runFor(2);
+}
+
+class MeshColorFunctionDynamicVerticesRenderTest : public RenderTest
+{
+public:
+
+  void createGeometry() override
+  {
+    auto mesh = std::make_shared<imstk::SurfaceMesh>();
+    auto points = std::make_shared<imstk::VecDataArray<double, 3>>();
+    auto tris = std::make_shared<imstk::VecDataArray<int, 3>>();
+    auto scalars = std::make_shared<imstk::DataArray<float>>();
+    mesh->initialize(points, tris);
+    geom = mesh;
+
+    double scale = 1.0;
+    auto   updateMesh = [mesh, &scale](Event*)
+    {
+      scale += 0.01;
+      auto points = std::make_shared<imstk::VecDataArray<double, 3>>();
+      auto tris = std::make_shared<imstk::VecDataArray<int, 3>>();
+      auto scalars = std::make_shared<imstk::DataArray<float>>();
+      mesh->clear();
+      for (int i = 0; i < 6; ++i)
+      {
+        points->push_back({ 0, 0, static_cast<double>(i) });
+        scalars->push_back(i);
+        points->push_back({ 1 * scale, 0, static_cast<double>(i) });
+        scalars->push_back(i);
+      }
+
+      for (int i = 0; i < 5; ++i)
+      {
+        int j = i * 2;
+        tris->push_back({ j + 2, j + 1, j });
+        tris->push_back({ j + 3, j + 1, j + 2 });
+      }
+
+      mesh->initialize(points, tris);
+      mesh->setVertexAttribute("scalars", scalars);
+      mesh->setVertexScalars("scalars");
+      mesh->computeVertexNormals();
+      mesh->postModified();
+    };
+
+    connect<Event>(viewer, VTKViewer::preUpdate, updateMesh);
+    updateMesh(nullptr);
+    applyColorFunction();
+
+    scene->getActiveCamera()->setPosition(Vec3d(0, 12, 3));
+    scene->getActiveCamera()->setFocalPoint(Vec3d(0, 0, 3.01));
+  }
+};
+TEST_F(MeshColorFunctionDynamicVerticesRenderTest, meshColorFunctionDynamicVertices)
+{
+    runFor(2);
+}
+
+class MeshColorFunctionDynamicCellsRenderTest : public RenderTest
+{
+public:
+
+  void createGeometry() override
+  {
+    auto mesh    = std::make_shared<imstk::SurfaceMesh>();
+    auto points  = std::make_shared<imstk::VecDataArray<double, 3>>();
+    auto tris    = std::make_shared<imstk::VecDataArray<int, 3>>();
+    auto scalars = std::make_shared<imstk::DataArray<float>>();
+    mesh->initialize(points, tris);
+    geom = mesh;
+
+    double scale      = 1.0;
+    auto   updateMesh = [mesh, &scale](Event*)
+    {
+        scale += 0.01;
+        auto points  = std::make_shared<imstk::VecDataArray<double, 3>>();
+        auto tris    = std::make_shared<imstk::VecDataArray<int, 3>>();
+        auto scalars = std::make_shared<imstk::DataArray<float>>();
+        mesh->clear();
+        for (int i = 0; i < 6; ++i)
+        {
+            points->push_back({ 0, 0, static_cast<double>(i) });
+            points->push_back({ 1, 0, static_cast<double>(i) });
+        }
+
+        for (int i = 0; i < 5; ++i)
+        {
+            int j = i * 2;
+            tris->push_back({ j + 2, j + 1, j });
+            scalars->push_back(i);
+            tris->push_back({ j + 3, j + 1, j + 2 });
+            scalars->push_back(i);
+        }
+
+        mesh->initialize(points, tris);
+        mesh->setCellAttribute("scalars", scalars);
+        mesh->setCellScalars("scalars");
+        mesh->computeVertexNormals();
+        mesh->postModified();
+    };
+
+    connect<Event>(viewer, viewer->preUpdate, updateMesh);
+    updateMesh(nullptr);
+    applyColorFunction();
+
+    scene->getActiveCamera()->setPosition(Vec3d(0, 12, 3));
+    scene->getActiveCamera()->setFocalPoint(Vec3d(0, 0, 3.01));
+  }
+};
+TEST_F(MeshColorFunctionDynamicCellsRenderTest, meshColorFunctionDynamicCells)
+{
+    runFor(2);
+}
diff --git a/Source/Rendering/Testing/imstkRenderTest.cpp b/Source/Rendering/Testing/imstkRenderTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0b21f597440ea5ad107f0bca44813eb2f70d4083
--- /dev/null
+++ b/Source/Rendering/Testing/imstkRenderTest.cpp
@@ -0,0 +1,235 @@
+/*=========================================================================
+
+   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 "imstkRenderTest.h"
+
+#include "imstkColorFunction.h"
+
+void RenderTest::SetUp()
+{
+  scene = std::make_shared<Scene>("Render Test Scene");
+  scene->getActiveCamera()->setPosition(Vec3d(0.0, 1.0, -3.0));
+
+  viewer = std::make_shared<VTKViewer>("Viewer");
+  viewer->setActiveScene(scene);
+
+  // Setup a scene manager to advance the scene in its own thread
+  sceneManager = std::make_shared<SceneManager>("Scene Manager");
+  sceneManager->setExecutionType(Module::ExecutionType::ADAPTIVE);
+  sceneManager->setActiveScene(scene);
+
+  driver = std::make_shared<SimulationManager>();
+  driver->addModule(viewer);
+  driver->addModule(sceneManager);
+
+  mouseControl = std::make_shared<MouseSceneControl>(viewer->getMouseDevice());
+  mouseControl->setSceneManager(sceneManager);
+  viewer->addControl(mouseControl);
+
+  keyControl = std::make_shared<KeyboardSceneControl>(viewer->getKeyboardDevice());
+  keyControl->setSceneManager(sceneManager);
+  keyControl->setModuleDriver(driver);
+  viewer->addControl(keyControl);
+
+  renderMaterial = std::make_shared<RenderMaterial>();
+
+  createGeometry();
+
+  ASSERT_TRUE(geom != nullptr) << "ERROR: No geometry";
+
+  visualModel = std::make_shared<VisualModel>(geom);
+  visualModel->setRenderMaterial(renderMaterial);
+
+  sceneObj = std::make_shared<SceneObject>("SceneObject");
+  sceneObj->addVisualModel(visualModel);
+  scene->addSceneObject(sceneObj);
+
+  driver->requestStatus(ModuleDriverRunning);
+}
+
+void RenderTest::runFor(int seconds)
+{
+  std::thread t(&SimulationManager::start, driver);
+  std::this_thread::sleep_for(std::chrono::seconds(seconds));
+  driver->requestStatus(ModuleDriverStopped);
+  t.join();
+}
+
+void RenderTest::runAllMaterials()
+{
+  complete = false;
+  displayMode = 0;
+  color = 0;
+  shadingModel = 0;
+  blendMode = 0;
+  updateMaterial();
+  connect<Event>(sceneManager, &SceneManager::postUpdate, [&](Event*)
+  {
+    double Dt = sceneManager->getDt();
+    elapsedTime += Dt;
+    if (elapsedTime > 0.05)
+    {
+      elapsedTime = 0;
+      updateMaterial();
+    }
+    geom->rotate(Vec3d(0.0, 1.0, 0.0), PI * Dt);
+    geom->postModified();
+  });
+
+  std::thread t(&SimulationManager::start, driver);
+  while (!complete)
+    std::this_thread::sleep_for(std::chrono::seconds(1));
+  driver->requestStatus(ModuleDriverStopped);
+  t.join();
+}
+
+void RenderTest::applyColorFunction()
+{
+  std::shared_ptr<ColorFunction> colorFunc = std::make_shared<ColorFunction>();
+  colorFunc->setNumberOfColors(3);
+  colorFunc->setColor(0, imstk::Color::Green);
+  colorFunc->setColor(1, imstk::Color::Blue);
+  colorFunc->setColor(2, imstk::Color::Red);
+  colorFunc->setColorSpace(imstk::ColorFunction::ColorSpace::RGB);
+  colorFunc->setRange(0, 6);
+
+  renderMaterial->setScalarVisibility(true);
+  renderMaterial->setColorLookupTable(colorFunc);
+}
+
+void RenderTest::updateMaterial()
+{
+  switch (displayMode)
+  {
+  case 0:
+    renderMaterial->setDisplayMode(RenderMaterial::DisplayMode::Surface);
+    dm = "Surface ";
+    break;
+  case 1:
+    renderMaterial->setDisplayMode(RenderMaterial::DisplayMode::Wireframe);
+    dm = "Wireframe ";
+    break;
+  case 2:
+    renderMaterial->setDisplayMode(RenderMaterial::DisplayMode::Points);
+    dm = "Points ";
+    break;
+  case 3:
+    renderMaterial->setDisplayMode(RenderMaterial::DisplayMode::WireframeSurface);
+    dm = "WireframeSurface ";
+    break;
+  case 4:
+    renderMaterial->setDisplayMode(RenderMaterial::DisplayMode::VolumeRendering);
+    dm = "VolumeRendering ";
+    break;
+  case 5:
+    renderMaterial->setDisplayMode(RenderMaterial::DisplayMode::Fluid);
+    dm = "Fluid ";
+    break;
+  case 6:
+    renderMaterial->setDisplayMode(RenderMaterial::DisplayMode::Image);
+    dm = "Image ";
+    break;
+  case 7:
+    renderMaterial->setDisplayMode(RenderMaterial::DisplayMode::SurfaceNormals);
+    dm = "SurfaceNormals ";
+    break;
+  }
+
+  switch (color)
+  {
+  case 0:
+    renderMaterial->setColor(Color::Blue);
+    c = "Blue ";
+    break;
+  case 1:
+    renderMaterial->setColor(Color::Green);
+    c = "Green ";
+    break;
+  case 2:
+    renderMaterial->setColor(Color::Red);
+    c = "Red ";
+    break;
+  }
+
+  switch (shadingModel)
+  {
+  case 0:
+    renderMaterial->setShadingModel(RenderMaterial::ShadingModel::None);
+    sm = "None ";
+    break;
+  case 1:
+    renderMaterial->setShadingModel(RenderMaterial::ShadingModel::Phong);
+    sm = "Phong ";
+    break;
+  case 2:
+    renderMaterial->setShadingModel(RenderMaterial::ShadingModel::Gouraud);
+    sm = "Gouraud ";
+    break;
+  case 3:
+    renderMaterial->setShadingModel(RenderMaterial::ShadingModel::Flat);
+    sm = "Flat ";
+    break;
+  case 4:
+    renderMaterial->setShadingModel(RenderMaterial::ShadingModel::PBR);
+    sm = "PBR ";
+    break;
+  }
+
+  switch (blendMode)
+  {
+  case 0:
+    renderMaterial->setBlendMode(RenderMaterial::BlendMode::Alpha);
+    bm = "Alpha ";
+    break;
+  case 1:
+    renderMaterial->setBlendMode(RenderMaterial::BlendMode::Additive);
+    bm = "Additive ";
+    break;
+  case 2:
+    renderMaterial->setBlendMode(RenderMaterial::BlendMode::MaximumIntensity);
+    bm = "MaximumIntensity ";
+    break;
+  case 3:
+    renderMaterial->setBlendMode(RenderMaterial::BlendMode::MinimumIntensity);
+    bm = "MinimumIntensity ";
+    break;
+  }
+
+  std::cout << "DisplayMode=" << dm << " Color=" << c << " Shading Model=" << sm << " Blend Mode=" << bm << "\n";
+  blendMode++;
+  if (blendMode == 4)
+  {
+    blendMode = 0;
+    shadingModel++;
+  }
+  if (shadingModel == 5)
+  {
+    shadingModel = 0;
+    color++;
+  }
+  if (color == 1)// Only check one color
+  {
+    color = 0;
+    displayMode++;
+  }
+  if (displayMode == 8)
+    complete = true;
+}
diff --git a/Source/Rendering/Testing/imstkRenderTest.h b/Source/Rendering/Testing/imstkRenderTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..9b1c9cfa96067ccabdc7340237df36540a9f199f
--- /dev/null
+++ b/Source/Rendering/Testing/imstkRenderTest.h
@@ -0,0 +1,80 @@
+/*=========================================================================
+
+   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.
+
+=========================================================================*/
+
+#pragma once
+
+#include "gtest/gtest.h"
+
+#include <memory>
+
+#include "imstkCamera.h"
+#include "imstkDirectionalLight.h"
+#include "imstkGeometry.h"
+#include "imstkKeyboardSceneControl.h"
+#include "imstkMouseSceneControl.h"
+#include "imstkRenderMaterial.h"
+#include "imstkScene.h"
+#include "imstkSceneObject.h"
+#include "imstkSceneManager.h"
+#include "imstkSimulationManager.h"
+#include "imstkVisualModel.h"
+#include "imstkVTKViewer.h"
+
+using namespace imstk;
+
+class RenderTest : public testing::Test
+{
+public:
+    void runFor(int seconds);
+    void runAllMaterials();
+protected:
+
+    void SetUp() override;
+
+    virtual void createGeometry()=0;
+
+    void updateMaterial();
+
+    void applyColorFunction();
+
+    // Render Frame
+    std::shared_ptr<Scene>                scene;
+    std::shared_ptr<VTKViewer>            viewer;
+    std::shared_ptr<SceneManager>         sceneManager;
+    std::shared_ptr<SimulationManager>    driver;
+    std::shared_ptr<MouseSceneControl>    mouseControl;
+    std::shared_ptr<KeyboardSceneControl> keyControl;
+    std::shared_ptr<DirectionalLight>     light;
+
+    // Render Contents
+    std::shared_ptr<Geometry>             geom;
+    std::shared_ptr<RenderMaterial>       renderMaterial;
+    std::shared_ptr<VisualModel>          visualModel;
+    std::shared_ptr<SceneObject>          sceneObj;
+
+    double elapsedTime = 0;
+    bool   complete=false;
+    int    displayMode;
+    int    color;
+    int    shadingModel;
+    int    blendMode;
+    std::string dm, c, sm, bm;
+};
\ No newline at end of file
diff --git a/Source/Rendering/Testing/imstkTetrahedralMeshRenderTest.cpp b/Source/Rendering/Testing/imstkRenderTetrahedralMeshTest.cpp
similarity index 71%
rename from Source/Rendering/Testing/imstkTetrahedralMeshRenderTest.cpp
rename to Source/Rendering/Testing/imstkRenderTetrahedralMeshTest.cpp
index 628062e2bcddb37bf3c2309bdfca4c2dc7459407..eb19460bef2e579738f6ce352d4d41237d0629db 100644
--- a/Source/Rendering/Testing/imstkTetrahedralMeshRenderTest.cpp
+++ b/Source/Rendering/Testing/imstkRenderTetrahedralMeshTest.cpp
@@ -19,18 +19,16 @@
 
 =========================================================================*/
 
-#include "imstkSetupRenderTest.h"
+#include "imstkRenderTest.h"
 
 #include "imstkTetrahedralMesh.h"
 #include "imstkVecDataArray.h"
 
-class TetrahedralMeshRenderTest : public RenderTest { };
-
-TEST_F(TetrahedralMeshRenderTest, createTetrahedralMesh)
+class TetrahedralMeshRenderTest : public RenderTest
 {
-    ASSERT_TRUE(scene != nullptr) << "ERROR: Unable to create scene object";
-
-    auto geom = std::make_shared<TetrahedralMesh>();
+  void createGeometry() override
+  {
+    geom = std::make_shared<TetrahedralMesh>();
 
     auto verticesPtr = std::make_shared<VecDataArray<double, 3>>(4);
     auto indicesPtr = std::make_shared<VecDataArray<int, 4>>(1);
@@ -38,16 +36,17 @@ TEST_F(TetrahedralMeshRenderTest, createTetrahedralMesh)
     VecDataArray<double, 3>& vertices = *verticesPtr;
     VecDataArray<int, 4>& indices = *indicesPtr;
 
-    vertices[0] = Vec3d(0.5, 0.5, -0.5);
-    vertices[1] = Vec3d(0.5, -0.5, -0.5);
-    vertices[2] = Vec3d(-0.5, -0.5, -0.5);
-    vertices[3] = Vec3d(0.5, -0.5, 0.5);
+    vertices[0] = Vec3d(-0.5, 0.0, -0.5);
+    vertices[1] = Vec3d(0.5, 0.0, -0.5);
+    vertices[2] = Vec3d(0.0, 0.0, 0.75);
+    vertices[3] = Vec3d(0.0, 0.5, 0.0);
 
     indices[0] = Vec4i(0, 1, 2, 3);
 
-    geom->initialize(verticesPtr, indicesPtr);
-
-    addGeometry(geom, Color::Blood);
-
-    run_for(driver.get(), 2);
+    std::dynamic_pointer_cast<TetrahedralMesh>(geom)->initialize(verticesPtr, indicesPtr);
+  }
+};
+TEST_F(TetrahedralMeshRenderTest, createTetrahedralMesh)
+{
+  runAllMaterials();
 }
\ No newline at end of file
diff --git a/Source/Rendering/Testing/imstkSetupRenderTest.h b/Source/Rendering/Testing/imstkSetupRenderTest.h
deleted file mode 100644
index 785b75634e16f062dceb8cf53a1b6634c6a8e0c1..0000000000000000000000000000000000000000
--- a/Source/Rendering/Testing/imstkSetupRenderTest.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*=========================================================================
-
-   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.
-
-=========================================================================*/
-
-#pragma once
-
-#include "gtest/gtest.h"
-
-#include <memory>
-
-#include "imstkCamera.h"
-#include "imstkDirectionalLight.h"
-#include "imstkGeometry.h"
-#include "imstkKeyboardSceneControl.h"
-#include "imstkMouseSceneControl.h"
-#include "imstkRenderMaterial.h"
-#include "imstkScene.h"
-#include "imstkSceneObject.h"
-#include "imstkSceneManager.h"
-#include "imstkSimulationManager.h"
-#include "imstkVisualModel.h"
-#include "imstkVTKViewer.h"
-
-using namespace imstk;
-
-namespace
-{
-void
-run_for(SimulationManager* driver, int i)
-{
-    std::thread t(&SimulationManager::start, driver);
-
-    std::this_thread::sleep_for(std::chrono::seconds(i));
-
-    driver->requestStatus(ModuleDriverStopped);
-    t.join();
-}
-}
-
-class RenderTest : public testing::Test
-{
-public:
-
-    void SetUp() override
-    {
-        scene  = std::make_shared<Scene>("Render Test Scene");
-        viewer = std::make_shared<VTKViewer>("Viewer");
-        viewer->setActiveScene(scene);
-
-        // Setup a scene manager to advance the scene in its own thread
-        sceneManager = std::make_shared<SceneManager>("Scene Manager");
-        sceneManager->setActiveScene(scene);
-
-        driver = std::make_shared<SimulationManager>();
-        driver->addModule(viewer);
-        driver->addModule(sceneManager);
-
-        mouseControl = std::make_shared<MouseSceneControl>(viewer->getMouseDevice());
-        mouseControl->setSceneManager(sceneManager);
-        viewer->addControl(mouseControl);
-
-        keyControl = std::make_shared<KeyboardSceneControl>(viewer->getKeyboardDevice());
-        keyControl->setSceneManager(sceneManager);
-        keyControl->setModuleDriver(driver);
-        viewer->addControl(keyControl);
-
-        driver->requestStatus(ModuleDriverRunning);
-    }
-
-    void addGeometry(std::shared_ptr<Geometry> geom, Color color)
-    {
-      scene->getActiveCamera()->setPosition(Vec3d(3.0, 5.0, 3.0));
-      auto light = std::make_shared<DirectionalLight>();
-      light->setDirection(Vec3d(5.0, -8.0, -5.0));
-      light->setIntensity(1.0);
-      scene->addLight("light", light);
-
-      geom->scale(0.5, Geometry::TransformType::ConcatenateToTransform);
-      geom->rotate(Vec3d(0.0, 1.0, 0), PI_2, Geometry::TransformType::ConcatenateToTransform);
-      geom->translate(Vec3d(0.0, 0.0, 0.0), Geometry::TransformType::ConcatenateToTransform);
-
-      auto renderMaterial = std::make_shared<RenderMaterial>();
-      renderMaterial->setColor(color);
-      renderMaterial->setDisplayMode(RenderMaterial::DisplayMode::WireframeSurface);
-      renderMaterial->setPointSize(6.0);
-      renderMaterial->setLineWidth(4.0);
-
-      auto visualModel = std::make_shared<VisualModel>(geom);
-      visualModel->setRenderMaterial(renderMaterial);
-
-      auto sceneObj = std::make_shared<SceneObject>("SceneObject");
-      sceneObj->addVisualModel(visualModel);
-      scene->addSceneObject(sceneObj);
-    }
-
-    std::shared_ptr<Scene>                scene;
-    std::shared_ptr<VTKViewer>            viewer;
-    std::shared_ptr<SceneManager>         sceneManager;
-    std::shared_ptr<SimulationManager>    driver;
-    std::shared_ptr<MouseSceneControl>    mouseControl;
-    std::shared_ptr<KeyboardSceneControl> keyControl;
-};
\ No newline at end of file
diff --git a/Source/Rendering/Testing/imstkSurfaceMeshRenderTest.cpp b/Source/Rendering/Testing/imstkSurfaceMeshRenderTest.cpp
deleted file mode 100644
index 138aeaa93c37394e8bffa1243f39bdce62bb0da3..0000000000000000000000000000000000000000
--- a/Source/Rendering/Testing/imstkSurfaceMeshRenderTest.cpp
+++ /dev/null
@@ -1,326 +0,0 @@
-/*=========================================================================
-
-   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 "imstkSetupRenderTest.h"
-
-#include "imstkColorFunction.h"
-#include "imstkEventObject.h"
-#include "imstkLogger.h"
-#include "imstkMeshIO.h"
-#include "imstkSurfaceMesh.h"
-#include "imstkVecDataArray.h"
-
-class MeshRenderTest : public RenderTest {};
-
-namespace
-{
-std::shared_ptr<RenderMaterial>
-makeMaterial()
-{
-    std::shared_ptr<ColorFunction> colorFunc = std::make_shared<ColorFunction>();
-    colorFunc->setNumberOfColors(3);
-    colorFunc->setColor(0, imstk::Color::Green);
-    colorFunc->setColor(1, imstk::Color::Blue);
-    colorFunc->setColor(2, imstk::Color::Red);
-    colorFunc->setColorSpace(imstk::ColorFunction::ColorSpace::RGB);
-    colorFunc->setRange(0, 6);
-
-    auto material = std::make_shared<imstk::RenderMaterial>();
-    material->setScalarVisibility(true);
-    material->setColorLookupTable(colorFunc);
-    return material;
-}
-
-std::shared_ptr<SceneObject>
-createAndAddMeshSceneObject(std::shared_ptr<Scene> scene,
-                              const std::string&     fileName,
-                              const std::string&     objectName)
-{
-    CHECK(scene != nullptr) << "Error: Scene object supplied is not valid!";
-    CHECK(!fileName.empty()) << "Error: Name is empty!";
-
-    auto mesh = MeshIO::read(fileName);
-    auto SurfaceMesh = std::dynamic_pointer_cast<imstk::SurfaceMesh>(mesh);
-
-    // Create object and add to scene
-    auto meshSceneObject = std::make_shared<SceneObject>("meshObject");
-    meshSceneObject->setVisualGeometry(SurfaceMesh);
-    meshSceneObject->setName(objectName);
-    scene->addSceneObject(meshSceneObject);
-
-    return meshSceneObject;
-}
-}
-
-TEST_F(RenderTest, plainMesh)
-{
-    auto sceneObj = createAndAddMeshSceneObject(scene, iMSTK_DATA_ROOT "/textured_organs/heart.obj", "Heart");
-
-    ASSERT_TRUE(sceneObj != nullptr) << "ERROR: Unable to create scene object";
-
-    run_for(driver.get(), 2);
-}
-
-TEST_F(MeshRenderTest, meshMaterial)
-{
-    auto sceneObj = createAndAddMeshSceneObject(scene, iMSTK_DATA_ROOT "/textured_organs/heart.obj", "Heart");
-
-    std::shared_ptr<RenderMaterial> material = std::make_shared<RenderMaterial>();
-    material->setDisplayMode(RenderMaterial::DisplayMode::Wireframe);
-    material->setPointSize(6.0);
-    material->setLineWidth(4.0);
-    sceneObj->getVisualModel(0)->setRenderMaterial(material);
-
-    ASSERT_TRUE(sceneObj != nullptr) << "ERROR: Unable to create scene object";
-
-    run_for(driver.get(), 2);
-}
-
-TEST_F(MeshRenderTest, materialColorFunctionVertices)
-{
-    imstk::VecDataArray<double, 3> points;
-    auto                           scalars = std::make_shared<imstk::DataArray<float>>();
-
-    for (int i = 0; i < 6; ++i)
-    {
-        points.push_back({ 0, 0, static_cast<double>(i) });
-        scalars->push_back(i);
-        points.push_back({ 1, 0, static_cast<double>(i) });
-        scalars->push_back(i);
-    }
-
-    auto mesh = std::make_shared<imstk::SurfaceMesh>();
-
-    imstk::VecDataArray<int, 3> tris;
-    for (int i = 0; i < 5; ++i)
-    {
-        int j = i * 2;
-        tris.push_back({ j + 2, j + 1, j });
-        tris.push_back({ j + 3, j + 1, j + 2 });
-    }
-
-    mesh->initialize(std::make_shared<VecDataArray<double, 3>>(points), std::make_shared<VecDataArray<int, 3>>(tris));
-    mesh->setVertexAttribute("scalars", scalars);
-    mesh->setVertexScalars("scalars");
-
-    auto visualModel = std::make_shared<VisualModel>(mesh);
-
-    std::shared_ptr<imstk::AbstractDataArray> abstracScalars = scalars;
-
-    float val = 0.0;
-    auto  onPreUpdate = [scalars, abstracScalars, &val](Event*) {
-                            if (val < 6.0)
-                            {
-                                val += 0.05;
-                            }
-                            else
-                            {
-                                val = 0.0;
-                            }
-                            (*scalars)[0] = val;
-                            (*scalars)[1] = val;
-                            (*scalars)[2] = val;
-                            (*scalars)[3] = val;
-                            abstracScalars->postModified();
-                        };
-
-    connect<Event>(viewer, VTKViewer::preUpdate, onPreUpdate);
-    onPreUpdate(nullptr);
-
-    visualModel->setRenderMaterial(makeMaterial());
-
-    auto sceneObj = std::make_shared<SceneObject>("plains");
-    sceneObj->addVisualModel(visualModel);
-    scene->addSceneObject(sceneObj);
-
-    scene->getActiveCamera()->setPosition(Vec3d(0, 12, 3));
-    scene->getActiveCamera()->setFocalPoint(Vec3d(0, 0, 3.01));
-
-    run_for(driver.get(), 2);
-}
-
-TEST_F(MeshRenderTest, materialColorFunctionCells)
-{
-    imstk::VecDataArray<double, 3> points;
-    auto                           scalars = std::make_shared<imstk::DataArray<float>>();
-
-    for (int i = 0; i < 6; ++i)
-    {
-        points.push_back({ 0, 0, static_cast<double>(i) });
-        points.push_back({ 1, 0, static_cast<double>(i) });
-    }
-
-    imstk::SurfaceMesh mesh;
-
-    imstk::VecDataArray<int, 3> tris;
-    for (int i = 0; i < 5; ++i)
-    {
-        int j = i * 2;
-        tris.push_back({ j + 2, j + 1, j });
-        scalars->push_back(i);
-        tris.push_back({ j + 3, j + 1, j + 2 });
-        scalars->push_back(i);
-    }
-    mesh.initialize(std::make_shared<VecDataArray<double, 3>>(points), std::make_shared<VecDataArray<int, 3>>(tris));
-    mesh.setCellAttribute("scalars", scalars);
-    mesh.setCellScalars("scalars");
-
-    float val = 0.0;
-    auto  onPreUpdate = [scalars, &val](Event*) {
-                            if (val < 6.0)
-                            {
-                                val += 0.05;
-                            }
-                            else
-                            {
-                                val = 0.0;
-                            }
-                            (*scalars)[0] = val;
-                            (*scalars)[1] = val;
-                            (*scalars)[2] = val;
-                            (*scalars)[3] = val;
-                            scalars->postModified();
-                        };
-
-    connect<Event>(viewer, VTKViewer::preUpdate, onPreUpdate);
-    onPreUpdate(nullptr);
-
-    auto visualModel = std::make_shared<VisualModel>(std::make_shared<SurfaceMesh>(mesh));
-    visualModel->setRenderMaterial(makeMaterial());
-
-    auto sceneObj = std::make_shared<SceneObject>("plains");
-    sceneObj->addVisualModel(visualModel);
-    scene->addSceneObject(sceneObj);
-
-    scene->getActiveCamera()->setPosition(Vec3d(0, 12, 3));
-    scene->getActiveCamera()->setFocalPoint(Vec3d(0, 0, 3.01));
-
-    run_for(driver.get(), 2);
-}
-
-TEST_F(MeshRenderTest, materialColorFunctionDynamicVertices)
-{
-    auto mesh    = std::make_shared<imstk::SurfaceMesh>();
-    auto points  = std::make_shared<imstk::VecDataArray<double, 3>>();
-    auto tris    = std::make_shared<imstk::VecDataArray<int, 3>>();
-    auto scalars = std::make_shared<imstk::DataArray<float>>();
-    mesh->initialize(points, tris);
-
-    double scale      = 1.0;
-    auto   updateMesh = [mesh, &scale](Event*)
-                        {
-                            scale += 0.01;
-                            auto points  = std::make_shared<imstk::VecDataArray<double, 3>>();
-                            auto tris    = std::make_shared<imstk::VecDataArray<int, 3>>();
-                            auto scalars = std::make_shared<imstk::DataArray<float>>();
-                            mesh->clear();
-                            for (int i = 0; i < 6; ++i)
-                            {
-                                points->push_back({ 0, 0, static_cast<double>(i) });
-                                scalars->push_back(i);
-                                points->push_back({ 1 * scale, 0, static_cast<double>(i) });
-                                scalars->push_back(i);
-                            }
-
-                            for (int i = 0; i < 5; ++i)
-                            {
-                                int j = i * 2;
-                                tris->push_back({ j + 2, j + 1, j });
-                                tris->push_back({ j + 3, j + 1, j + 2 });
-                            }
-
-                            mesh->initialize(points, tris);
-                            mesh->setVertexAttribute("scalars", scalars);
-                            mesh->setVertexScalars("scalars");
-                            mesh->computeVertexNormals();
-                            mesh->postModified();
-                        };
-
-    connect<Event>(viewer, VTKViewer::preUpdate, updateMesh);
-
-    auto visualModel = std::make_shared<VisualModel>(mesh);
-    updateMesh(nullptr);
-
-    visualModel->setRenderMaterial(makeMaterial());
-
-    auto sceneObj = std::make_shared<SceneObject>("plains");
-    sceneObj->addVisualModel(visualModel);
-    scene->addSceneObject(sceneObj);
-
-    scene->getActiveCamera()->setPosition(Vec3d(0, 12, 3));
-    scene->getActiveCamera()->setFocalPoint(Vec3d(0, 0, 3.01));
-
-    run_for(driver.get(), 2);
-}
-
-TEST_F(MeshRenderTest, materialColorFunctionDynamicCells)
-{
-    auto mesh    = std::make_shared<imstk::SurfaceMesh>();
-    auto points  = std::make_shared<imstk::VecDataArray<double, 3>>();
-    auto tris    = std::make_shared<imstk::VecDataArray<int, 3>>();
-    auto scalars = std::make_shared<imstk::DataArray<float>>();
-    mesh->initialize(points, tris);
-
-    double scale      = 1.0;
-    auto   updateMesh = [mesh, &scale](Event*)
-                        {
-                            scale += 0.01;
-                            auto points  = std::make_shared<imstk::VecDataArray<double, 3>>();
-                            auto tris    = std::make_shared<imstk::VecDataArray<int, 3>>();
-                            auto scalars = std::make_shared<imstk::DataArray<float>>();
-                            mesh->clear();
-                            for (int i = 0; i < 6; ++i)
-                            {
-                                points->push_back({ 0, 0, static_cast<double>(i) });
-                                points->push_back({ 1, 0, static_cast<double>(i) });
-                            }
-
-                            for (int i = 0; i < 5; ++i)
-                            {
-                                int j = i * 2;
-                                tris->push_back({ j + 2, j + 1, j });
-                                scalars->push_back(i);
-                                tris->push_back({ j + 3, j + 1, j + 2 });
-                                scalars->push_back(i);
-                            }
-
-                            mesh->initialize(points, tris);
-                            mesh->setCellAttribute("scalars", scalars);
-                            mesh->setCellScalars("scalars");
-                            mesh->computeVertexNormals();
-                            mesh->postModified();
-                        };
-
-    connect<Event>(viewer, viewer->preUpdate, updateMesh);
-
-    auto visualModel = std::make_shared<VisualModel>(mesh);
-    updateMesh(nullptr);
-    visualModel->setRenderMaterial(makeMaterial());
-
-    auto sceneObj = std::make_shared<SceneObject>("plains");
-    sceneObj->addVisualModel(visualModel);
-    scene->addSceneObject(sceneObj);
-
-    scene->getActiveCamera()->setPosition(Vec3d(0, 12, 3));
-    scene->getActiveCamera()->setFocalPoint(Vec3d(0, 0, 3.01));
-
-    run_for(driver.get(), 2);
-}
\ No newline at end of file