0024887: Visualization - revise and extend Raytracing controls
authordbp <dbp@opencascade.com>
Thu, 22 May 2014 14:57:34 +0000 (18:57 +0400)
committerapn <apn@opencascade.com>
Thu, 22 May 2014 15:00:18 +0000 (19:00 +0400)
Fix material test case.
Fix ray-tracing test case and sample.

18 files changed:
samples/tcl/raytrace.tcl
src/Graphic3d/FILES
src/Graphic3d/Graphic3d.cdl
src/Graphic3d/Graphic3d_CView.hxx
src/Graphic3d/Graphic3d_RenderingParams.hxx [new file with mode: 0644]
src/OpenGl/OpenGl_GraphicDriver_7.cxx
src/OpenGl/OpenGl_Workspace.cxx
src/OpenGl/OpenGl_Workspace.hxx
src/OpenGl/OpenGl_Workspace_Raytrace.cxx
src/Shaders/RaytraceBase.fs
src/V3d/V3d_View.cdl
src/V3d/V3d_View_5.cxx
src/ViewerTest/ViewerTest_ViewerCommands.cxx
tests/v3d/materials/bug24855
tests/v3d/raytrace/bug24130
tests/v3d/raytrace/connected
tests/v3d/raytrace/plastic
tests/v3d/raytrace/refraction

index efe00e4..f203a17 100644 (file)
@@ -31,7 +31,6 @@ vfit
 
 # set ray tracing
 puts "Trying raytrace mode..."
-if { ! [catch {vraytrace 1}] } {
+if { ! [catch {vrenderparams -raytrace -shadows -reflections -fsaa -rayDepth 5}] } {
   vtextureenv on 1
-  vsetraytracemode shad=1 refl=1 aa=1
 }
index b17e375..84af421 100755 (executable)
@@ -67,3 +67,4 @@ Graphic3d_SequenceOfHClipPlane_Handle.hxx
 Graphic3d_Camera.cxx
 Graphic3d_Camera.hxx
 Graphic3d_Camera_Handle.hxx
+Graphic3d_RenderingParams.hxx
index dcf0a93..e08f81a 100644 (file)
@@ -339,6 +339,13 @@ is
     -- - ASPECT_MARKER: aspect for marker primitives;
     -- - ASPECT_FILL_AREA: aspect for face primitives.
 
+    enumeration RenderingMode is
+      RM_RASTERIZATION, RM_RAYTRACING
+    end RenderingMode;
+    ---Purpose: Describes rendering modes.
+    -- - RM_RASTERIZATION: enables OpenGL rasterization mode;
+    -- - RM_RAYTRACING: enables GPU ray-tracing mode.
+
     ---------------------------
     -- Category: Imported types
     ---------------------------
@@ -404,6 +411,10 @@ is
     imported CView;
     ---Purpose: Defines the C structure <aview>
     ---Category: Imported types
+    
+    imported RenderingParams;
+    ---Purpose: Describes rendering parameters and effects.
+    ---Category: Imported types
 
     imported CGraduatedTrihedron;
     ---Purpose: Defines the C structure of a graduated trihedron.
index 980a4ad..e8d9e73 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <InterfaceGraphic_Graphic3d.hxx>
 #include <InterfaceGraphic_Visual3d.hxx>
+#include <Graphic3d_RenderingParams.hxx>
 #include <Graphic3d_TextureEnv.hxx>
 #include <Graphic3d_Camera.hxx>
 
@@ -96,11 +97,7 @@ public:
     GDisplayCB  (NULL),
     GClientData (NULL),
     ptrFBO (NULL),
-    WasRedrawnGL (0),
-    IsRaytracing (0),
-    IsShadowsEnabled (1),
-    IsReflectionsEnabled (0),
-    IsAntialiasingEnabled (0)
+    WasRedrawnGL (0)
   {
          memset(&DefWindow,0,sizeof(DefWindow));
   }
@@ -134,17 +131,8 @@ public:
   //! Was the window redrawn by standard OpenGL?
   mutable int WasRedrawnGL;
 
-  //! Enables/disables OpenCL-based ray-tracing.
-  int IsRaytracing;
-
-  //! Enables/disables ray-traced sharp shadows.
-  int IsShadowsEnabled;
-  
-  //! Enables/disables ray-traced reflections.
-  int IsReflectionsEnabled;
-  
-  //! Enables/disables ray-traced adaptive anti-aliasing.
-  int IsAntialiasingEnabled;
+  //! Specifies rendering parameters and effects.
+  Graphic3d_RenderingParams RenderParams;
 
 };
 
