0026571: Visualization, TKOpenGl - write depth values within RayTracing program
authorduv <duv@uzbex.nnov.opencascade.com>
Mon, 29 Feb 2016 14:11:34 +0000 (17:11 +0300)
committerabv <abv@opencascade.com>
Fri, 4 Mar 2016 04:31:07 +0000 (07:31 +0300)
View-projection matrix was added to raytrace shaders (as uniform) in order to compute correct depth values for OpenGL.
For path tracing the additional depth buffer sampler was added to Display.fs program. It allows propagation of depth values from internal FBO to resulting FBO.
The old approach of mixing of OpenGL and ray-tracing graphics was kept in order to keep correct blending of transparent ray-traced objects with non-transparent OpenGL objects.

src/OpenGl/OpenGl_View.hxx
src/OpenGl/OpenGl_View_Raytrace.cxx
src/Shaders/Display.fs
src/Shaders/PathtraceBase.fs
src/Shaders/RaytraceBase.fs

index 026c583..3cc7fb3 100644 (file)
@@ -653,6 +653,7 @@ protected: //! @name data types related to ray-tracing
     OpenGl_RT_uDirectLB,
     OpenGl_RT_uDirectRT,
     OpenGl_RT_uDirectRB,
+    OpenGl_RT_uViewMat,
     OpenGl_RT_uUnviewMat,
 
     // 3D scene params
@@ -705,9 +706,10 @@ protected: //! @name data types related to ray-tracing
 
     OpenGl_RT_FsaaInputTexture = 11,
     OpenGl_RT_PrevAccumTexture = 12,
+    OpenGl_RT_DepthTexture = 13,
 
-    OpenGl_RT_OpenGlColorTexture = 13,
-    OpenGl_RT_OpenGlDepthTexture = 14
+    OpenGl_RT_OpenGlColorTexture = 14,
+    OpenGl_RT_OpenGlDepthTexture = 15
   };
 
   //! Tool class for management of shader sources.
@@ -939,6 +941,7 @@ protected: //! @name methods related to ray-tracing
                      const OpenGl_Mat4& theViewMapping,
                      OpenGl_Vec3*       theOrigins,
                      OpenGl_Vec3*       theDirects,
+                     OpenGl_Mat4&       theView,
                      OpenGl_Mat4&       theUnView);
 
   //! Binds ray-trace textures to corresponding texture units.
@@ -950,6 +953,7 @@ protected: //! @name methods related to ray-tracing
   //! Sets uniform state for the given ray-tracing shader program.
   Standard_Boolean setUniformState (const OpenGl_Vec3*            theOrigins,
                                     const OpenGl_Vec3*            theDirects,
+                                    const OpenGl_Mat4&            theViewMat,
                                     const OpenGl_Mat4&            theUnviewMat,
                                     const Standard_Integer        theProgramId,
                                     const Handle(OpenGl_Context)& theGlContext);
@@ -959,6 +963,7 @@ protected: //! @name methods related to ray-tracing
                                        const Standard_Integer        theSizeY,
                                        const OpenGl_Vec3*            theOrigins,
                                        const OpenGl_Vec3*            theDirects,
+                                       const OpenGl_Mat4&            theViewMat,
                                        const OpenGl_Mat4&            theUnviewMat,
                                        Graphic3d_Camera::Projection  theProjection,
                                        OpenGl_FrameBuffer*           theReadDrawFbo,
