0024837: Visualization - revise design and implementation of connected Interactive...
[occt.git] / src / OpenGl / OpenGl_Workspace_Raytrace.cxx
old mode 100755 (executable)
new mode 100644 (file)
index ab077f4..3c408ce
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
+#include <OpenGl_Workspace.hxx>
+
 #include <NCollection_Mat4.hxx>
 #include <OpenGl_ArbFBO.hxx>
 #include <OpenGl_FrameBuffer.hxx>
+#include <OpenGl_PrimitiveArray.hxx>
 #include <OpenGl_Texture.hxx>
 #include <OpenGl_VertexBuffer.hxx>
 #include <OpenGl_View.hxx>
-#include <OpenGl_Workspace.hxx>
 #include <OSD_File.hxx>
 #include <OSD_Protection.hxx>
 #include <Standard_Assert.hxx>
@@ -84,7 +86,7 @@ Standard_Boolean OpenGl_Workspace::UpdateRaytraceGeometry (GeomUpdateMode theMod
   std::set<const OpenGl_Structure*> anElements;
 
   // Set of all currently visible and "raytracable" primitive arrays.
-  std::set<const OpenGl_PrimitiveArray*> anArrays;
+  std::set<Standard_Size> anArrayIDs;
 
   const OpenGl_LayerList& aList = myView->LayerList();
 
@@ -103,8 +105,6 @@ Standard_Boolean OpenGl_Workspace::UpdateRaytraceGeometry (GeomUpdateMode theMod
 
       for (aStructIt.Init (aStructArray (anIndex)); aStructIt.More(); aStructIt.Next())
       {
-        Standard_ShortReal* aTransform (NULL);
-
         const OpenGl_Structure* aStructure = aStructIt.Value();
 
         if (theMode == OpenGl_GUM_CHECK)
@@ -130,7 +130,7 @@ Standard_Boolean OpenGl_Workspace::UpdateRaytraceGeometry (GeomUpdateMode theMod
               if (aPrimArray != NULL)
               {
                 // Collect all primitive arrays in scene.
-                anArrays.insert (aPrimArray);
+                anArrayIDs.insert (aPrimArray->GetUID());
               }
             }
           }
@@ -140,22 +140,8 @@ Standard_Boolean OpenGl_Workspace::UpdateRaytraceGeometry (GeomUpdateMode theMod
           if (!aStructure->IsRaytracable())
             continue;
 
-          if (aStructure->Transformation()->mat != NULL)
-          {
-            if (aTransform == NULL)
-              aTransform = new Standard_ShortReal[16];
-
-            for (Standard_Integer i = 0; i < 4; ++i)
-              for (Standard_Integer j = 0; j < 4; ++j)
-              {
-                aTransform[j * 4 + i] = aStructure->Transformation()->mat[i][j];
-              }
-          }
-
-          AddRaytraceStructure (aStructure, aTransform, anElements);
+          AddRaytraceStructure (aStructure, anElements);
         }
-
-        delete [] aTransform;
       }
     }
   }
@@ -174,11 +160,11 @@ Standard_Boolean OpenGl_Workspace::UpdateRaytraceGeometry (GeomUpdateMode theMod
       // If primitive array of object not in "anArrays" set then it was hided or deleted.
       // If primitive array present in "anArrays" set but we don't have associated object yet, then
       // the object is new and still has to be built.
-      if ((aTriangleSet != NULL) && ((anArrays.find (aTriangleSet->AssociatedPArray())) != anArrays.end()))
+      if ((aTriangleSet != NULL) && ((anArrayIDs.find (aTriangleSet->AssociatedPArrayID())) != anArrayIDs.end()))
       {
         anUnchangedObjects.Append (myRaytraceGeometry.Objects().Value (anObjectIdx));
 
-        myArrayToTrianglesMap[aTriangleSet->AssociatedPArray()] = aTriangleSet;
+        myArrayToTrianglesMap[aTriangleSet->AssociatedPArrayID()] = aTriangleSet;
       }
     }
 