diff --git a/src/Graphic3d/Graphic3d_RenderingParams.hxx b/src/Graphic3d/Graphic3d_RenderingParams.hxx
new file mode 100644 (file)
index 0000000..12d1fd0
--- /dev/null
@@ -0,0 +1,65 @@
+// Created on: 2014-05-14
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Graphic3d_RenderingParams_HeaderFile
+#define _Graphic3d_RenderingParams_HeaderFile
+
+#include <Graphic3d_RenderingMode.hxx>
+
+//! Helper class to store rendering parameters.
+class Graphic3d_RenderingParams
+{
+public:
+
+  //! Default ray-tracing depth.
+  static const Standard_Integer THE_DEFAULT_DEPTH = 3;
+
+public:
+
+  //! Creates default rendering parameters.
+  Graphic3d_RenderingParams()
+  : Method (Graphic3d_RM_RASTERIZATION),
+    RaytracingDepth (THE_DEFAULT_DEPTH),
+    IsShadowEnabled (Standard_True),
+    IsReflectionEnabled (Standard_False),
+    IsAntialiasingEnabled (Standard_False),
+    IsTransparentShadowEnabled (Standard_False)
+  {
+    //
+  }
+
+public:
+
+  //! Specifies rendering mode.
+  Graphic3d_RenderingMode Method;
+
+  //! Maximum ray-tracing depth.
+  Standard_Integer RaytracingDepth;
+
+  //! Enables/disables shadows rendering.
+  Standard_Boolean IsShadowEnabled;
+
+  //! Enables/disables specular reflections.
+  Standard_Boolean IsReflectionEnabled;
+  
+  //! Enables/disables adaptive anti-aliasing.
+  Standard_Boolean IsAntialiasingEnabled;
+
+  //! Enables/disables light propagation through transparent media.
+  Standard_Boolean IsTransparentShadowEnabled;
+
+};
+
+#endif // _Graphic3d_RenderingParams_HeaderFile
index a7087e3..9eabd7f 100644 (file)
@@ -103,7 +103,7 @@ void OpenGl_GraphicDriver::Redraw (const Graphic3d_CView& ACView,
                                    const Standard_Integer /*width*/, 
                                    const Standard_Integer /*height*/)
 {
-  if (!myCaps->vboDisable && ACView.IsRaytracing)
+  if (!myCaps->vboDisable && ACView.RenderParams.Method == Graphic3d_RM_RAYTRACING)
   {
     if (ACView.WasRedrawnGL)
     {
index 35db132..b6dd166 100644 (file)
@@ -148,7 +148,6 @@ OpenGl_Workspace::OpenGl_Workspace (const Handle(Aspect_DisplayConnection)& theD
   //
   myComputeInitStatus (OpenGl_RT_NONE),
   myIsRaytraceDataValid (Standard_False),
-  myTraversalStackSize (THE_DEFAULT_STACK_SIZE),
   myViewModificationStatus (0),
   myLayersModificationStatus (0),
   //
@@ -579,7 +578,7 @@ void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
     toSwap = 0; // no need to swap buffers
   }
 
-  if (!theCView.IsRaytracing || myComputeInitStatus == OpenGl_RT_FAIL)
+  if (theCView.RenderParams.Method != Graphic3d_RM_RAYTRACING || myComputeInitStatus == OpenGl_RT_FAIL)
   {
     const Standard_Boolean isImmediate = !myView->ImmediateStructures().IsEmpty();
     redraw1 (theCView, theCUnderLayer, theCOverLayer, isImmediate ? 0 : toSwap);
index c5b7f16..d9f9634 100755 (executable)
@@ -363,9 +363,34 @@ protected:
 
   };
 
+  //! Default ray-tracing depth.
+  static const Standard_Integer THE_DEFAULT_RAY_DEPTH = 3;
+
   //! Default size of traversal stack.
   static const Standard_Integer THE_DEFAULT_STACK_SIZE = 24;
 
+  //! Compile-time ray-tracing parameters.
+  struct RaytracingParams
+  {
+    //! Actual size of traversal stack in shader program.
+    Standard_Integer StackSize;
+
+    //! Actual ray-tracing depth (number of ray bounces).
+    Standard_Integer TraceDepth;
+
+    //! Sets light propagation through transparent media.
+    Standard_Boolean TransparentShadows;
+
+    //! Creates default compile-time ray-tracing parameters.
+    RaytracingParams()
+    : StackSize (THE_DEFAULT_STACK_SIZE),
+      TraceDepth (THE_DEFAULT_RAY_DEPTH),
+      TransparentShadows (Standard_False)
+    {
+      //
+    }
+  };
+
 protected: //! @name methods related to ray-tracing
 
   //! Updates 3D scene geometry for ray-tracing.
@@ -444,7 +469,7 @@ protected: //! @name methods related to ray-tracing
   Standard_Boolean SafeFailBack (const TCollection_ExtendedString& theMessage);
 
   //! Initializes OpenGL/GLSL shader programs.
-  Standard_Boolean InitRaytraceResources();
+  Standard_Boolean InitRaytraceResources (const Graphic3d_CView& theCView);
 
   //! Releases OpenGL/GLSL shader programs.
   void ReleaseRaytraceResources();
@@ -493,8 +518,8 @@ protected: //! @name fields related to ray-tracing
   //! Scene epsilon to prevent self-intersections.
   Standard_ShortReal myRaytraceSceneEpsilon;
 
-  //! Actual size of traversal stack in shader program.
-  Standard_Integer myTraversalStackSize;
+  //! Compile-time ray-tracing parameters.
+  RaytracingParams myRaytraceParameters;
 
   //! OpenGL/GLSL source of ray-tracing fragment shader.
   ShaderSource myRaytraceShaderSource;
index ab077f4..91792ce 100755 (executable)
@@ -467,7 +467,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;
@@ -546,7 +546,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 +1119,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 +1131,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);
+
+      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 (aStackSizeStr);
-      myPostFSAAShaderSource.SetPrefix (aStackSizeStr);
+      myRaytraceShaderSource.SetPrefix (aPrefixString);
+      myPostFSAAShaderSource.SetPrefix (aPrefixString);
 
       if (!myRaytraceShader->LoadSource (myGlContext, myRaytraceShaderSource.Source())
        || !myPostFSAAShader->LoadSource (myGlContext, myPostFSAAShaderSource.Source()))
@@ -1197,6 +1218,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 +1234,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 +1264,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 +1320,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);
 
@@ -1487,8 +1517,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 +1524,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 +1617,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 +1666,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 +1836,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
@@ -1844,7 +1871,7 @@ void OpenGl_Workspace::UpdateCamera (const NCollection_Mat4<GLdouble>& theOrient
 {
   NCollection_Mat4<GLdouble> aInvModelProj;
 
-  // compute invserse model-view-projection matrix
+  // compute inverse model-view-projection matrix
   (theViewMapping * theOrientation).Inverted (aInvModelProj);
 
   Standard_Integer aOriginIndex = 0;
@@ -1917,7 +1944,7 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th
   myRaytraceLightSrcTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceLightSrcTexture);
   mySceneTransformTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneTransformTexture);
 
-  if (theCView.IsAntialiasingEnabled) // render source image to FBO
+  if (theCView.RenderParams.IsAntialiasingEnabled) // render source image to FBO
   {
     myRaytraceFBO1->BindBuffer (myGlContext);
     
@@ -1954,9 +1981,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,7 +1996,7 @@ 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);
 
@@ -2005,9 +2032,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;
@@ -2087,7 +2114,7 @@ Standard_Boolean OpenGl_Workspace::Raytrace (const Graphic3d_CView& theCView,
   if (!UpdateRaytraceGeometry (OpenGl_GUM_CHECK))
     return Standard_False;
 
-  if (!InitRaytraceResources())
+  if (!InitRaytraceResources (theCView))
     return Standard_False;
 
   if (!ResizeRaytraceBuffers (theSizeX, theSizeY))
index 39d2c77..38a8d88 100644 (file)
@@ -103,34 +103,47 @@ struct SIntersect
 
 
 // =======================================================================
-// function : MatrixRowMultiply
+// function : MatrixRowMultiplyDir
 // purpose  : Multiplies a vector by matrix
 // =======================================================================
-vec3 MatrixRowMultiply (in vec4 v,
-                        in vec4 m0,
-                        in vec4 m1,
-                        in vec4 m2,
-                        in vec4 m3)
+vec3 MatrixRowMultiplyDir (in vec3 v,
+                           in vec4 m0,
+                           in vec4 m1,
+                           in vec4 m2)
 {
-  return vec3 (dot (m0, v),
-               dot (m1, v),
-               dot (m2, v));
+  return vec3 (dot (m0.xyz, v),
+               dot (m1.xyz, v),
+               dot (m2.xyz, v));
 }
 
+// =======================================================================
+// function : MatrixColMultiplyPnt
+// purpose  : Multiplies a vector by matrix
+// =======================================================================
+vec3 MatrixColMultiplyPnt (in vec3 v,
+                           in vec4 m0,
+                           in vec4 m1,
+                           in vec4 m2,
+                           in vec4 m3)
+{
+  return vec3 (m0[0] * v.x + m1[0] * v.y + m2[0] * v.z + m3[0],
+               m0[1] * v.x + m1[1] * v.y + m2[1] * v.z + m3[1],
+               m0[2] * v.x + m1[2] * v.y + m2[2] * v.z + m3[2]);
+}
 
 // =======================================================================
-// function : MatrixColMultiply
+// function : MatrixColMultiplyDir
 // purpose  : Multiplies a vector by matrix
 // =======================================================================
-vec3 MatrixColMultiply (in vec4 v,
-                        in vec4 m0,
-                        in vec4 m1,
-                        in vec4 m2,
-                        in vec4 m3)
+vec3 MatrixColMultiplyDir (in vec3 v,
+                           in vec4 m0,
+                           in vec4 m1,
+                           in vec4 m2,
+                           in vec4 m3)
 {
-  return vec3 (m0[0] * v.x + m1[0] * v.y + m2[0] * v.z + m3[0] * v.w,
-               m0[1] * v.x + m1[1] * v.y + m2[1] * v.z + m3[1] * v.w,
-               m0[2] * v.x + m1[2] * v.y + m2[2] * v.z + m3[2] * v.w);
+  return vec3 (m0[0] * v.x + m1[0] * v.y + m2[0] * v.z,
+               m0[1] * v.x + m1[1] * v.y + m2[1] * v.z,
+               m0[2] * v.x + m1[2] * v.y + m2[2] * v.z);
 }
 
 /////////////////////////////////////////////////////////////////////////////////////////
@@ -218,25 +231,28 @@ int Stack[STACK_SIZE];
 ivec4 ObjectNearestHit (in int theBVHOffset, in int theVrtOffset, in int theTrgOffset,
   in SRay theRay, in vec3 theInverse, inout SIntersect theHit, in int theSentinel)
 {
-  int aHead = theSentinel; // stack pointer
-  int aNode = 0;           // node to visit
+  int aHead = theSentinel;  // stack pointer
+  int aNode = theBVHOffset; // node to visit
 
   ivec4 aTriIndex = INALID_HIT;
 
-  float aTimeOut;
-  float aTimeLft;
-  float aTimeRgh;
-
   while (true)
   {
-    ivec3 aData = texelFetch (uObjectNodeInfoTexture, aNode + theBVHOffset).xyz;
+    ivec3 aData = texelFetch (uObjectNodeInfoTexture, aNode).xyz;
 
     if (aData.x == 0) // if inner node
     {
-      vec3 aNodeMinLft = texelFetch (uObjectMinPointTexture, aData.y + theBVHOffset).xyz;
-      vec3 aNodeMaxLft = texelFetch (uObjectMaxPointTexture, aData.y + theBVHOffset).xyz;
-      vec3 aNodeMinRgh = texelFetch (uObjectMinPointTexture, aData.z + theBVHOffset).xyz;
-      vec3 aNodeMaxRgh = texelFetch (uObjectMaxPointTexture, aData.z + theBVHOffset).xyz;
+      float aTimeOut;
+      float aTimeLft;
+      float aTimeRgh;
+      
+      aData.y += theBVHOffset;
+      aData.z += theBVHOffset;
+  
+      vec3 aNodeMinLft = texelFetch (uObjectMinPointTexture, aData.y).xyz;
+      vec3 aNodeMaxLft = texelFetch (uObjectMaxPointTexture, aData.y).xyz;
+      vec3 aNodeMinRgh = texelFetch (uObjectMinPointTexture, aData.z).xyz;
+      vec3 aNodeMaxRgh = texelFetch (uObjectMaxPointTexture, aData.z).xyz;
 
       vec3 aTime0 = (aNodeMinLft - theRay.Origin) * theInverse;
       vec3 aTime1 = (aNodeMaxLft - theRay.Origin) * theInverse;
@@ -290,9 +306,9 @@ ivec4 ObjectNearestHit (in int theBVHOffset, in int theVrtOffset, in int theTrgO
       {
         ivec4 aTriangle = texelFetch (uGeometryTriangTexture, anIdx + theTrgOffset);
 
-        vec3 aPoint0 = texelFetch (uGeometryVertexTexture, aTriangle.x + theVrtOffset).xyz;
-        vec3 aPoint1 = texelFetch (uGeometryVertexTexture, aTriangle.y + theVrtOffset).xyz;
-        vec3 aPoint2 = texelFetch (uGeometryVertexTexture, aTriangle.z + theVrtOffset).xyz;
+        vec3 aPoint0 = texelFetch (uGeometryVertexTexture, aTriangle.x += theVrtOffset).xyz;
+        vec3 aPoint1 = texelFetch (uGeometryVertexTexture, aTriangle.y += theVrtOffset).xyz;
+        vec3 aPoint2 = texelFetch (uGeometryVertexTexture, aTriangle.z += theVrtOffset).xyz;
 
         float aTime = IntersectTriangle (theRay,
                                          aPoint0,
@@ -319,6 +335,14 @@ ivec4 ObjectNearestHit (in int theBVHOffset, in int theVrtOffset, in int theTrgO
   return aTriIndex;
 }
 
+#define MATERIAL_AMBN(index) (7 * index + 0)
+#define MATERIAL_DIFF(index) (7 * index + 1)
+#define MATERIAL_SPEC(index) (7 * index + 2)
+#define MATERIAL_EMIS(index) (7 * index + 3)
+#define MATERIAL_REFL(index) (7 * index + 4)
+#define MATERIAL_REFR(index) (7 * index + 5)
+#define MATERIAL_TRAN(index) (7 * index + 6)
+
 // =======================================================================
 // function : ObjectAnyHit
 // purpose  : Finds intersection with any object triangle
@@ -326,23 +350,30 @@ ivec4 ObjectNearestHit (in int theBVHOffset, in int theVrtOffset, in int theTrgO
 float ObjectAnyHit (in int theBVHOffset, in int theVrtOffset, in int theTrgOffset,
   in SRay theRay, in vec3 theInverse, in float theDistance, in int theSentinel)
 {
-  int aHead = theSentinel; // stack pointer
-  int aNode = 0;           // node to visit
+  int aHead = theSentinel;  // stack pointer
+  int aNode = theBVHOffset; // node to visit
 
-  float aTimeOut;
-  float aTimeLft;
-  float aTimeRgh;
+#ifdef TRANSPARENT_SHADOWS
+  float aFactor = 1.0f;
+#endif
 
   while (true)
   {
-    ivec4 aData = texelFetch (uObjectNodeInfoTexture, aNode + theBVHOffset);
+    ivec4 aData = texelFetch (uObjectNodeInfoTexture, aNode);
 
     if (aData.x == 0) // if inner node
     {
-      vec3 aNodeMinLft = texelFetch (uObjectMinPointTexture, aData.y + theBVHOffset).xyz;
-      vec3 aNodeMaxLft = texelFetch (uObjectMaxPointTexture, aData.y + theBVHOffset).xyz;
-      vec3 aNodeMinRgh = texelFetch (uObjectMinPointTexture, aData.z + theBVHOffset).xyz;
-      vec3 aNodeMaxRgh = texelFetch (uObjectMaxPointTexture, aData.z + theBVHOffset).xyz;
+      float aTimeOut;
+      float aTimeLft;
+      float aTimeRgh;
+      
+      aData.y += theBVHOffset;
+      aData.z += theBVHOffset;
+  
+      vec3 aNodeMinLft = texelFetch (uObjectMinPointTexture, aData.y).xyz;
+      vec3 aNodeMaxLft = texelFetch (uObjectMaxPointTexture, aData.y).xyz;
+      vec3 aNodeMinRgh = texelFetch (uObjectMinPointTexture, aData.z).xyz;
+      vec3 aNodeMaxRgh = texelFetch (uObjectMaxPointTexture, aData.z).xyz;
 
       vec3 aTime0 = (aNodeMinLft - theRay.Origin) * theInverse;
       vec3 aTime1 = (aNodeMaxLft - theRay.Origin) * theInverse;
@@ -380,8 +411,13 @@ float ObjectAnyHit (in int theBVHOffset, in int theVrtOffset, in int theTrgOffse
         }
         else
         {
+#ifdef TRANSPARENT_SHADOWS
+          if (aHead == theSentinel)
+            return aFactor;
+#else
           if (aHead == theSentinel)
             return 1.0f;
+#endif
 
           aNode = Stack[aHead--];
         }
@@ -406,19 +442,35 @@ float ObjectAnyHit (in int theBVHOffset, in int theVrtOffset, in int theTrgOffse
                                          aPoint2,
                                          aParams,
                                          aNormal);
-                                         
+
+#ifdef TRANSPARENT_SHADOWS
+        if (aTime < theDistance)
+        {
+          aFactor *= 1.0f - texelFetch (uRaytraceMaterialTexture, MATERIAL_TRAN (aTriangle.w)).x;
+        }
+#else
         if (aTime < theDistance)
           return 0.0f;
+#endif
       }
       
+#ifdef TRANSPARENT_SHADOWS
+      if (aHead == theSentinel || aFactor < 0.1f)
+        return aFactor;
+#else
       if (aHead == theSentinel)
         return 1.0f;
+#endif
 
       aNode = Stack[aHead--];
     }
   }
 
+#ifdef TRANSPARENT_SHADOWS
+  return aFactor;
+#else
   return 1.0f;
+#endif
 }
 
 // =======================================================================
@@ -431,10 +483,6 @@ ivec4 SceneNearestHit (in SRay theRay, in vec3 theInverse, inout SIntersect theH
   int aNode =  0; // node to visit
 
   ivec4 aHitObject = INALID_HIT;
-  
-  float aTimeOut;
-  float aTimeLft;
-  float aTimeRgh;
 
   while (true)
   {
@@ -454,34 +502,31 @@ ivec4 SceneNearestHit (in SRay theRay, in vec3 theInverse, inout SIntersect theH
       {
         // fetch object transformation
         int anObjectId = aData.x - 1;
+
         vec4 aInvTransf0 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 0);
         vec4 aInvTransf1 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 1);
         vec4 aInvTransf2 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 2);
         vec4 aInvTransf3 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 3);
 
-        SRay aNewRay;
+        SRay aTrsfRay = SRay (
+          MatrixColMultiplyPnt (theRay.Origin, aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3),
+          MatrixColMultiplyDir (theRay.Direct, aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3));
 
-        aNewRay.Origin = MatrixColMultiply (vec4 (theRay.Origin, 1.0f), 
-          aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3);
+        vec3 aTrsfInverse = 1.0f / max (abs (aTrsfRay.Direct), SMALL);
 
-        aNewRay.Direct = MatrixColMultiply (vec4 (theRay.Direct, 0.0f), 
-          aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3);
-
-        vec3 aNewInverse = 1.0f / max (abs (aNewRay.Direct), SMALL);
-        
-        aNewInverse.x = aNewRay.Direct.x < 0.0f ? -aNewInverse.x : aNewInverse.x;
-        aNewInverse.y = aNewRay.Direct.y < 0.0f ? -aNewInverse.y : aNewInverse.y;
-        aNewInverse.z = aNewRay.Direct.z < 0.0f ? -aNewInverse.z : aNewInverse.z;
+        aTrsfInverse.x = aTrsfRay.Direct.x < 0.f ? -aTrsfInverse.x : aTrsfInverse.x;
+        aTrsfInverse.y = aTrsfRay.Direct.y < 0.f ? -aTrsfInverse.y : aTrsfInverse.y;
+        aTrsfInverse.z = aTrsfRay.Direct.z < 0.f ? -aTrsfInverse.z : aTrsfInverse.z;
 
         ivec4 aTriIndex = ObjectNearestHit (
-          aData.y, aData.z, aData.w, aNewRay, aNewInverse, theHit, aHead);
+          aData.y, aData.z, aData.w, aTrsfRay, aTrsfInverse, theHit, aHead);
 
         if (aTriIndex.x != -1)
         {
-          aHitObject = ivec4 (aTriIndex.x + aData.z,  // vertex 0
-                              aTriIndex.y + aData.z,  // vertex 1
-                              aTriIndex.z + aData.z,  // vertex 2
-                              aTriIndex.w);           // material
+          aHitObject = ivec4 (aTriIndex.x,  // vertex 0
+                              aTriIndex.y,  // vertex 1
+                              aTriIndex.z,  // vertex 2
+                              aTriIndex.w); // material
 
           theObjectId = anObjectId;
         }
@@ -494,6 +539,10 @@ ivec4 SceneNearestHit (in SRay theRay, in vec3 theInverse, inout SIntersect theH
     }
     else // if inner node
     {
+      float aTimeOut;
+      float aTimeLft;
+      float aTimeRgh;
+
       vec3 aNodeMinLft = texelFetch (uSceneMinPointTexture, aData.y).xyz;
       vec3 aNodeMaxLft = texelFetch (uSceneMaxPointTexture, aData.y).xyz;
       vec3 aNodeMinRgh = texelFetch (uSceneMinPointTexture, aData.z).xyz;
@@ -555,10 +604,10 @@ float SceneAnyHit (in SRay theRay, in vec3 theInverse, in float theDistance)
 {
   int aHead = -1; // stack pointer
   int aNode =  0; // node to visit
-  
-  float aTimeOut;
-  float aTimeLft;
-  float aTimeRgh;
+
+#ifdef TRANSPARENT_SHADOWS
+  float aFactor = 1.0f;
+#endif
 
   while (true)
   {
@@ -568,35 +617,44 @@ float SceneAnyHit (in SRay theRay, in vec3 theInverse, in float theDistance)
     {
       // fetch object transformation
       int anObjectId = aData.x - 1;
+
       vec4 aInvTransf0 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 0);
       vec4 aInvTransf1 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 1);
       vec4 aInvTransf2 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 2);
       vec4 aInvTransf3 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 3);
 
-      SRay aNewRay;
+      SRay aTrsfRay = SRay (
+        MatrixColMultiplyPnt (theRay.Origin, aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3),
+        MatrixColMultiplyDir (theRay.Direct, aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3));
 
-      aNewRay.Origin = MatrixColMultiply (vec4 (theRay.Origin, 1.0f), 
-        aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3);
+      vec3 aTrsfInverse = 1.0f / max (abs (aTrsfRay.Direct), SMALL);
 
-      aNewRay.Direct = MatrixColMultiply (vec4 (theRay.Direct, 0.0f), 
-        aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3);
+      aTrsfInverse.x = aTrsfRay.Direct.x < 0.0f ? -aTrsfInverse.x : aTrsfInverse.x;
+      aTrsfInverse.y = aTrsfRay.Direct.y < 0.0f ? -aTrsfInverse.y : aTrsfInverse.y;
+      aTrsfInverse.z = aTrsfRay.Direct.z < 0.0f ? -aTrsfInverse.z : aTrsfInverse.z;
 
-      vec3 aNewInverse = 1.0f / max (abs (aNewRay.Direct), SMALL);
-      
-      aNewInverse.x = aNewRay.Direct.x < 0.0f ? -aNewInverse.x : aNewInverse.x;
-      aNewInverse.y = aNewRay.Direct.y < 0.0f ? -aNewInverse.y : aNewInverse.y;
-      aNewInverse.z = aNewRay.Direct.z < 0.0f ? -aNewInverse.z : aNewInverse.z;
+#ifdef TRANSPARENT_SHADOWS
+      aFactor *= ObjectAnyHit (
+        aData.y, aData.z, aData.w, aTrsfRay, aTrsfInverse, theDistance, aHead);
 
+      if (aHead < 0 || aFactor < 0.1f)
+        return aFactor;
+#else
       bool isShadow = 0.0f == ObjectAnyHit (
-        aData.y, aData.z, aData.w, aNewRay, aNewInverse, theDistance, aHead);
+        aData.y, aData.z, aData.w, aTrsfRay, aTrsfInverse, theDistance, aHead);
         
       if (aHead < 0 || isShadow)
         return isShadow ? 0.0f : 1.0f;
+#endif
             
       aNode = Stack[aHead--];
     }
     else // if inner node
     {
+      float aTimeOut;
+      float aTimeLft;
+      float aTimeRgh;
+
       vec3 aNodeMinLft = texelFetch (uSceneMinPointTexture, aData.y).xyz;
       vec3 aNodeMaxLft = texelFetch (uSceneMaxPointTexture, aData.y).xyz;
       vec3 aNodeMinRgh = texelFetch (uSceneMinPointTexture, aData.z).xyz;
@@ -638,8 +696,13 @@ float SceneAnyHit (in SRay theRay, in vec3 theInverse, in float theDistance)
         }
         else
         {
+#ifdef TRANSPARENT_SHADOWS
+          if (aHead < 0)
+            return aFactor;
+#else
           if (aHead < 0)
             return 1.0f;
+#endif
 
           aNode = Stack[aHead--];
         }
@@ -647,7 +710,11 @@ float SceneAnyHit (in SRay theRay, in vec3 theInverse, in float theDistance)
     }
   }
   
+#ifdef TRANSPARENT_SHADOWS
+  return aFactor;
+#else
   return 1.0f;
+#endif
 }
 
 #define PI 3.1415926f
@@ -683,7 +750,7 @@ vec3 SmoothNormal (in vec2 theUV, in ivec4 theTriangle)
 
 // =======================================================================
 // function : Refract
-// purpose  :
+// purpose  : Computes refraction ray (also handles TIR)
 // =======================================================================
 vec3 Refract (in vec3 theInput,
               in vec3 theNormal,
@@ -706,18 +773,10 @@ vec3 Refract (in vec3 theInput,
   float aNdotT = sqrt (1.0f - aSquare);
   
   return normalize (anIndex * theInput -
-  (anIndex * aNdotI + (aNdotI < 0.0f ? aNdotT : -aNdotT)) * theNormal);
+    (anIndex * aNdotI + (aNdotI < 0.0f ? aNdotT : -aNdotT)) * theNormal);
 }
 
-#define THRESHOLD vec3 (0.1f, 0.1f, 0.1f)
-
-#define MATERIAL_AMBN(index) (7 * index + 0)
-#define MATERIAL_DIFF(index) (7 * index + 1)
-#define MATERIAL_SPEC(index) (7 * index + 2)
-#define MATERIAL_EMIS(index) (7 * index + 3)
-#define MATERIAL_REFL(index) (7 * index + 4)
-#define MATERIAL_REFR(index) (7 * index + 5)
-#define MATERIAL_TRAN(index) (7 * index + 6)
+#define THRESHOLD vec3 (0.1f)
 
 #define LIGHT_POS(index) (2 * index + 1)
 #define LIGHT_PWR(index) (2 * index + 0)
@@ -733,7 +792,7 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
 
   int anObjectId;
   
-  for (int aDepth = 0; aDepth < 5; ++aDepth)
+  for (int aDepth = 0; aDepth < TRACE_DEPTH; ++aDepth)
   {
     SIntersect aHit = SIntersect (MAXFLOAT, vec2 (ZERO), ZERO);
     
@@ -779,10 +838,9 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
     vec4 aInvTransf0 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 0);
     vec4 aInvTransf1 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 1);
     vec4 aInvTransf2 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 2);
