0028794: Visualization, Ray tracing - Implement tone mapping
authorage <age@opencascade.com>
Thu, 25 May 2017 11:34:34 +0000 (14:34 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 9 Jun 2017 09:59:04 +0000 (12:59 +0300)
Added enum Graphic3d_ToneMappingMethod for choosing tone mapping mode.
Added new rendering parameters.
Added tone mapping to Display.fs shader.

src/Graphic3d/FILES
src/Graphic3d/Graphic3d_RenderingParams.hxx
src/Graphic3d/Graphic3d_ToneMappingMethod.hxx [new file with mode: 0644]
src/OpenGl/OpenGl_View.hxx
src/OpenGl/OpenGl_View_Raytrace.cxx
src/Shaders/Display.fs
src/ViewerTest/ViewerTest_ViewerCommands.cxx
tests/v3d/raytrace/tone_mapping [new file with mode: 0644]

index 5ae409a..a8570d8 100755 (executable)
@@ -130,6 +130,7 @@ Graphic3d_TextureParams.cxx
 Graphic3d_TextureParams.hxx
 Graphic3d_TextureRoot.cxx
 Graphic3d_TextureRoot.hxx
+Graphic3d_ToneMappingMethod.hxx
 Graphic3d_TransformError.hxx
 Graphic3d_TransformPers.hxx
 Graphic3d_TransformPers.cxx
index afc678f..4175134 100644 (file)
@@ -20,6 +20,7 @@
 #include <Graphic3d_RenderTransparentMethod.hxx>
 #include <Graphic3d_RenderingMode.hxx>
 #include <Graphic3d_StereoMode.hxx>
+#include <Graphic3d_ToneMappingMethod.hxx>
 #include <Graphic3d_Vec4.hxx>
 
 //! Helper class to store rendering parameters.
@@ -67,6 +68,9 @@ public:
     RadianceClampingValue       (30.0),
     RebuildRayTracingShaders    (Standard_False),
     NbRayTracingTiles           (16 * 16),
+    ToneMappingMethod           (Graphic3d_ToneMappingMethod_Disabled),
+    Exposure                    (0.f),
+    WhitePoint                  (1.f),
     // stereoscopic parameters
     StereoMode (Graphic3d_StereoMode_QuadBuffer),
     AnaglyphFilter (Anaglyph_RedCyan_Optimized),
@@ -116,6 +120,10 @@ public:
   Standard_Boolean                  RebuildRayTracingShaders;    //!< forces rebuilding ray tracing shaders at the next frame
   Standard_Integer                  NbRayTracingTiles;           //!< total number of screen tiles used in adaptive sampling mode (PT only)
 
+  Graphic3d_ToneMappingMethod       ToneMappingMethod;           //!< specifies tone mapping method for path tracing, Graphic3d_ToneMappingMethod_Disabled by default
+  Standard_ShortReal                Exposure;                    //!< exposure value used for tone mapping (path tracing), 0.0 by default
+  Standard_ShortReal                WhitePoint;                  //!< white point value used in filmic tone mapping (path tracing), 1.0 by default
+
   Graphic3d_StereoMode              StereoMode;                  //!< stereoscopic output mode, Graphic3d_StereoMode_QuadBuffer by default
   Anaglyph                          AnaglyphFilter;              //!< filter for anaglyph output, Anaglyph_RedCyan_Optimized by default
   Graphic3d_Mat4                    AnaglyphLeft;                //!< left  anaglyph filter (in normalized colorspace), Color = AnaglyphRight * theColorRight + AnaglyphLeft * theColorLeft;
diff --git a/src/Graphic3d/Graphic3d_ToneMappingMethod.hxx b/src/Graphic3d/Graphic3d_ToneMappingMethod.hxx
new file mode 100644 (file)
index 0000000..e10c91d
--- /dev/null
@@ -0,0 +1,26 @@
+// Created on: 2017-05-26
+// Created by: Andrey GOLODYAEV
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Graphic3d_ToneMappingMethod_HeaderFile
+#define _Graphic3d_ToneMappingMethod_HeaderFile
+
+//! Enumerates tone mapping methods.
+enum Graphic3d_ToneMappingMethod
+{
+  Graphic3d_ToneMappingMethod_Disabled,      //!< Don't use tone mapping
+  Graphic3d_ToneMappingMethod_Filmic         //!< Use filmic tone mapping
+};
+
+#endif // _Graphic3d_ToneMappingMethod_HeaderFile
\ No newline at end of file
index cfe2e55..9b98aa9 100644 (file)
@@ -30,6 +30,7 @@
 #include <Graphic3d_CView.hxx>
 #include <Graphic3d_GraduatedTrihedron.hxx>
 #include <Graphic3d_SequenceOfHClipPlane.hxx>
+#include <Graphic3d_ToneMappingMethod.hxx>
 #include <Graphic3d_TypeOfShadingModel.hxx>
 #include <Graphic3d_WorldViewProjState.hxx>
 #include <Graphic3d_ZLayerSettings.hxx>
@@ -740,6 +741,9 @@ protected: //! @name data types related to ray-tracing
     
     //! Number of tiles in Y dimension (in adaptive sampling mode).
     Standard_Integer NbTilesY;
+    
+    //! Tone mapping method for path tracing.
+    Graphic3d_ToneMappingMethod ToneMappingMethod;
 
     //! Creates default compile-time ray-tracing parameters.
     RaytracingParams()
@@ -753,7 +757,8 @@ protected: //! @name data types related to ray-tracing
       UseEnvMapForBackground (Standard_False),
       RadianceClampingValue  (30.0),
       NbTilesX               (16),
-      NbTilesY               (16) { }
+      NbTilesY               (16),
+      ToneMappingMethod      (Graphic3d_ToneMappingMethod_Disabled) { }
   };
 
   //! Describes state of OpenGL structure.
