From 495aa898411f180e434e1624e82cdfc5557de3a0 Mon Sep 17 00:00:00 2001 From: duv Date: Tue, 14 Jul 2015 16:52:30 +0300 Subject: [PATCH] 0026432: Improving Path Tracing functionality --- src/Graphic3d/Graphic3d_RenderingParams.hxx | 2 + src/OpenGl/OpenGl_View.hxx | 1 + src/OpenGl/OpenGl_View_Raytrace.cxx | 50 +++++++++++++++++--- src/Shaders/Display.fs | 47 +++++++++++++++++- src/ViewerTest/ViewerTest_ViewerCommands.cxx | 44 +++++++++++++++++ 5 files changed, 135 insertions(+), 9 deletions(-) diff --git a/src/Graphic3d/Graphic3d_RenderingParams.hxx b/src/Graphic3d/Graphic3d_RenderingParams.hxx index d56a9cfcd9..7983450571 100644 --- a/src/Graphic3d/Graphic3d_RenderingParams.hxx +++ b/src/Graphic3d/Graphic3d_RenderingParams.hxx @@ -55,6 +55,7 @@ public: IsReflectionEnabled (Standard_False), IsAntialiasingEnabled (Standard_False), IsTransparentShadowEnabled (Standard_False), + IsGIFilteringEnabled (Standard_False), CoherentPathTracingMode (Standard_False), UseEnvironmentMapBackground (Standard_False), @@ -85,6 +86,7 @@ public: Standard_Boolean IsAntialiasingEnabled; //!< enables/disables adaptive anti-aliasing, False by default Standard_Boolean IsTransparentShadowEnabled; //!< enables/disables light propagation through transparent media, False by default Standard_Boolean UseEnvironmentMapBackground; //!< enables/disables environment map background + Standard_Boolean IsGIFilteringEnabled; //!< enables/disables post-processing of GI rendering results Standard_Boolean CoherentPathTracingMode; //!< enables/disables 'coherent' tracing mode (single RNG seed within 16x16 image blocks) Graphic3d_StereoMode StereoMode; //!< stereoscopic output mode, Graphic3d_StereoMode_QuadBuffer by default diff --git a/src/OpenGl/OpenGl_View.hxx b/src/OpenGl/OpenGl_View.hxx index e0b62317d3..0bfe03624c 100644 --- a/src/OpenGl/OpenGl_View.hxx +++ b/src/OpenGl/OpenGl_View.hxx @@ -350,6 +350,7 @@ protected: //! @name data types related to ray-tracing // sampled frame params OpenGl_RT_uSampleWeight, OpenGl_RT_uFrameRndSeed, + OpenGl_RT_BilateralFilteringEnabled, // adaptive FSAA params OpenGl_RT_uOffsetX, diff --git a/src/OpenGl/OpenGl_View_Raytrace.cxx b/src/OpenGl/OpenGl_View_Raytrace.cxx index 048aaec6a3..0af7a21258 100644 --- a/src/OpenGl/OpenGl_View_Raytrace.cxx +++ b/src/OpenGl/OpenGl_View_Raytrace.cxx @@ -1578,6 +1578,9 @@ Standard_Boolean OpenGl_View::initRaytraceResources (const Graphic3d_CView& theC theGlContext->BindProgram (myOutImageProgram); + myUniformLocations[0][OpenGl_RT_BilateralFilteringEnabled] = + myOutImageProgram->GetUniformLocation (theGlContext, "uBilateralEnabled"); + myOutImageProgram->SetSampler (theGlContext, "uInputTexture", OpenGl_RT_PrevAccumTexture); @@ -2395,16 +2398,47 @@ Standard_Boolean OpenGl_View::runRaytraceShaders (const Graphic3d_CView& if (myRaytraceParameters.GlobalIllumination) { - // Set frame accumulation weight - myRaytraceProgram->SetUniform (theGlContext, - myUniformLocations[0][OpenGl_RT_uSampleWeight], 1.f / (myAccumFrames + 1)); - // Set random number generator seed myRaytraceProgram->SetUniform (theGlContext, myUniformLocations[0][OpenGl_RT_uFrameRndSeed], static_cast (myRNG.NextInt() >> 2)); - } - theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6); + Standard_Integer aSamplesPerPixel = theCView.RenderParams.SamplesPerPixel; + + if (aSamplesPerPixel == 0) + { + // Set frame accumulation weight + myRaytraceProgram->SetUniform (theGlContext, + myUniformLocations[0][OpenGl_RT_uSampleWeight], 1.f / (myAccumFrames + 1)); + + theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6); + } + else + { + for (int aPassIndex = 0; aPassIndex < aSamplesPerPixel; ++aPassIndex) + { + aRenderFramebuffer = myAccumFrames % 2 ? myRaytraceFBO1 : myRaytraceFBO2; + anAccumFramebuffer = myAccumFrames % 2 ? myRaytraceFBO2 : myRaytraceFBO1; + + aRenderFramebuffer->BindBuffer (theGlContext); + + anAccumFramebuffer->ColorTexture()->Bind ( + theGlContext, GL_TEXTURE0 + OpenGl_RT_PrevAccumTexture); + + // Set frame accumulation weight + myRaytraceProgram->SetUniform (theGlContext, + myUniformLocations[0][OpenGl_RT_uSampleWeight], 1.f / (myAccumFrames + 1)); + + theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6); + ++myAccumFrames; + glFinish(); + } + } + } + else + { + theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6); + ++myAccumFrames; + } if (myRaytraceParameters.GlobalIllumination) { @@ -2425,9 +2459,11 @@ Standard_Boolean OpenGl_View::runRaytraceShaders (const Graphic3d_CView& aRenderFramebuffer->ColorTexture()->Bind ( theGlContext, GL_TEXTURE0 + OpenGl_RT_PrevAccumTexture); + myOutImageProgram->SetUniform (theGlContext, + myUniformLocations[0][OpenGl_RT_BilateralFilteringEnabled], theCView.RenderParams.IsGIFilteringEnabled ? 1 : 0); + theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6); - ++myAccumFrames; } else if (theCView.RenderParams.IsAntialiasingEnabled) { diff --git a/src/Shaders/Display.fs b/src/Shaders/Display.fs index b6ac211d28..e496e71a63 100644 --- a/src/Shaders/Display.fs +++ b/src/Shaders/Display.fs @@ -1,13 +1,56 @@ //! Input image. uniform sampler2D uInputTexture; +uniform int uBilateralEnabled; + //! Output pixel color. out vec4 OutColor; +const float rI = 0.270 * 1.0f; // The intensity radius (in pixels). +const float rL = 1.71 * 0.5f; // The geometric radius (in pixels). +const int WindowSize = 8; // The window size (in pixels). + +float gaussian (float theL, float theR) +{ + return exp (-theL * theL / (2.0f * theR * theR)); +} + +vec4 bilateral() +{ + // Get the sizes + int aWindow = WindowSize / 2; + vec4 anOutCol = vec4 (0.f, 0.f, 0.f, 0.f); + vec4 aRefCol = texelFetch (uInputTexture, ivec2 (gl_FragCoord.xy), 0); + float aNorm = 0.f; + + // Compute the kernel + for (int i = -aWindow; i <= aWindow; i++) + { + for (int j = -aWindow; j <= aWindow; j++) + { + vec4 aCol = texelFetch (uInputTexture, ivec2 (gl_FragCoord.xy) + ivec2 (j, i), 0); + float A = gaussian (distance (aCol, aRefCol), rI); + float B = gaussian (length (vec2(j, i)), rL); + anOutCol += aCol * A * B; + aNorm += A * B; + } + } + return anOutCol * (1.f / aNorm); +} + void main (void) { - vec4 aColor = texelFetch (uInputTexture, ivec2 (gl_FragCoord.xy), 0); + vec4 aColor; + + if (bool (uBilateralEnabled)) + { + aColor = bilateral(); + } + else + { + aColor = texelFetch (uInputTexture, ivec2 (gl_FragCoord.xy), 0); + } // apply gamma correction (we use gamma = 2) OutColor = vec4 (sqrt (aColor.rgb), aColor.a); -} +} \ No newline at end of file diff --git a/src/ViewerTest/ViewerTest_ViewerCommands.cxx b/src/ViewerTest/ViewerTest_ViewerCommands.cxx index b7e5f7de2b..32fdee65df 100644 --- a/src/ViewerTest/ViewerTest_ViewerCommands.cxx +++ b/src/ViewerTest/ViewerTest_ViewerCommands.cxx @@ -8354,6 +8354,8 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI, theDI << "gleam: " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n"; theDI << "GI: " << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << "\n"; theDI << "blocked RNG: " << (aParams.CoherentPathTracingMode ? "on" : "off") << "\n"; + theDI << "samples: " << aParams.SamplesPerPixel << "\n"; + theDI << "filtering: " << (aParams.IsGIFilteringEnabled ? "on" : "off") << "\n"; theDI << "shadingModel: "; switch (aView->ShadingModel()) { @@ -8452,6 +8454,32 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI, aParams.RaytracingDepth = aDepth; } } + else if (aFlag == "-samples" + || aFlag == "-spp") + { + if (toPrint) + { + theDI << aParams.SamplesPerPixel << " "; + continue; + } + else if (++anArgIter >= theArgNb) + { + std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n"; + return 1; + } + + const Standard_Integer aSamples = Draw::Atoi (theArgVec[anArgIter]); + + if (aSamples < 0) + { + std::cerr << "Error: invalid ray-tracing samples per pixel " << aSamples << ". SPP should be a positive number.\n"; + return 1; + } + else + { + aParams.SamplesPerPixel = aSamples; + } + } else if (aFlag == "-shad" || aFlag == "-shadows") { @@ -8555,6 +8583,22 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI, } aParams.CoherentPathTracingMode = toEnable; } + else if (aFlag == "-filter" || aFlag == "-pp" ) + { + if (toPrint) + { + theDI << (aParams.IsGIFilteringEnabled ? "on" : "off") << " "; + continue; + } + + Standard_Boolean toEnable = Standard_True; + if (++anArgIter < theArgNb + && !parseOnOff (theArgVec[anArgIter], toEnable)) + { + --anArgIter; + } + aParams.IsGIFilteringEnabled = toEnable; + } else if (aFlag == "-env") { if (toPrint) -- 2.39.5