-    vec4 aInvTransf3 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 3);
 
-    aNormal = MatrixRowMultiply (vec4 (aNormal, 0.0f), aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3);
-    aNormal = normalize (aNormal);
+    aNormal = normalize (MatrixRowMultiplyDir (
+      aNormal, aInvTransf0, aInvTransf1, aInvTransf2));
     
     aHit.Normal = normalize (aHit.Normal);
     
@@ -825,14 +883,14 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
  
         float aLdotN = dot (aShadow.Direct, aNormal);
         
-        if (aOpacity.y > 0.0f)    // force two-sided lighting
+        if (aOpacity.y > 0.0f)   // force two-sided lighting
           aLdotN = abs (aLdotN); // for transparent surfaces
           
         if (aLdotN > 0.0f)
         {
           float aRdotV = dot (reflect (aShadow.Direct, aNormal), theRay.Direct);
           
-          aResult.xyz += aWeight.xyz * aOpacity.x * aIntensity *
+          aResult.xyz += aWeight.xyz * (aOpacity.x * aVisibility) * aIntensity *
             (aDiffuse * aLdotN + aSpecular.xyz * pow (max (0.0f, aRdotV), aSpecular.w));
         }
       }
@@ -845,15 +903,18 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
     {
       aWeight *= aOpacity.y;
       
-      theRay.Direct = Refract (theRay.Direct, aNormal, aOpacity.z, aOpacity.w);
+      if (aOpacity.z != 1.0f)
+      {
+        theRay.Direct = Refract (theRay.Direct, aNormal, aOpacity.z, aOpacity.w);
 
-      theInverse = 1.0f / max (abs (theRay.Direct), SMALL);
-      
-      theInverse.x = theRay.Direct.x < 0.0f ? -theInverse.x : theInverse.x;
-      theInverse.y = theRay.Direct.y < 0.0f ? -theInverse.y : theInverse.y;
-      theInverse.z = theRay.Direct.z < 0.0f ? -theInverse.z : theInverse.z;
-      
-      aPoint += aHit.Normal * (dot (aHit.Normal, theRay.Direct) >= 0.0f ? uSceneEpsilon : -uSceneEpsilon);
+        theInverse = 1.0f / max (abs (theRay.Direct), SMALL);
+        
+        theInverse.x = theRay.Direct.x < 0.0f ? -theInverse.x : theInverse.x;
+        theInverse.y = theRay.Direct.y < 0.0f ? -theInverse.y : theInverse.y;
+        theInverse.z = theRay.Direct.z < 0.0f ? -theInverse.z : theInverse.z;
+
+        aPoint += aHit.Normal * (dot (aHit.Normal, theRay.Direct) >= 0.0f ? uSceneEpsilon : -uSceneEpsilon);     
+      }
     }
     else
     {
index fab492e..5a24af6 100644 (file)
@@ -135,6 +135,8 @@ uses
         PrintAlgo                         from Aspect,
         ClipPlane_Handle                  from Graphic3d,
         SequenceOfHClipPlane              from Graphic3d,
+        RenderingMode                     from Graphic3d,
+        RenderingParams                   from Graphic3d,
         XYZ                               from gp
 raises
 
@@ -1627,37 +1629,15 @@ is
     -- @param theDXv [in] the translation in "x" direction.
     -- @param theDYv [in] the translation in "y" direction.
 
-        SetRaytracingMode (me : mutable) is static;
-     ---Level: Public
-     ---Purpose: enables OpenCL-based ray-tracing mode
-
-        SetRasterizationMode (me : mutable) is static;
-     ---Level: Public
-     ---Purpose: enables OpenGL-based rasterization mode
-
-        EnableRaytracedShadows (me : mutable) is static;
-     ---Level: Public
-     ---Purpose: enables sharp shadows in OpenCL-based ray-tracing mode
-
-        EnableRaytracedReflections (me : mutable) is static;
-     ---Level: Public
-     ---Purpose: enables specular reflections in OpenCL-based ray-tracing mode
-
-        EnableRaytracedAntialiasing (me : mutable) is static;
-     ---Level: Public
-     ---Purpose: enables antialiasing in OpenCL-based ray-tracing mode
-
-        DisableRaytracedShadows (me : mutable) is static;
-     ---Level: Public
-     ---Purpose: disables sharp shadows in OpenCL-based ray-tracing mode
-
-        DisableRaytracedReflections (me : mutable) is static;
-     ---Level: Public
-     ---Purpose: disables specular reflections in OpenCL-based ray-tracing mode
-
-        DisableRaytracedAntialiasing (me : mutable) is static;
-     ---Level: Public
-     ---Purpose: disables antialiasing in OpenCL-based ray-tracing mode
+    RenderingParams (me) returns RenderingParams from Graphic3d is static;
+    ---C++: return const &
+    ---Level: Public
+    ---Purpose: Returns current rendering parameters and effect settings.
+    
+    ChangeRenderingParams (me : mutable) returns RenderingParams from Graphic3d is static;
+    ---C++: return &
+    ---Level: Public
+    ---Purpose: Returns reference to current rendering parameters and effect settings.
 
 fields
 
index 2454aa7..8433b06 100644 (file)
@@ -53,60 +53,14 @@ Standard_Boolean V3d_View::IsGLLightEnabled() const
   return MyView->IsGLLightEnabled();
 }
 
