diff --git a/demos/optical_bench/src/Optix Files/laser_caster.cu b/demos/optical_bench/src/Optix Files/laser_caster.cu
index 9f6708342dee674938ddd124155011bbad467224..fe91ede80250788fb22a67591a7008787e0e8138 100644
--- a/demos/optical_bench/src/Optix Files/laser_caster.cu	
+++ b/demos/optical_bench/src/Optix Files/laser_caster.cu	
@@ -4,7 +4,7 @@
 #include "helpers.h"
 #include "random.h"
 
-#define PERCENTILE 4.5f
+#define PERCENTILE 1.47579f
 
 using namespace optix;
 
@@ -38,7 +38,7 @@ RT_PROGRAM void laser_caster(){
 	//convert to normal distrubution
 	float r = sqrtf(-2*log(random.x));
 	float theta = 2*3.141592654f*random.y;
-	random = clamp(make_float2(r*cosf(theta), r*sinf(theta)), -PERCENTILE, PERCENTILE) * laserBeamWidth/PERCENTILE;
+	random = clamp(make_float2(r*cosf(theta), r*sinf(theta)), -4.5f, 4.5f) * laserBeamWidth/PERCENTILE;
 	ray_origin += (launch_index.z != 0) * (laser_right * random.x + laser_up * random.y);
 	
 	PerRayData_radiance_iterative prd;
diff --git a/demos/optical_bench/src/Optix Files/laser_target_material.cu b/demos/optical_bench/src/Optix Files/laser_target_material.cu
index 725c6450d8f0ec4cdcdffcafb2a4a06b74fbdbfe..ae36f57015efc7b28848a0271334092aefe10a81 100644
--- a/demos/optical_bench/src/Optix Files/laser_target_material.cu	
+++ b/demos/optical_bench/src/Optix Files/laser_target_material.cu	
@@ -31,23 +31,11 @@ rtDeclareVariable(float, hit_depth, rtIntersectionDistance, );
 rtDeclareVariable(float, max_power, , );
 rtDeclareVariable(optix::Ray, ray, rtCurrentRay, );
 
-rtBuffer<float, 1> targetBufferMax;
+rtBuffer<unsigned int, 1> targetBufferMax;
 rtBuffer<float, 2> targetBuffer;
 rtDeclareVariable(float2, targetBufferDim, , );
 rtDeclareVariable(int, targetBufferWrite, , );
 
-//thanks stackoverflow!
-__device__ static float atomicMax(float* address, float val){
-    int* address_as_i = (int*) address;
-    int old = *address_as_i, assumed;
-    do {
-        assumed = old;
-        old = ::atomicCAS(address_as_i, assumed,
-            __float_as_int(::fmaxf(val, __int_as_float(assumed))));
-    } while (assumed != old);
-    return __int_as_float(old);
-}
-
 RT_PROGRAM void any_hit_radiance(){ 
 	rtIgnoreIntersection();
 	//prd_radiance.result = make_float3(1.0f, 0.0f, 0.0f);
@@ -62,6 +50,6 @@ RT_PROGRAM void closest_hit_iterative()
 	
 	if(targetBufferWrite && writeable_surface){
 		atomicAdd(&targetBuffer[make_uint2(texture_coord * targetBufferDim)], prd_radiance_it.power);
-		atomicMax(&targetBufferMax[0], targetBuffer[make_uint2(texture_coord * targetBufferDim)]);
+		atomicMax(&targetBufferMax[0], (unsigned int) targetBuffer[make_uint2(texture_coord * targetBufferDim)]);
 	}
 }
diff --git a/demos/optical_bench/src/hmd_navigation_behavior.cpp b/demos/optical_bench/src/hmd_navigation_behavior.cpp
index 1be3dbbcbba24d5db272f8f6b24e22b35605d7e6..530dee2b27e05d2b02d0e929234d5987f0e2562e 100644
--- a/demos/optical_bench/src/hmd_navigation_behavior.cpp
+++ b/demos/optical_bench/src/hmd_navigation_behavior.cpp
@@ -117,7 +117,7 @@ HMDNavigationBehavior::HMDNavigationBehavior(
           ->GetFirstComponent<phx::Transform>());
 
   rotation_helper_ = new RotationHelper(scene);
-  translation_helper_ = new TranslationHelper(scene);
+  translation_helper_ = new TranslationHelper(scene, engine);
 
   // create enitity to attach helpers to when not needed
   empty_holder_ = scene->CreateEntity();
@@ -149,6 +149,7 @@ void HMDNavigationBehavior::OnUpdate() {
       if (!rotation_helper_->SelectablePartOf(select_->GetGrabbed()) &&
           !translation_helper_->SelectablePartOf(select_->GetGrabbed())) {
         setLastSelected(select_->GetGrabbed());
+        grip_mode = 0;  // disable helpers
         updateHelpers();
       }
       trigger_pressed = true;
@@ -214,9 +215,9 @@ void HMDNavigationBehavior::OnUpdate() {
   }
 }
 
-void HMDNavigationBehavior::DeletedObject(){
-	setLastSelected(nullptr);
-	updateHelpers();
+void HMDNavigationBehavior::DeletedObject() {
+  setLastSelected(nullptr);
+  updateHelpers();
 }
 
 void HMDNavigationBehavior::updateHelpers() {
diff --git a/demos/optical_bench/src/laser_menu.cpp b/demos/optical_bench/src/laser_menu.cpp
index e474037630a3a73971fe8bb7bcf2d1022a80447b..4b44457ed7207de2c6d0be354ebabe4e156848c8 100644
--- a/demos/optical_bench/src/laser_menu.cpp
+++ b/demos/optical_bench/src/laser_menu.cpp
@@ -1,6 +1,7 @@
 #include "laser_menu.hpp"
 
 #include "menu_helper.hpp"
+#include "object_manager.hpp"
 #include "ray_pass.hpp"
 #include "selector.hpp"
 #include "text.hpp"
@@ -44,7 +45,8 @@ LaserMenu::LaserMenu(phx::Scene* scene, phx::Engine* engine) {
     }
   }
 
-  MenuHelper::createButtonPairVertical(up_p_, down_p_, text_p_, -0.1f, -0.05f,
+  // Laser Pattern
+  MenuHelper::createButtonPairVertical(up_p_, down_p_, text_p_, -0.022f, -0.05f,
                                        scene, engine, entity_);
   up_p_->SetOnPress([rayPass, this](phx::Transform*, glm::mat4) {
     rayPass->NextLaserPattern();
@@ -56,6 +58,19 @@ LaserMenu::LaserMenu(phx::Scene* scene, phx::Engine* engine) {
   });
   text_p_->SetText(rayPass->GetCurrentPatternName());
 
+  // Target Color
+  MenuHelper::createButtonPairVertical(up_tc_, down_tc_, text_tc_, 0.11f,
+                                       -0.05f, scene, engine, entity_);
+  up_tc_->SetOnPress([rayPass, this](phx::Transform*, glm::mat4) {
+    rayPass->ToggleTargetColorMode();
+    text_tc_->SetText((rayPass->GetTargetColorMode()) ? "Rainbow" : "Grey");
+  });
+  down_tc_->SetOnPress([rayPass, this](phx::Transform*, glm::mat4) {
+    rayPass->ToggleTargetColorMode();
+    text_tc_->SetText((rayPass->GetTargetColorMode()) ? "Rainbow" : "Grey");
+  });
+  text_tc_->SetText((rayPass->GetTargetColorMode()) ? "Rainbow" : "Grey");
+
   // TIR
   switch_tir_ = new MenuSwitch(engine, scene, rayPass->GetRayTIR());
   switch_tir_->SetOnSwitch([this, rayPass](bool a) {
@@ -65,11 +80,11 @@ LaserMenu::LaserMenu(phx::Scene* scene, phx::Engine* engine) {
   switch_tir_->GetTransform()->SetParent(
       entity_->GetFirstComponent<phx::Transform>(), false);
   switch_tir_->GetTransform()->SetLocalTranslation(
-      glm::vec3(0.0f, -0.075f, 0.1f));
+      glm::vec3(0.0f, -0.075f, 0.045f));
 
   auto text_entity = scene->CreateEntity();
   text_entity->AddComponent<phx::Transform>()
-      ->Translate(glm::vec3(-0.001f, -0.05f, 0.1f))
+      ->Translate(glm::vec3(-0.001f, -0.05f, 0.045f))
       .SetLocalRotationEuler(glm::vec3(180, -90, 0))
       .SetParent(entity_->GetFirstComponent<phx::Transform>());
   text_tir_ = text_entity->AddComponent<phx::Text>("", 0.006f);
@@ -77,7 +92,6 @@ LaserMenu::LaserMenu(phx::Scene* scene, phx::Engine* engine) {
   text_tir_->SetGradient(glm::vec4(0), glm::vec4(0));
 
   // target write
-
   switch_tw_ = new MenuSwitch(engine, scene, rayPass->getTargetBufferWrite());
   switch_tw_->SetOnSwitch([this, rayPass](bool a) {
     rayPass->setTargetBufferWrite(a);
@@ -86,11 +100,11 @@ LaserMenu::LaserMenu(phx::Scene* scene, phx::Engine* engine) {
   switch_tw_->GetTransform()->SetParent(
       entity_->GetFirstComponent<phx::Transform>(), false);
   switch_tw_->GetTransform()->SetLocalTranslation(
-      glm::vec3(0.0f, -0.025f, 0.0f));
+      glm::vec3(0.0f, -0.025f, -0.097f));
 
   auto text_entity2 = scene->CreateEntity();
   text_entity2->AddComponent<phx::Transform>()
-      ->Translate(glm::vec3(-0.001f, -0.05f, 0.0f))
+      ->Translate(glm::vec3(-0.001f, -0.05f, -0.097f))
       .SetLocalRotationEuler(glm::vec3(180, -90, 0))
       .SetParent(entity_->GetFirstComponent<phx::Transform>());
   text_tw_ = text_entity2->AddComponent<phx::Text>("", 0.006f);
@@ -104,7 +118,7 @@ LaserMenu::LaserMenu(phx::Scene* scene, phx::Engine* engine) {
   clear_target_->GetTransform()->SetLocalRotationEuler(glm::vec3(0, -90, 90));
   clear_target_->GetTransform()->SetLocalScale(glm::vec3(0.06f, 0.01f, 0.017f));
   clear_target_->GetTransform()->SetLocalTranslation(
-      glm::vec3(0.0f, -0.08f, 0.0f));
+      glm::vec3(0.0f, -0.08f, -0.097f));
   clear_target_->SetImage(phx::ResourceUtils::LoadResourceFromFile<phx::Image>(
       "models/opticalBench/menu/Clear.png"));
   clear_target_->SetHoldable(false);
@@ -112,23 +126,30 @@ LaserMenu::LaserMenu(phx::Scene* scene, phx::Engine* engine) {
     rayPass->clearTargetBuffers();
   });
 
-  //width
-  MenuHelper::createSliderTextPair(scene, engine, slider_width_, text_width_, 0.05f, 0.07f, 0.0001f, 0.0001f, 0.04f, entity_, [this, rayPass](float val) {
-	  rayPass->SetLaserRayWidth(val);
+  // width
+  MenuHelper::createSliderTextPair(
+      scene, engine, slider_width_, text_width_, 0.05f, 0.073f, 0.0001f,
+      0.0001f, 0.04f, entity_, [this, rayPass](float val) {
+        rayPass->SetLaserRayWidth(val);
 
-	  static char te[] = "40.1mm";
-	  snprintf(te, sizeof(te), "%4.1fmm", val * 1000);
-	  text_width_->SetText(std::string(te));
-  });
-  
-  //Wavelength
-  MenuHelper::createSliderTextPair(scene, engine, slider_wlength_, text_wlength_, 0.05f, 0.035f, 5.0f, 450.0f, 1075.0f, entity_, [this, rayPass](float val) {
-	  rayPass->SetLaserWaveLength(val);
-
-	  static char te[] = "1000nm";
-	  snprintf(te, sizeof(te), "%4.0fnm", val);
-	  text_wlength_->SetText(std::string(te));
-  });
+        static char te[] = "40.1mm";
+        snprintf(te, sizeof(te), "%4.1fmm", val * 1000);
+        text_width_->SetText(std::string(te));
+      });
+
+  auto obj_m = engine->GetSystem<ObjectManager>();
+
+  // Wavelength
+  MenuHelper::createSliderTextPair(
+      scene, engine, slider_wlength_, text_wlength_, 0.05f, 0.038f, 5.0f,
+      450.0f, 1075.0f, entity_, [this, rayPass, obj_m](float val) {
+        rayPass->SetLaserWaveLength(val);
+        obj_m->ChangedWavelength(val);
+
+        static char te[] = "1000nm";
+        snprintf(te, sizeof(te), "%4.0fnm", val);
+        text_wlength_->SetText(std::string(te));
+      });
 
   slider_width_->SetValue(rayPass->GetLaserRayWidth());
   slider_wlength_->SetValue(rayPass->GetLaserWaveLength());
@@ -138,6 +159,8 @@ LaserMenu::~LaserMenu() {
   delete switch_tir_;
   delete up_p_;
   delete down_p_;
+  delete up_tc_;
+  delete down_tc_;
   delete clear_target_;
   delete switch_tw_;
   delete text_tw_;
@@ -145,4 +168,5 @@ LaserMenu::~LaserMenu() {
   delete text_wlength_;
   delete slider_width_;
   delete text_width_;
+  delete text_tc_;
 }
diff --git a/demos/optical_bench/src/laser_menu.hpp b/demos/optical_bench/src/laser_menu.hpp
index 6a99d223ee344c4dc02d8b671f1b419f4c5eddc9..cd9a7c3bad3991cc04b8e945cc0cb20d9d4ef960 100644
--- a/demos/optical_bench/src/laser_menu.hpp
+++ b/demos/optical_bench/src/laser_menu.hpp
@@ -7,8 +7,8 @@
 #include "lens.hpp"
 #include "menu_button.hpp"
 #include "menu_helper.hpp"
-#include "menu_switch.hpp"
 #include "menu_slider.hpp"
+#include "menu_switch.hpp"
 #include "selector.hpp"
 #include "text.hpp"
 
@@ -29,14 +29,16 @@ class LaserMenu {
     return entity_->GetFirstComponent<phx::Transform>();
   };
 
+  float GetCurrentWaveLength() { return slider_wlength_->GetValue(); };
+
  private:
   phx::Entity* entity_;
 
-  //RayWidth
+  // RayWidth
   MenuSlider* slider_width_;
   phx::Text* text_width_;
 
-  //RayWaveLength
+  // RayWaveLength
   MenuSlider* slider_wlength_;
   phx::Text* text_wlength_;
 
@@ -45,6 +47,11 @@ class LaserMenu {
   MenuButton* down_p_;
   phx::Text* text_p_;
 
+  // Target Color Pattern
+  MenuButton* up_tc_;
+  MenuButton* down_tc_;
+  phx::Text* text_tc_;
+
   // Total internal reflection
   MenuSwitch* switch_tir_;
   phx::Text* text_tir_;
diff --git a/demos/optical_bench/src/lens.cpp b/demos/optical_bench/src/lens.cpp
index c9a9d12deb37efda39ecad0063f42834822176f2..dd13c003a5ef357002a91ee08a65c19585902e38 100644
--- a/demos/optical_bench/src/lens.cpp
+++ b/demos/optical_bench/src/lens.cpp
@@ -1,5 +1,6 @@
 #include "lens.hpp"
 #include <optix.h>
+#include "object_manager.hpp"
 #include "optix_context_manager.hpp"
 
 #include "phx/rendering/components/transform.hpp"
@@ -18,14 +19,14 @@ SUPPRESS_WARNINGS_BEGIN
 #include "glm/gtx/string_cast.hpp"
 SUPPRESS_WARNINGS_END
 
-Lens::Lens(phx::Scene* scene, OptixContextManager* manager, LensSideType type1,
-           LensSideType type2, optix::float3 frontCenter, float lensradius,
-           float thickness, float radius, float radius2) {
+Lens::Lens(phx::Engine* engine, phx::Scene* scene, OptixContextManager* manager,
+           LensSideType type1, LensSideType type2, optix::float3 frontCenter,
+           float lensradius, float thickness, float radius, float radius2) {
   manager_ = manager;
 
+  CreateGlassMaterialInstance();
   geometry = manager->getContext()->createGeometryInstance(
-      manager->GetLensGeometry(), &manager->GetGlassMaterial(),
-      &manager->GetGlassMaterial() + 1);
+      manager->GetLensGeometry(), &glass_material, &glass_material + 1);
 
   geometry["center"]->setFloat(0, 0, 0);
   geometry["radius"]->setFloat(radius);
@@ -56,32 +57,52 @@ Lens::Lens(phx::Scene* scene, OptixContextManager* manager, LensSideType type1,
 
   // Attach handles
   entity_ = scene->CreateEntity();
-  auto center = frontCenter - normalize(optix::make_float3(0.f, 0.f, -1.f)) *
-                                  cylinderLength / 2;
+  auto center =
+      frontCenter - optix::make_float3(0.f, 0.f, -1.f) * thickness / 2;
   entity_->AddComponent<phx::Transform>()->Translate(
       glm::vec3(center.x, center.y, center.z));
   selector_ = entity_->AddComponent<phx::Selector>(nullptr, true);
-  selector_->SetMove([this](phx::Transform* t, glm::mat4 r) {
-    entity_->GetFirstComponent<phx::Transform>()->SetGlobalTranslation(
-        glm::vec3((t->GetGlobalMatrix() * r)[3]));
 
+  support_rod_ = new SupportRod(scene, selector_, false);
+
+  auto obj_m = engine->GetSystem<ObjectManager>();
+
+  // Set Moving
+  selector_->SetMove([this, obj_m](phx::Transform* t, glm::mat4 r) {
+    auto pos = glm::vec3((t->GetGlobalMatrix() * r)[3]);
+    auto pos_proj =
+        glm::dot(pos - obj_m->GetCenterAxisPos(), glm::vec3(0, 0, 1)) *
+            glm::vec3(0, 0, 1) +
+        obj_m->GetCenterAxisPos();
+
+    // close enough? Then snap!
+    if (glm::length(pos - pos_proj) <= obj_m->GetSnapDistance()) pos = pos_proj;
+
+    entity_->GetFirstComponent<phx::Transform>()->SetGlobalTranslation(pos);
     glm::mat4 trans =
         entity_->GetFirstComponent<phx::Transform>()->GetGlobalMatrix();
     transform->setMatrix(true, &(trans[0][0]), &(inverse(trans)[0][0]));
+
+    support_rod_->Moved();
   });
   selector_->SetExternalUpdate([this]() {
-    selector_->Move(entity_->GetFirstComponent<phx::Transform>(), glm::mat4());
+    glm::mat4 trans =
+        entity_->GetFirstComponent<phx::Transform>()->GetGlobalMatrix();
+    transform->setMatrix(true, &(trans[0][0]), &(inverse(trans)[0][0]));
+
+    support_rod_->Moved();
   });
+
+  // Store if grabbed
   selector_->SetGrab([this](phx::Transform*, glm::mat4) { grabbed_ = true; });
   selector_->SetRelease([this]() { grabbed_ = false; });
 
   recalcBB();
-
-  support_rod_ = new SupportRod(scene, selector_);
 }
 
 Lens::~Lens() {
   manager_->getTopObject()->removeChild(transform);
+  glass_material->destroy();
   geometry->destroy();
   acceleration_structure_->destroy();
   geometry_group_->destroy();
@@ -129,6 +150,16 @@ void Lens::PreviousLensSideType2() {
                    static_cast<LensSideType>(s2));
 }
 
+void Lens::NextGlassType() {
+  glass_type_ = static_cast<GlassType>((glass_type_ + 1) % 3);
+  ChangedWaveLength(current_wavelength_nm_);
+}
+
+void Lens::PreviousGlassType() {
+  glass_type_ = static_cast<GlassType>((glass_type_ - 1 + 3) % 3);
+  ChangedWaveLength(current_wavelength_nm_);
+}
+
 std::string Lens::GetLensTypeName1() {
   return getTypeString(
       static_cast<LensSideType>(geometry["side1Type"]->getInt()));
@@ -139,6 +170,20 @@ std::string Lens::GetLensTypeName2() {
       static_cast<LensSideType>(geometry["side2Type"]->getInt()));
 }
 
+std::string Lens::GetGlassTypeName() {
+  switch (glass_type_) {
+    case BK7:
+      return "BK7";
+    case SF5:
+      return "SF5";
+    case SF11:
+      return "SF11";
+    case FUSED_SILICA:
+      return "Fused Silica";
+  }
+  return "Unknown";
+}
+
 void Lens::Translate(glm::vec3 pos) {
   GetEntity()->GetFirstComponent<phx::Transform>()->SetGlobalTranslation(pos);
   selector_->ExternalUpdate();
@@ -146,6 +191,20 @@ void Lens::Translate(glm::vec3 pos) {
 
 void Lens::SetSelected(bool s) { support_rod_->SetMarked(s); }
 
+void Lens::ChangedWaveLength(float wavelength_nm) {
+  double wl2 = glm::pow(wavelength_nm / 1000.0, 2);
+  float index = (float)sqrt(1 +
+                            (glass_definitions[glass_type_][0].x * wl2) /
+                                (wl2 - glass_definitions[glass_type_][1].x) +
+                            (glass_definitions[glass_type_][0].y * wl2) /
+                                (wl2 - glass_definitions[glass_type_][1].y) +
+                            (glass_definitions[glass_type_][0].z * wl2) /
+                                (wl2 - glass_definitions[glass_type_][1].z));
+
+  glass_material["refraction_index"]->setFloat(index);
+  current_wavelength_nm_ = wavelength_nm;
+}
+
 std::array<glm::vec3, 2u> Lens::ComputeAABBFromCylinder(glm::vec3 orientation,
                                                         float halfLength1,
                                                         float halfLength2,
@@ -192,6 +251,13 @@ std::array<glm::vec3, 2u> Lens::ComputeAABBFromCylinder(glm::vec3 orientation,
   return res;
 }
 
+glm::vec3 Lens::GetFrontCenter() {
+  return entity_->GetFirstComponent<phx::Transform>()->GetGlobalTranslation() +
+         glm::mat3(
+             entity_->GetFirstComponent<phx::Transform>()->GetGlobalMatrix()) *
+             glm::vec3(0.f, 0.f, -1.f) * GetThickness() / 2.0f;
+}
+
 float Lens::getCylinderLength(float thickness) {
   float lr = geometry["lensRadius"]->getFloat();
   float r1 = geometry["radius"]->getFloat();
@@ -268,3 +334,29 @@ std::string Lens::getTypeString(LensSideType t) {
   }
   return "Unknown";
 }
+
+void Lens::CreateGlassMaterialInstance() {
+  optix::Program closeHitP = manager_->getContext()->createProgramFromPTXString(
+      OptixContextManager::getPtxString("glass_perspective_camera.cu"),
+      "closest_hit_radiance");
+  optix::Program closeHitI = manager_->getContext()->createProgramFromPTXString(
+      OptixContextManager::getPtxString("glass_iterative_camera.cu"),
+      "closest_hit_radiance");
+
+  glass_material = manager_->getContext()->createMaterial();
+  glass_material->setClosestHitProgram(0, closeHitP);
+  glass_material->setClosestHitProgram(1, closeHitI);
+
+  glass_material["importance_cutoff"]->setFloat(1e-2f);
+  glass_material["cutoff_color"]->setFloat(0.034f, 0.055f, 0.085f);
+  glass_material["fresnel_exponent"]->setFloat(3.0f);
+  glass_material["fresnel_minimum"]->setFloat(0.1f);
+  glass_material["fresnel_maximum"]->setFloat(1.0f);
+  glass_material["refraction_index"]->setFloat(1.4f);
+  glass_material["refraction_color"]->setFloat(1.0f, 1.0f, 1.0f);
+  glass_material["reflection_color"]->setFloat(1.0f, 1.0f, 1.0f);
+  glass_material["refraction_maxdepth"]->setInt(10);
+  glass_material["reflection_maxdepth"]->setInt(5);
+  glass_material["extinction_constant"]->setFloat(log(0.83f), log(0.83f),
+                                                  log(0.83f));
+}
diff --git a/demos/optical_bench/src/lens.hpp b/demos/optical_bench/src/lens.hpp
index 7a2b090983220961636c85cfec3b9a259ed49f0c..2a183ac02b7c50693abef918ca0ffd55640b46ec 100644
--- a/demos/optical_bench/src/lens.hpp
+++ b/demos/optical_bench/src/lens.hpp
@@ -5,8 +5,10 @@
 
 #include <optixu/optixpp_namespace.h>
 #include <optixu/optixu_math_stream_namespace.h>
+#include <array>
 #include <iostream>
 
+#include "phx/core/system.hpp"
 #include "phx/suppress_warnings.hpp"
 
 SUPPRESS_WARNINGS_BEGIN
@@ -18,13 +20,15 @@ SUPPRESS_WARNINGS_END
 class Lens {
  public:
   enum LensSideType { CONVEX = 1, CONCAVE = -1, PLANE = 0 };
-  Lens(phx::Scene* scene, OptixContextManager* manager, LensSideType type1,
-       LensSideType type2, optix::float3 frontCenter, float lensradius,
-       float thickness, float radius, float radius2 = 0.0f);
+  enum GlassType { BK7 = 0, SF5 = 1, SF11 = 2, FUSED_SILICA = 3 };
+  Lens(phx::Engine* engine, phx::Scene* scene, OptixContextManager* manager,
+       LensSideType type1, LensSideType type2, optix::float3 frontCenter,
+       float lensradius, float thickness, float radius, float radius2 = 0.0f);
   ~Lens();
 
   optix::Transform transform;
   optix::GeometryInstance geometry;
+  optix::Material glass_material;
 
   void SetThickness(float f) {
     geometry["halfCylinderLength"]->setFloat(getCylinderLength(f) / 2);
@@ -60,6 +64,8 @@ class Lens {
     return entity_->GetFirstComponent<phx::Transform>();
   }
 
+  glm::vec3 GetFrontCenter();
+
   float getCylinderLength(float thickness);
   float getThickness(float cylinder_length);
 
@@ -69,9 +75,12 @@ class Lens {
   void PreviousLensSideType1();
   void NextLensSideType2();
   void PreviousLensSideType2();
+  void NextGlassType();
+  void PreviousGlassType();
 
   std::string GetLensTypeName1();
   std::string GetLensTypeName2();
+  std::string GetGlassTypeName();
 
   bool isGrabbed() { return grabbed_; };
 
@@ -79,6 +88,8 @@ class Lens {
 
   void SetSelected(bool s);
 
+  void ChangedWaveLength(float wavelength_nm);
+
  private:
   std::array<glm::vec3, 2u> ComputeAABBFromCylinder(glm::vec3 orientation,
                                                     float halfLength1,
@@ -88,6 +99,8 @@ class Lens {
   phx::Entity* entity_;
   LensSideType type_1_;
   LensSideType type_2_;
+  GlassType glass_type_ = GlassType::BK7;
+  float current_wavelength_nm_ = 0.0f;
   void recalcBB();
   void markDirty();
   SupportRod* support_rod_;
@@ -99,4 +112,24 @@ class Lens {
 
   optix::Acceleration acceleration_structure_;
   optix::GeometryGroup geometry_group_;
+
+  void CreateGlassMaterialInstance();
+
+  // clang-format off
+  //Keep Clang out of here, else it is barely readable
+  const std::array<std::array<glm::vec3, 2>, 4> glass_definitions = {{
+      {//BK7
+          glm::vec3(1.03961212f, 0.231792344f, 1.01046945f), //B
+          glm::vec3(0.00600069867f, 0.0200179144f, 103.560653f) //C
+      },{ //SF5
+          glm::vec3(1.52481889f, 0.187085527f, 1.42729015f), //B
+          glm::vec3(0.011254756f, 0.0588995392f, 129.141675f) //C
+      },{ //SF11
+          glm::vec3(1.73759695f, 0.313747346f, 1.89878101f), //B
+          glm::vec3(0.013188707f, 0.0623068142f, 155.23629f) //C
+      },{ //Fused Silica
+          glm::vec3(0.6961663f, 0.4079426f, 0.8974794f), //B
+          glm::vec3(0.0684043f, 0.1162414f, 9.896161f) //C
+      } }};
+  // clang-format on
 };
diff --git a/demos/optical_bench/src/lens_menu.cpp b/demos/optical_bench/src/lens_menu.cpp
index 4bb0e87825e643b5af21a1493b616e1d5bc3ae0c..b2496e4e551122a2cad9fbb7b8cde025b1176906 100644
--- a/demos/optical_bench/src/lens_menu.cpp
+++ b/demos/optical_bench/src/lens_menu.cpp
@@ -101,7 +101,7 @@ LensMenu::LensMenu(phx::Scene* scene, phx::Engine* engine, Lens* lens) {
         text_lens_radius_->SetText(std::string(te));
       });
 
-  MenuHelper::createButtonPairVertical(up_l1_, down_l1_, text_l1_, -0.01f,
+  MenuHelper::createButtonPairVertical(up_l1_, down_l1_, text_l1_, 0.02f,
                                        -0.055f, scene, engine, entity_);
   up_l1_->SetOnPress([this](phx::Transform*, glm::mat4) {
     if (current_lens_ == nullptr) return;
@@ -114,7 +114,7 @@ LensMenu::LensMenu(phx::Scene* scene, phx::Engine* engine, Lens* lens) {
     text_l1_->SetText(current_lens_->GetLensTypeName1());
   });
 
-  MenuHelper::createButtonPairVertical(up_l2_, down_l2_, text_l2_, +0.11f,
+  MenuHelper::createButtonPairVertical(up_l2_, down_l2_, text_l2_, 0.11f,
                                        -0.055f, scene, engine, entity_);
   up_l2_->SetOnPress([this](phx::Transform*, glm::mat4) {
     if (current_lens_ == nullptr) return;
@@ -127,6 +127,19 @@ LensMenu::LensMenu(phx::Scene* scene, phx::Engine* engine, Lens* lens) {
     text_l2_->SetText(current_lens_->GetLensTypeName2());
   });
 
+  MenuHelper::createButtonPairVertical(up_gl_, down_gl_, text_gl_, -0.045f,
+                                       -0.055f, scene, engine, entity_);
+  up_gl_->SetOnPress([this](phx::Transform*, glm::mat4) {
+    if (current_lens_ == nullptr) return;
+    current_lens_->NextGlassType();
+    text_gl_->SetText(current_lens_->GetGlassTypeName());
+  });
+  down_gl_->SetOnPress([this](phx::Transform*, glm::mat4) {
+    if (current_lens_ == nullptr) return;
+    current_lens_->PreviousGlassType();
+    text_gl_->SetText(current_lens_->GetGlassTypeName());
+  });
+
   SetCurrentLens(lens);
 }
 
@@ -140,11 +153,14 @@ LensMenu::~LensMenu() {
   delete text_radius1_;
   delete text_radius2_;
   delete text_thickness_;
+  delete text_gl_;
 
   delete up_l1_;
   delete down_l1_;
   delete up_l2_;
   delete down_l2_;
+  delete up_gl_;
+  delete down_gl_;
 }
 
 void LensMenu::SetCurrentLens(phx::Entity* e) {
@@ -187,6 +203,7 @@ void LensMenu::SetCurrentLens(Lens* lens) {
 
   text_l1_->SetText(current_lens_->GetLensTypeName1());
   text_l2_->SetText(current_lens_->GetLensTypeName2());
+  text_gl_->SetText(current_lens_->GetGlassTypeName());
 }
 
 void LensMenu::RegisterLens(Lens* lens) {
diff --git a/demos/optical_bench/src/lens_menu.hpp b/demos/optical_bench/src/lens_menu.hpp
index a614d2b574374671dbc42a43191b0f43e7e3379a..3b09194ffa790d016389c21573586583554c2208 100644
--- a/demos/optical_bench/src/lens_menu.hpp
+++ b/demos/optical_bench/src/lens_menu.hpp
@@ -60,4 +60,9 @@ class LensMenu {
   MenuButton* up_l2_;
   MenuButton* down_l2_;
   phx::Text* text_l2_;
+
+  // Glass
+  MenuButton* up_gl_;
+  MenuButton* down_gl_;
+  phx::Text* text_gl_;
 };
diff --git a/demos/optical_bench/src/menu_slider.cpp b/demos/optical_bench/src/menu_slider.cpp
index 4ca2eaff317b42ecc508219f4f663d484fd3b43a..9cb55de569d8dc3c4fd870e506ff1b7cc452d32d 100644
--- a/demos/optical_bench/src/menu_slider.cpp
+++ b/demos/optical_bench/src/menu_slider.cpp
@@ -235,6 +235,12 @@ void MenuSlider::SetValue(float f) {
   if (value_changed_ != nullptr) value_changed_(f);
 }
 
+float MenuSlider::GetValue() {
+  return posToValue(slider_grip_->GetFirstComponent<phx::Transform>()
+                        ->GetLocalTranslation()
+                        .z);
+}
+
 float MenuSlider::posToValue(float p) {
   p = (p + 0.4f) / 0.8f;  //[0,1]
   p = p * (min_max_value_[1] - min_max_value_[0]) +
diff --git a/demos/optical_bench/src/menu_slider.hpp b/demos/optical_bench/src/menu_slider.hpp
index ac30ca3d649a35d906e2091eb748d6db1d756f61..0c07e49c71174f06ccdd21b26505b4c3c52b75e2 100644
--- a/demos/optical_bench/src/menu_slider.hpp
+++ b/demos/optical_bench/src/menu_slider.hpp
@@ -31,6 +31,7 @@ class MenuSlider {
 
   void SetMinMax(float min, float max, bool changed_event = true);
   void SetValue(float f);
+  float GetValue();
 
   std::array<float, 2> getMinMaxValue() { return min_max_value_; }
 
diff --git a/demos/optical_bench/src/object_manager.cpp b/demos/optical_bench/src/object_manager.cpp
index 2ee732a6db06533327a63493ff79750660d92965..f4fce83137849041624e6714cdd596f46eee6fb5 100644
--- a/demos/optical_bench/src/object_manager.cpp
+++ b/demos/optical_bench/src/object_manager.cpp
@@ -27,8 +27,8 @@ ObjectManager::ObjectManager(phx::Engine* engine, phx::Scene* scene,
   bin_->AddComponent<phx::Selector>(bin_)->SetMove(nullptr);  // deactivate move
 
   bin_->GetFirstComponent<phx::Transform>()->Translate(
-       glm::vec3(0.0f, 0.0f, -1.5f)); // Position on floor
-      //glm::vec3(0.50f, 1.0f, 1.0f));  // Position on table
+      glm::vec3(0.0f, 0.0f, -1.5f));  // Position on floor
+  // glm::vec3(0.50f, 1.0f, 1.0f));  // Position on table
 
   auto transform = bin_->GetFirstComponent<phx::Transform>();
   for (auto i = 0u; i < transform->GetChildCount(); i++) {
@@ -45,6 +45,17 @@ ObjectManager::ObjectManager(phx::Engine* engine, phx::Scene* scene,
 
   // intersection
   intersection_thread_ = std::thread(&ObjectManager::intersectThread, this);
+
+  // Lens axis
+  center_axis_ = phx::SceneLoader::InsertModelIntoScene(
+      "models/opticalBench/table/Axis.obj", scene);
+  center_axis_->GetFirstComponent<phx::Transform>()
+      ->GetChild(0)
+      ->GetEntity()
+      ->GetFirstComponent<phx::MaterialHandle>()
+      ->GetMaterial()
+      ->SetAmbientColor(glm::vec3(1, 0, 0));
+  ShowCenterAxis(false);
 }
 
 ObjectManager::~ObjectManager() {}
@@ -83,9 +94,10 @@ void ObjectManager::Update(const phx::FrameTimer::TimeInfo&) {
 }
 
 Lens* ObjectManager::CreateLens(glm::vec3 pos) {
-  auto lens = new Lens(scene_, manager_, Lens::CONVEX, Lens::CONVEX,
+  auto lens = new Lens(engine_, scene_, manager_, Lens::CONVEX, Lens::CONVEX,
                        optix::make_float3(pos.x, pos.y, pos.z), 0.1f, 0.025f,
                        0.8f, 1.0f);
+  lens->ChangedWaveLength(current_wavelength_nm_);
   registered_lenses_.push_back(lens);
   menu_->RegisterLens(lens);
   make_invalid_ = true;
@@ -129,6 +141,42 @@ void ObjectManager::KillThread() {
   intersection_thread_.join();
 }
 
+void ObjectManager::SetMenuManager(MenuManager* manager) {
+  menu_ = manager;
+  current_wavelength_nm_ = manager->GetLaserMenu()->GetCurrentWaveLength();
+}
+
+void ObjectManager::ChangedWavelength(float wavelength_nm) {
+  current_wavelength_nm_ = wavelength_nm;
+
+  for (auto l : registered_lenses_) {
+    l->ChangedWaveLength(wavelength_nm);
+  }
+}
+
+float ObjectManager::GetDistanceToNextLens(Lens* l, float own_z_pos) {
+  auto own_z = (l == nullptr) ? own_z_pos : l->GetFrontCenter().z;
+  float closest = INFINITY;
+  float curr_z = 0;
+
+  for (auto rl : registered_lenses_) {
+    if (rl == l) continue;
+    curr_z = rl->GetFrontCenter().z;
+    if (curr_z < own_z && abs(curr_z - own_z) <= closest) {
+      closest = abs(curr_z - own_z);
+    }
+  }
+
+  return (closest == INFINITY) ? 0.0f : closest;
+}
+
+Lens* ObjectManager::GetLens(phx::Entity* e) {
+  for (auto rl : registered_lenses_) {
+    if (rl->GetEntity() == e) return rl;
+  }
+  return nullptr;
+}
+
 void ObjectManager::intersectThread() {
   auto select_bin = bin_->GetFirstComponent<phx::Selector>();
 
diff --git a/demos/optical_bench/src/object_manager.hpp b/demos/optical_bench/src/object_manager.hpp
index 1e5518de358f2748bfea6791787c98ee9b3b0437..71b4d45eca4f4ddd52c34d25187d814ebbfee017 100644
--- a/demos/optical_bench/src/object_manager.hpp
+++ b/demos/optical_bench/src/object_manager.hpp
@@ -1,10 +1,10 @@
 #pragma once
 
+#include "hmd_navigation_behavior.hpp"
 #include "lens.hpp"
 #include "menu_manager.hpp"
 #include "phx/suppress_warnings.hpp"
 #include "test_pattern_frame.hpp"
-#include "hmd_navigation_behavior.hpp"
 
 #include <mutex>
 #include <vector>
@@ -36,18 +36,40 @@ class ObjectManager : public phx::System {
 
   void KillThread();
 
-  void SetMenuManager(MenuManager* manager) { menu_ = manager; }
+  void SetMenuManager(MenuManager* manager);
+
+  void registerHMDNav(HMDNavigationBehavior* nav) { hmd_nav_ = nav; }
 
-  void registerHMDNav(HMDNavigationBehavior* nav) {
-	  hmd_nav_ = nav;
+  void ChangedWavelength(float wavelength_nm);
+
+  void ShowCenterAxis(bool visible) {
+    center_axis_->GetFirstComponent<phx::Transform>()->SetLocalTranslation(
+        visible ? center_axis_pos_ : glm::vec3(0, -120, 0));
+    axis_visible_ = visible;
+  }
+  void SetCenterAxisPos(glm::vec3 p) {
+    center_axis_pos_ = p;
+    if (axis_visible_) ShowCenterAxis(axis_visible_);
   }
+  glm::vec3 GetCenterAxisPos() { return center_axis_pos_; }
+  float GetSnapDistance() { return 0.02f; }
+
+  float GetDistanceToNextLens(Lens* l, float own_z_pos = 0.0f);
+  Lens* GetLens(phx::Entity* e);
 
  private:
   phx::Entity* bin_;
+
   phx::MaterialHandle* bin_mat_ = nullptr;
   glm::vec3 bin_color_base = glm::vec3(0.189474f, 0.189474f, 0.189474f);
   glm::vec3 bin_color_highlight = glm::vec3(0.475f, 0.059f, 0.071f);
 
+  float current_wavelength_nm_ = 0.0f;
+
+  phx::Entity* center_axis_;
+  glm::vec3 center_axis_pos_ = glm::vec3(0, 1.20f, 0);
+  bool axis_visible_ = false;
+
   std::thread intersection_thread_;
   void intersectThread();
   bool intersector_run_ = true;
diff --git a/demos/optical_bench/src/object_menu.cpp b/demos/optical_bench/src/object_menu.cpp
index c5af308966628a97d54560f809d59a47d0095e5b..c3488da96020acc307cfd76b99e0b3d06134772b 100644
--- a/demos/optical_bench/src/object_menu.cpp
+++ b/demos/optical_bench/src/object_menu.cpp
@@ -49,7 +49,8 @@ ObjectMenu::ObjectMenu(phx::Scene* scene, phx::Engine* engine) {
   create_frame_1_->GetTransform()->SetLocalRotationEuler(glm::vec3(0, -90, 90));
   create_frame_1_->GetTransform()->SetLocalScale(
       glm::vec3(0.05f, 0.01f, 0.05f));
-  create_frame_1_->GetTransform()->SetLocalTranslation(glm::vec3(0, 0, -0.1f));
+  create_frame_1_->GetTransform()->SetLocalTranslation(
+      glm::vec3(0, 0.0275f, -0.1f));
   create_frame_1_->SetImage(
       phx::ResourceUtils::LoadResourceFromFile<phx::Image>(
           "laser/target/Checker.png"));
@@ -66,7 +67,7 @@ ObjectMenu::ObjectMenu(phx::Scene* scene, phx::Engine* engine) {
   create_frame_2_->GetTransform()->SetLocalScale(
       glm::vec3(0.05f, 0.01f, 0.05f));
   create_frame_2_->GetTransform()->SetLocalTranslation(
-      glm::vec3(0, -0.055f, -0.1f));
+      glm::vec3(0, -0.0275f, -0.1f));
   create_frame_2_->SetImage(
       phx::ResourceUtils::LoadResourceFromFile<phx::Image>(
           "laser/target/CheckerRed.png"));
@@ -83,15 +84,15 @@ ObjectMenu::ObjectMenu(phx::Scene* scene, phx::Engine* engine) {
   create_frame_3_->GetTransform()->SetLocalScale(
       glm::vec3(0.05f, 0.01f, 0.05f));
   create_frame_3_->GetTransform()->SetLocalTranslation(
-      glm::vec3(0, 0, -0.045f));
+      glm::vec3(0, 0.0275f, -0.045f));
   create_frame_3_->SetImage(
       phx::ResourceUtils::LoadResourceFromFile<phx::Image>(
           "laser/target/Circles.png"));
   create_frame_3_->SetHoldable(false);
-  create_frame_3_->SetOnPress([this, object_manager](phx::Transform* t,
-                                                     glm::mat4) {
-    object_manager->CreateTarget(t->GetGlobalTranslation(), "Circles.png");
-  });
+  create_frame_3_->SetOnPress(
+      [this, object_manager](phx::Transform* t, glm::mat4) {
+        object_manager->CreateTarget(t->GetGlobalTranslation(), "Circles.png");
+      });
 
   create_frame_4_ = new MenuButton(engine, scene, MenuButton::RECTANGULAR);
   create_frame_4_->GetTransform()->SetParent(
@@ -100,28 +101,44 @@ ObjectMenu::ObjectMenu(phx::Scene* scene, phx::Engine* engine) {
   create_frame_4_->GetTransform()->SetLocalScale(
       glm::vec3(0.05f, 0.01f, 0.05f));
   create_frame_4_->GetTransform()->SetLocalTranslation(
-      glm::vec3(0, -0.055f, -0.045f));
+      glm::vec3(0, -0.0275f, -0.045f));
   create_frame_4_->SetImage(
       phx::ResourceUtils::LoadResourceFromFile<phx::Image>(
           "laser/target/Raster.png"));
   create_frame_4_->SetHoldable(false);
-  create_frame_4_->SetOnPress([this, object_manager](phx::Transform* t,
-                                                     glm::mat4) {
-    object_manager->CreateTarget(t->GetGlobalTranslation(), "Raster.png");
-  });
+  create_frame_4_->SetOnPress(
+      [this, object_manager](phx::Transform* t, glm::mat4) {
+        object_manager->CreateTarget(t->GetGlobalTranslation(), "Raster.png");
+      });
 
   create_lens_ = new MenuButton(engine, scene, MenuButton::LENS);
   create_lens_->GetTransform()->SetParent(
       entity_->GetFirstComponent<phx::Transform>(), false);
   create_lens_->GetTransform()->SetLocalRotationEuler(glm::vec3(0, -90, 90));
   create_lens_->GetTransform()->SetLocalScale(glm::vec3(0.1f, 0.01f, 0.1f));
-  create_lens_->GetTransform()->SetLocalTranslation(
-      glm::vec3(0, -0.025f, 0.075f));
+  create_lens_->GetTransform()->SetLocalTranslation(glm::vec3(0, 0.0f, 0.075f));
   create_lens_->SetHoldable(false);
   create_lens_->SetOnPress(
       [this, object_manager](phx::Transform* t, glm::mat4) {
         object_manager->CreateLens(t->GetGlobalTranslation());
       });
+
+  toggle_guide_ = new MenuButton(engine, scene, MenuButton::RECTANGULAR);
+  toggle_guide_->GetTransform()->SetParent(
+      entity_->GetFirstComponent<phx::Transform>(), false);
+  toggle_guide_->GetTransform()->SetLocalRotationEuler(glm::vec3(0, -90, 90));
+  toggle_guide_->GetTransform()->SetLocalRotationEuler(glm::vec3(0, -90, 90));
+  toggle_guide_->GetTransform()->SetLocalScale(
+      glm::vec3(0.095f, 0.01f, 0.019f));
+  toggle_guide_->GetTransform()->SetLocalTranslation(glm::vec3(0, -0.08f, 0));
+  toggle_guide_->SetImage(phx::ResourceUtils::LoadResourceFromFile<phx::Image>(
+      "models/opticalBench/menu/ToggleAxis.png"));
+  toggle_guide_->SetHoldable(false);
+  toggle_guide_->SetOnPress([this, object_manager](phx::Transform*, glm::mat4) {
+    static bool active = false;
+    active = !active;
+    object_manager->ShowCenterAxis(active);
+  });
 }
 
 ObjectMenu::~ObjectMenu() {
@@ -130,4 +147,5 @@ ObjectMenu::~ObjectMenu() {
   delete create_frame_3_;
   delete create_frame_4_;
   delete create_lens_;
+  delete toggle_guide_;
 }
diff --git a/demos/optical_bench/src/object_menu.hpp b/demos/optical_bench/src/object_menu.hpp
index 7d86401ed6ad71cf8d6b052079cb5a2508eba2a6..57cd0faa757a39d81685bf925dbb9c32a4bdcb04 100644
--- a/demos/optical_bench/src/object_menu.hpp
+++ b/demos/optical_bench/src/object_menu.hpp
@@ -33,4 +33,5 @@ class ObjectMenu {
   MenuButton* create_frame_2_;
   MenuButton* create_frame_3_;
   MenuButton* create_frame_4_;
+  MenuButton* toggle_guide_;
 };
diff --git a/demos/optical_bench/src/object_support_rod.cpp b/demos/optical_bench/src/object_support_rod.cpp
index 52baa52b160445ed50791920e24357a29de7b4f0..dd54abb7d2d1eaa4e9ccb773ce45b328519f534c 100644
--- a/demos/optical_bench/src/object_support_rod.cpp
+++ b/demos/optical_bench/src/object_support_rod.cpp
@@ -16,7 +16,8 @@ SUPPRESS_WARNINGS_BEGIN
 #include "glm/gtx/string_cast.hpp"
 SUPPRESS_WARNINGS_END
 
-SupportRod::SupportRod(phx::Scene* scene, phx::Selector* selector) {
+SupportRod::SupportRod(phx::Scene* scene, phx::Selector* selector,
+                       bool append_to_move) {
   selector_ = selector;
   rod_support_entity_ = loadAndInsertRod(scene);
   rod_holder_entity_ = loadAndInsertRod(scene);
@@ -39,11 +40,7 @@ SupportRod::SupportRod(phx::Scene* scene, phx::Selector* selector) {
   holder_mat_->GetMaterial()->SetAmbientColor(color_unselected_);
   holder_mat_->GetMaterial()->SetDiffuseColor(color_unselected_);
 
-  auto prevFunc = selector->GetMove();
-  selector->SetMove([trans_for_holder, trans_for_support, selector, prevFunc](
-                        phx::Transform* t, glm::mat4 r) {
-    if (prevFunc != nullptr) prevFunc(t, r);
-
+  move_function_ = [trans_for_holder, trans_for_support, selector]() {
     auto centerBottom = selector->GetBottomCenter();
 
     trans_for_holder->SetLocalScale(glm::vec3(1, centerBottom.y - 0.95f, 1));
@@ -56,10 +53,20 @@ SupportRod::SupportRod(phx::Scene* scene, phx::Selector* selector) {
 
     trans_for_holder->SetLocalTranslation(
         glm::vec3(centerBottom.x, 0.95f, centerBottom.z));
-  });
-
-  selector->GetMove()(
-      selector->GetEntity()->GetFirstComponent<phx::Transform>(), glm::mat4());
+  };
+
+  if (append_to_move) {
+    auto prevFunc = selector->GetMove();
+    selector->SetMove([trans_for_holder, trans_for_support, selector, prevFunc,
+                       this](phx::Transform* t, glm::mat4 r) {
+      if (prevFunc != nullptr) prevFunc(t, r);
+      move_function_();
+    });
+
+    selector->GetMove()(
+        selector->GetEntity()->GetFirstComponent<phx::Transform>(),
+        glm::mat4());
+  }
 }
 
 SupportRod::~SupportRod() {
diff --git a/demos/optical_bench/src/object_support_rod.hpp b/demos/optical_bench/src/object_support_rod.hpp
index f5eb8af597146edab20cc7470927c58a8d02bcb7..59310dba14aea730a99ab56d924daffa0a80fe83 100644
--- a/demos/optical_bench/src/object_support_rod.hpp
+++ b/demos/optical_bench/src/object_support_rod.hpp
@@ -9,7 +9,8 @@
 
 class SupportRod {
  public:
-  explicit SupportRod(phx::Scene* scene, phx::Selector* selector);
+  explicit SupportRod(phx::Scene* scene, phx::Selector* selector,
+                      bool append_to_move = true);
   ~SupportRod();
 
   phx::Selector* GetCollider() { return selector_; }
@@ -25,6 +26,8 @@ class SupportRod {
     }
   }
 
+  void Moved() { move_function_(); }
+
  private:
   phx::Entity* loadAndInsertRod(phx::Scene* scene);
   phx::Entity* rod_support_entity_;
@@ -33,6 +36,7 @@ class SupportRod {
   phx::MaterialHandle* holder_mat_ = nullptr;
   glm::vec3 color_selected_ = glm::vec3(0.792f, 0.416f, 0.0f);
   glm::vec3 color_unselected_ = glm::vec3(0.221f, 0.221f, 0.221f);
+  std::function<void()> move_function_;
 };
 
 #endif  // OPTICAL_BENCH_SUPPORT_ROD_HPP_
diff --git a/demos/optical_bench/src/optix_context_manager.cpp b/demos/optical_bench/src/optix_context_manager.cpp
index ba440c82ece6e62cb44fb3f9aa92c2ba33d2ccd4..ab03ef90d3d9410c3f904906eda7926893874cdd 100644
--- a/demos/optical_bench/src/optix_context_manager.cpp
+++ b/demos/optical_bench/src/optix_context_manager.cpp
@@ -65,7 +65,6 @@ OptixContextManager::OptixContextManager() {
   createTargetGeometry();
   createLensGeometry();
   createDebugMaterial();
-  createGlassMaterial();
   createTargetMaterial();
   createSkybox();
 
@@ -76,7 +75,6 @@ OptixContextManager::~OptixContextManager() {
   if (context_) {
     top_object->destroy();
     debugMaterial->destroy();
-    glassMaterial->destroy();
     targetMaterial->destroy();
     lensGeomerty->destroy();
     targetGeomerty->destroy();
@@ -130,33 +128,6 @@ void OptixContextManager::createDebugMaterial() {
   }
 }
 
-void OptixContextManager::createGlassMaterial() {
-  optix::Program closeHitP = context_->createProgramFromPTXString(
-      getPtxString("glass_perspective_camera.cu"), "closest_hit_radiance");
-  optix::Program closeHitI = context_->createProgramFromPTXString(
-      getPtxString("glass_iterative_camera.cu"), "closest_hit_radiance");
-  try {
-    glassMaterial = context_->createMaterial();
-    glassMaterial->setClosestHitProgram(0, closeHitP);
-    glassMaterial->setClosestHitProgram(1, closeHitI);
-
-    glassMaterial["importance_cutoff"]->setFloat(1e-2f);
-    glassMaterial["cutoff_color"]->setFloat(0.034f, 0.055f, 0.085f);
-    glassMaterial["fresnel_exponent"]->setFloat(3.0f);
-    glassMaterial["fresnel_minimum"]->setFloat(0.1f);
-    glassMaterial["fresnel_maximum"]->setFloat(1.0f);
-    glassMaterial["refraction_index"]->setFloat(1.4f);
-    glassMaterial["refraction_color"]->setFloat(1.0f, 1.0f, 1.0f);
-    glassMaterial["reflection_color"]->setFloat(1.0f, 1.0f, 1.0f);
-    glassMaterial["refraction_maxdepth"]->setInt(10);
-    glassMaterial["reflection_maxdepth"]->setInt(5);
-    glassMaterial["extinction_constant"]->setFloat(
-        log(0.83f), log(0.83f), log(0.83f));
-  } catch (optix::Exception e) {
-    phx::error(e.getErrorString().c_str());
-  }
-}
-
 void OptixContextManager::createTargetMaterial() {
   const std::string ptx =
       OptixContextManager::getPtxString("frame_material.cu");
diff --git a/demos/optical_bench/src/optix_context_manager.hpp b/demos/optical_bench/src/optix_context_manager.hpp
index 1ede81ced0faee2703647d3f455532ecebfdf686..2af04859d08a9343d6e69a8103c6990ed85cf5d8 100644
--- a/demos/optical_bench/src/optix_context_manager.hpp
+++ b/demos/optical_bench/src/optix_context_manager.hpp
@@ -25,7 +25,6 @@ class OptixContextManager {
   static optix::TextureSampler loadTexture(
       optix::Context context, phx::ResourcePointer<phx::Image> image);
 
-  optix::Material& GetGlassMaterial() { return glassMaterial; }
   optix::Material& GetDebugMaterial() { return debugMaterial; }
   optix::Material& GetTargetMaterial() { return targetMaterial; }
   optix::Geometry& GetLensGeometry() { return lensGeomerty; }
@@ -35,13 +34,11 @@ class OptixContextManager {
   optix::Context context_;
   optix::Group top_object;
   optix::Material debugMaterial;
-  optix::Material glassMaterial;
   optix::Material targetMaterial;
   optix::Geometry lensGeomerty;
   optix::Geometry targetGeomerty;
 
   void createDebugMaterial();
-  void createGlassMaterial();
   void createTargetMaterial();
   void createLensGeometry();
   void createTargetGeometry();
diff --git a/demos/optical_bench/src/ray_pass.cpp b/demos/optical_bench/src/ray_pass.cpp
index 8450d9dc821617cdb1e4ce754e3703d72d7cdac1..f2986b8b6b656c30226971d795e0f3bb84845bd1 100644
--- a/demos/optical_bench/src/ray_pass.cpp
+++ b/demos/optical_bench/src/ray_pass.cpp
@@ -21,6 +21,7 @@
 //------------------------------------------------------------------------------
 
 #include "ray_pass.hpp"
+#include "object_manager.hpp"
 #include "opticalBenchConfig.h"
 #include "selector.hpp"
 
@@ -34,6 +35,7 @@
 #include "phx/suppress_warnings.hpp"
 
 SUPPRESS_WARNINGS_BEGIN
+#include "glm/glm.hpp"
 #include "glm/gtc/matrix_transform.hpp"
 SUPPRESS_WARNINGS_END
 
@@ -127,16 +129,27 @@ void RayPass::Initialize() {
       glm::vec3(0, 1.20f, 1));
   auto selector =
       laser_object_->AddComponent<phx::Selector>(laser_object_, true);
-  selector->SetMove([this](phx::Transform* t, glm::mat4 r) {
+  rod_ = new SupportRod(engine_->GetScene().get(), selector, false);
+
+  auto obj_m = engine_->GetSystem<ObjectManager>();
+
+  selector->SetMove([this, obj_m](phx::Transform* t, glm::mat4 r) {
+    auto pos = glm::vec3((t->GetGlobalMatrix() * r)[3]);
+    auto pos_proj =
+        glm::dot(pos - obj_m->GetCenterAxisPos(), glm::vec3(0, 0, 1)) *
+            glm::vec3(0, 0, 1) +
+        obj_m->GetCenterAxisPos();
+
+    // close enough? Then snap!
+    if (glm::length(pos - pos_proj) <= obj_m->GetSnapDistance()) pos = pos_proj;
+
     laser_object_->GetFirstComponent<phx::Transform>()->SetGlobalTranslation(
-        glm::vec3((t->GetGlobalMatrix() * r)[3]));
-  });
-  selector->SetExternalUpdate([selector]() {
-    selector->GetMove()(
-        selector->GetEntity()->GetFirstComponent<phx::Transform>(),
-        glm::mat4());
+        pos);
+
+    rod_->Moved();
   });
-  rod_ = new SupportRod(engine_->GetScene().get(), selector);
+  selector->SetExternalUpdate([this]() { rod_->Moved(); });
+  rod_->Moved();
 }
 
 void RayPass::Execute() {
@@ -290,9 +303,19 @@ void RayPass::createTarget() {
   targetBuffer = context->createBuffer(RT_BUFFER_INPUT_OUTPUT, RT_FORMAT_FLOAT,
                                        target_res, target_res);
   targetMaxBuffer =
-      context->createBuffer(RT_BUFFER_INPUT_OUTPUT, RT_FORMAT_FLOAT, 1);
+      context->createBuffer(RT_BUFFER_INPUT_OUTPUT, RT_FORMAT_UNSIGNED_INT, 1);
   clearTargetBuffers();
 
+  // Init LUT
+  auto lut_img = phx::ResourceUtils::LoadResourceFromFile<phx::Image>(
+                     "models/opticalBench/laser/Target_LUT.png")
+                     .Get();
+  auto color = lut_img->GetPixelColor({0, 0});
+  for (auto i = 0u; i < 256u; i++) {
+    color = lut_img->GetPixelColor({i, 0});
+    LUT[i] = glm::vec3(color[0], color[1], color[2]);
+  }
+
   // Material
   std::string ptx =
       OptixContextManager::getPtxString("laser_target_material.cu");
@@ -349,10 +372,8 @@ void RayPass::createTarget() {
         targetEntity->GetFirstComponent<phx::Transform>()->GetGlobalMatrix();
     targetTransform->setMatrix(true, &(trans[0][0]), &(inverse(trans)[0][0]));
   });
-
-  selector->SetExternalUpdate([this, selector]() {
-    selector->GetMove()(targetEntity->GetFirstComponent<phx::Transform>(),
-                        glm::mat4());
+  selector->SetRelease([this]() {
+    if (getTargetBufferWrite()) clearTargetBuffers();
   });
 
   selector->intersection_dist = 1.5f;
@@ -361,22 +382,44 @@ void RayPass::createTarget() {
 }
 
 void RayPass::copyAndScaleTargetData() {
+  const static float highlight_color_value = 0.8f;
+  const static glm::vec3 highlight_color = glm::vec3(1, 0, 0);
+
   // fetch max
-  float max =
-      *(static_cast<float*>(targetMaxBuffer->map(0, RT_BUFFER_MAP_READ)));
+  float max = (float)*(
+      static_cast<unsigned int*>(targetMaxBuffer->map(0, RT_BUFFER_MAP_READ)));
   targetMaxBuffer->unmap();
   if (max == 0) max = 1;
 
   // expand & scale buffer
-  float curr_val = 0;
   float* buffer_data =
       static_cast<float*>(targetBuffer->map(0, RT_BUFFER_MAP_READ));
-  for (unsigned long i = 0; i < target_res * target_res; i++) {
-    curr_val = buffer_data[i] / max;
-    textureDataBuffer[i * 3] = curr_val;
-    textureDataBuffer[i * 3 + 1] = curr_val;
-    textureDataBuffer[i * 3 + 2] = curr_val;
+
+  float curr_val = 0;
+  glm::vec3* curr_color;
+  bool tmp = false;
+  if (!target_color_mode_) {
+    for (unsigned long i = 0; i < target_res * target_res; i++) {
+      curr_val = buffer_data[i] / max;
+      tmp = curr_val >= highlight_color_value;
+      textureDataBuffer[i * 3] = (tmp) ? highlight_color.x : curr_val;
+      textureDataBuffer[i * 3 + 1] = (tmp) ? highlight_color.y : curr_val;
+      textureDataBuffer[i * 3 + 2] = (tmp) ? highlight_color.z : curr_val;
+    }
+  } else {
+    for (unsigned long i = 0; i < target_res * target_res; i++) {
+      curr_val = buffer_data[i] / max;
+
+      // LUT
+      curr_color = &LUT[(int)(255 * curr_val)];
+
+      // color highest values red
+      textureDataBuffer[i * 3] = curr_color->x;
+      textureDataBuffer[i * 3 + 1] = curr_color->y;
+      textureDataBuffer[i * 3 + 2] = curr_color->z;
+    }
   }
+
   targetBuffer->unmap();
 
   // copy to texture
@@ -425,10 +468,10 @@ void RayPass::moveLaser(glm::vec3 pos, glm::vec3 forward, glm::vec3 right,
   context["laser_up"]->setFloat(up.x, up.y, up.z);
 }
 
-void RayPass::SetLaserRayWidth(float width){
-	optixContextManager_->getContext()["laserBeamWidth"]->setFloat(width);
-	//min needed to not make rays invisible
-	shader_program_->SetUniform("line_thickness", glm::max(width, 0.001f));
+void RayPass::SetLaserRayWidth(float width) {
+  optixContextManager_->getContext()["laserBeamWidth"]->setFloat(width);
+  // min needed to not make rays invisible
+  shader_program_->SetUniform("line_thickness", glm::max(width, 0.001f));
 }
 
 void RayPass::SetLaserPattern(unsigned int index) {
diff --git a/demos/optical_bench/src/ray_pass.hpp b/demos/optical_bench/src/ray_pass.hpp
index b8b1e985e553b57458bf0de9364dbbd2860e0f02..a801ce35e5353f7e748d9b10c4881ef2a71ce799 100644
--- a/demos/optical_bench/src/ray_pass.hpp
+++ b/demos/optical_bench/src/ray_pass.hpp
@@ -67,6 +67,8 @@ class RayPass : public RenderPass {
   void setTargetBufferWrite(bool a) {
     targetGeometry["targetBufferWrite"]->setInt(a);
   };
+  void ToggleTargetColorMode() { target_color_mode_ = !target_color_mode_; }
+  bool GetTargetColorMode() { return target_color_mode_; }
 
   void launchLaser();
   void moveLaser(glm::mat4 transform);
@@ -74,19 +76,18 @@ class RayPass : public RenderPass {
                  glm::vec3 up);
   unsigned int GetLaserMaxDepth() { return laser_max_depth; }
 
-  //Ray Parameter
+  // Ray Parameter
   void SetLaserRayWidth(float width);
   float GetLaserRayWidth() {
-	  return optixContextManager_->getContext()["laserBeamWidth"]->getFloat();
+    return optixContextManager_->getContext()["laserBeamWidth"]->getFloat();
   };
   void SetLaserWaveLength(float wavelength) {
-	  optixContextManager_->getContext()["laserWaveLength"]->setFloat(wavelength);
+    optixContextManager_->getContext()["laserWaveLength"]->setFloat(wavelength);
   };
   float GetLaserWaveLength() {
-	  return optixContextManager_->getContext()["laserWaveLength"]->getFloat();
+    return optixContextManager_->getContext()["laserWaveLength"]->getFloat();
   };
 
-
   size_t GetMaxNumberOfLaserPatterns() { return patterns_.size(); }
   void SetLaserPattern(unsigned int index);
   void NextLaserPattern();
@@ -96,7 +97,6 @@ class RayPass : public RenderPass {
 
   void clearTargetBuffers();
 
-
  private:
   const unsigned int laser_max_depth = 20;
   const std::vector<std::string> pattern_files_ = {"Crosshair", "Pointer",
@@ -132,6 +132,8 @@ class RayPass : public RenderPass {
   const unsigned long target_res = 512l;
   optix::Buffer targetBuffer;
   optix::Buffer targetMaxBuffer;
+  bool target_color_mode_ = false;  // false = grey, true = LUT
+  std::array<glm::vec3, 256u> LUT;
 
   // target object
   void createTarget();
diff --git a/demos/optical_bench/src/rotation_helper.cpp b/demos/optical_bench/src/rotation_helper.cpp
index 9f9bf6952dcbe38afcf3a75905937e4bcbfbc181..914ce4236d2b09a9279a91b580d89ccb5f0a52f9 100644
--- a/demos/optical_bench/src/rotation_helper.cpp
+++ b/demos/optical_bench/src/rotation_helper.cpp
@@ -75,10 +75,10 @@ RotationHelper::RotationHelper(phx::Scene* scene) {
   text_trans_h->SetParent(
       horizontal_rod_ball->GetFirstComponent<phx::Transform>(), false);
   text_node_h->SetManualUpdate([root_t, text_node_h, this]() {
-    static char deg[] = "000.11�";
+    static char deg[] = "000�";
     float degr = -glm::degrees(angle_horizontal_);
     if (degr < 0) degr += 360.0f;
-    snprintf(deg, sizeof(deg), "%06.2f�", degr);
+    snprintf(deg, sizeof(deg), "%.0f�", glm::round(degr));
     text_node_h->SetText(std::string(deg));
   });
   text_node_h->SetBillboard(true);
@@ -90,10 +90,10 @@ RotationHelper::RotationHelper(phx::Scene* scene) {
   text_trans_v->SetParent(
       vertical_rod_ball->GetFirstComponent<phx::Transform>(), false);
   text_node_v->SetManualUpdate([root_t, text_node_v, this]() {
-    static char deg[] = "000.11�";
+    static char deg[] = "000�";
     float degr = glm::degrees(angle_vertical_);
     if (degr < 0) degr += 360.0f;
-    snprintf(deg, sizeof(deg), "%06.2f�", degr);
+    snprintf(deg, sizeof(deg), "%.0f�", glm::round(degr));
     text_node_v->SetText(std::string(deg));
   });
   text_node_v->SetBillboard(true);
diff --git a/demos/optical_bench/src/text.cpp b/demos/optical_bench/src/text.cpp
index c60a98c0be707cac18203234abd9a5286e8d5b8c..f991efd4ecc8447c5e183aeeae0ca30a688031f5 100644
--- a/demos/optical_bench/src/text.cpp
+++ b/demos/optical_bench/src/text.cpp
@@ -50,9 +50,8 @@ std::string Text::ToString() const {
   return "Text Element with Text: '" + text_ + "'";
 }
 void Text::SetText(std::string text) {
-  if (text_.compare(text) != 0) {
-    recalc_metrics_ = true;
-  }
+  recalc_metrics_ |= text_.compare(text) != 0;
+
   text_ = text;
 
   updatedTextRel();  // writes text too
@@ -78,7 +77,8 @@ void Text::SetAnchor(Anchor a) { alignment_x_ = static_cast<float>(a); }
 void Text::updatedTextRel() {
   glm::vec4 *data = new glm::vec4[text_.length()];
   for (auto i = 0u; i < text_.length(); i++) {
-    data[i].x = static_cast<float>(text_[i]);
+	//cast to unsigned to guarantee positive numbers
+    data[i].x = static_cast<float>((unsigned char) text_[i]);
     data[i].y = width_rel_[i];
   }
   unsigned int length = (unsigned int)text_.length();
diff --git a/demos/optical_bench/src/translation_helper.cpp b/demos/optical_bench/src/translation_helper.cpp
index 9cc2e749508e5658da4101f45430537b45825278..2b4c0e5cb36c53e08677d27ded4212bfc0489019 100644
--- a/demos/optical_bench/src/translation_helper.cpp
+++ b/demos/optical_bench/src/translation_helper.cpp
@@ -2,6 +2,7 @@
 #include <optix.h>
 #include "optix_context_manager.hpp"
 
+#include "object_manager.hpp"
 #include "phx/rendering/components/transform.hpp"
 #include "selector.hpp"
 
@@ -19,7 +20,9 @@ SUPPRESS_WARNINGS_BEGIN
 #include "glm/gtx/string_cast.hpp"
 SUPPRESS_WARNINGS_END
 
-TranslationHelper::TranslationHelper(phx::Scene* scene) {
+TranslationHelper::TranslationHelper(phx::Scene* scene, phx::Engine* engine) {
+  engine_ = engine;
+
   root_ = scene->CreateEntity();
   root_->SetName("TranslationHelper");
   auto root_t = root_->AddComponent<phx::Transform>();
@@ -69,15 +72,31 @@ TranslationHelper::TranslationHelper(phx::Scene* scene) {
   z_rod_->GetFirstComponent<phx::Transform>()->SetLocalScale(
       glm::vec3(1, 1, grip_offset));
 
+  auto obj_m = engine_->GetSystem<ObjectManager>();
+
   text_ = scene->CreateEntity();
   auto text_trans = text_->AddComponent<phx::Transform>();
   auto text_node = text_->AddComponent<phx::Text>("", 0.0125f);
   text_trans->SetLocalTranslation(glm::vec3(0, 1, 0));
-  text_node->SetManualUpdate([root_t, text_node]() {
-    static char pos[] = "(+0.111m, +0.111m, +0.111m)";
-    snprintf(pos, sizeof(pos), "(%+1.3fm, %+1.3fm, %+1.3fm)",
-             root_t->GetGlobalTranslation().x, root_t->GetGlobalTranslation().y,
-             root_t->GetGlobalTranslation().z);
+  text_node->SetManualUpdate([root_t, text_node, obj_m, this]() {
+    float z_pos = (current_lens_ == nullptr)
+                      ? parent_->GetGlobalTranslation().z
+                      : current_lens_->GetFrontCenter().z;
+    float dist = obj_m->GetDistanceToNextLens(current_lens_, z_pos);
+
+    glm::vec3 global_pos =
+        root_t->GetGlobalTranslation() - obj_m->GetCenterAxisPos();
+
+    static char pos[] = "(+250.11cm, +250.11cm, +250.11cm)";
+    if (dist == 0.0f) {
+      snprintf(pos, sizeof(pos), "(%.1fcm, %.1fcm, Front)",
+               root_t->GetGlobalTranslation().x,
+               root_t->GetGlobalTranslation().y);
+    } else {
+      snprintf(pos, sizeof(pos), "(%.1fcm, %.1fcm, %.1fcm)", global_pos.x * 100,
+               global_pos.y * 100, dist * 100);
+    }
+
     text_node->SetText(std::string(pos));
   });
   text_node->SetBillboard(true);
@@ -189,6 +208,9 @@ TranslationHelper::~TranslationHelper() {}
 void TranslationHelper::SetParent(phx::Transform* parent) {
   parent_ = parent;
 
+  current_lens_ =
+      engine_->GetSystem<ObjectManager>()->GetLens(parent->GetEntity());
+
   x_rod_grip_->GetFirstComponent<phx::Transform>()->SetLocalTranslation(
       glm::vec3(grip_offset, 0, 0));
   y_rod_grip_->GetFirstComponent<phx::Transform>()->SetLocalTranslation(
diff --git a/demos/optical_bench/src/translation_helper.hpp b/demos/optical_bench/src/translation_helper.hpp
index b8cfe50f07cd317df5b15636af11421abb85cdd5..79b33bf990f2f712dd3d4cccc7807129802a1db7 100644
--- a/demos/optical_bench/src/translation_helper.hpp
+++ b/demos/optical_bench/src/translation_helper.hpp
@@ -17,9 +17,11 @@ SUPPRESS_WARNINGS_END
 #include "phx/core/scene.hpp"
 #include "phx/rendering/components/transform.hpp"
 
+#include "lens.hpp"
+
 class TranslationHelper {
  public:
-  TranslationHelper(phx::Scene* scene);
+  TranslationHelper(phx::Scene* scene, phx::Engine* engine);
   ~TranslationHelper();
 
   void SetParent(phx::Transform* parent);
@@ -41,6 +43,9 @@ class TranslationHelper {
   phx::Entity* root_;
   phx::Transform* parent_;
 
+  Lens* current_lens_ = nullptr;
+  phx::Engine* engine_;
+
   float x_grip_start_ = 0;
   float y_grip_start_ = 0;
   float z_grip_start_ = 0;
diff --git a/resources/models/opticalBench/laser/Target_LUT.png b/resources/models/opticalBench/laser/Target_LUT.png
new file mode 100644
index 0000000000000000000000000000000000000000..3b241ee7c0909e2fcc9f0fb120a2263f3e557abc
--- /dev/null
+++ b/resources/models/opticalBench/laser/Target_LUT.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f6963f3ad077c4e70ed4b8d52cf22200a47511b15b49a3424589fa8297ae6d97
+size 309
diff --git a/resources/models/opticalBench/menu/Screen_Laser.png b/resources/models/opticalBench/menu/Screen_Laser.png
index 4e422b95f74565cdb1da760d5fadb4cd13166809..c257562da2558596951dcb95e860e5f960b312c5 100644
--- a/resources/models/opticalBench/menu/Screen_Laser.png
+++ b/resources/models/opticalBench/menu/Screen_Laser.png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:be8db1942cb5d01930b4b81c785556c52292c826774069762965f679eabb1614
-size 58118
+oid sha256:f2a5e7a3e424b3ad6e22d548cfa88b84c366f0ee8bb5f0aee61db74466f4a056
+size 55430
diff --git a/resources/models/opticalBench/menu/Screen_Lens.png b/resources/models/opticalBench/menu/Screen_Lens.png
index 4919332486b5a400765ce76aa22d98b7327434a8..45cad0d1c086f26de1f0912766b7185bc0f632da 100644
--- a/resources/models/opticalBench/menu/Screen_Lens.png
+++ b/resources/models/opticalBench/menu/Screen_Lens.png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:31d57ddb0243cb56ece90a59b5812735bdf00727fea8cb2f93ae8b5ee61cc19d
-size 110758
+oid sha256:d804e3ba9b793c3f113dd93eb85ec54322dd38876ebacf85638e32d99bee03e7
+size 111983
diff --git a/resources/models/opticalBench/menu/Screen_Object.png b/resources/models/opticalBench/menu/Screen_Object.png
index 0f73fe60f9c3c1c7d77bfca73e36c5e26d46d94a..2c46882f72c0cd1bbcd794b186b04cad77c58e4f 100644
--- a/resources/models/opticalBench/menu/Screen_Object.png
+++ b/resources/models/opticalBench/menu/Screen_Object.png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:6f8fbabdab7014f42e73a598d26f3029b0d9191e316eaedbf5ce10347f563425
-size 65585
+oid sha256:91b4063f2e0187bd418a33ee1d6c2c256b78cee14a5a86615c3514cb5bf173f1
+size 66944
diff --git a/resources/models/opticalBench/menu/ToggleAxis.png b/resources/models/opticalBench/menu/ToggleAxis.png
new file mode 100644
index 0000000000000000000000000000000000000000..86a66f9ac45f55f6a69a6c5cff9c659f74b9bcad
--- /dev/null
+++ b/resources/models/opticalBench/menu/ToggleAxis.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:fa3f14b2f72783d4e702a1b25471782f0cfc26501b716224ea99dd915e965941
+size 2162
diff --git a/resources/models/opticalBench/table/Axis.mtl b/resources/models/opticalBench/table/Axis.mtl
new file mode 100644
index 0000000000000000000000000000000000000000..c5553c9db73ee550a6132dc620509c27728f0006
--- /dev/null
+++ b/resources/models/opticalBench/table/Axis.mtl
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2471e4132d53d4a6e75278f4d96966dd6a51ebd8b738fb572a9c8fdab524f6ec
+size 230
diff --git a/resources/models/opticalBench/table/Axis.obj b/resources/models/opticalBench/table/Axis.obj
new file mode 100644
index 0000000000000000000000000000000000000000..dc36ff37b7b44a3e2c8953af15d6b9ae9112e2d8
--- /dev/null
+++ b/resources/models/opticalBench/table/Axis.obj
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b5dbb319a5322fa530c3a4940097dc7d08d47a3f9d5dc83020c7a8f6be69e14b
+size 568
diff --git a/resources/models/opticalBench/table/axis.blend b/resources/models/opticalBench/table/axis.blend
new file mode 100644
index 0000000000000000000000000000000000000000..c60d9cbd8260e511201b80668f476d6602dad5b3
Binary files /dev/null and b/resources/models/opticalBench/table/axis.blend differ
diff --git a/resources/models/opticalBench/table/axis.blend1 b/resources/models/opticalBench/table/axis.blend1
new file mode 100644
index 0000000000000000000000000000000000000000..d270b971e3f11b357ba4c1c7afc80707eb5c3929
Binary files /dev/null and b/resources/models/opticalBench/table/axis.blend1 differ