diff --git a/demos/optical_bench/src/Optix Files/laser_target.cu b/demos/optical_bench/src/Optix Files/laser_target.cu
new file mode 100644
index 0000000000000000000000000000000000000000..2d7020f028e1fe02ff307ad96e00f2edd32212d3
--- /dev/null
+++ b/demos/optical_bench/src/Optix Files/laser_target.cu	
@@ -0,0 +1,53 @@
+#include <optix.h>
+#include <optix_world.h>
+
+using namespace optix;
+
+rtDeclareVariable(float3,  p1, , );
+rtDeclareVariable(float3,  p2, , );
+rtDeclareVariable(float2,  stretchXY1, , );
+rtDeclareVariable(float2,  stretchXY2, , );
+
+rtDeclareVariable(float,   scene_epsilon, , );
+
+rtDeclareVariable(optix::Ray, ray, rtCurrentRay, );
+
+rtDeclareVariable(float2, texture_coord, attribute texture_coord, );
+rtDeclareVariable(int, writeable_surface, attribute writeable_surface, );
+
+RT_PROGRAM void intersect(int primIdx)
+{
+	float invDir = 1.0f / ray.direction.z;
+
+	float t_1 = (p1.z - ray.origin.z) * invDir;
+	float t_2 = (p2.z - ray.origin.z) * invDir;
+	
+	float tmin = fminf(t_1, t_2);
+	float3 hit_point = ray.origin + ray.direction * tmin;
+	float2 rel_size;
+	if(tmin == t_1){
+		rel_size = (make_float2(hit_point) - (make_float2(p1) - stretchXY1/2))/stretchXY1;
+	}else{
+		rel_size = (make_float2(hit_point) - (make_float2(p2) - stretchXY2/2))/stretchXY2;
+	}
+	
+	if(rel_size.x < 1 && rel_size.y < 1 && rel_size.x >= 0 && rel_size.y >= 0 && rtPotentialIntersection(tmin)) {
+		texture_coord = rel_size;
+		writeable_surface = tmin == t_1;
+		rtReportIntersection(0);
+	}
+}
+
+RT_PROGRAM void bounds (int, optix::Aabb* aabb)
+{
+	float min_x = fminf(p1.x, p2.x) -  fmaxf(stretchXY1, stretchXY2).x/2;
+	float min_y = fminf(p1.y, p2.y) -  fmaxf(stretchXY1, stretchXY2).y/2;
+	float min_z = fminf(p1.z, p2.z);
+	
+	float max_x = fmaxf(p1.x, p2.x) +  fmaxf(stretchXY1, stretchXY2).x/2;
+	float max_y = fmaxf(p1.y, p2.y) +  fmaxf(stretchXY1, stretchXY2).y/2;
+	float max_z = fmaxf(p1.z, p2.z);
+
+	aabb->m_min = make_float3(min_x,min_y,min_z);
+	aabb->m_max = make_float3(max_x,max_y,max_z);
+}
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 07fdcec200b5e1aa91fb54bfc1abd4efacdde878..459aa62dd9a27ffe753c7e4ff6603fda6d3d1a3a 100644
--- a/demos/optical_bench/src/Optix Files/laser_target_material.cu	
+++ b/demos/optical_bench/src/Optix Files/laser_target_material.cu	
@@ -25,6 +25,7 @@
 rtDeclareVariable(PerRayData_radiance, prd_radiance, rtPayload, );
 rtDeclareVariable(PerRayData_radiance_iterative, prd_radiance_it, rtPayload, );
 rtDeclareVariable(float2, texture_coord, attribute texture_coord, );
+rtDeclareVariable(int, writeable_surface, attribute writeable_surface, );
 rtDeclareVariable(float, hit_depth, rtIntersectionDistance, );
 rtDeclareVariable(optix::Ray, ray, rtCurrentRay, );
 
@@ -49,5 +50,5 @@ RT_PROGRAM void closest_hit_iterative()
 	float3 hit_point = ray.origin + hit_depth * ray.direction;
 	prd_radiance_it.origin = hit_point;
 	prd_radiance_it.done = true;
-	if(targetBufferWrite) targetBuffer[make_uint2(texture_coord * targetBufferDim)] = prd_radiance_it.radiance;
+	if(targetBufferWrite && writeable_surface) targetBuffer[make_uint2(texture_coord * targetBufferDim)] = prd_radiance_it.radiance;
 }