-void V3d_View::SetRaytracingMode()
+const Graphic3d_RenderingParams& V3d_View::RenderingParams() const
 {
-  Graphic3d_CView* cView = (Graphic3d_CView* )MyView->CView();
-
-  cView->IsRaytracing = 1;
-}
-
-void V3d_View::SetRasterizationMode()
-{
-  Graphic3d_CView* cView = (Graphic3d_CView* )MyView->CView();
-
-  cView->IsRaytracing = 0;
-}
-
-void V3d_View::EnableRaytracedShadows()
-{
-  Graphic3d_CView* cView = (Graphic3d_CView* )MyView->CView();
-
-  cView->IsShadowsEnabled = 1;
-}
-
-void V3d_View::EnableRaytracedReflections()
-{
-  Graphic3d_CView* cView = (Graphic3d_CView* )MyView->CView();
-
-  cView->IsReflectionsEnabled = 1;
+  return static_cast<Graphic3d_CView*> (MyView->CView())->RenderParams;
 }
 
-void V3d_View::EnableRaytracedAntialiasing()
+Graphic3d_RenderingParams& V3d_View::ChangeRenderingParams()
 {
-  Graphic3d_CView* cView = (Graphic3d_CView* )MyView->CView();
-
-  cView->IsAntialiasingEnabled = 1;
-}
-
-void V3d_View::DisableRaytracedShadows()
-{
-  Graphic3d_CView* cView = (Graphic3d_CView* )MyView->CView();
-
-  cView->IsShadowsEnabled = 0;
-}
-
-void V3d_View::DisableRaytracedReflections()
-{
-  Graphic3d_CView* cView = (Graphic3d_CView* )MyView->CView();
-
-  cView->IsReflectionsEnabled = 0;
-}
-
-void V3d_View::DisableRaytracedAntialiasing()
-{
-  Graphic3d_CView* cView = (Graphic3d_CView* )MyView->CView();
-
-  cView->IsAntialiasingEnabled = 0;
+  return static_cast<Graphic3d_CView*> (MyView->CView())->RenderParams;
 }
 
 void V3d_View::SetLayerMgr(const Handle(V3d_LayerMgr)& aMgr)
