0030640: Visualization, Graphic3d_Camera - add option creating Projection matrix...
authorkgv <kgv@opencascade.com>
Wed, 3 Mar 2021 11:58:46 +0000 (14:58 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 5 Mar 2021 14:41:27 +0000 (17:41 +0300)
Added new property Graphic3d_Camera::IsZeroToOneDepth() and OpenGl_Caps::useZeroToOneDepth
for activating [0,1] depth range instead of [-1,1] range using glClipControl() within OpenGL 4.5+.

25 files changed:
src/Graphic3d/Graphic3d_Camera.cxx
src/Graphic3d/Graphic3d_Camera.hxx
src/OpenGl/OpenGl_Caps.cxx
src/OpenGl/OpenGl_Caps.hxx
src/OpenGl/OpenGl_Context.cxx
src/OpenGl/OpenGl_Context.hxx
src/OpenGl/OpenGl_GlFunctions.cxx
src/OpenGl/OpenGl_ShaderProgram.cxx
src/OpenGl/OpenGl_ShadowMap.cxx
src/OpenGl/OpenGl_View.hxx
src/OpenGl/OpenGl_View_Raytrace.cxx
src/OpenGl/OpenGl_Workspace.cxx
src/SelectMgr/SelectMgr_BaseFrustum.cxx
src/SelectMgr/SelectMgr_FrustumBuilder.cxx
src/SelectMgr/SelectMgr_FrustumBuilder.hxx
src/SelectMgr/SelectMgr_ViewerSelector.cxx
src/Shaders/DirectionalLightShadow.glsl
src/Shaders/PathtraceBase.fs
src/Shaders/RaytraceBase.fs
src/Shaders/Shaders_DirectionalLightShadow_glsl.pxx
src/Shaders/Shaders_PathtraceBase_fs.pxx
src/Shaders/Shaders_RaytraceBase_fs.pxx
src/V3d/V3d_View.cxx
src/ViewerTest/ViewerTest_ViewerCommands.cxx
tests/v3d/shadows/dir3 [new file with mode: 0644]

index a7820bf..b97d4d5 100644 (file)
@@ -87,6 +87,7 @@ Graphic3d_Camera::Graphic3d_Camera()
   myZNear (DEFAULT_ZNEAR),
   myZFar (DEFAULT_ZFAR),
   myAspect (1.0),
+  myIsZeroToOneDepth (false),
   myScale (1000.0),
   myZFocus (1.0),
   myZFocusType (FocusType_Relative),
@@ -119,6 +120,7 @@ Graphic3d_Camera::Graphic3d_Camera (const Handle(Graphic3d_Camera)& theOther)
   myZNear (DEFAULT_ZNEAR),
   myZFar (DEFAULT_ZFAR),
   myAspect (1.0),
+  myIsZeroToOneDepth (false),
   myScale (1000.0),
   myZFocus (1.0),
   myZFocusType (FocusType_Relative),
@@ -139,6 +141,7 @@ Graphic3d_Camera::Graphic3d_Camera (const Handle(Graphic3d_Camera)& theOther)
 // =======================================================================
 void Graphic3d_Camera::CopyMappingData (const Handle(Graphic3d_Camera)& theOtherCamera)
 {
+  SetZeroToOneDepth (theOtherCamera->IsZeroToOneDepth());
   SetProjectionType (theOtherCamera->ProjectionType());
   SetFOVy           (theOtherCamera->FOVy());
   SetFOV2d          (theOtherCamera->FOV2d());
@@ -1247,7 +1250,7 @@ template <typename Elem_t>
 void Graphic3d_Camera::orthoProj (NCollection_Mat4<Elem_t>& theOutMx,
                                   const Aspect_FrustumLRBT<Elem_t>& theLRBT,
                                   const Elem_t theNear,
-                                  const Elem_t theFar)
+                                  const Elem_t theFar) const
 {
   // row 0
   theOutMx.ChangeValue (0, 0) = Elem_t (2.0) / (theLRBT.Right - theLRBT.Left);
@@ -1264,8 +1267,16 @@ void Graphic3d_Camera::orthoProj (NCollection_Mat4<Elem_t>& theOutMx,
   // row 2
   theOutMx.ChangeValue (2, 0) = Elem_t (0.0);
   theOutMx.ChangeValue (2, 1) = Elem_t (0.0);
-  theOutMx.ChangeValue (2, 2) = Elem_t (-2.0) / (theFar - theNear);
-  theOutMx.ChangeValue (2, 3) = - (theFar + theNear) / (theFar - theNear);
+  if (myIsZeroToOneDepth)
+  {
+    theOutMx.ChangeValue (2, 2) = Elem_t (-1.0) / (theFar - theNear);
+    theOutMx.ChangeValue (2, 3) = -theNear / (theFar - theNear);
+  }
+  else
+  {
+    theOutMx.ChangeValue (2, 2) = Elem_t (-2.0) / (theFar - theNear);
+    theOutMx.ChangeValue (2, 3) = - (theFar + theNear) / (theFar - theNear);
+  }
 
   // row 3
   theOutMx.ChangeValue (3, 0) = Elem_t (0.0);
@@ -1282,7 +1293,7 @@ template <typename Elem_t>
 void Graphic3d_Camera::perspectiveProj (NCollection_Mat4<Elem_t>& theOutMx,
                                         const Aspect_FrustumLRBT<Elem_t>& theLRBT,
                                         const Elem_t theNear,
-                                        const Elem_t theFar)
+                                        const Elem_t theFar) const
 {
   // column 0
   theOutMx.ChangeValue (0, 0) = (Elem_t (2.0) * theNear) / (theLRBT.Right - theLRBT.Left);
@@ -1299,13 +1310,27 @@ void Graphic3d_Camera::perspectiveProj (NCollection_Mat4<Elem_t>& theOutMx,
   // column 2
   theOutMx.ChangeValue (0, 2) = (theLRBT.Right + theLRBT.Left) / (theLRBT.Right - theLRBT.Left);
   theOutMx.ChangeValue (1, 2) = (theLRBT.Top + theLRBT.Bottom) / (theLRBT.Top - theLRBT.Bottom);
-  theOutMx.ChangeValue (2, 2) = -(theFar + theNear) / (theFar - theNear);
+  if (myIsZeroToOneDepth)
+  {
+    theOutMx.ChangeValue (2, 2) = theFar / (theNear - theFar);
+  }
+  else
+  {
+    theOutMx.ChangeValue (2, 2) = -(theFar + theNear) / (theFar - theNear);
+  }
   theOutMx.ChangeValue (3, 2) = Elem_t (-1.0);
 
   // column 3
   theOutMx.ChangeValue (0, 3) = Elem_t (0.0);
   theOutMx.ChangeValue (1, 3) = Elem_t (0.0);
-  theOutMx.ChangeValue (2, 3) = -(Elem_t (2.0) * theFar * theNear) / (theFar - theNear);
+  if (myIsZeroToOneDepth)
+  {
+    theOutMx.ChangeValue (2, 3) = -(theFar * theNear) / (theFar - theNear);
+  }
+  else
+  {
+    theOutMx.ChangeValue (2, 3) = -(Elem_t (2.0) * theFar * theNear) / (theFar - theNear);
+  }
   theOutMx.ChangeValue (3, 3) = Elem_t (0.0);
 }
 
@@ -1320,7 +1345,7 @@ void Graphic3d_Camera::stereoEyeProj (NCollection_Mat4<Elem_t>& theOutMx,
                                       const Elem_t theFar,
                                       const Elem_t theIOD,
                                       const Elem_t theZFocus,
-                                      const Aspect_Eye theEyeIndex)
+                                      const Aspect_Eye theEyeIndex) const
 {
   Elem_t aDx = theEyeIndex == Aspect_Eye_Left ? Elem_t (0.5) * theIOD : Elem_t (-0.5) * theIOD;
   Elem_t aDXStereoShift = aDx * theNear / theZFocus;
@@ -1829,12 +1854,10 @@ void Graphic3d_Camera::FrustumPoints (NCollection_Array1<Graphic3d_Vec3d>& thePo
 
   Standard_Real nLeft = 0.0, nRight = 0.0, nTop = 0.0, nBottom = 0.0;
   Standard_Real fLeft = 0.0, fRight = 0.0, fTop = 0.0, fBottom = 0.0;
-  Standard_Real aNear = 0.0, aFar = 0.0;
+  Standard_Real aNear = myZNear, aFar = myZFar;
   if (!IsOrthographic())
   {
     // handle perspective projection
-    aNear = aProjectionMat.GetValue (2, 3) / (-1.0 + aProjectionMat.GetValue (2, 2));
-    aFar  = aProjectionMat.GetValue (2, 3) / ( 1.0 + aProjectionMat.GetValue (2, 2));
     // Near plane
     nLeft   = aNear * (aProjectionMat.GetValue (0, 2) - 1.0) / aProjectionMat.GetValue (0, 0);
     nRight  = aNear * (aProjectionMat.GetValue (0, 2) + 1.0) / aProjectionMat.GetValue (0, 0);
@@ -1849,8 +1872,6 @@ void Graphic3d_Camera::FrustumPoints (NCollection_Array1<Graphic3d_Vec3d>& thePo
   else
   {
     // handle orthographic projection
-    aNear = (1.0 / aProjectionMat.GetValue (2, 2)) * (aProjectionMat.GetValue (2, 3) + 1.0);
-    aFar  = (1.0 / aProjectionMat.GetValue (2, 2)) * (aProjectionMat.GetValue (2, 3) - 1.0);
     // Near plane
     nLeft   = ( 1.0 + aProjectionMat.GetValue (0, 3)) / (-aProjectionMat.GetValue (0, 0));
     fLeft   = nLeft;
index 966bd57..8197b42 100644 (file)
@@ -413,6 +413,20 @@ public:
     return myZFar;
   }
 
+  //! Return TRUE if camera should calculate projection matrix for [0, 1] depth range or for [-1, 1] range.
+  //! FALSE by default.
+  Standard_Boolean IsZeroToOneDepth() const { return myIsZeroToOneDepth; }
+
+  //! Set using [0, 1] depth range or [-1, 1] range.
+  void SetZeroToOneDepth (Standard_Boolean theIsZeroToOne)
+  {
+    if (myIsZeroToOneDepth != theIsZeroToOne)
+    {
+      myIsZeroToOneDepth = theIsZeroToOne;
+      InvalidateProjection();
+    }
+  }
+
   //! Changes width / height display ratio.
   //! @param theAspect [in] the display ratio.
   Standard_EXPORT void SetAspect (const Standard_Real theAspect);
@@ -747,10 +761,10 @@ private:
   //! @param theNear [in] the near mapping (clipping) coordinate
   //! @param theFar [in] the far mapping (clipping) coordinate
   template <typename Elem_t>
-  static void orthoProj (NCollection_Mat4<Elem_t>& theOutMx,
-                         const Aspect_FrustumLRBT<Elem_t>& theLRBT,
-                         const Elem_t theNear,
-                         const Elem_t theFar);
+  void orthoProj (NCollection_Mat4<Elem_t>& theOutMx,
+                  const Aspect_FrustumLRBT<Elem_t>& theLRBT,
+                  const Elem_t theNear,
+                  const Elem_t theFar) const;
 
   //! Compose perspective projection matrix for the passed camera volume mapping.
   //! @param theOutMx [out] the projection matrix
@@ -758,10 +772,10 @@ private:
   //! @param theNear [in] the near mapping (clipping) coordinate
   //! @param theFar [in] the far mapping (clipping) coordinate
   template <typename Elem_t>
-  static void perspectiveProj (NCollection_Mat4<Elem_t>& theOutMx,
-                               const Aspect_FrustumLRBT<Elem_t>& theLRBT,
-                               const Elem_t theNear,
-                               const Elem_t theFar);
+  void perspectiveProj (NCollection_Mat4<Elem_t>& theOutMx,
+                        const Aspect_FrustumLRBT<Elem_t>& theLRBT,
+                        const Elem_t theNear,
+                        const Elem_t theFar) const;
 
   //! Compose projection matrix for L/R stereo eyes.
   //! @param theOutMx [out] the projection matrix
@@ -772,13 +786,13 @@ private:
   //! @param theZFocus [in] the z coordinate of off-axis projection plane with zero parallax
   //! @param theEyeIndex [in] choose between L/R eyes
   template <typename Elem_t>
-  static void stereoEyeProj (NCollection_Mat4<Elem_t>& theOutMx,
-                             const Aspect_FrustumLRBT<Elem_t>& theLRBT,
-                             const Elem_t theNear,
-                             const Elem_t theFar,
-                             const Elem_t theIOD,
-                             const Elem_t theZFocus,
-                             const Aspect_Eye theEyeIndex);
+  void stereoEyeProj (NCollection_Mat4<Elem_t>& theOutMx,
+                      const Aspect_FrustumLRBT<Elem_t>& theLRBT,
+                      const Elem_t theNear,
+                      const Elem_t theFar,
+                      const Elem_t theIOD,
+                      const Elem_t theZFocus,
+                      const Aspect_Eye theEyeIndex) const;
 
   //! Construct "look at" orientation transformation.
   //! Reference point differs for perspective and ortho modes 
@@ -835,6 +849,7 @@ private:
   Standard_Real myZNear;    //!< Distance to near clipping plane.
   Standard_Real myZFar;     //!< Distance to far clipping plane.
   Standard_Real myAspect;   //!< Width to height display ratio.
+  Standard_Boolean myIsZeroToOneDepth; //!< use [0, 1] depth range or [-1, 1]
 
   Standard_Real myScale;      //!< Specifies parallel scale for orthographic projection.
   Standard_Real myZFocus;     //!< Stereographic focus value.
index 03ecc8b..b339c15 100755 (executable)
@@ -37,6 +37,7 @@ OpenGl_Caps::OpenGl_Caps()
   useSystemBuffer   (Standard_True),
 #endif
   swapInterval      (1),
+  useZeroToOneDepth (Standard_False),
   buffersNoSwap     (Standard_False),
   buffersOpaqueAlpha(Standard_False),
   contextStereo     (Standard_False),
@@ -78,6 +79,7 @@ OpenGl_Caps& OpenGl_Caps::operator= (const OpenGl_Caps& theCopy)
   ffpEnable         = theCopy.ffpEnable;
   useSystemBuffer   = theCopy.useSystemBuffer;
   swapInterval      = theCopy.swapInterval;
+  useZeroToOneDepth = theCopy.useZeroToOneDepth;
   buffersNoSwap     = theCopy.buffersNoSwap;
   buffersOpaqueAlpha= theCopy.buffersOpaqueAlpha;
   contextStereo     = theCopy.contextStereo;
index 6657515..d940260 100755 (executable)
@@ -36,6 +36,7 @@ public: //! @name flags to disable particular functionality, should be used only
   Standard_Boolean usePolygonMode;    //!< Enables Polygon Mode instead of built-in GLSL programs (OFF by default; unsupported on OpenGL ES)
   Standard_Boolean useSystemBuffer;   //!< Enables usage of system backbuffer for blitting (OFF by default on desktop OpenGL and ON on OpenGL ES for testing)
   Standard_Integer swapInterval;      //!< controls swap interval - 0 for VSync off and 1 for VSync on, 1 by default
+  Standard_Boolean useZeroToOneDepth; //!< use [0, 1] depth range instead of [-1, 1] range, when possible (OFF by default)
 
 public: //! @name context creation parameters
 
index 39d3edc..1fcd4c8 100644 (file)
@@ -184,6 +184,7 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
   arbTexBindless (NULL),
   arbTBO (NULL),
   arbTboRGB32 (Standard_False),
+  arbClipControl (Standard_False),
   arbIns (NULL),
   arbDbg (NULL),
   arbFBO (NULL),
index 55b766b..e72ea2e 100644 (file)
@@ -1110,6 +1110,7 @@ public: //! @name extensions
   OpenGl_ArbTexBindless* arbTexBindless;     //!< GL_ARB_bindless_texture
   OpenGl_ArbTBO*         arbTBO;             //!< GL_ARB_texture_buffer_object (on desktop OpenGL - since 3.1 or as extension GL_ARB_texture_buffer_object; on OpenGL ES - since 3.2)
   Standard_Boolean       arbTboRGB32;        //!< GL_ARB_texture_buffer_object_rgb32 (3-component TBO), in core since 4.0 (on OpenGL ES - since 3.2)
+  Standard_Boolean       arbClipControl;     //!< GL_ARB_clip_control, in core since 4.5
   OpenGl_ArbIns*         arbIns;             //!< GL_ARB_draw_instanced (on desktop OpenGL - since 3.1 or as extension GL_ARB_draw_instanced; on OpenGL ES - since 3.0 or as extension GL_ANGLE_instanced_arrays to WebGL 1.0)
   OpenGl_ArbDbg*         arbDbg;             //!< GL_ARB_debug_output (on desktop OpenGL - since 4.3 or as extension GL_ARB_debug_output; on OpenGL ES - since 3.2 or as extension GL_KHR_debug)
   OpenGl_ArbFBO*         arbFBO;             //!< GL_ARB_framebuffer_object
index 3f3fd23..63afab4 100644 (file)
@@ -65,6 +65,7 @@ void OpenGl_GlFunctions::load (OpenGl_Context& theCtx,
   theCtx.core46back = NULL;
   theCtx.arbTBO     = NULL;
   theCtx.arbTboRGB32 = false;
+  theCtx.arbClipControl = false;
   theCtx.arbIns     = NULL;
   theCtx.arbDbg     = NULL;
   theCtx.arbFBO     = NULL;
@@ -1636,6 +1637,7 @@ void OpenGl_GlFunctions::load (OpenGl_Context& theCtx,
   if (has45)
   {
     theCtx.core45 = (OpenGl_GlCore45* )this;
+    theCtx.arbClipControl = true;
     if (!isCoreProfile)
     {
       theCtx.core45back = (OpenGl_GlCore45Back* )this;
@@ -1718,6 +1720,13 @@ void OpenGl_GlFunctions::load (OpenGl_Context& theCtx,
     theCtx.arbTexBindless = (OpenGl_ArbTexBindless* )this;
   }
 
+  if (!has45
+    && checkExtensionShort ("GL_ARB_clip_control")
+    && FindProcShort (glClipControl))
+  {
+    theCtx.arbClipControl = true;
+  }
+
   if (has30)
   {
     if (!has32
index 040724f..252e024 100755 (executable)
@@ -436,6 +436,11 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
     {
       aHeaderConstants += TCollection_AsciiString("#define THE_NB_SHADOWMAPS ") + myNbShadowMaps + "\n";
     }
+    if (theCtx->caps->useZeroToOneDepth
+     && theCtx->arbClipControl)
+    {
+      aHeaderConstants += "#define THE_ZERO_TO_ONE_DEPTH\n";
+    }
     if (!myProxy.IsNull()
       && myProxy->HasDefaultSampler())
     {
index c1db3db..749e9c8 100644 (file)
@@ -115,6 +115,7 @@ bool OpenGl_ShadowMap::UpdateCamera (const Graphic3d_CView& theView,
         theView.Camera()->OrientationMatrix().Inverted (anOrientInv);
         aDir = anOrientInv * aDir;
       }
+      myShadowCamera->SetZeroToOneDepth (theView.Camera()->IsZeroToOneDepth());
       myShadowCamera->SetProjectionType (Graphic3d_Camera::Projection_Orthographic);
       myShadowCamera->SetDirection (gp_Dir (aDir.x(), aDir.y(), aDir.z()));
       myShadowCamera->SetUp (!myShadowCamera->Direction().IsParallel (gp::DY(), Precision::Angular())
index 8ccda34..5a8d6f0 100644 (file)
@@ -745,6 +745,9 @@ protected: //! @name data types related to ray-tracing
     //! Actual ray-tracing depth (number of ray bounces).
     Standard_Integer NbBounces;
 
+    //! Define depth computation
+    Standard_Boolean IsZeroToOneDepth;
+
     //! Enables/disables light propagation through transparent media.
     Standard_Boolean TransparentShadows;
 
@@ -785,6 +788,7 @@ protected: //! @name data types related to ray-tracing
     RaytracingParams()
     : StackSize              (THE_DEFAULT_STACK_SIZE),
       NbBounces              (THE_DEFAULT_NB_BOUNCES),
+      IsZeroToOneDepth       (Standard_False),
       TransparentShadows     (Standard_False),
       GlobalIllumination     (Standard_False),
       UseBindlessTextures    (Standard_False),
index 9c6662a..c3cb44a 100644 (file)
@@ -1139,6 +1139,11 @@ TCollection_AsciiString OpenGl_View::generateShaderPrefix (const Handle(OpenGl_C
     TCollection_AsciiString ("#define STACK_SIZE ") + TCollection_AsciiString (myRaytraceParameters.StackSize) + "\n" +
     TCollection_AsciiString ("#define NB_BOUNCES ") + TCollection_AsciiString (myRaytraceParameters.NbBounces);
 
+  if (myRaytraceParameters.IsZeroToOneDepth)
+  {
+    aPrefixString += TCollection_AsciiString ("\n#define THE_ZERO_TO_ONE_DEPTH");
+  }
+
   if (myRaytraceParameters.TransparentShadows)
   {
     aPrefixString += TCollection_AsciiString ("\n#define TRANSPARENT_SHADOWS");
@@ -1364,13 +1369,17 @@ Standard_Boolean OpenGl_View::initRaytraceResources (const Standard_Integer theS
       }
     }
 
-    if (myRenderParams.RaytracingDepth             != myRaytraceParameters.NbBounces
+    const bool isZeroToOneDepth = myCaps->useZeroToOneDepth
+                               && myWorkspace->GetGlContext()->arbClipControl;
+    if (isZeroToOneDepth                           != myRaytraceParameters.IsZeroToOneDepth
+     || myRenderParams.RaytracingDepth             != myRaytraceParameters.NbBounces
      || myRenderParams.IsTransparentShadowEnabled  != myRaytraceParameters.TransparentShadows
      || myRenderParams.IsGlobalIlluminationEnabled != myRaytraceParameters.GlobalIllumination
      || myRenderParams.TwoSidedBsdfModels          != myRaytraceParameters.TwoSidedBsdfModels
      || myRaytraceGeometry.HasTextures()           != myRaytraceParameters.UseBindlessTextures
      || myRenderParams.ToIgnoreNormalMapInRayTracing != myRaytraceParameters.ToIgnoreNormalMap)
     {
+      myRaytraceParameters.IsZeroToOneDepth    = isZeroToOneDepth;
       myRaytraceParameters.NbBounces           = myRenderParams.RaytracingDepth;
       myRaytraceParameters.TransparentShadows  = myRenderParams.IsTransparentShadowEnabled;
       myRaytraceParameters.GlobalIllumination  = myRenderParams.IsGlobalIlluminationEnabled;
index 04cb70d..fc595a4 100644 (file)
@@ -180,6 +180,20 @@ Standard_Boolean OpenGl_Workspace::Activate()
     }
   }
 
+  if (myGlContext->caps->useZeroToOneDepth
+  && !myGlContext->arbClipControl)
+  {
+    Message::SendWarning ("Warning: glClipControl() requires OpenGL 4.5 or GL_ARB_clip_control extension");
+    myGlContext->caps->useZeroToOneDepth = false;
+  }
+  myView->Camera()->SetZeroToOneDepth (myGlContext->caps->useZeroToOneDepth);
+#if !defined(GL_ES_VERSION_2_0)
+  if (myGlContext->arbClipControl)
+  {
+    myGlContext->Functions()->glClipControl (GL_LOWER_LEFT, myGlContext->caps->useZeroToOneDepth ? GL_ZERO_TO_ONE : GL_NEGATIVE_ONE_TO_ONE);
+  }
+#endif
+
   ResetAppliedAspect();
 
   // reset state for safety
index ffc984f..a373ad0 100644 (file)
@@ -41,7 +41,7 @@ void SelectMgr_BaseFrustum::SetCamera (const Handle(Graphic3d_Camera)& theCamera
 {
   myCamera = theCamera;
   myBuilder->SetWorldViewMatrix (theCamera->OrientationMatrix());
-  myBuilder->SetProjectionMatrix (theCamera->ProjectionMatrix());
+  myBuilder->SetProjectionMatrix (theCamera->ProjectionMatrix(), theCamera->IsZeroToOneDepth());
   myBuilder->SetWorldViewProjState (theCamera->WorldViewProjState());
   myIsOrthographic = theCamera->IsOrthographic();
   myBuilder->InvalidateViewport();
@@ -58,7 +58,7 @@ void SelectMgr_BaseFrustum::SetCamera (const Graphic3d_Mat4d& theProjection,
 {
   myCamera.Nullify();
   myBuilder->SetWorldViewMatrix (theWorldView);
-  myBuilder->SetProjectionMatrix (theProjection);
+  myBuilder->SetProjectionMatrix (theProjection, false);
   myBuilder->SetWorldViewProjState (theWVPState);
   myIsOrthographic = theIsOrthographic;
 }
index c5c8348..3cb0b31 100644 (file)
@@ -31,7 +31,8 @@ SelectMgr_FrustumBuilder::SelectMgr_FrustumBuilder()
   myWorldViewProjState(),
   myWidth (INT_MAX),
   myHeight (INT_MAX),
-  myIsViewportSet (Standard_False)
+  myIsViewportSet (Standard_False),
+  myIsZeroToOneDepth (Standard_False)
 {
   //
 }
@@ -58,9 +59,11 @@ const Graphic3d_Mat4d& SelectMgr_FrustumBuilder::WorldViewMatrix() const
 // function : SetProjectionMatrix
 // purpose  : Stores current projection matrix
 //=======================================================================
-void SelectMgr_FrustumBuilder::SetProjectionMatrix (const Graphic3d_Mat4d& theProjection)
+void SelectMgr_FrustumBuilder::SetProjectionMatrix (const Graphic3d_Mat4d& theProjection,
+                                                    const Standard_Boolean theIsZeroToOneDepth)
 {
   myProjection = theProjection;
+  myIsZeroToOneDepth = theIsZeroToOneDepth;
 }
 
 //=======================================================================
@@ -180,23 +183,19 @@ static NCollection_Vec4<Standard_Real> safePointCast (const gp_Pnt& thePnt)
 //=======================================================================
 gp_Pnt SelectMgr_FrustumBuilder::unProject (const gp_Pnt& thePnt) const
 {
-  Graphic3d_Mat4d aInvView;
-  Graphic3d_Mat4d aInvProj;
-
-  // this case should never happen
+  // inversed matrices could be cached
+  Graphic3d_Mat4d aInvView, aInvProj;
   if (!myWorldView.Inverted (aInvView) || !myProjection.Inverted (aInvProj))
   {
-    return gp_Pnt (0.0, 0.0, 0.0);
+    return gp_Pnt (0.0, 0.0, 0.0); // this case should never happen
   }
 
   // use compatible type of point
   NCollection_Vec4<Standard_Real> aPnt = safePointCast (thePnt);
-
   aPnt = aInvProj * aPnt; // convert to view coordinate space
   aPnt = aInvView * aPnt; // convert to world coordinate space
 
   const Standard_Real aInvW = 1.0 / Standard_Real (aPnt.w());
-
   return gp_Pnt (aPnt.x() * aInvW, aPnt.y() * aInvW, aPnt.z() * aInvW);
 }
 
@@ -210,23 +209,19 @@ gp_Pnt SelectMgr_FrustumBuilder::ProjectPntOnViewPlane (const Standard_Real& the
                                                         const Standard_Real& theY,
                                                         const Standard_Real& theZ) const
 {
-  Standard_Real aX, anY, aZ;
-
   // map coords to NDC
+  gp_Pnt anXYZ;
   if (!myIsViewportSet)
   {
-    aX = 2.0 * theX / myWidth - 1.0;
-    anY = (myHeight - 1 - theY) / myHeight * 2.0 - 1.0;
-    aZ = 2.0 * theZ - 1.0;
+    anXYZ.SetCoord (2.0 * theX / myWidth - 1.0,
+                    (myHeight - 1 - theY) / myHeight * 2.0 - 1.0,
+                    myIsZeroToOneDepth ? theZ : (2.0 * theZ - 1.0));
   }
   else
   {
-    aX = 2.0 * (theX - myWidth * myViewport.x()) /
-      (myWidth * (myViewport.z() - myViewport.x())) - 1.0;
-    anY = 2.0 * (theY - myHeight * myViewport.y()) /
-      (myHeight * (myViewport.w() - myViewport.y())) - 1.0;
-    aZ = theZ;
+    anXYZ.SetCoord (2.0 * (theX - myWidth  * myViewport.x()) / (myWidth  * (myViewport.z() - myViewport.x())) - 1.0,
+                    2.0 * (theY - myHeight * myViewport.y()) / (myHeight * (myViewport.w() - myViewport.y())) - 1.0,
+                    theZ);
   }
-
-  return unProject (gp_Pnt (aX, anY, aZ));
+  return unProject (anXYZ);
 }
index 7dc0d64..e6f84ca 100644 (file)
@@ -39,7 +39,8 @@ public:
   Standard_EXPORT const Graphic3d_Mat4d& WorldViewMatrix() const;
 
   //! Stores current projection matrix
-  Standard_EXPORT void SetProjectionMatrix (const Graphic3d_Mat4d& theProjection);
+  Standard_EXPORT void SetProjectionMatrix (const Graphic3d_Mat4d& theProjection,
+                                            const Standard_Boolean theIsZeroToOneDepth);
 
   //! @return current projection matrix
   Standard_EXPORT const Graphic3d_Mat4d& ProjectionMatrix() const;
@@ -93,6 +94,7 @@ private:
   Standard_Integer                  myHeight;
   NCollection_Vec4<Standard_Real>   myViewport;
   Standard_Boolean                  myIsViewportSet;
+  Standard_Boolean                  myIsZeroToOneDepth;
 };
 
 DEFINE_STANDARD_HANDLE(SelectMgr_FrustumBuilder, Standard_Transient)
index 6f6171d..30805b3 100644 (file)
@@ -652,7 +652,8 @@ void SelectMgr_ViewerSelector::TraverseSensitives()
 
       // define corresponding frustum builder parameters
       Handle(SelectMgr_FrustumBuilder) aBuilder = new SelectMgr_FrustumBuilder();
-      aBuilder->SetProjectionMatrix (mySelectingVolumeMgr.ProjectionMatrix());
+      aBuilder->SetProjectionMatrix (mySelectingVolumeMgr.ProjectionMatrix(),
+                                     !aCamera.IsNull() && aCamera->IsZeroToOneDepth());
       aBuilder->SetWorldViewMatrix (SelectMgr_ViewerSelector_THE_IDENTITY_MAT);
       aBuilder->SetWindowSize (aWidth, aHeight);
       aMgr = mySelectingVolumeMgr.ScaleAndTransform (1, aTFrustum, aBuilder);
index 25a90a0..dd98071 100644 (file)
@@ -16,7 +16,12 @@ float occDirectionalLightShadow (in sampler2D theShadow,
 {
   vec4 aPosLightSpace = PosLightSpace[occLight_Index(theId)];
   vec3 aLightDir = vec3 (occWorldViewMatrix * vec4 (occLight_Position (theId), 0.0));
-  vec3 aProjCoords = (aPosLightSpace.xyz / aPosLightSpace.w) * 0.5 + vec3 (0.5);
+  vec3 aProjCoords = (aPosLightSpace.xyz / aPosLightSpace.w);
+#ifdef THE_ZERO_TO_ONE_DEPTH
+  aProjCoords.xy = aProjCoords.xy * 0.5 + vec2 (0.5);
+#else
+  aProjCoords = aProjCoords * 0.5 + vec3 (0.5);
+#endif
   float aCurrentDepth = aProjCoords.z;
   if (aProjCoords.x < 0.0 || aProjCoords.x > 1.0
    || aProjCoords.y < 0.0 || aProjCoords.y > 1.0
index 46a6870..caea6c1 100644 (file)
@@ -820,7 +820,11 @@ vec4 PathTrace (in SRay theRay, in vec3 theInverse, in int theNbSamples)
       vec4 aNDCPoint = uViewMat * vec4 (theRay.Origin, 1.f);
 
       float aPolygonOffset = PolygonOffset (aHit.Normal, theRay.Origin);
+    #ifdef THE_ZERO_TO_ONE_DEPTH
+      aRaytraceDepth = (aNDCPoint.z / aNDCPoint.w + aPolygonOffset * POLYGON_OFFSET_SCALE);
+    #else
       aRaytraceDepth = (aNDCPoint.z / aNDCPoint.w + aPolygonOffset * POLYGON_OFFSET_SCALE) * 0.5f + 0.5f;
+    #endif
     }
 
     SBSDF aBSDF;
index 176cbe6..e31b56e 100644 (file)
@@ -1082,7 +1082,11 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
       vec4 aNDCPoint = uViewMat * vec4 (theRay.Origin, 1.f);
 
       float aPolygonOffset = PolygonOffset (aHit.Normal, theRay.Origin);
+    #ifdef THE_ZERO_TO_ONE_DEPTH
+      aRaytraceDepth = (aNDCPoint.z / aNDCPoint.w + aPolygonOffset * POLYGON_OFFSET_SCALE);
+    #else
       aRaytraceDepth = (aNDCPoint.z / aNDCPoint.w + aPolygonOffset * POLYGON_OFFSET_SCALE) * 0.5f + 0.5f;
+    #endif
     }
 
     vec3 aNormal = SmoothNormal (aHit.UV, aTriIndex);
index aed61e5..5b93571 100644 (file)
@@ -19,7 +19,12 @@ static const char Shaders_DirectionalLightShadow_glsl[] =
   "{\n"
   "  vec4 aPosLightSpace = PosLightSpace[occLight_Index(theId)];\n"
   "  vec3 aLightDir = vec3 (occWorldViewMatrix * vec4 (occLight_Position (theId), 0.0));\n"
-  "  vec3 aProjCoords = (aPosLightSpace.xyz / aPosLightSpace.w) * 0.5 + vec3 (0.5);\n"
+  "  vec3 aProjCoords = (aPosLightSpace.xyz / aPosLightSpace.w);\n"
+  "#ifdef THE_ZERO_TO_ONE_DEPTH\n"
+  "  aProjCoords.xy = aProjCoords.xy * 0.5 + vec2 (0.5);\n"
+  "#else\n"
+  "  aProjCoords = aProjCoords * 0.5 + vec3 (0.5);\n"
+  "#endif\n"
   "  float aCurrentDepth = aProjCoords.z;\n"
   "  if (aProjCoords.x < 0.0 || aProjCoords.x > 1.0\n"
   "   || aProjCoords.y < 0.0 || aProjCoords.y > 1.0\n"
index ab7c0dd..6da9ccd 100644 (file)
@@ -823,7 +823,11 @@ static const char Shaders_PathtraceBase_fs[] =
   "      vec4 aNDCPoint = uViewMat * vec4 (theRay.Origin, 1.f);\n"
   "\n"
   "      float aPolygonOffset = PolygonOffset (aHit.Normal, theRay.Origin);\n"
+  "    #ifdef THE_ZERO_TO_ONE_DEPTH\n"
+  "      aRaytraceDepth = (aNDCPoint.z / aNDCPoint.w + aPolygonOffset * POLYGON_OFFSET_SCALE);\n"
+  "    #else\n"
   "      aRaytraceDepth = (aNDCPoint.z / aNDCPoint.w + aPolygonOffset * POLYGON_OFFSET_SCALE) * 0.5f + 0.5f;\n"
+  "    #endif\n"
   "    }\n"
   "\n"
   "    SBSDF aBSDF;\n"
index c7f6a4a..3b54d4e 100644 (file)
@@ -1085,7 +1085,11 @@ static const char Shaders_RaytraceBase_fs[] =
   "      vec4 aNDCPoint = uViewMat * vec4 (theRay.Origin, 1.f);\n"
   "\n"
   "      float aPolygonOffset = PolygonOffset (aHit.Normal, theRay.Origin);\n"
+  "    #ifdef THE_ZERO_TO_ONE_DEPTH\n"
+  "      aRaytraceDepth = (aNDCPoint.z / aNDCPoint.w + aPolygonOffset * POLYGON_OFFSET_SCALE);\n"
+  "    #else\n"
   "      aRaytraceDepth = (aNDCPoint.z / aNDCPoint.w + aPolygonOffset * POLYGON_OFFSET_SCALE) * 0.5f + 0.5f;\n"
+  "    #endif\n"
   "    }\n"
   "\n"
   "    vec3 aNormal = SmoothNormal (aHit.UV, aTriIndex);\n"
index a5a5c3f..08b4a03 100644 (file)
@@ -1701,25 +1701,23 @@ void V3d_View::Convert(const Standard_Real Xv,
 //function : Convert
 //purpose  :
 //=======================================================================
-void V3d_View::Convert(const Standard_Integer Xp,
-                       const Standard_Integer Yp,
-                       Standard_Real& X,
-                       Standard_Real& Y,
-                       Standard_Real& Z) const
+void V3d_View::Convert(const Standard_Integer theXp,
+                       const Standard_Integer theYp,
+                       Standard_Real& theX,
+                       Standard_Real& theY,
+                       Standard_Real& theZ) const
 {
   V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
-  Standard_Integer aHeight, aWidth;
+  Standard_Integer aHeight = 0, aWidth = 0;
   MyWindow->Size (aWidth, aHeight);
 
-  Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
-  Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
-  Standard_Real  aZ = 2.0 * 0.0 - 1.0;
-
-  gp_Pnt aResult = Camera()->UnProject (gp_Pnt (anX, anY, aZ));
-
-  X = aResult.X();
-  Y = aResult.Y();
-  Z = aResult.Z();
+  const gp_Pnt anXYZ (2.0 * theXp / aWidth - 1.0,
+                      2.0 * (aHeight - 1 - theYp) / aHeight - 1.0,
+                      Camera()->IsZeroToOneDepth() ? 0.0 : -1.0);
+  const gp_Pnt aResult = Camera()->UnProject (anXYZ);
+  theX = aResult.X();
+  theY = aResult.Y();
+  theZ = aResult.Z();
 }
 
 //=======================================================================
@@ -1817,7 +1815,9 @@ void V3d_View::Project (const Standard_Real theX,
   // NDC [-1, 1] --> PROJ [ -size / 2, +size / 2 ]
   theXp = aPoint.X() * aXSize * 0.5;
   theYp = aPoint.Y() * aYSize * 0.5;
-  theZp = aPoint.Z() * aZSize * 0.5;
+  theZp = Camera()->IsZeroToOneDepth()
+        ? aPoint.Z() * aZSize
+        : aPoint.Z() * aZSize * 0.5;
 }
 
 //=======================================================================
index 29b7d26..09355aa 100644 (file)
@@ -6761,6 +6761,7 @@ static int VCaps (Draw_Interpretor& theDI,
     theDI << "SoftMode:" << (aCaps->contextNoAccel    ? "1" : "0") << "\n";
     theDI << "FFP:     " << (aCaps->ffpEnable         ? "1" : "0") << "\n";
     theDI << "PolygonMode: " << (aCaps->usePolygonMode ? "1" : "0") << "\n";
+    theDI << "DepthZeroToOne: " << (aCaps->useZeroToOneDepth ? "1" : "0") << "\n";
     theDI << "VSync:   " <<  aCaps->swapInterval                   << "\n";
     theDI << "Compatible:" << (aCaps->contextCompatible ? "1" : "0") << "\n";
     theDI << "Stereo:  " << (aCaps->contextStereo ? "1" : "0") << "\n";
@@ -6854,6 +6855,19 @@ static int VCaps (Draw_Interpretor& theDI,
       }
       aCaps->pntSpritesDisable = !toEnable;
     }
+    else if (anArgCase == "-depthzerotoone"
+          || anArgCase == "-zerotoonedepth"
+          || anArgCase == "-usezerotoonedepth"
+          || anArgCase == "-iszerotoonedepth")
+    {
+      Standard_Boolean toEnable = Standard_True;
+      if (++anArgIter < theArgNb
+      && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
+      {
+        --anArgIter;
+      }
+      aCaps->useZeroToOneDepth = toEnable;
+    }
     else if (anArgCase == "-softmode")
     {
       Standard_Boolean toEnable = Standard_True;
@@ -15072,6 +15086,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     "\n\t\t:       [-vsync {0|1}] [-useWinBuffer {0|1}] [-opaqueAlpha {0|1}]"
     "\n\t\t:       [-quadBuffer {0|1}] [-stereo {0|1}]"
     "\n\t\t:       [-softMode {0|1}] [-noupdate|-update]"
+    "\n\t\t:       [-zeroToOneDepth {0|1}]"
     "\n\t\t:       [-noExtensions {0|1}] [-maxVersion Major Minor]"
     "\n\t\t: Modify particular graphic driver options:"
     "\n\t\t:  sRGB     - enable/disable sRGB rendering"
@@ -15086,6 +15101,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     "\n\t\t:  vsync    - switch VSync on or off"
     "\n\t\t:  opaqueAlpha - disable writes in alpha component of color buffer"
     "\n\t\t:  winBuffer - allow using window buffer for rendering"
+    "\n\t\t:  zeroToOneDepth - use [0,1] depth range instead of [-1,1] range"
     "\n\t\t: Context creation options:"
     "\n\t\t:  softMode          - software OpenGL implementation"
     "\n\t\t:  compatibleProfile - backward-compatible profile"
diff --git a/tests/v3d/shadows/dir3 b/tests/v3d/shadows/dir3
new file mode 100644 (file)
index 0000000..603e77b
--- /dev/null
@@ -0,0 +1,32 @@
+puts "========"
+puts "0030640: Visualization, Graphic3d_Camera - add option creating Projection matrix with 0 to 1 depth range"
+puts "Test shadow map from a single directional light source on a box geometry."
+puts "========"
+
+pload MODELING VISUALIZATION
+if { $::tcl_platform(os) == "Darwin" } { vcaps -core }
+vcaps -depthZeroToOne 1
+box b 1 2 3
+box bb -5 -5 0 10 10 0 -preview
+vgldebug 1
+vcaps -core
+vcaps -vsync 0
+vclear
+vinit View1
+vrenderparams -shadingModel PHONG
+vdisplay -dispMode 1 b bb
+vaspects bb -material STONE
+vfit
+vselect 250 200
+vlight -change 0 -castShadows 1 -direction 1 1 -1 -head 0
+
+vraytrace 1
+vdump $::imagedir/${::casename}_raytrace.png
+
+vraytrace 0
+vrenderparams -shadingModel phong
+vrenderparams -shadowMapBias 0.01
+vdump $::imagedir/${::casename}_phong.png
+
+vrenderparams -shadingModel pbr
+vdump $::imagedir/${::casename}_pbr.png