@@ -219,7 +205,7 @@ Standard_Boolean OpenGl_Workspace::UpdateRaytraceGeometry (GeomUpdateMode theMod
 
     const BVH_Vec4f aSize = myRaytraceGeometry.Box().Size();
 
-    myRaytraceSceneEpsilon = Max (1e-7f, 1e-4f * sqrtf (
+    myRaytraceSceneEpsilon = Max (1e-6f, 1e-4f * sqrtf (
       aSize.x() * aSize.x() + aSize.y() * aSize.y() + aSize.z() * aSize.z()));
 
     return UploadRaytraceData();
@@ -309,8 +295,7 @@ void CreateMaterial (const OPENGL_SURF_PROP& theProp, OpenGl_RaytraceMaterial& t
 // function : AddRaytraceStructure
 // purpose  : Adds OpenGL structure to ray-traced scene geometry
 // =======================================================================
-Standard_Boolean OpenGl_Workspace::AddRaytraceStructure (const OpenGl_Structure* theStructure,
-  const Standard_ShortReal* theTransform, std::set<const OpenGl_Structure*>& theElements)
+Standard_Boolean OpenGl_Workspace::AddRaytraceStructure (const OpenGl_Structure* theStructure, std::set<const OpenGl_Structure*>& theElements)
 {
   theElements.insert (theStructure);
 
@@ -333,6 +318,41 @@ Standard_Boolean OpenGl_Workspace::AddRaytraceStructure (const OpenGl_Structure*
     myRaytraceGeometry.Materials.push_back (aStructMaterial);
   }
 
+  Standard_ShortReal  aStructTransformArr[16];
+  Standard_ShortReal* aStructTransform = NULL;
+  if (theStructure->Transformation()->mat != NULL)
+  {
+    aStructTransform = aStructTransformArr;
+    for (Standard_Integer i = 0; i < 4; ++i)
+    {
+      for (Standard_Integer j = 0; j < 4; ++j)
+      {
+        aStructTransform[j * 4 + i] = theStructure->Transformation()->mat[i][j];
+      }
+    }
+  }
+
+  AddRaytraceGroups (theStructure, aStructMatID, aStructTransform);
+
+  // Process all connected OpenGL structures
+  for (OpenGl_ListOfStructure::Iterator anIts (theStructure->ConnectedStructures()); anIts.More(); anIts.Next())
+  {
+    if (anIts.Value()->IsRaytracable())
+      AddRaytraceGroups (anIts.Value(), aStructMatID, aStructTransform);
+  }
+
+  myStructureStates[theStructure] = theStructure->ModificationState();
+  return Standard_True;
+}
+
+// =======================================================================
+// function : AddRaytraceGroups
+// purpose  : Adds OpenGL groups to ray-traced scene geometry
+// =======================================================================
+Standard_Boolean OpenGl_Workspace::AddRaytraceGroups (const OpenGl_Structure*   theStructure,
+                                                      const Standard_Integer    theStructMatId,
+                                                      const Standard_ShortReal* theTransform)
+{
   for (OpenGl_Structure::GroupIterator aGroupIter (theStructure->DrawGroups()); aGroupIter.More(); aGroupIter.Next())
   {
     // Get group material
@@ -347,7 +367,7 @@ Standard_Boolean OpenGl_Workspace::AddRaytraceStructure (const OpenGl_Structure*
       myRaytraceGeometry.Materials.push_back (aGroupMaterial);
     }
 
-    Standard_Integer aMatID = aGroupMatID < 0 ? aStructMatID : aGroupMatID;
+    Standard_Integer aMatID = aGroupMatID < 0 ? theStructMatId : aGroupMatID;
 
     if (aMatID < 0)
     {
@@ -373,10 +393,10 @@ Standard_Boolean OpenGl_Workspace::AddRaytraceStructure (const OpenGl_Structure*
       {
         OpenGl_PrimitiveArray* aPrimArray = dynamic_cast<OpenGl_PrimitiveArray*> (aNode->elem);
 
-        std::map<const OpenGl_PrimitiveArray*, OpenGl_TriangleSet*>::iterator aSetIter = myArrayToTrianglesMap.find (aPrimArray);
-
         if (aPrimArray != NULL)
         {
+          std::map<Standard_Size, OpenGl_TriangleSet*>::iterator aSetIter = myArrayToTrianglesMap.find (aPrimArray->GetUID());
+
           if (aSetIter != myArrayToTrianglesMap.end())
           {
             OpenGl_TriangleSet* aSet = aSetIter->second;
@@ -419,32 +439,6 @@ Standard_Boolean OpenGl_Workspace::AddRaytraceStructure (const OpenGl_Structure*
     }
   }
 
-  Standard_ShortReal* aTransform = NULL;
-
-  // Process all connected OpenGL structures
-  for (OpenGl_ListOfStructure::Iterator anIts (theStructure->ConnectedStructures()); anIts.More(); anIts.Next())
-  {
-    if (anIts.Value()->Transformation()->mat != NULL)
-    {
-      if (aTransform == NULL)
-        aTransform = new Standard_ShortReal[16];
-
-      for (Standard_Integer i = 0; i < 4; ++i)
-        for (Standard_Integer j = 0; j < 4; ++j)
-        {
-          aTransform[j * 4 + i] =
-            anIts.Value()->Transformation()->mat[i][j];
-        }
-    }
-
-    if (anIts.Value()->IsRaytracable())
-      AddRaytraceStructure (anIts.Value(), aTransform != NULL ? aTransform : theTransform, theElements);
-  }
-
-  delete[] aTransform;
-
-  myStructureStates[theStructure] = theStructure->ModificationState();
-
   return Standard_True;
 }
 
@@ -467,7 +461,7 @@ OpenGl_TriangleSet* OpenGl_Workspace::AddRaytracePrimitiveArray (const OpenGl_Pr
   }
 
 #ifdef RAY_TRACE_PRINT_INFO
-  switch (aPArray->DrawMode())
+  switch (theArray->DrawMode())
   {
     case GL_POLYGON:        std::cout << "\tAdding GL_POLYGON\n";        break;
     case GL_TRIANGLES:      std::cout << "\tAdding GL_TRIANGLES\n";      break;
@@ -478,7 +472,7 @@ OpenGl_TriangleSet* OpenGl_Workspace::AddRaytracePrimitiveArray (const OpenGl_Pr
   }
 #endif
 
-  OpenGl_TriangleSet* aSet = new OpenGl_TriangleSet (theArray);
+  OpenGl_TriangleSet* aSet = new OpenGl_TriangleSet (theArray->GetUID());
   {
     aSet->Vertices.reserve (anAttribs->NbElements);
     aSet->Normals .reserve (anAttribs->NbElements);
@@ -546,7 +540,7 @@ OpenGl_TriangleSet* OpenGl_Workspace::AddRaytracePrimitiveArray (const OpenGl_Pr
     if (!aBounds.IsNull())
     {
   #ifdef RAY_TRACE_PRINT_INFO
-      std::cout << "\tNumber of bounds = " << aPArray->num_bounds << std::endl;
+      std::cout << "\tNumber of bounds = " << aBounds->NbBounds << std::endl;
   #endif
 
       Standard_Integer aBoundStart = 0;
@@ -1119,7 +1113,7 @@ Standard_Boolean OpenGl_Workspace::SafeFailBack (const TCollection_ExtendedStrin
 // function : InitRaytraceResources
 // purpose  : Initializes OpenGL/GLSL shader programs
 // =======================================================================
-Standard_Boolean OpenGl_Workspace::InitRaytraceResources()
+Standard_Boolean OpenGl_Workspace::InitRaytraceResources (const Graphic3d_CView& theCView)
 {
   Standard_Boolean aToRebuildShaders = Standard_False;
 
@@ -1131,39 +1125,60 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources()
     const Standard_Integer aRequiredStackSize =
       myRaytraceGeometry.HighLevelTreeDepth() + myRaytraceGeometry.BottomLevelTreeDepth();
 
-    if (myTraversalStackSize < aRequiredStackSize)
+    if (myRaytraceParameters.StackSize < aRequiredStackSize)
     {
-      myTraversalStackSize = Max (aRequiredStackSize, THE_DEFAULT_STACK_SIZE);
+      myRaytraceParameters.StackSize = Max (aRequiredStackSize, THE_DEFAULT_STACK_SIZE);
 
       aToRebuildShaders = Standard_True;
     }
     else
     {
-      if (aRequiredStackSize < myTraversalStackSize)
+      if (aRequiredStackSize < myRaytraceParameters.StackSize)
       {
-        if (myTraversalStackSize > THE_DEFAULT_STACK_SIZE)
+        if (myRaytraceParameters.StackSize > THE_DEFAULT_STACK_SIZE)
         {
-          myTraversalStackSize = Max (aRequiredStackSize, THE_DEFAULT_STACK_SIZE);
-
+          myRaytraceParameters.StackSize = Max (aRequiredStackSize, THE_DEFAULT_STACK_SIZE);
           aToRebuildShaders = Standard_True;
         }
       }
     }
 
+    if (theCView.RenderParams.RaytracingDepth != myRaytraceParameters.TraceDepth)
+    {
+      myRaytraceParameters.TraceDepth = theCView.RenderParams.RaytracingDepth;
+      aToRebuildShaders = Standard_True;
+    }
+
+    if (theCView.RenderParams.IsTransparentShadowEnabled != myRaytraceParameters.TransparentShadows)
+    {
+      myRaytraceParameters.TransparentShadows = theCView.RenderParams.IsTransparentShadowEnabled;
+      aToRebuildShaders = Standard_True;
+    }
+
     if (aToRebuildShaders)
     {
 #ifdef RAY_TRACE_PRINT_INFO
-      std::cout << "Info: Rebuild shaders with stack size: " << myTraversalStackSize << std::endl;
+      std::cout << "Info: Rebuild shaders with stack size: " << myRaytraceParameters.StackSize << std::endl;
 #endif
 
-      // Change state to force update all uniforms.
+      // Change state to force update all uniforms
       ++myViewModificationStatus;
 
-      TCollection_AsciiString aStackSizeStr =
-        TCollection_AsciiString ("#define STACK_SIZE ") + TCollection_AsciiString (myTraversalStackSize);
+      TCollection_AsciiString aPrefixString =
+        TCollection_AsciiString ("#define STACK_SIZE ") + TCollection_AsciiString (myRaytraceParameters.StackSize) + "\n" +
+        TCollection_AsciiString ("#define TRACE_DEPTH ") + TCollection_AsciiString (myRaytraceParameters.TraceDepth);
 
-      myRaytraceShaderSource.SetPrefix (aStackSizeStr);
-      myPostFSAAShaderSource.SetPrefix (aStackSizeStr);
+      if (myRaytraceParameters.TransparentShadows)
+      {
+        aPrefixString += TCollection_AsciiString ("\n#define TRANSPARENT_SHADOWS");
+      }
+
+#ifdef RAY_TRACE_PRINT_INFO
+      std::cout << "GLSL prefix string:" << std::endl << aPrefixString << std::endl;
+#endif
+
+      myRaytraceShaderSource.SetPrefix (aPrefixString);
+      myPostFSAAShaderSource.SetPrefix (aPrefixString);
 
       if (!myRaytraceShader->LoadSource (myGlContext, myRaytraceShaderSource.Source())
        || !myPostFSAAShader->LoadSource (myGlContext, myPostFSAAShaderSource.Source()))
@@ -1197,6 +1212,8 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources()
       return Standard_False;
     }
 
+    myRaytraceParameters.TraceDepth = theCView.RenderParams.RaytracingDepth;
+
     TCollection_AsciiString aFolder = Graphic3d_ShaderProgram::ShadersFolder();
 
     if (aFolder.IsEmpty())
@@ -1211,10 +1228,23 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources()
 
     if (myIsRaytraceDataValid)
     {
-      myTraversalStackSize = Max (THE_DEFAULT_STACK_SIZE,
+      myRaytraceParameters.StackSize = Max (THE_DEFAULT_STACK_SIZE,
         myRaytraceGeometry.HighLevelTreeDepth() + myRaytraceGeometry.BottomLevelTreeDepth());
     }
 
+    TCollection_AsciiString aPrefixString =
+      TCollection_AsciiString ("#define STACK_SIZE ") + TCollection_AsciiString (myRaytraceParameters.StackSize) + "\n" +
+      TCollection_AsciiString ("#define TRACE_DEPTH ") + TCollection_AsciiString (myRaytraceParameters.TraceDepth);
+
+    if (myRaytraceParameters.TransparentShadows)
+    {
+      aPrefixString += TCollection_AsciiString ("\n#define TRANSPARENT_SHADOWS");
+    }
+
+#ifdef RAY_TRACE_PRINT_INFO
+    std::cout << "GLSL prefix string:" << std::endl << aPrefixString << std::endl;
+#endif
+
     {
       Handle(OpenGl_ShaderObject) aBasicVertShader = LoadShader (
         ShaderSource (aFolder + "/RaytraceBase.vs"), GL_VERTEX_SHADER);
@@ -1228,10 +1258,7 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources()
 
       myRaytraceShaderSource.Load (aFiles, 2);
 
-      TCollection_AsciiString aStackSizeStr =
-        TCollection_AsciiString ("#define STACK_SIZE ") + TCollection_AsciiString (myTraversalStackSize);
-
-      myRaytraceShaderSource.SetPrefix (aStackSizeStr);
+      myRaytraceShaderSource.SetPrefix (aPrefixString);
 
       myRaytraceShader = LoadShader (myRaytraceShaderSource, GL_FRAGMENT_SHADER);
 
@@ -1287,10 +1314,7 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources()
 
       myPostFSAAShaderSource.Load (aFiles, 2);
 
-      TCollection_AsciiString aStackSizeStr =
-        TCollection_AsciiString ("#define STACK_SIZE ") + TCollection_AsciiString (myTraversalStackSize);
-
-      myPostFSAAShaderSource.SetPrefix (aStackSizeStr);
+      myPostFSAAShaderSource.SetPrefix (aPrefixString);
     
       myPostFSAAShader = LoadShader (myPostFSAAShaderSource, GL_FRAGMENT_SHADER);
 
@@ -1370,6 +1394,11 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources()
       aShaderProgram->SetSampler (myGlContext,
         "uEnvironmentMapTexture", OpenGl_RT_EnvironmentMapTexture);
 
+      aShaderProgram->SetSampler (myGlContext,
+        "uOpenGlColorTexture", OpenGl_RT_OpenGlColorTexture);
+      aShaderProgram->SetSampler (myGlContext,
+        "uOpenGlDepthTexture", OpenGl_RT_OpenGlDepthTexture);
+
       if (anIndex == 1)
       {
         aShaderProgram->SetSampler (myGlContext,
@@ -1395,6 +1424,8 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources()
         aShaderProgram->GetUniformLocation (myGlContext, "uDirectLT");
       myUniformLocations[anIndex][OpenGl_RT_uDirectRT] =
         aShaderProgram->GetUniformLocation (myGlContext, "uDirectRT");
+      myUniformLocations[anIndex][OpenGl_RT_uInvModelProj] =
+        aShaderProgram->GetUniformLocation (myGlContext, "uInvModelProj");
 
       myUniformLocations[anIndex][OpenGl_RT_uLightCount] =
         aShaderProgram->GetUniformLocation (myGlContext, "uLightCount");
@@ -1474,6 +1505,7 @@ inline void NullifyResource (const Handle(OpenGl_Context)& theContext,
 // =======================================================================
 void OpenGl_Workspace::ReleaseRaytraceResources()
 {
+  NullifyResource (myGlContext, myOpenGlFBO);
   NullifyResource (myGlContext, myRaytraceFBO1);
   NullifyResource (myGlContext, myRaytraceFBO2);
 
@@ -1487,8 +1519,6 @@ void OpenGl_Workspace::ReleaseRaytraceResources()
   NullifyResource (myGlContext, mySceneMinPointTexture);
   NullifyResource (myGlContext, mySceneMaxPointTexture);
 
-  NullifyResource (myGlContext, mySceneTransformTexture);
-
   NullifyResource (myGlContext, myObjectNodeInfoTexture);
   NullifyResource (myGlContext, myObjectMinPointTexture);
   NullifyResource (myGlContext, myObjectMaxPointTexture);
@@ -1496,6 +1526,7 @@ void OpenGl_Workspace::ReleaseRaytraceResources()
   NullifyResource (myGlContext, myGeometryVertexTexture);
   NullifyResource (myGlContext, myGeometryNormalTexture);
   NullifyResource (myGlContext, myGeometryTriangTexture);
+  NullifyResource (myGlContext, mySceneTransformTexture);
 
   NullifyResource (myGlContext, myRaytraceLightSrcTexture);
   NullifyResource (myGlContext, myRaytraceMaterialTexture);
@@ -1588,7 +1619,7 @@ Standard_Boolean OpenGl_Workspace::UploadRaytraceData()
   }
 
   /////////////////////////////////////////////////////////////////////////////
-  // Write OpenGL texture buffers
+  // Write top-level BVH buffers
 
   const NCollection_Handle<BVH_Tree<Standard_ShortReal, 4> >& aBVH = myRaytraceGeometry.BVH();
 
@@ -1637,6 +1668,7 @@ Standard_Boolean OpenGl_Workspace::UploadRaytraceData()
   delete[] aNodeTransforms;
 
   /////////////////////////////////////////////////////////////////////////////
+  // Write geometry and bottom-level BVH buffers
 
   Standard_Size aTotalVerticesNb = 0;
   Standard_Size aTotalElementsNb = 0;
@@ -1806,9 +1838,6 @@ Standard_Boolean OpenGl_Workspace::UploadRaytraceData()
   aMemUsed += static_cast<Standard_ShortReal> (
     myRaytraceGeometry.BVH()->MaxPointBuffer().size() * sizeof (BVH_Vec4f));
 
-  aMemUsed += static_cast<Standard_ShortReal> (
-    aTransformsNb * sizeof (BVH_Vec4f) * 4);
-
   std::cout << "GPU Memory Used (MB): ~" << aMemUsed / 1048576 << std::endl;
 
 #endif
@@ -1840,12 +1869,11 @@ Standard_Boolean OpenGl_Workspace::ResizeRaytraceBuffers (const Standard_Integer
 void OpenGl_Workspace::UpdateCamera (const NCollection_Mat4<GLdouble>& theOrientation,
                                      const NCollection_Mat4<GLdouble>& theViewMapping,
                                      OpenGl_Vec3                       theOrigins[4],
-                                     OpenGl_Vec3                       theDirects[4])
+                                     OpenGl_Vec3                       theDirects[4],
+                                     NCollection_Mat4<GLdouble>&       theInvModelProj)
 {
-  NCollection_Mat4<GLdouble> aInvModelProj;
-
-  // compute invserse model-view-projection matrix
-  (theViewMapping * theOrientation).Inverted (aInvModelProj);
+  // compute inverse model-view-projection matrix
+  (theViewMapping * theOrientation).Inverted (theInvModelProj);
 
   Standard_Integer aOriginIndex = 0;
   Standard_Integer aDirectIndex = 0;
@@ -1859,7 +1887,7 @@ void OpenGl_Workspace::UpdateCamera (const NCollection_Mat4<GLdouble>& theOrient
                            -1.0,
                             1.0);
 
-      aOrigin = aInvModelProj * aOrigin;
+      aOrigin = theInvModelProj * aOrigin;
 
       aOrigin.x() = aOrigin.x() / aOrigin.w();
       aOrigin.y() = aOrigin.y() / aOrigin.w();
@@ -1870,7 +1898,7 @@ void OpenGl_Workspace::UpdateCamera (const NCollection_Mat4<GLdouble>& theOrient
                             1.0,
                             1.0);
 
-      aDirect = aInvModelProj * aDirect;
+      aDirect = theInvModelProj * aDirect;
 
       aDirect.x() = aDirect.x() / aDirect.w();
       aDirect.y() = aDirect.y() / aDirect.w();
@@ -1902,6 +1930,7 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th
                                                        const Standard_Integer theSizeY,
                                                        const OpenGl_Vec3      theOrigins[4],
                                                        const OpenGl_Vec3      theDirects[4],
+                                                       const OpenGl_Matrix&   theInvModelProj,
                                                        OpenGl_FrameBuffer*    theFrameBuffer)
 {
   mySceneMinPointTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMinPointTexture);
@@ -1913,11 +1942,14 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th
   myGeometryVertexTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryVertexTexture);
   myGeometryNormalTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryNormalTexture);
   myGeometryTriangTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryTriangTexture);
+  mySceneTransformTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneTransformTexture);
   myRaytraceMaterialTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceMaterialTexture);
   myRaytraceLightSrcTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceLightSrcTexture);
-  mySceneTransformTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneTransformTexture);
+  
+  myOpenGlFBO->ColorTexture()->Bind        (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlColorTexture);
+  myOpenGlFBO->DepthStencilTexture()->Bind (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlDepthTexture);
 
-  if (theCView.IsAntialiasingEnabled) // render source image to FBO
+  if (theCView.RenderParams.IsAntialiasingEnabled) // render source image to FBO
   {
     myRaytraceFBO1->BindBuffer (myGlContext);
     
@@ -1945,6 +1977,8 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th
     myUniformLocations[0][OpenGl_RT_uDirectLT], theDirects[2]);
   myRaytraceProgram->SetUniform (myGlContext,
     myUniformLocations[0][OpenGl_RT_uDirectRT], theDirects[3]);
+  myRaytraceProgram->SetUniform (myGlContext,
+    myUniformLocations[0][OpenGl_RT_uInvModelProj], theInvModelProj);
   myRaytraceProgram->SetUniform (myGlContext,
     myUniformLocations[0][OpenGl_RT_uSceneRad], myRaytraceSceneRadius);
   myRaytraceProgram->SetUniform (myGlContext,
@@ -1954,9 +1988,9 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th
   myRaytraceProgram->SetUniform (myGlContext,
     myUniformLocations[0][OpenGl_RT_uLightAmbnt], myRaytraceGeometry.Ambient);
   myRaytraceProgram->SetUniform (myGlContext,
-    myUniformLocations[0][OpenGl_RT_uShadEnabled], theCView.IsShadowsEnabled);
+    myUniformLocations[0][OpenGl_RT_uShadEnabled], theCView.RenderParams.IsShadowEnabled ? 1 : 0);
   myRaytraceProgram->SetUniform (myGlContext,
-    myUniformLocations[0][OpenGl_RT_uReflEnabled], theCView.IsReflectionsEnabled);
+    myUniformLocations[0][OpenGl_RT_uReflEnabled], theCView.RenderParams.IsReflectionEnabled ? 1 : 0);
 
   myGlContext->core20fwd->glEnableVertexAttribArray (
     myUniformLocations[0][OpenGl_RT_aPosition]);
@@ -1969,10 +2003,27 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th
   myGlContext->core20fwd->glDisableVertexAttribArray (
     myUniformLocations[0][OpenGl_RT_aPosition]);
   
-  if (!theCView.IsAntialiasingEnabled)
+  if (!theCView.RenderParams.IsAntialiasingEnabled)
   {
     myRaytraceProgram->Unbind (myGlContext);
 
+    myOpenGlFBO->ColorTexture()->Unbind        (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlColorTexture);
+    myOpenGlFBO->DepthStencilTexture()->Unbind (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlDepthTexture);
+    mySceneMinPointTexture->UnbindTexture      (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMinPointTexture);
+    mySceneMaxPointTexture->UnbindTexture      (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMaxPointTexture);
+    mySceneNodeInfoTexture->UnbindTexture      (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneNodeInfoTexture);
+    myObjectMinPointTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_ObjectMinPointTexture);
+    myObjectMaxPointTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_ObjectMaxPointTexture);
+    myObjectNodeInfoTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_ObjectNodeInfoTexture);
+    myGeometryVertexTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryVertexTexture);
+    myGeometryNormalTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryNormalTexture);
+    myGeometryTriangTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryTriangTexture);
+    myRaytraceMaterialTexture->UnbindTexture   (myGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceMaterialTexture);
+    myRaytraceLightSrcTexture->UnbindTexture   (myGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceLightSrcTexture);
+    mySceneTransformTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneTransformTexture);
+
+    myGlContext->core15fwd->glActiveTexture (GL_TEXTURE0);
+
     return Standard_True;
   }
 
@@ -1996,6 +2047,8 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th
     myUniformLocations[1][OpenGl_RT_uDirectLT], theDirects[2]);
   myPostFSAAProgram->SetUniform (myGlContext,
     myUniformLocations[1][OpenGl_RT_uDirectRT], theDirects[3]);
+  myRaytraceProgram->SetUniform (myGlContext,
+    myUniformLocations[1][OpenGl_RT_uInvModelProj], theInvModelProj);
   myPostFSAAProgram->SetUniform (myGlContext,
     myUniformLocations[1][OpenGl_RT_uSceneRad], myRaytraceSceneRadius);
   myPostFSAAProgram->SetUniform (myGlContext,
@@ -2005,9 +2058,9 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th
   myPostFSAAProgram->SetUniform (myGlContext,
     myUniformLocations[1][OpenGl_RT_uLightAmbnt], myRaytraceGeometry.Ambient);
   myPostFSAAProgram->SetUniform (myGlContext,
-    myUniformLocations[1][OpenGl_RT_uShadEnabled], theCView.IsShadowsEnabled);
+    myUniformLocations[1][OpenGl_RT_uShadEnabled], theCView.RenderParams.IsShadowEnabled ? 1 : 0);
   myPostFSAAProgram->SetUniform (myGlContext,
-    myUniformLocations[1][OpenGl_RT_uReflEnabled], theCView.IsReflectionsEnabled);
+    myUniformLocations[1][OpenGl_RT_uReflEnabled], theCView.RenderParams.IsReflectionEnabled ? 1 : 0);
 
   const Standard_ShortReal aMaxOffset = 0.559017f;
   const Standard_ShortReal aMinOffset = 0.186339f;
@@ -2070,6 +2123,23 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th
     myUniformLocations[1][OpenGl_RT_aPosition]);
 
   myPostFSAAProgram->Unbind (myGlContext);
+  myRaytraceFBO1->ColorTexture()->Unbind     (myGlContext, GL_TEXTURE0 + OpenGl_RT_FSAAInputTexture);
+  myOpenGlFBO->ColorTexture()->Unbind        (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlColorTexture);
+  myOpenGlFBO->DepthStencilTexture()->Unbind (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlDepthTexture);
+  mySceneMinPointTexture->UnbindTexture      (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMinPointTexture);
+  mySceneMaxPointTexture->UnbindTexture      (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMaxPointTexture);
+  mySceneNodeInfoTexture->UnbindTexture      (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneNodeInfoTexture);
+  myObjectMinPointTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_ObjectMinPointTexture);
+  myObjectMaxPointTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_ObjectMaxPointTexture);
+  myObjectNodeInfoTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_ObjectNodeInfoTexture);
+  myGeometryVertexTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryVertexTexture);
+  myGeometryNormalTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryNormalTexture);
+  myGeometryTriangTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryTriangTexture);
+  myRaytraceMaterialTexture->UnbindTexture   (myGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceMaterialTexture);
+  myRaytraceLightSrcTexture->UnbindTexture   (myGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceLightSrcTexture);
+  mySceneTransformTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneTransformTexture);
+
+  myGlContext->core15fwd->glActiveTexture (GL_TEXTURE0);
 
   return Standard_True;
 }