index 49943e1..f60b096 100644 (file)
@@ -6395,84 +6395,207 @@ static int VLight (Draw_Interpretor& theDi,
   return 0;
 }
 
-//=======================================================================
-//function : VRaytrace
-//purpose  : Enables/disables OpenCL-based ray-tracing
-//=======================================================================
-
-static Standard_Integer VRaytrace (Draw_Interpretor& ,
-                                   Standard_Integer  theArgNb,
-                                   const char**      theArgVec)
+inline Standard_Boolean parseOnOff (Standard_CString  theArg,
+                                    Standard_Boolean& theIsOn)
 {
-  Handle(V3d_View) aView = ViewerTest::CurrentView();
-  if (aView.IsNull())
-  {
-    std::cerr << "Use 'vinit' command before " << theArgVec[0] << "\n";
-    return 1;
-  }
-
-  if (theArgNb < 2
-   || Draw::Atoi (theArgVec[1]))
+  TCollection_AsciiString aFlag (theArg);
+  aFlag.LowerCase();
+  if (aFlag == "on")
   {
-    aView->SetRaytracingMode();
+    theIsOn = Standard_True;
+    return Standard_True;
   }
-  else
+  else if (aFlag == "off")
   {
-    aView->SetRasterizationMode();
+    theIsOn = Standard_False;
+    return Standard_True;
   }
-  aView->Redraw();
-  return 0;
+  return Standard_False;
 }
 
 //=======================================================================
