]> OCCT Git - occt-copy.git/commitdiff
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 026c583469cf539c2e9eba6609500f6aa0bafae3..3cc7fb32933f7ecabad5e95f23047aa6c829f7b2 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 09e48f63e2ef066cf3a5b546d2c5edc1a081bcd1..ecc26ac7bed6da666eca97e78c474c0a9e860d35 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)
@@ -2218,6 +2228,8 @@ Standard_Boolean OpenGl_View::setUniformState (const OpenGl_Vec3*            the
     myUniformLocations[theProgramId][OpenGl_RT_uDirectLT], theDirects[2]);
   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);
 
@@ -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 b6ac211d28ada004c8996d8a32564bd4bc3dcd03..85ebec20e0e4672f65aa66370b1276777fbb47f2 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 5d11762f609bcc9da4e3c0389cf534436b3f2ed4..a9c2e10931d82ab824f480d1ca865d18fe740bca 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 13f17b26d4bbfbbd917f8d38f8d2bd1d05385ec5..23569063a5dd499cbb838998bf4a6375caa00a19 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,