@@ -2082,12 +2152,11 @@ Standard_Boolean OpenGl_Workspace::Raytrace (const Graphic3d_CView& theCView,
                                              const Standard_Integer theSizeX,
                                              const Standard_Integer theSizeY,
                                              const Standard_Boolean theToSwap,
+                                             const Aspect_CLayer2d& theCOverLayer,
+                                             const Aspect_CLayer2d& theCUnderLayer,
                                              OpenGl_FrameBuffer*    theFrameBuffer)
 {
-  if (!UpdateRaytraceGeometry (OpenGl_GUM_CHECK))
-    return Standard_False;
-
-  if (!InitRaytraceResources())
+  if (!InitRaytraceResources (theCView))
     return Standard_False;
 
   if (!ResizeRaytraceBuffers (theSizeX, theSizeY))
@@ -2122,17 +2191,33 @@ Standard_Boolean OpenGl_Workspace::Raytrace (const Graphic3d_CView& theCView,
 
   OpenGl_Vec3 aOrigins[4];
   OpenGl_Vec3 aDirects[4];
+  NCollection_Mat4<GLdouble> anInvModelProj;
 
   UpdateCamera (aOrientationMatrix,
                 aViewMappingMatrix,
                 aOrigins,
-                aDirects);
+                aDirects,
+                anInvModelProj);
+
+  OpenGl_Matrix anInvModelProjMatrix;
+  for (Standard_Integer j = 0; j < 4; ++j)
+  {
+    for (Standard_Integer i = 0; i < 4; ++i)
+    {
+      anInvModelProjMatrix.mat[j][i] = static_cast<GLfloat>(anInvModelProj.GetValue(i,j));
+    }
+  }
 
   Standard_Boolean wasBlendingEnabled = glIsEnabled (GL_BLEND);
   Standard_Boolean wasDepthTestEnabled = glIsEnabled (GL_DEPTH_TEST);
 
   glDisable (GL_DEPTH_TEST);
 
+  if (theFrameBuffer != NULL)
+  {
+    theFrameBuffer->BindBuffer (myGlContext);
+  }
+
   if (NamedStatus & OPENGL_NS_WHITEBACK)
   {
     glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
@@ -2147,16 +2232,17 @@ Standard_Boolean OpenGl_Workspace::Raytrace (const Graphic3d_CView& theCView,
 
   glClear (GL_COLOR_BUFFER_BIT);
 
-  if (theFrameBuffer != NULL)
-    theFrameBuffer->BindBuffer (myGlContext);
-
   myView->DrawBackground (*this);
 
+  myView->RedrawLayer2d (myPrintContext, theCView, theCUnderLayer);
+
   // Generate ray-traced image
   glMatrixMode (GL_PROJECTION);
+  glPushMatrix();
   glLoadIdentity();
 
   glMatrixMode (GL_MODELVIEW);
+  glPushMatrix();
   glLoadIdentity();
 
   glEnable (GL_BLEND);
@@ -2171,6 +2257,7 @@ Standard_Boolean OpenGl_Workspace::Raytrace (const Graphic3d_CView& theCView,
                         theSizeY,
                         aOrigins,
                         aDirects,
+                        anInvModelProjMatrix,
                         theFrameBuffer);
 
     myRaytraceScreenQuad.Unbind (myGlContext);
@@ -2182,6 +2269,20 @@ Standard_Boolean OpenGl_Workspace::Raytrace (const Graphic3d_CView& theCView,
   if (wasDepthTestEnabled)
     glEnable (GL_DEPTH_TEST);
 
+  glMatrixMode (GL_PROJECTION);
+  glPopMatrix();
+  glMatrixMode (GL_MODELVIEW);
+  glPopMatrix();
+
+  // Redraw trihedron
+  myView->RedrawTrihedron (this);
+
+  // Redraw overlay
+  const int aMode = 0;
+  DisplayCallback (theCView, (aMode | OCC_PRE_OVERLAY));
+  myView->RedrawLayer2d (myPrintContext, theCView, theCOverLayer);
+  DisplayCallback (theCView, aMode);
+
   // Swap the buffers
   if (theToSwap)
   {
@@ -2195,3 +2296,21 @@ Standard_Boolean OpenGl_Workspace::Raytrace (const Graphic3d_CView& theCView,
 
   return Standard_True;
 }
+
+IMPLEMENT_STANDARD_HANDLE(OpenGl_RaytraceFilter, OpenGl_RenderFilter)
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_RaytraceFilter, OpenGl_RenderFilter)
+
+// =======================================================================
+// function : CanRender
+// purpose  :
+// =======================================================================
+Standard_Boolean OpenGl_RaytraceFilter::CanRender (const OpenGl_Element* theElement)
+{
+  Standard_Boolean aPrevFilterResult = Standard_True;
+  if (!myPrevRenderFilter.IsNull())
+  {
+    aPrevFilterResult = myPrevRenderFilter->CanRender(theElement);
+  }
+  return aPrevFilterResult &&
+         !OpenGl_Raytrace::IsRaytracedElement (theElement);
+}