-//function : VSetRaytraceMode
-//purpose  : Enables/disables features of OpenCL-based ray-tracing
+//function : VRenderParams
+//purpose  : Enables/disables rendering features
 //=======================================================================
 
-static Standard_Integer VSetRaytraceMode (Draw_Interpretor&,
-                                          Standard_Integer theArgNb,
-                                          const char ** theArgVec)
+static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
+                                       Standard_Integer  theArgNb,
+                                       const char**      theArgVec)
 {
   Handle(V3d_View) aView = ViewerTest::CurrentView();
   if (aView.IsNull())
   {
-    std::cerr << "Use 'vinit' command before " << theArgVec[0] << "\n";
+    std::cerr << "Error: no active viewer!\n";
     return 1;
   }
-  else if (theArgNb < 2)
+
+  Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams();
+
+  if (theArgNb < 2)
   {
-    std::cerr << "Usage : " << theArgVec[0] << " [shad=0|1] [refl=0|1] [aa=0|1]\n";
-    return 1;
+    theDI << "renderMode:  ";
+    switch (aParams.Method)
+    {
+      case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
+      case Graphic3d_RM_RAYTRACING:    theDI << "raytrace ";      break;
+    }
+    theDI << "\n";
+    theDI << "fsaa:        " << (aParams.IsAntialiasingEnabled      ? "on" : "off") << "\n";
+    theDI << "shadows:     " << (aParams.IsShadowEnabled            ? "on" : "off") << "\n";
+    theDI << "reflections: " << (aParams.IsReflectionEnabled        ? "on" : "off") << "\n";
+    theDI << "rayDepth:    " <<  aParams.RaytracingDepth                            << "\n";
+    theDI << "gleam:       " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
+    return 0;
   }
 
+  Standard_Boolean toPrint = Standard_False;
   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
   {
-    const TCollection_AsciiString anArg (theArgVec[anArgIter]);
-
-    if (anArg.Search ("shad=") > -1)
+    Standard_CString        anArg (theArgVec[anArgIter]);
+    TCollection_AsciiString aFlag (anArg);
+    aFlag.LowerCase();
+    if (aFlag == "-echo"
+     || aFlag == "-print")
     {
-      if (anArg.Token ("=", 2).IntegerValue() != 0)
-        aView->EnableRaytracedShadows();
-      else
-        aView->DisableRaytracedShadows();
+      toPrint = Standard_True;
     }
-    else if (anArg.Search ("refl=") > -1)
+    else if (aFlag == "-mode"
+          || aFlag == "-rendermode"
+          || aFlag == "-render_mode")
     {
-      if (anArg.Token ("=", 2).IntegerValue() != 0)
-        aView->EnableRaytracedReflections();
+      if (toPrint)
+      {
+        switch (aParams.Method)
+        {
+          case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
+          case Graphic3d_RM_RAYTRACING:    theDI << "ray-tracing ";   break;
+        }
+        continue;
+      }
       else
-        aView->DisableRaytracedReflections();
+      {
+        std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
+        return 1;
+      }
+    }
+    else if (aFlag == "-ray"
+          || aFlag == "-raytrace")
+    {
+      if (toPrint)
+      {
+        theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "true" : "false") << " ";
+        continue;
+      }
+
+      aParams.Method = Graphic3d_RM_RAYTRACING;
     }
-    else if (anArg.Search ("aa=") > -1)
+    else if (aFlag == "-rast"
+          || aFlag == "-raster"
+          || aFlag == "-rasterization")
     {
-      if (anArg.Token ("=", 2).IntegerValue() != 0)
-        aView->EnableRaytracedAntialiasing();
+      if (toPrint)
+      {
+        theDI << (aParams.Method == Graphic3d_RM_RASTERIZATION ? "true" : "false") << " ";
+        continue;
+      }
+
+      aParams.Method = Graphic3d_RM_RASTERIZATION;
+    }
+    else if (aFlag == "-raydepth"
+          || aFlag == "-ray_depth")
+    {
+      if (toPrint)
+      {
+        theDI << aParams.RaytracingDepth << " ";
+        continue;
+      }
+      else if (++anArgIter >= theArgNb)
+      {
+        std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
+        return 1;
+      }
+
+      const Standard_Integer aDepth = Draw::Atoi (theArgVec[anArgIter]);
+      if (aDepth < 1 || aDepth > 10)
+      {
+        std::cerr << "Error: invalid ray-tracing depth " << aDepth << ". Should be within range [1; 10]\n";
+        return 1;
+      }
       else
-        aView->DisableRaytracedAntialiasing();
+      {
+        aParams.RaytracingDepth = aDepth;
+      }
+    }
+    else if (aFlag == "-shad"
+          || aFlag == "-shadows")
+    {
+      if (toPrint)
+      {
+        theDI << (aParams.IsShadowEnabled ? "on" : "off") << " ";
+        continue;
+      }
+
+      Standard_Boolean toEnable = Standard_True;
+      if (++anArgIter < theArgNb
+      && !parseOnOff (theArgVec[anArgIter], toEnable))
+      {
+        --anArgIter;
+      }
+      aParams.IsShadowEnabled = toEnable;
+    }
+    else if (aFlag == "-refl"
+          || aFlag == "-reflections")
+    {
+      if (toPrint)
+      {
+        theDI << (aParams.IsReflectionEnabled ? "on" : "off") << " ";
+        continue;
+      }
+
+      Standard_Boolean toEnable = Standard_True;
+      if (++anArgIter < theArgNb
+      && !parseOnOff (theArgVec[anArgIter], toEnable))
+      {
+        --anArgIter;
+      }
+      aParams.IsReflectionEnabled = toEnable;
+    }
+    else if (aFlag == "-fsaa")
+    {
+      if (toPrint)
+      {
+        theDI << (aParams.IsAntialiasingEnabled ? "on" : "off") << " ";
+        continue;
+      }
+
+      Standard_Boolean toEnable = Standard_True;
+      if (++anArgIter < theArgNb
+      && !parseOnOff (theArgVec[anArgIter], toEnable))
+      {
+        --anArgIter;
+      }
+      aParams.IsAntialiasingEnabled = toEnable;
+    }
+    else if (aFlag == "-gleam")
+    {
+      if (toPrint)
+      {
+        theDI << (aParams.IsTransparentShadowEnabled ? "on" : "off") << " ";
+        continue;
+      }
+
+      Standard_Boolean toEnable = Standard_True;
+      if (++anArgIter < theArgNb
+      && !parseOnOff (theArgVec[anArgIter], toEnable))
+      {
+        --anArgIter;
+      }
+      aParams.IsTransparentShadowEnabled = toEnable;
     }
     else
     {
-      std::cerr << "Unknown argument: " << anArg << "\n";
+      std::cout << "Error: wrong syntax, unknown flag '" << anArg << "'\n";
+      return 1;
     }
   }
 
