diff --git a/src/OpenGl/OpenGl_View.hxx b/src/OpenGl/OpenGl_View.hxx index 026c583469..3cc7fb3293 100644 --- a/src/OpenGl/OpenGl_View.hxx +++ b/src/OpenGl/OpenGl_View.hxx @@ -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, diff --git a/src/OpenGl/OpenGl_View_Raytrace.cxx b/src/OpenGl/OpenGl_View_Raytrace.cxx index 09e48f63e2..ecc26ac7be 100644 --- a/src/OpenGl/OpenGl_View_Raytrace.cxx +++ b/src/OpenGl/OpenGl_View_Raytrace.cxx @@ -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; } diff --git a/src/Shaders/Display.fs b/src/Shaders/Display.fs index b6ac211d28..85ebec20e0 100644 --- a/src/Shaders/Display.fs +++ b/src/Shaders/Display.fs @@ -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); } diff --git a/src/Shaders/PathtraceBase.fs b/src/Shaders/PathtraceBase.fs index 5d11762f60..a9c2e10931 100644 --- a/src/Shaders/PathtraceBase.fs +++ b/src/Shaders/PathtraceBase.fs @@ -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); } diff --git a/src/Shaders/RaytraceBase.fs b/src/Shaders/RaytraceBase.fs index 13f17b26d4..23569063a5 100644 --- a/src/Shaders/RaytraceBase.fs +++ b/src/Shaders/RaytraceBase.fs @@ -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,