index 02d69d1..88c7682 100644 (file)
@@ -1148,6 +1148,15 @@ TCollection_AsciiString OpenGl_View::generateShaderPrefix (const Handle(OpenGl_C
     {
       aPrefixString += TCollection_AsciiString ("\n#define TWO_SIDED_BXDF");
     }
+
+    switch (myRaytraceParameters.ToneMappingMethod)
+    {
+      case Graphic3d_ToneMappingMethod_Disabled:
+        break;
+      case Graphic3d_ToneMappingMethod_Filmic:
+        aPrefixString += TCollection_AsciiString ("\n#define TONE_MAPPING_FILMIC");
+        break;
+    }
   }
 
   return aPrefixString;
@@ -1412,6 +1421,12 @@ Standard_Boolean OpenGl_View::initRaytraceResources (const Handle(OpenGl_Context
       aToRebuildShaders = Standard_True;
     }
 
+    if (myRenderParams.ToneMappingMethod != myRaytraceParameters.ToneMappingMethod)
+    {
+      myRaytraceParameters.ToneMappingMethod = myRenderParams.ToneMappingMethod;
+      aToRebuildShaders = true;
+    }
+
     if (aToRebuildShaders)
     {
       // Reject accumulated frames
@@ -2931,6 +2946,19 @@ Standard_Boolean OpenGl_View::runPathtrace (const Standard_Integer
     myOutImageProgram->SetUniform (theGlContext, "uDebugAdaptive", myRenderParams.ShowSamplingTiles ?  1 : 0);
   }
 
+  if (myRaytraceParameters.GlobalIllumination)
+  {
+    myOutImageProgram->SetUniform(theGlContext, "uExposure", myRenderParams.Exposure);
+    switch (myRaytraceParameters.ToneMappingMethod)
+    {
+      case Graphic3d_ToneMappingMethod_Disabled:
+        break;
+      case Graphic3d_ToneMappingMethod_Filmic:
+        myOutImageProgram->SetUniform (theGlContext, "uWhitePoint", myRenderParams.WhitePoint);
+        break;
+    }
+  }
+
   if (theReadDrawFbo != NULL)
   {
     theReadDrawFbo->BindBuffer (theGlContext);
index 6aff9c1..ec949eb 100644 (file)
@@ -26,6 +26,16 @@ uniform int uAccumFrames;
 //! Is debug mode enabled for importance screen sampling.
 uniform int uDebugAdaptive;
 
+//! Exposure value for tone mapping.
+uniform float uExposure;
+
+#ifdef TONE_MAPPING_FILMIC
+
+//! White point value for filmic tone mapping.
+uniform float uWhitePoint;
+
+#endif // TONE_MAPPING
+
 //! Output pixel color.
 out vec4 OutColor;
 
@@ -35,6 +45,18 @@ out vec4 OutColor;
 //! Scale factor used to quantize visual error.
 #define SCALE_FACTOR 1.0e6f
 
+// =======================================================================
+// function : ToneMappingFilmic
+// purpose  :
+// =======================================================================
+vec4 ToneMappingFilmic(vec4 theColor, float theWhitePoint)
+{
+  vec4 aPackColor = vec4 (theColor.rgb, theWhitePoint);
+  vec4 aFilmicCurve = 1.425f * aPackColor + vec4 (0.05f);
+  vec4 aResultColor = (aPackColor * aFilmicCurve + vec4 (0.004f)) / (aPackColor * (aFilmicCurve + vec4 (0.55f)) + vec4 (0.0491f)) - vec4 (0.0821f);
+  return vec4 (aResultColor.rgb / aResultColor.www, 1.0);
+}
+
 // =======================================================================
 // function : main
 // purpose  :
@@ -112,12 +134,18 @@ void main (void)
 
 #ifdef PATH_TRACING
 
-   // apply gamma correction (we use gamma = 2)
-   OutColor = vec4 (sqrt (aColor.rgb), 0.f);
+  aColor *= pow (2, uExposure);
+
+#ifdef TONE_MAPPING_FILMIC
+  aColor = ToneMappingFilmic (aColor, uWhitePoint);
+#endif // TONE_MAPPING
+
+  // apply gamma correction (we use gamma = 2)
+  OutColor = vec4 (sqrt (aColor.rgb), 0.f);
 
 #else // not PATH_TRACING
 
-   OutColor = aColor;
+  OutColor = aColor;
 
 #endif
 }
index f8cea47..6ac6cc6 100644 (file)
@@ -9648,6 +9648,69 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
       }
       aParams.RebuildRayTracingShaders = toEnable;
     }
+    else if (aFlag == "-exposure")
+    {
+      if (++anArgIter >= theArgNb)
+      {
+        std::cout << "Error: wrong syntax at argument '" << anArg << "'\n";
+        return 1;
+      }
+
+      TCollection_AsciiString anExposure (theArgVec[anArgIter]);
+      if (anExposure.IsRealValue())
+      {
+        aView->ChangeRenderingParams().Exposure = static_cast<float> (anExposure.RealValue());
+      }
+      else
+      {
+        std::cout << "Error: wrong syntax at argument'" << anArg << "'.\n";
+        return 1;
+      }
+    }
+    else if (aFlag == "-whitepoint")
+    {
+      if (++anArgIter >= theArgNb)
+      {
+        std::cout << "Error: wrong syntax at argument '" << anArg << "'\n";
+        return 1;
+      }
+
+      TCollection_AsciiString aWhitePoint (theArgVec[anArgIter]);
+      if (aWhitePoint.IsRealValue())
+      {
+        aView->ChangeRenderingParams().WhitePoint = static_cast<float> (aWhitePoint.RealValue());
+      }
+      else
+      {
+        std::cout << "Error: wrong syntax at argument'" << anArg << "'.\n";
+        return 1;
+      }
+    }
+    else if (aFlag == "-tonemapping")
+    {
+      if (++anArgIter >= theArgNb)
+      {
+        std::cout << "Error: wrong syntax at argument '" << anArg << "'\n";
+        return 1;
+      }
+
+      TCollection_AsciiString aMode (theArgVec[anArgIter]);
+      aMode.LowerCase();
+
+      if (aMode == "disabled")
+      {
+        aView->ChangeRenderingParams().ToneMappingMethod = Graphic3d_ToneMappingMethod_Disabled;
+      }
+      else if (aMode == "filmic")
+      {
+        aView->ChangeRenderingParams().ToneMappingMethod = Graphic3d_ToneMappingMethod_Filmic;
+      }
+      else
+      {
+        std::cout << "Error: wrong syntax at argument'" << anArg << "'.\n";
+        return 1;
+      }
+    }
     else
     {
       std::cout << "Error: wrong syntax, unknown flag '" << anArg << "'\n";
@@ -11143,6 +11206,9 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     "\n      '-shadingModel model'       Controls shading model from enumeration"
     "\n                                  color, flat, gouraud, phong"
     "\n      '-resolution   value'       Sets a new pixels density (PPI), defines scaling factor for parameters like text size"
+    "\n      '-exposure     value'       Exposure value for tone mapping (0.0 value disables the effect)"
+    "\n      '-whitepoint   value'       White point value for filmic tone mapping"
+    "\n      '-tonemapping  mode'        Tone mapping mode (disabled, filmic)"
     "\n    Unlike vcaps, these parameters dramatically change visual properties."
     "\n    Command is intended to control presentation quality depending on"
     "\n    hardware capabilities and performance.",
diff --git a/tests/v3d/raytrace/tone_mapping b/tests/v3d/raytrace/tone_mapping
new file mode 100644 (file)
index 0000000..e950aae
--- /dev/null
@@ -0,0 +1,73 @@
+puts "========"
+puts "Ray Tracing - check tone mapping"
+puts "========"
+
+pload MODELING VISUALIZATION
+
+vclear
+vinit View1
+
+vlight add positional head 0 pos 0.5 0.5 0.85
+vlight change 0 sm 0.06
+vlight change 0 int 25.0
+
+vsetdispmode 1
+vcamera -persp
+
+box b 1 1 1 
+explode b FACE 
+vdisplay -noupdate b_1 b_2 b_3 b_5 b_6
+vlocation -noupdate b_1 -setLocation  1  0  0
+vlocation -noupdate b_2 -setLocation -1  0  0
+vlocation -noupdate b_3 -setLocation  0  1  0
+vlocation -noupdate b_5 -setLocation  0  0  1
+vlocation -noupdate b_6 -setLocation  0  0 -1
+
+vsetmaterial -noupdate b_1 plastic
+vsetmaterial -noupdate b_2 plastic
+vsetmaterial -noupdate b_3 plastic
+vsetmaterial -noupdate b_5 plastic
+vsetmaterial -noupdate b_6 plastic
+vbsdf b_1 -kd 1 0.3 0.3 -ks 0
+vbsdf b_2 -kd 0.3 0.5 1 -ks 0
+vbsdf b_3 -kd 1 -ks 0
+vbsdf b_5 -kd 1 -ks 0
+vbsdf b_6 -kd 1 -ks 0
+
+vfront
+vfit
+
+psphere s 0.2
+vdisplay     -noupdate s
+vlocation    -noupdate s -setLocation 0.21 0.3 0.2
+vsetmaterial -noupdate s glass
+vbsdf s -absorpColor 0.8 0.8 1.0
+vbsdf s -absorpCoeff 6
+
+box c 0.3 0.3 0.2
+vdisplay     -noupdate c
+vlocation    -noupdate c -setLocation 0.55 0.3 0.0
+vlocation    -noupdate c -rotate 0 0 0 0 0 1 -30
+vsetmaterial -noupdate c plastic
+vbsdf c -kd 1.0 0.8 0.2 -ks 0.3 -n
+
+box g 0.15 0.15 0.3
+vdisplay     -noupdate g
+vlocation    -noupdate g -setLocation 0.7 0.25 0.2
+vlocation    -noupdate g -rotate 0 0 0 0 0 1 10
+vsetmaterial -noupdate g glass
+vbsdf g -absorpColor 0.8 1.0 0.8
+vbsdf g -absorpCoeff 6
+
+psphere r 0.1
+vdisplay -noupdate r
+vsetmaterial -noupdate r plastic
+vbsdf r -kd 0.5 0.9 0.3 -ks 0.3 -baseRoughness 0.0 -n
+vbsdf r -baseFresnel Constant 1.0
+vlocation r -setLocation 0.5 0.65 0.1
+
+vrenderparams -ray -gi -rayDepth 10 -iss
+
+vrenderparams -tonemapping filmic
+vrenderparams -exposure -1.0
+vrenderparams -whitepoint 7.0