@@ -6835,10 +6958,14 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     "\n\n        example: vlight add positional head 1 pos 0 1 1 color red"
     "\n        example: vlight change 0 direction 0 -1 0 linearAttenuation 0.2",
     __FILE__, VLight, group);
-  theCommands.Add("vraytrace",
-    "vraytrace 0|1",
-    __FILE__,VRaytrace,group);
-  theCommands.Add("vsetraytracemode",
-    "vsetraytracemode [shad=0|1] [refl=0|1] [aa=0|1]",
-    __FILE__,VSetRaytraceMode,group);
+  theCommands.Add("vrenderparams",
+    "\n    Manages rendering parameters: "
+    "\n      '-rayTrace'            Enables  GPU ray-tracing"
+    "\n      '-raster'              Disables GPU ray-tracing"
+    "\n      '-rayDepth    0..10'   Defines maximum ray-tracing depth"
+    "\n      '-shadows     on|off'  Enables/disables shadows rendering"
+    "\n      '-reflections on|off'  Enables/disables specular reflections"
+    "\n      '-fsaa        on|off'  Enables/disables adaptive anti-aliasing"
+    "\n      '-gleam       on|off'  Enables/disables transparency shadow effects",
+    __FILE__, VRenderParams, group);
 }
index 8b6a7ea..6ed0bab 100644 (file)
@@ -31,13 +31,12 @@ testmat $imagedir $casename
 vshaderprog s phong
 testmat $imagedir ${casename}_phong
 