index 09e48f6..ecc26ac 100644 (file)
@@ -1514,6 +1514,8 @@ Standard_Boolean OpenGl_View::initRaytraceResources (const Handle(OpenGl_Context
         aShaderProgram->GetUniformLocation (theGlContext, "uDirectLT");
       myUniformLocations[anIndex][OpenGl_RT_uDirectRT] =
         aShaderProgram->GetUniformLocation (theGlContext, "uDirectRT");
+      myUniformLocations[anIndex][OpenGl_RT_uViewMat] =
+        aShaderProgram->GetUniformLocation (theGlContext, "uViewMat");
       myUniformLocations[anIndex][OpenGl_RT_uUnviewMat] =
         aShaderProgram->GetUniformLocation (theGlContext, "uUnviewMat");
 
@@ -1563,6 +1565,9 @@ Standard_Boolean OpenGl_View::initRaytraceResources (const Handle(OpenGl_Context
     myOutImageProgram->SetSampler (theGlContext,
       "uInputTexture", OpenGl_RT_PrevAccumTexture);
 
+    myOutImageProgram->SetSampler (theGlContext,
+      "uDepthTexture", OpenGl_RT_DepthTexture);
+
     theGlContext->BindProgram (NULL);
   }
 
@@ -1681,10 +1686,14 @@ void OpenGl_View::updateCamera (const OpenGl_Mat4& theOrientation,
                                 const OpenGl_Mat4& theViewMapping,
                                 OpenGl_Vec3*       theOrigins,
                                 OpenGl_Vec3*       theDirects,
+                                OpenGl_Mat4&       theView,
                                 OpenGl_Mat4&       theUnview)
 {
-  // compute inverse model-view-projection matrix
-  (theViewMapping * theOrientation).Inverted (theUnview);
+  // compute view-projection matrix
+  theView = theViewMapping * theOrientation;
+
+  // compute inverse view-projection matrix
+  theView.Inverted (theUnview);
 
   Standard_Integer aOriginIndex = 0;
   Standard_Integer aDirectIndex = 0;
@@ -2186,6 +2195,7 @@ Standard_Boolean OpenGl_View::updateRaytraceEnvironmentMap (const Handle(OpenGl_
 // =======================================================================
 Standard_Boolean OpenGl_View::setUniformState (const OpenGl_Vec3*            theOrigins,
                                                const OpenGl_Vec3*            theDirects,
+                                               const OpenGl_Mat4&            theViewMat,
                                                const OpenGl_Mat4&            theUnviewMat,
                                                const Standard_Integer        theProgramId,
                                                const Handle(OpenGl_Context)& theGlContext)
@@ -2219,6 +2229,8 @@ Standard_Boolean OpenGl_View::setUniformState (const OpenGl_Vec3*            the
   theProgram->SetUniform (theGlContext,
     myUniformLocations[theProgramId][OpenGl_RT_uDirectRT], theDirects[3]);
   theProgram->SetUniform (theGlContext,
+    myUniformLocations[theProgramId][OpenGl_RT_uViewMat], theViewMat);
+  theProgram->SetUniform (theGlContext,
     myUniformLocations[theProgramId][OpenGl_RT_uUnviewMat], theUnviewMat);
 
   // Set scene parameters
@@ -2337,6 +2349,7 @@ Standard_Boolean OpenGl_View::runRaytraceShaders (const Standard_Integer
                                                   const Standard_Integer        theSizeY,
                                                   const OpenGl_Vec3*            theOrigins,
                                                   const OpenGl_Vec3*            theDirects,
+                                                  const OpenGl_Mat4&            theViewMat,
                                                   const OpenGl_Mat4&            theUnviewMat,
                                                   Graphic3d_Camera::Projection  theProjection,
                                                   OpenGl_FrameBuffer*           theReadDrawFbo,
@@ -2365,14 +2378,13 @@ Standard_Boolean OpenGl_View::runRaytraceShaders (const Standard_Integer
   else if (myRenderParams.IsAntialiasingEnabled) // if 2-pass ray-tracing is used
   {
     myRaytraceFBO1[aFBOIdx]->BindBuffer (theGlContext);
-
-    glDisable (GL_BLEND);
   }
 
   Standard_Boolean aResult = theGlContext->BindProgram (myRaytraceProgram);
 
   aResult &= setUniformState (theOrigins,
                               theDirects,
+                              theViewMat,
                               theUnviewMat,
                               0, // ID of RT program
                               theGlContext);
@@ -2398,8 +2410,6 @@ Standard_Boolean OpenGl_View::runRaytraceShaders (const Standard_Integer
   if (myRaytraceParameters.GlobalIllumination)
   {
     // Output accumulated image
-    glDisable (GL_BLEND);
-
     theGlContext->BindProgram (myOutImageProgram);
 
     if (theReadDrawFbo != NULL)
@@ -2414,7 +2424,16 @@ Standard_Boolean OpenGl_View::runRaytraceShaders (const Standard_Integer
     aRenderFramebuffer->ColorTexture()->Bind (
       theGlContext, GL_TEXTURE0 + OpenGl_RT_PrevAccumTexture);
 
+    aRenderFramebuffer->DepthStencilTexture()->Bind (
+      theGlContext, GL_TEXTURE0 + OpenGl_RT_DepthTexture);
+
     theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
+
+    aRenderFramebuffer->DepthStencilTexture()->Unbind (
+      theGlContext, GL_TEXTURE0 + OpenGl_RT_DepthTexture);
+
+    aRenderFramebuffer->ColorTexture()->Unbind (
+      theGlContext, GL_TEXTURE0 + OpenGl_RT_PrevAccumTexture);
   }
   else if (myRenderParams.IsAntialiasingEnabled)
   {
@@ -2424,6 +2443,7 @@ Standard_Boolean OpenGl_View::runRaytraceShaders (const Standard_Integer
 
     aResult &= setUniformState (theOrigins,
                                 theDirects,
+                                theViewMat,
                                 theUnviewMat,
                                 1, // ID of FSAA program
                                 theGlContext);
@@ -2532,17 +2552,16 @@ Standard_Boolean OpenGl_View::raytrace (const Standard_Integer        theSizeX,
 
   OpenGl_Vec3 aOrigins[4];
   OpenGl_Vec3 aDirects[4];
+  OpenGl_Mat4 aViewMat;
   OpenGl_Mat4 anUnviewMat;
 
   updateCamera (aOrientationMatrix,
                 aViewMappingMatrix,
                 aOrigins,
                 aDirects,
+                aViewMat,
                 anUnviewMat);
 
-  glDisable (GL_BLEND);
-  glDisable (GL_DEPTH_TEST);
-
   if (theReadDrawFbo != NULL)
   {
     theReadDrawFbo->BindBuffer (theGlContext);
@@ -2559,15 +2578,26 @@ Standard_Boolean OpenGl_View::raytrace (const Standard_Integer        theSizeX,
         0, GL_DEBUG_SEVERITY_MEDIUM, "Error: Failed to acquire OpenGL image textures");
     }
 
+    // Remember the old depth function
+    GLint aDepthFunc;
+    theGlContext->core11fwd->glGetIntegerv (GL_DEPTH_FUNC, &aDepthFunc);
+
+    glDisable (GL_BLEND);
+    glDepthFunc (GL_ALWAYS);
+
     Standard_Boolean aResult = runRaytraceShaders (theSizeX,
                                                    theSizeY,
                                                    aOrigins,
                                                    aDirects,
+                                                   aViewMat,
                                                    anUnviewMat,
                                                    theProjection,
                                                    theReadDrawFbo,
                                                    theGlContext);
 
+    // Restore depth function
+    glDepthFunc (aDepthFunc);
+
     if (!aResult)
     {
       theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR,
@@ -2583,8 +2613,5 @@ Standard_Boolean OpenGl_View::raytrace (const Standard_Integer        theSizeX,
     myRaytraceScreenQuad.UnbindVertexAttrib (theGlContext, Graphic3d_TOA_POS);
   }
 
-  glDisable (GL_BLEND);
-  glEnable (GL_DEPTH_TEST);
-
   return Standard_True;
 }
index b6ac211..85ebec2 100644 (file)
@@ -1,6 +1,9 @@
 //! Input image.
 uniform sampler2D uInputTexture;
 
+//! Ray tracing depth image.
+uniform sampler2D uDepthTexture;
+
 //! Output pixel color.
 out vec4 OutColor;
 
@@ -8,6 +11,9 @@ void main (void)
 {
   vec4 aColor = texelFetch (uInputTexture, ivec2 (gl_FragCoord.xy), 0);
 
+  float aDepth = texelFetch (uDepthTexture, ivec2 (gl_FragCoord.xy), 0).r;
+  gl_FragDepth = aDepth;
+
   // apply gamma correction (we use gamma = 2)
   OutColor = vec4 (sqrt (aColor.rgb), aColor.a);
 }
index 5d11762..a9c2e10 100644 (file)
@@ -614,6 +614,7 @@ vec3 intersectLight (in SRay theRay, in bool isViewRay, in int theBounce, in flo
 vec4 PathTrace (in SRay theRay, in vec3 theInverse)
 {
   float anOpenGlDepth = ComputeOpenGlDepth (theRay);
+  float aRaytraceDepth = MAXFLOAT;
 
   vec3 aRadiance   = ZERO;
   vec3 aThroughput = UNIT;
@@ -659,11 +660,22 @@ vec4 PathTrace (in SRay theRay, in vec3 theInverse)
       vec4 aSrcColorRGBA = ComputeOpenGlColor();
 
       aRadiance   += aThroughput.xyz * aSrcColorRGBA.xyz;
-      aThroughput *= aSrcColorRGBA.w;
+
+      aDepth = INVALID_BOUNCES; // terminate path
     }
 
     theRay.Origin += theRay.Direct * aHit.Time; // get new intersection point
 
+    // Evaluate depth
+    if (aDepth == 0)
+    {
+      // Hit point in NDC-space [-1,1] (the polygon offset is applied in the world space)
+      vec4 aNDCPoint = uViewMat * vec4 (theRay.Origin + theRay.Direct * aPolygonOffset, 1.f);
+      aNDCPoint.xyz *= 1.f / aNDCPoint.w;
+
+      aRaytraceDepth = aNDCPoint.z * 0.5f + 0.5f;
+    }
+
     // fetch material (BSDF)
     SMaterial aMaterial = SMaterial (
       vec4 (texelFetch (uRaytraceMaterialTexture, MATERIAL_KD      (aTriIndex.w))),
@@ -779,6 +791,8 @@ vec4 PathTrace (in SRay theRay, in vec3 theInverse)
     anOpenGlDepth = MAXFLOAT; // disable combining image with OpenGL output
   }
 
+  gl_FragDepth = aRaytraceDepth;
+
   return vec4 (aRadiance, 0.f);
 }
 
index 13f17b2..2356906 100644 (file)
@@ -36,6 +36,9 @@ uniform vec3 uDirectRB;
 //! Inverse model-view-projection matrix.
 uniform mat4 uUnviewMat;
 
+//! Model-view-projection matrix.
+uniform mat4 uViewMat;
+
 //! Texture buffer of data records of bottom-level BVH nodes.
 uniform isamplerBuffer uSceneNodeInfoTexture;
 //! Texture buffer of minimum points of bottom-level BVH nodes.
@@ -777,6 +780,7 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
   int aTrsfId;
 
   float anOpenGlDepth = ComputeOpenGlDepth (theRay);
+  float aRaytraceDepth = MAXFLOAT;
 
   for (int aDepth = 0; aDepth < NB_BOUNCES; ++aDepth)
   {
@@ -831,6 +835,16 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
 
     theRay.Origin += theRay.Direct * aHit.Time; // intersection point
 
+    // Evaluate depth
+    if (aDepth == 0)
+    {
+      // Hit point in NDC-space [-1,1] (the polygon offset is applied in the world space)
+      vec4 aNDCPoint = uViewMat * vec4 (theRay.Origin + theRay.Direct * aPolygonOffset, 1.f);
+      aNDCPoint.xyz *= 1.f / aNDCPoint.w;
+
+      aRaytraceDepth = aNDCPoint.z * 0.5f + 0.5f;
+    }
+
     vec3 aNormal = SmoothNormal (aHit.UV, aTriIndex);
 
     aNormal = normalize (vec3 (dot (aInvTransf0, aNormal),
@@ -970,6 +984,8 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
     theRay.Origin += theRay.Direct * uSceneEpsilon;
   }
 
+  gl_FragDepth = aRaytraceDepth;
+
   return vec4 (aResult.x,
                aResult.y,
                aResult.z,