From b09447ed89783497b0639d2ed53b899585c52e55 Mon Sep 17 00:00:00 2001 From: dbp Date: Wed, 18 Jan 2017 14:24:13 +0300 Subject: [PATCH] 0028369: Visualization, Path Tracing - Expose radiance clamping setting in path tracing mode New parameter was added in the vrenderparams command: vrenderparams -maxrad --- src/Graphic3d/Graphic3d_RenderingParams.hxx | 2 + src/OpenGl/OpenGl_View.hxx | 19 +++-- src/OpenGl/OpenGl_View_Raytrace.cxx | 73 +++++++++++++------- src/Shaders/PathtraceBase.fs | 2 +- src/Shaders/RaytraceRender.fs | 8 +-- src/Shaders/Shaders_PathtraceBase_fs.pxx | 2 +- src/Shaders/Shaders_RaytraceRender_fs.pxx | 8 +-- src/ViewerTest/ViewerTest_ViewerCommands.cxx | 33 +++++++++ tests/v3d/raytrace/sample_cube_clamp | 22 ++++++ 9 files changed, 129 insertions(+), 40 deletions(-) create mode 100644 tests/v3d/raytrace/sample_cube_clamp diff --git a/src/Graphic3d/Graphic3d_RenderingParams.hxx b/src/Graphic3d/Graphic3d_RenderingParams.hxx index 60c8212ec1..b264d44361 100644 --- a/src/Graphic3d/Graphic3d_RenderingParams.hxx +++ b/src/Graphic3d/Graphic3d_RenderingParams.hxx @@ -60,6 +60,7 @@ public: AdaptiveScreenSampling (Standard_False), ShowSamplingTiles (Standard_False), TwoSidedBsdfModels (Standard_False), + RadianceClampingValue (30.0), RebuildRayTracingShaders (Standard_False), // stereoscopic parameters StereoMode (Graphic3d_StereoMode_QuadBuffer), @@ -102,6 +103,7 @@ public: Standard_Boolean AdaptiveScreenSampling; //!< enables/disables adaptive screen sampling mode for path tracing, FALSE by default Standard_Boolean ShowSamplingTiles; //!< enables/disables debug mode for adaptive screen sampling, FALSE by default Standard_Boolean TwoSidedBsdfModels; //!< forces path tracing to use two-sided versions of original one-sided scattering models + Standard_ShortReal RadianceClampingValue; //!< maximum radiance value used for clamping radiance estimation. Standard_Boolean RebuildRayTracingShaders; //!< forces rebuilding ray tracing shaders at the next frame 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 463b980d63..45f44cc5fe 100644 --- a/src/OpenGl/OpenGl_View.hxx +++ b/src/OpenGl/OpenGl_View.hxx @@ -581,10 +581,13 @@ protected: //! @name data types related to ray-tracing OpenGl_RT_uOffsetY, OpenGl_RT_uSamples, - // adaptive path tracing images + // images used by ISS mode OpenGl_RT_uRenderImage, OpenGl_RT_uOffsetImage, + // maximum radiance value + OpenGl_RT_uMaxRadiance, + OpenGl_RT_NbVariables // special field }; @@ -702,15 +705,23 @@ protected: //! @name data types related to ray-tracing //! Enables/disables adaptive screen sampling for path tracing. Standard_Boolean AdaptiveScreenSampling; + //! Enables/disables environment map for background. + Standard_Boolean UseEnvMapForBackground; + + //! Maximum radiance value used for clamping radiance estimation. + Standard_ShortReal RadianceClampingValue; + //! Creates default compile-time ray-tracing parameters. RaytracingParams() - : StackSize (THE_DEFAULT_STACK_SIZE), - NbBounces (THE_DEFAULT_NB_BOUNCES), + : StackSize (THE_DEFAULT_STACK_SIZE), + NbBounces (THE_DEFAULT_NB_BOUNCES), TransparentShadows (Standard_False), GlobalIllumination (Standard_False), UseBindlessTextures (Standard_False), TwoSidedBsdfModels (Standard_False), - AdaptiveScreenSampling (Standard_False) { } + AdaptiveScreenSampling (Standard_False), + UseEnvMapForBackground (Standard_False), + RadianceClampingValue (30.0) { } }; //! Describes state of OpenGL structure. diff --git a/src/OpenGl/OpenGl_View_Raytrace.cxx b/src/OpenGl/OpenGl_View_Raytrace.cxx index ba286a25f4..54494ef0d1 100644 --- a/src/OpenGl/OpenGl_View_Raytrace.cxx +++ b/src/OpenGl/OpenGl_View_Raytrace.cxx @@ -1731,6 +1731,9 @@ Standard_Boolean OpenGl_View::initRaytraceResources (const Handle(OpenGl_Context aShaderProgram->GetUniformLocation (theGlContext, "uBackColorTop"); myUniformLocations[anIndex][OpenGl_RT_uBackColorBot] = aShaderProgram->GetUniformLocation (theGlContext, "uBackColorBot"); + + myUniformLocations[anIndex][OpenGl_RT_uMaxRadiance] = + aShaderProgram->GetUniformLocation (theGlContext, "uMaxRadiance"); } theGlContext->BindProgram (myOutImageProgram); @@ -2465,38 +2468,24 @@ Standard_Boolean OpenGl_View::setUniformState (const Standard_Integer the theProgram->SetUniform (theGlContext, myUniformLocations[theProgramId][OpenGl_RT_uUnviewMat], anUnviewMat); - // Set ray-tracing intersection parameters - theProgram->SetUniform (theGlContext, - myUniformLocations[theProgramId][OpenGl_RT_uSceneRad], myRaytraceSceneRadius); - theProgram->SetUniform (theGlContext, - myUniformLocations[theProgramId][OpenGl_RT_uSceneEps], myRaytraceSceneEpsilon); - - const Standard_Integer aLightSourceBufferSize = - static_cast (myRaytraceGeometry.Sources.size()); - - // Set ray-tracing light source parameters - theProgram->SetUniform (theGlContext, - myUniformLocations[theProgramId][OpenGl_RT_uLightCount], aLightSourceBufferSize); - theProgram->SetUniform (theGlContext, - myUniformLocations[theProgramId][OpenGl_RT_uLightAmbnt], myRaytraceGeometry.Ambient); - - // Enable/disable run-time rendering effects - theProgram->SetUniform (theGlContext, - myUniformLocations[theProgramId][OpenGl_RT_uShadowsEnabled], myRenderParams.IsShadowEnabled ? 1 : 0); - theProgram->SetUniform (theGlContext, - myUniformLocations[theProgramId][OpenGl_RT_uReflectEnabled], myRenderParams.IsReflectionEnabled ? 1 : 0); - // Set screen dimensions myRaytraceProgram->SetUniform (theGlContext, myUniformLocations[theProgramId][OpenGl_RT_uWinSizeX], theWinSizeX); myRaytraceProgram->SetUniform (theGlContext, myUniformLocations[theProgramId][OpenGl_RT_uWinSizeY], theWinSizeY); - if (myRenderParams.IsGlobalIlluminationEnabled) // if Monte-Carlo sampling enabled - { - theProgram->SetUniform (theGlContext, - myUniformLocations[theProgramId][OpenGl_RT_uBlockedRngEnabled], myRenderParams.CoherentPathTracingMode ? 1 : 0); - } + // Set 3D scene parameters + theProgram->SetUniform (theGlContext, + myUniformLocations[theProgramId][OpenGl_RT_uSceneRad], myRaytraceSceneRadius); + theProgram->SetUniform (theGlContext, + myUniformLocations[theProgramId][OpenGl_RT_uSceneEps], myRaytraceSceneEpsilon); + + // Set light source parameters + const Standard_Integer aLightSourceBufferSize = + static_cast (myRaytraceGeometry.Sources.size()); + + theProgram->SetUniform (theGlContext, + myUniformLocations[theProgramId][OpenGl_RT_uLightCount], aLightSourceBufferSize); // Set array of 64-bit texture handles if (theGlContext->arbTexBindless != NULL && myRaytraceGeometry.HasTextures()) @@ -2525,6 +2514,7 @@ Standard_Boolean OpenGl_View::setUniformState (const Standard_Integer the myUniformLocations[theProgramId][OpenGl_RT_uBackColorBot], aBackColor); } + // Set environment map parameters const Standard_Boolean toDisableEnvironmentMap = myTextureEnv.IsNull() || !myTextureEnv->IsValid(); theProgram->SetUniform (theGlContext, @@ -2533,6 +2523,37 @@ Standard_Boolean OpenGl_View::setUniformState (const Standard_Integer the theProgram->SetUniform (theGlContext, myUniformLocations[theProgramId][OpenGl_RT_uSphereMapForBack], myRenderParams.UseEnvironmentMapBackground ? 1 : 0); + if (myRenderParams.IsGlobalIlluminationEnabled) // GI parameters + { + theProgram->SetUniform (theGlContext, + myUniformLocations[theProgramId][OpenGl_RT_uMaxRadiance], myRenderParams.RadianceClampingValue); + + theProgram->SetUniform (theGlContext, + myUniformLocations[theProgramId][OpenGl_RT_uBlockedRngEnabled], myRenderParams.CoherentPathTracingMode ? 1 : 0); + + // Check whether we should restart accumulation for run-time parameters + if (myRenderParams.RadianceClampingValue != myRaytraceParameters.RadianceClampingValue + || myRenderParams.UseEnvironmentMapBackground != myRaytraceParameters.UseEnvMapForBackground) + { + myAccumFrames = 0; // accumulation should be restarted + + myRaytraceParameters.RadianceClampingValue = myRenderParams.RadianceClampingValue; + myRaytraceParameters.UseEnvMapForBackground = myRenderParams.UseEnvironmentMapBackground; + } + } + else // RT parameters + { + // Set ambient light source + theProgram->SetUniform (theGlContext, + myUniformLocations[theProgramId][OpenGl_RT_uLightAmbnt], myRaytraceGeometry.Ambient); + + // Enable/disable run-time ray-tracing effects + theProgram->SetUniform (theGlContext, + myUniformLocations[theProgramId][OpenGl_RT_uShadowsEnabled], myRenderParams.IsShadowEnabled ? 1 : 0); + theProgram->SetUniform (theGlContext, + myUniformLocations[theProgramId][OpenGl_RT_uReflectEnabled], myRenderParams.IsReflectionEnabled ? 1 : 0); + } + return Standard_True; } diff --git a/src/Shaders/PathtraceBase.fs b/src/Shaders/PathtraceBase.fs index 8e8dd42ef9..76b44e86f9 100644 --- a/src/Shaders/PathtraceBase.fs +++ b/src/Shaders/PathtraceBase.fs @@ -785,7 +785,7 @@ vec4 PathTrace (in SRay theRay, in vec3 theInverse) vec4 aTexColor = textureLod ( sampler2D (uTextureSamplers[int (aMaterial.Kd.w)]), aTexCoord.st, 0.f); - aMaterial.Kd.rgb *= (aTexColor.rgb, aTexColor.rgb) * aTexColor.w; // de-gamma correction (for gamma = 2) + aMaterial.Kd.rgb *= (aTexColor.rgb * aTexColor.rgb) * aTexColor.w; // de-gamma correction (for gamma = 2) if (aTexColor.w != 1.0f) { diff --git a/src/Shaders/RaytraceRender.fs b/src/Shaders/RaytraceRender.fs index 009270ecba..15ed8d8f50 100644 --- a/src/Shaders/RaytraceRender.fs +++ b/src/Shaders/RaytraceRender.fs @@ -13,9 +13,9 @@ uniform int uBlockedRngEnabled; uniform sampler2D uAccumTexture; #endif -//! Maximum radiance that can be added to the pixel. Decreases noise -//! level, but introduces some bias. -#define MAX_RADIANCE vec3 (50.f) +//! Maximum radiance that can be added to the pixel. +//! Decreases noise level, but introduces some bias. +uniform float uMaxRadiance = 50.f; // ======================================================================= // function : main @@ -64,7 +64,7 @@ void main (void) aColor.rgb = ZERO; } - aColor.rgb = min (aColor.rgb, MAX_RADIANCE); + aColor.rgb = min (aColor.rgb, vec3 (uMaxRadiance)); #ifdef ADAPTIVE_SAMPLING diff --git a/src/Shaders/Shaders_PathtraceBase_fs.pxx b/src/Shaders/Shaders_PathtraceBase_fs.pxx index a0064a213b..fb1746cff0 100644 --- a/src/Shaders/Shaders_PathtraceBase_fs.pxx +++ b/src/Shaders/Shaders_PathtraceBase_fs.pxx @@ -788,7 +788,7 @@ static const char Shaders_PathtraceBase_fs[] = " vec4 aTexColor = textureLod (\n" " sampler2D (uTextureSamplers[int (aMaterial.Kd.w)]), aTexCoord.st, 0.f);\n" "\n" - " aMaterial.Kd.rgb *= (aTexColor.rgb, aTexColor.rgb) * aTexColor.w; // de-gamma correction (for gamma = 2)\n" + " aMaterial.Kd.rgb *= (aTexColor.rgb * aTexColor.rgb) * aTexColor.w; // de-gamma correction (for gamma = 2)\n" "\n" " if (aTexColor.w != 1.0f)\n" " {\n" diff --git a/src/Shaders/Shaders_RaytraceRender_fs.pxx b/src/Shaders/Shaders_RaytraceRender_fs.pxx index e32c754690..46afbe0731 100644 --- a/src/Shaders/Shaders_RaytraceRender_fs.pxx +++ b/src/Shaders/Shaders_RaytraceRender_fs.pxx @@ -16,9 +16,9 @@ static const char Shaders_RaytraceRender_fs[] = " uniform sampler2D uAccumTexture;\n" "#endif\n" "\n" - "//! Maximum radiance that can be added to the pixel. Decreases noise\n" - "//! level, but introduces some bias.\n" - "#define MAX_RADIANCE vec3 (50.f)\n" + "//! Maximum radiance that can be added to the pixel.\n" + "//! Decreases noise level, but introduces some bias.\n" + "uniform float uMaxRadiance = 50.f;\n" "\n" "// =======================================================================\n" "// function : main\n" @@ -67,7 +67,7 @@ static const char Shaders_RaytraceRender_fs[] = " aColor.rgb = ZERO;\n" " }\n" "\n" - " aColor.rgb = min (aColor.rgb, MAX_RADIANCE);\n" + " aColor.rgb = min (aColor.rgb, vec3 (uMaxRadiance));\n" "\n" "#ifdef ADAPTIVE_SAMPLING\n" "\n" diff --git a/src/ViewerTest/ViewerTest_ViewerCommands.cxx b/src/ViewerTest/ViewerTest_ViewerCommands.cxx index 4fdf4d1baa..ce91b42a55 100644 --- a/src/ViewerTest/ViewerTest_ViewerCommands.cxx +++ b/src/ViewerTest/ViewerTest_ViewerCommands.cxx @@ -9075,6 +9075,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI, theDI << "iss: " << (aParams.AdaptiveScreenSampling ? "on" : "off") << "\n"; theDI << "iss debug: " << (aParams.ShowSamplingTiles ? "on" : "off") << "\n"; theDI << "two-sided BSDF: " << (aParams.TwoSidedBsdfModels ? "on" : "off") << "\n"; + theDI << "max radiance: " << aParams.RadianceClampingValue << "\n"; theDI << "shadingModel: "; switch (aView->ShadingModel()) { @@ -9300,6 +9301,37 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI, } aParams.CoherentPathTracingMode = toEnable; } + else if (aFlag == "-maxrad") + { + if (toPrint) + { + theDI << aParams.RadianceClampingValue << " "; + continue; + } + else if (++anArgIter >= theArgNb) + { + std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n"; + return 1; + } + + const TCollection_AsciiString aMaxRadStr = theArgVec[anArgIter]; + if (!aMaxRadStr.IsRealValue()) + { + std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n"; + return 1; + } + + const Standard_Real aMaxRadiance = aMaxRadStr.RealValue(); + if (aMaxRadiance <= 0.0) + { + std::cerr << "Error: invalid radiance clamping value " << aMaxRadiance << ".\n"; + return 1; + } + else + { + aParams.RadianceClampingValue = static_cast (aMaxRadiance); + } + } else if (aFlag == "-iss") { if (toPrint) @@ -10906,6 +10938,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands) "\n '-twoside on|off' Enables/disables two-sided BSDF models (PT mode)" "\n '-iss on|off' Enables/disables adaptive screen sampling (PT mode)" "\n '-issd on|off' Shows screen sampling distribution in ISS mode" + "\n '-maxrad > 0.0' Value used for clamping radiance estimation (PT mode)" "\n '-rebuildGlsl on|off' Rebuild Ray-Tracing GLSL programs (for debugging)" "\n '-shadingModel model' Controls shading model from enumeration" "\n color, flat, gouraud, phong" diff --git a/tests/v3d/raytrace/sample_cube_clamp b/tests/v3d/raytrace/sample_cube_clamp new file mode 100644 index 0000000000..7f603d00a9 --- /dev/null +++ b/tests/v3d/raytrace/sample_cube_clamp @@ -0,0 +1,22 @@ +puts "============" +puts "Visualization - Path Tracing, Cube sample with radiance clamping" +puts "============" +puts "" + +source $env(CSF_OCCTSamplesPath)/tcl/pathtrace_cube.tcl + +vrenderparams -maxrad 1.0 +vfps 100 +vdump $imagedir/${casename}_1.png + +vrenderparams -maxrad 2.0 +vfps 100 +vdump $imagedir/${casename}_2.png + +vrenderparams -maxrad 10.0 +vfps 100 +vdump $imagedir/${casename}_10.png + +vrenderparams -maxrad 100.0 +vfps 100 +vdump $imagedir/${casename}_100.png \ No newline at end of file