-vraytrace 1
+vrenderparams -raytrace -reflections -fsaa
 vtextureenv on 5
-vsetraytracemode aa=1 refl=1
 
 testmat $imagedir ${casename}_rt
 
 vclear
-vraytrace 0
+vrenderparams -rasterization
 vtextureenv off
 source $env(CASROOT)/samples/tcl/materials.tcl
index 2837eec..f258d7a 100644 (file)
@@ -18,17 +18,18 @@ restore $aShape2 s2
 vdisplay s1 s2
 vsetmaterial s1 Silver
 vsetmaterial s2 Pewter
+vsetlocation s1 0.0 0.1 0.0
 vlight change 0 pos -1 1 1
 vfit
 
 # activate ray-tracing
-vraytrace 1
+vrenderparams -raytrace
 
 set aModeNum 0
-for { set aAAMode 0 } { $aAAMode <= 1 } { incr aAAMode } {
-  for { set aReflMode 0 } { $aReflMode <= 1 } { incr aReflMode } {
-    for { set aShadMode 0 } { $aShadMode <= 1 } { incr aShadMode } {
-      vsetraytracemode shad=$aShadMode refl=$aReflMode aa=$aAAMode
+foreach aFSAAMode {off on} {
+  foreach aReflMode {off on} {
+    foreach aShadMode {off on} {
+      vrenderparams -shadows $aShadMode -reflections $aReflMode -fsaa $aFSAAMode
       vdump $imagedir/${casename}_${aModeNum}.png
       incr aModeNum
     }
@@ -36,9 +37,18 @@ for { set aAAMode 0 } { $aAAMode <= 1 } { incr aAAMode } {
 }
 
 vtextureenv on 5
-for { set aAAMode 0 } { $aAAMode <= 1 } { incr aAAMode } {
-  for { set aShadMode 0 } { $aShadMode <= 1 } { incr aShadMode } {
-    vsetraytracemode shad=$aShadMode refl=1 aa=$aAAMode
+foreach aFSAAMode {off on} {
+  foreach aShadMode {off on} {
+    vrenderparams -shadows $aShadMode -reflections -fsaa $aFSAAMode
+    vdump $imagedir/${casename}_${aModeNum}.png
+    incr aModeNum
+  }
+}
+
+vsettransparency s2 0.5
+for { set aDepth 2 } { $aDepth <= 5 } { incr aDepth } {
+  foreach aFSAAMode {off on} {
+    vrenderparams -raydepth $aDepth -shadows off -fsaa $aFSAAMode
     vdump $imagedir/${casename}_${aModeNum}.png
     incr aModeNum
   }
index 3d67b60..b53631d 100644 (file)
@@ -9,8 +9,8 @@ box b2 3 0 0 3 2 1
 # draw box
 vinit View1
 vclear
+vrenderparams -rasterization
 vsetdispmode 1
-vraytrace 0
 vaxo
 vconnectsh b1c -3 0 0 1 0 0 0 0 1 b1 b2
 vfit
@@ -23,7 +23,7 @@ vconnectsh b1c -3 0 0 1 0 0 0 0 1 b1 b2
 vdump $::imagedir/${::casename}_OFF.png
 
 # turn on ray tracing
-vraytrace 1
+vrenderparams -raytrace
 vdump $::imagedir/${::casename}_rt1.png
 
 vclear
index b46b862..e8cb157 100644 (file)
@@ -8,6 +8,7 @@ box b 1 2 3
 # draw box
 vinit View1
 vclear
+vrenderparams -rasterization
 vsetdispmode 1
 vaxo
 vdisplay     b
@@ -24,7 +25,7 @@ if { "$aColorL" != "GREEN3" || "$aColorR" != "GREEN4" } {
   puts "Error: wrong color (fixed pipeline)!"
 }
 
-vraytrace 1
+vrenderparams -raytrace
 set aColorL [vreadpixel 150 250 rgb name]
 set aColorR [vreadpixel 250 250 rgb name]
 #if { "$aColorL" != "GREEN3" || "$aColorR" != "GREEN4" } {
index 6ded478..c60be19 100644 (file)
@@ -3,6 +3,8 @@ puts "Ray Tracing - check refraction"
 puts "========"
 
 vinit View1
+vclear
+vrenderparams -rasterization
 vsetdispmode 1
 vsetgradientbg 180 200 255 180 180 180 2
 
@@ -52,7 +54,7 @@ vsetmaterial B3 diamond
 
 vsetmaterial wall1 stone
 vsetmaterial wall2 stone
-vsetmaterial wall3 stone
+vsetmaterial wall3 pewter
 
 vsetcolor wall1 red
 vsetcolor wall2 green
@@ -70,5 +72,4 @@ vturnview 0 -0.3 0
 vfit
 vlight change 0 pos 1 1 1
 vlight add directional
-vraytrace 1
-vsetraytracemode aa=0 shad=0 refl=0
+vrenderparams -raytrace -raydepth 5 -shadows off -reflections -fsaa