diff --git a/demos/optical_bench/src/optix_context_manager.cpp b/demos/optical_bench/src/optix_context_manager.cpp
index f5ea683523fb02e3a828696c1d31e3fd44e86d26..2195007fd7a09b660a2e05cdc4d517a46e745545 100644
--- a/demos/optical_bench/src/optix_context_manager.cpp
+++ b/demos/optical_bench/src/optix_context_manager.cpp
@@ -178,7 +178,8 @@ void OptixContextManager::createLensGeometry() {
   lensGeomerty = context_->createGeometry();
   lensGeomerty->setPrimitiveCount(1u);
 
-  std::string ptx = OptixContextManager::getPtxString("lens_parametric.cu");
+  const std::string ptx =
+      OptixContextManager::getPtxString("lens_parametric.cu");
   lensGeomerty->setBoundingBoxProgram(
       context_->createProgramFromPTXString(ptx, "bounds"));
   lensGeomerty->setIntersectionProgram(
@@ -189,7 +190,7 @@ void OptixContextManager::createTargetGeometry() {
   targetGeomerty = context_->createGeometry();
   targetGeomerty->setPrimitiveCount(1u);
 
-  std::string ptx = OptixContextManager::getPtxString("box_intersect.cu");
+  const std::string ptx = OptixContextManager::getPtxString("box_intersect.cu");
   targetGeomerty->setBoundingBoxProgram(
       context_->createProgramFromPTXString(ptx, "bounds"));
   targetGeomerty->setIntersectionProgram(
diff --git a/demos/optical_bench/src/ray_pass.cpp b/demos/optical_bench/src/ray_pass.cpp
index 3d431f54584578279a088e23d628f5ad9c83c97b..0f77b89c0e65006df3c685fe1c69e180626af9b6 100644
--- a/demos/optical_bench/src/ray_pass.cpp
+++ b/demos/optical_bench/src/ray_pass.cpp
@@ -257,11 +257,11 @@ void RayPass::createTarget() {
 
   // Buffer
   targetBuffer = context->createBuffer(RT_BUFFER_INPUT_OUTPUT, RT_FORMAT_FLOAT3,
-                                       target_dims.x, target_dims.y);
+                                       target_res, target_res);
   clearTarget();
 
   // Material
-  const std::string ptx =
+  std::string ptx =
       OptixContextManager::getPtxString("laser_target_material.cu");
   optix::Program closeHitP =
       context->createProgramFromPTXString(ptx, "closest_hit_radiance");
@@ -273,32 +273,45 @@ void RayPass::createTarget() {
   targetMaterial->setClosestHitProgram(1, closeHitI);
 
   // Geometry
+  auto geo = context->createGeometry();
+  geo->setPrimitiveCount(1u);
+
+  ptx = OptixContextManager::getPtxString("laser_target.cu");
+  geo->setBoundingBoxProgram(
+      context->createProgramFromPTXString(ptx, "bounds"));
+  geo->setIntersectionProgram(
+      context->createProgramFromPTXString(ptx, "intersect"));
+
   targetTransform = context->createTransform();
-  targetGeometry =
-      context->createGeometryInstance(optixContextManager_->GetTargetGeometry(),
-                                      &targetMaterial, &targetMaterial + 1);
+  targetGeometry = context->createGeometryInstance(geo, &targetMaterial,
+                                                   &targetMaterial + 1);
   targetGroup = context->createGeometryGroup();
   targetGroup->addChild(targetGeometry);
   targetAcc = context->createAcceleration("Trbvh");
   targetGroup->setAcceleration(targetAcc);
 
-  glm::vec3 size = glm::vec3(0.2f, 0.2f * target_dims.y / target_dims.x, 0.02);
+  targetGeometry["p1"]->setFloat(0, 0.0336f, 0.059f);
+  targetGeometry["p2"]->setFloat(0, 0.0869f, -0.059f);
+
+  targetGeometry["stretchXY1"]->setFloat(0.05f, 0.05f);
+  targetGeometry["stretchXY2"]->setFloat(0.15f, 0.15f);
 
-  targetGeometry["size"]->setFloat(size.x, size.y, size.z);
   targetGeometry["targetBufferWrite"]->setInt(1);
   targetGeometry["targetBuffer"]->setBuffer(targetBuffer);
-  targetGeometry["targetBufferDim"]->setFloat((float)target_dims.x,
-                                              (float)target_dims.y);
+  targetGeometry["targetBufferDim"]->setFloat((float)target_res,
+                                              (float)target_res);
 
   targetTransform->setChild<optix::GeometryGroup>(targetGroup);
 
   optixContextManager_->getTopObject()->addChild(targetTransform);
   optixContextManager_->getTopObject()->getAcceleration()->markDirty();
 
-  targetEntity = engine_->GetScene()->CreateEntity();
-  targetEntity->AddComponent<phx::Transform>()->Translate(
+  targetEntity = phx::SceneLoader::InsertModelIntoScene(
+      "models/opticalBench/laser/target.obj", engine_->GetScene().get());
+  targetEntity->GetFirstComponent<phx::Transform>()->Translate(
       glm::vec3(-0.2f, 1.20f, -0.6f));
-  auto selector = targetEntity->AddComponent<phx::Selector>();
+
+  auto selector = targetEntity->AddComponent<phx::Selector>(targetEntity);
 
   selector->SetMove([this](phx::Transform* t, glm::mat4 r) {
     targetEntity->GetFirstComponent<phx::Transform>()->SetGlobalMatrix(
@@ -316,10 +329,6 @@ void RayPass::createTarget() {
 
   selector->intersection_dist = 1.5f;
 
-  selector->SetCollider(
-      glm::vec3(-size.x / 2.0f, -size.y / 2.0f, -size.z / 2.0f),
-      glm::vec3(size.x / 2.0f, size.y / 2.0f, size.z / 2.0f));
-
   targetSupportRod = new SupportRod(engine_->GetScene().get(), selector);
 }
 
@@ -327,7 +336,7 @@ void RayPass::clearTarget() {
   // null initially
   float* buffer_data =
       static_cast<float*>(targetBuffer->map(0, RT_BUFFER_MAP_WRITE_DISCARD));
-  for (unsigned int i = 0; i < target_dims.x * target_dims.y * 3; ++i) {
+  for (unsigned int i = 0; i < target_res * target_res * 3; ++i) {
     buffer_data[i] = 0.0f;
   }
   targetBuffer->unmap();
diff --git a/demos/optical_bench/src/ray_pass.hpp b/demos/optical_bench/src/ray_pass.hpp
index d6a3e2f02c0fbd4abe0d64f8ae68603ca6f8c07b..0017fc216a254a3dcabe9e6dd753c53db15c7846 100644
--- a/demos/optical_bench/src/ray_pass.hpp
+++ b/demos/optical_bench/src/ray_pass.hpp
@@ -113,7 +113,7 @@ class RayPass : public RenderPass {
   std::vector<phx::ResourcePointer<phx::Image>> patterns_;
   unsigned int current_pattern_index_;
 
-  const glm::uvec2 target_dims = {100, 100};
+  const unsigned int target_res = 150u;
   void createLaser();
   void createTarget();
   optix::Buffer targetBuffer;
diff --git a/resources/models/opticalBench/laser/target.blend b/resources/models/opticalBench/laser/target.blend
new file mode 100644
index 0000000000000000000000000000000000000000..c98913e275eb4f470fd400afd784af98786223eb
Binary files /dev/null and b/resources/models/opticalBench/laser/target.blend differ
diff --git a/resources/models/opticalBench/laser/target.blend1 b/resources/models/opticalBench/laser/target.blend1
new file mode 100644
index 0000000000000000000000000000000000000000..7e07c40f20cc658a6e31f47dfa32ca0873c0a289
Binary files /dev/null and b/resources/models/opticalBench/laser/target.blend1 differ
diff --git a/resources/models/opticalBench/laser/target.mtl b/resources/models/opticalBench/laser/target.mtl
new file mode 100644
index 0000000000000000000000000000000000000000..dd079d10b0aa14b03a7b2a451cb149a6e46ab4e9
--- /dev/null
+++ b/resources/models/opticalBench/laser/target.mtl
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:64bbe84dd51ab53c28e310fd697dbf1ebade3f89ebf1554b709fb292b8ba140b
+size 232
diff --git a/resources/models/opticalBench/laser/target.obj b/resources/models/opticalBench/laser/target.obj
new file mode 100644
index 0000000000000000000000000000000000000000..6086c840795aeccba4a968d80c68ee6d796b7c8c
--- /dev/null
+++ b/resources/models/opticalBench/laser/target.obj
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d5d5315f4dd77607ce68ee765168a4a99beba692027658b32c1468e230910983
+size 27976