0030700: Visualization, TKOpenGl - support PBR Metallic-Roughness shading model
authoriko <iko@opencascade.com>
Thu, 20 Jun 2019 06:53:20 +0000 (09:53 +0300)
committerapn <apn@opencascade.com>
Fri, 1 Nov 2019 15:25:28 +0000 (18:25 +0300)
Metallic-Roughness shading model Graphic3d_TOSM_PBR has been implemented.
New materials descriptors Graphic3d_PBRMaterial have been added to Graphic3d_MaterialAspect.
PBR shading model requires OpenGL 3.0+ or OpenGL ES 3.0+ hardware.
Environment cubemap is expected to be provided for realistic look of metallic materials.

occLight_IsHeadlight() now returns bool instead of int.
Avoid using lowp for enumerations to workaround occLight_IsHeadlight()
ignorance on Adreno 308 caused by some GLSL optimizator bugs.

OpenGl_Texture::EstimatedDataSize() - fixed estimation for Cubemap textures.
OpenGl_Sampler::applySamplerParams() - fixed uninitialized GL_TEXTURE_WRAP_R in case of GL_TEXTURE_CUBE_MAP target.

75 files changed:
src/Graphic3d/FILES
src/Graphic3d/Graphic3d_BSDF.cxx
src/Graphic3d/Graphic3d_BSDF.hxx
src/Graphic3d/Graphic3d_CView.hxx
src/Graphic3d/Graphic3d_CubeMap.hxx
src/Graphic3d/Graphic3d_MaterialAspect.cxx
src/Graphic3d/Graphic3d_MaterialAspect.hxx
src/Graphic3d/Graphic3d_PBRMaterial.cxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_PBRMaterial.hxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_RenderingParams.hxx
src/Graphic3d/Graphic3d_ShaderProgram.cxx
src/Graphic3d/Graphic3d_ShaderProgram.hxx
src/Graphic3d/Graphic3d_TextureParams.cxx
src/Graphic3d/Graphic3d_TextureParams.hxx
src/Graphic3d/Graphic3d_TypeOfLimit.hxx
src/Graphic3d/Graphic3d_TypeOfShadingModel.hxx
src/Image/Image_Color.hxx
src/Image/Image_Format.hxx
src/Image/Image_PixMap.cxx
src/Media/Media_Frame.cxx
src/OpenGl/FILES
src/OpenGl/OpenGl_Context.cxx
src/OpenGl/OpenGl_Context.hxx
src/OpenGl/OpenGl_FrameBuffer.cxx
src/OpenGl/OpenGl_GlFunctions.hxx
src/OpenGl/OpenGl_GraphicDriver.cxx
src/OpenGl/OpenGl_LayerList.cxx
src/OpenGl/OpenGl_Material.hxx
src/OpenGl/OpenGl_PBREnvironment.cxx [new file with mode: 0644]
src/OpenGl/OpenGl_PBREnvironment.hxx [new file with mode: 0644]
src/OpenGl/OpenGl_Sampler.cxx
src/OpenGl/OpenGl_ShaderManager.cxx
src/OpenGl/OpenGl_ShaderManager.hxx
src/OpenGl/OpenGl_ShaderProgram.cxx
src/OpenGl/OpenGl_ShaderProgram.hxx
src/OpenGl/OpenGl_ShaderStates.hxx
src/OpenGl/OpenGl_Texture.cxx
src/OpenGl/OpenGl_Texture.hxx
src/OpenGl/OpenGl_TextureFormat.cxx
src/OpenGl/OpenGl_View.cxx
src/OpenGl/OpenGl_View.hxx
src/OpenGl/OpenGl_View_Redraw.cxx
src/OpenGl/OpenGl_Workspace.cxx
src/Shaders/Declarations.glsl
src/Shaders/DeclarationsImpl.glsl
src/Shaders/FILES
src/Shaders/PBRCookTorrance.glsl [new file with mode: 0644]
src/Shaders/PBRDistribution.glsl [new file with mode: 0644]
src/Shaders/PBREnvBaking.fs [new file with mode: 0644]
src/Shaders/PBREnvBaking.vs [new file with mode: 0644]
src/Shaders/PBRFresnel.glsl [new file with mode: 0644]
src/Shaders/PBRGeometry.glsl [new file with mode: 0644]
src/Shaders/PBRIllumination.glsl [new file with mode: 0644]
src/Shaders/PhongShading.fs
src/Shaders/Shaders_DeclarationsImpl_glsl.pxx
src/Shaders/Shaders_Declarations_glsl.pxx
src/Shaders/Shaders_PBRCookTorrance_glsl.pxx [new file with mode: 0644]
src/Shaders/Shaders_PBRDistribution_glsl.pxx [new file with mode: 0644]
src/Shaders/Shaders_PBREnvBaking_fs.pxx [new file with mode: 0644]
src/Shaders/Shaders_PBREnvBaking_vs.pxx [new file with mode: 0644]
src/Shaders/Shaders_PBRFresnel_glsl.pxx [new file with mode: 0644]
src/Shaders/Shaders_PBRGeometry_glsl.pxx [new file with mode: 0644]
src/Shaders/Shaders_PBRIllumination_glsl.pxx [new file with mode: 0644]
src/Textures/FILES
src/Textures/Textures_EnvLUT.pxx [new file with mode: 0644]
src/V3d/V3d_View.cxx
src/V3d/V3d_View.hxx
src/ViewerTest/ViewerTest.cxx
src/ViewerTest/ViewerTest_OpenGlCommands.cxx
src/ViewerTest/ViewerTest_ViewerCommands.cxx
src/XCAFDoc/XCAFDoc_VisMaterial.cxx
tests/de_mesh/gltf_read/end
tests/de_mesh/obj_read/end
tests/v3d/glsl/pbr_spheres [new file with mode: 0644]
tests/v3d/materials/pbr1 [new file with mode: 0644]

index 4e1e2b8..7fe5539 100755 (executable)
@@ -110,6 +110,8 @@ Graphic3d_NameOfTexture2D.hxx
 Graphic3d_NameOfTextureEnv.hxx
 Graphic3d_NameOfTexturePlane.hxx
 Graphic3d_NMapOfTransient.hxx
+Graphic3d_PBRMaterial.cxx
+Graphic3d_PBRMaterial.hxx
 Graphic3d_PolygonOffset.cxx
 Graphic3d_PolygonOffset.hxx
 Graphic3d_PriorityDefinitionError.hxx
index 4421e9c..f3e6710 100644 (file)
@@ -15,6 +15,8 @@
 
 #include <Graphic3d_BSDF.hxx>
 
+#include <Graphic3d_PBRMaterial.hxx>
+
 #include <algorithm>
 
 // =======================================================================
@@ -63,6 +65,7 @@ Graphic3d_Fresnel Graphic3d_Fresnel::CreateConductor (const Graphic3d_Vec3& theR
 // purpose  :
 // =======================================================================
 Graphic3d_BSDF::Graphic3d_BSDF()
+: Ks (Graphic3d_Vec3 (0.f), 1.f)
 {
   FresnelCoat = Graphic3d_Fresnel::CreateConstant (0.f);
   FresnelBase = Graphic3d_Fresnel::CreateConstant (1.f);
@@ -189,4 +192,21 @@ Graphic3d_BSDF Graphic3d_BSDF::CreateGlass (const Graphic3d_Vec3& theWeight,
                                      theAbsorptionCoeff);
 
   return aBSDF;
-}
\ No newline at end of file
+}
+
+// =======================================================================
+// function : CreateMetallicRoughness
+// purpose  :
+// =======================================================================
+Graphic3d_BSDF Graphic3d_BSDF::CreateMetallicRoughness (const Graphic3d_PBRMaterial& thePbr)
+{
+  const Graphic3d_Vec3 aDiff = (Graphic3d_Vec3 )thePbr.Color().GetRGB() * thePbr.Alpha();
+  const Standard_ShortReal aRougness2 = thePbr.NormalizedRoughness() * thePbr.NormalizedRoughness();
+
+  Graphic3d_BSDF aBsdf;
+  aBsdf.FresnelBase = Graphic3d_Fresnel::CreateSchlick (aDiff * thePbr.Metallic());
+  aBsdf.Ks.SetValues (Graphic3d_Vec3 (thePbr.Alpha()), aRougness2);
+  aBsdf.Kt = Graphic3d_Vec3 (1.0f - thePbr.Alpha());
+  aBsdf.Kd = aDiff * (1.0f - thePbr.Metallic());
+  return aBsdf;
+}
index 7919089..37c1f47 100644 (file)
@@ -19,6 +19,8 @@
 #include <Graphic3d_Vec3.hxx>
 #include <Graphic3d_Vec4.hxx>
 
+class Graphic3d_PBRMaterial;
+
 //! Type of the Fresnel model.
 enum Graphic3d_FresnelModel
 {
@@ -169,6 +171,9 @@ public:
                                                      const Standard_ShortReal theAbsorptionCoeff,
                                                      const Standard_ShortReal theRefractionIndex);
 
+  //! Creates BSDF from PBR metallic-roughness material.
+  static Standard_EXPORT Graphic3d_BSDF CreateMetallicRoughness (const Graphic3d_PBRMaterial& thePbr);
+
 public:
 
   //! Creates uninitialized BSDF.
index ac0df39..f3a2836 100644 (file)
@@ -378,7 +378,23 @@ public:
   virtual Handle(Graphic3d_CubeMap) BackgroundCubeMap() const = 0;
 
   //! Sets environment cubemap as background.
-  virtual void SetBackgroundCubeMap (const Handle(Graphic3d_CubeMap)& theCubeMap) = 0;
+  //! @param theCubeMap cubemap source to be set as background
+  //! @param theToUpdatePBREnv defines whether IBL maps will be generated or not (see 'GeneratePBREnvironment')
+  virtual void SetBackgroundCubeMap (const Handle(Graphic3d_CubeMap)& theCubeMap,
+                                     Standard_Boolean theToUpdatePBREnv = Standard_True) = 0;
+
+  //! Generates PBR specular probe and irradiance map
+  //! in order to provide environment indirect illumination in PBR shading model (Image Based Lighting).
+  //! The source of environment data is background cubemap.
+  //! If PBR is unavailable it does nothing.
+  //! If PBR is available but there is no cubemap being set to background it clears all IBL maps (see 'ClearPBREnvironment').
+  virtual void GeneratePBREnvironment() = 0;
+
+  //! Fills PBR specular probe and irradiance map with white color.
+  //! So that environment indirect illumination will be constant
+  //! and will be fully controlled by ambient light sources.
+  //! If PBR is unavailable it does nothing.
+  virtual void ClearPBREnvironment() = 0;
 
   //! Returns environment texture set for the view.
   virtual Handle(Graphic3d_TextureEnv) TextureEnv() const = 0; 
index c9e859a..494ce29 100644 (file)
@@ -26,21 +26,25 @@ class Graphic3d_CubeMap : public Graphic3d_TextureMap
 public:
 
   //! Constructor defining loading cubemap from file.
-  Graphic3d_CubeMap (const TCollection_AsciiString& theFileName) :
+  Graphic3d_CubeMap (const TCollection_AsciiString& theFileName,
+                     Standard_Boolean               theToGenerateMipmaps = Standard_False) :
     Graphic3d_TextureMap (theFileName, Graphic3d_TOT_CUBEMAP),
     myCurrentSide  (Graphic3d_CMS_POS_X),
     myEndIsReached (false),
     myIsTopDown    (true),
-    myZIsInverted  (false)
+    myZIsInverted  (false),
+    myHasMipmaps   (theToGenerateMipmaps)
   {}
 
   //! Constructor defining direct cubemap initialization from PixMap.
-  Graphic3d_CubeMap (const Handle(Image_PixMap)& thePixmap = Handle(Image_PixMap)()) :
+  Graphic3d_CubeMap (const Handle(Image_PixMap)& thePixmap = Handle(Image_PixMap)(),
+                     Standard_Boolean            theToGenerateMipmaps = Standard_False) :
     Graphic3d_TextureMap (thePixmap, Graphic3d_TOT_CUBEMAP),
     myCurrentSide  (Graphic3d_CMS_POS_X),
     myEndIsReached (false),
     myIsTopDown    (true),
-    myZIsInverted  (false)
+    myZIsInverted  (false),
+    myHasMipmaps   (theToGenerateMipmaps)
   {}
 
   //! Returns whether the iterator has reached the end (true if it hasn't). 
@@ -81,6 +85,12 @@ public:
     return myZIsInverted;
   }
 
+  //! Returns whether mipmaps of cubemap will be generated or not.
+  Standard_Boolean HasMipmaps() const { return myHasMipmaps; }
+
+  //! Sets whether to generate mipmaps of cubemap or not.
+  void SetMipmapsGeneration (Standard_Boolean theToGenerateMipmaps) { myHasMipmaps = theToGenerateMipmaps; }
+
   //! Returns PixMap containing current side of cubemap.
   //! Returns null handle if current side is invalid.
   virtual Handle(Image_PixMap) Value() = 0;
@@ -102,6 +112,7 @@ protected:
   Standard_Boolean      myEndIsReached; //!< Indicates whether end of iteration has been reached or hasn't
   Standard_Boolean      myIsTopDown;    //!< Stores rows's memory layout
   Standard_Boolean      myZIsInverted;  //!< Indicates whether Z axis is inverted that allows to synchronize vertical flip of cubemap
+  Standard_Boolean      myHasMipmaps;   //!< Indicates whether mipmaps of cubemap will be generated or not
 
 };
 
index f90c9e6..99cbf9b 100644 (file)
@@ -25,6 +25,7 @@ namespace
   {
     const char*              StringName;
     Graphic3d_BSDF           BSDF;
+    Graphic3d_PBRMaterial    PBRMaterial;
     Quantity_Color           Colors[Graphic3d_TypeOfReflection_NB];
     Standard_ShortReal       TransparencyCoef;
     Standard_ShortReal       RefractionIndex;
@@ -99,6 +100,7 @@ RawMaterial::RawMaterial (Graphic3d_NameOfMaterial theName, const char* theStrin
       BSDF.Kd = Graphic3d_Vec3 (0.2f);
       BSDF.Ks = Graphic3d_Vec4 (0.00784314f, 0.00784314f, 0.00784314f, 0.25f);
       BSDF.Normalize();
+
       break;
     case Graphic3d_NOM_SHINY_PLASTIC:
       MaterialType = Graphic3d_MATERIAL_ASPECT;
@@ -124,6 +126,7 @@ RawMaterial::RawMaterial (Graphic3d_NameOfMaterial theName, const char* theStrin
 
       BSDF.Kd = Graphic3d_Vec3 (0.2f);
       BSDF.Ks = Graphic3d_Vec4 (0.6f);
+
       break;
     case Graphic3d_NOM_NEON_GNC:
       MaterialType = Graphic3d_MATERIAL_ASPECT;
@@ -221,6 +224,7 @@ RawMaterial::RawMaterial (Graphic3d_NameOfMaterial theName, const char* theStrin
       Colors[Graphic3d_TOR_EMISSION] = Quantity_Color (Graphic3d_Vec3 (0.0f));
 
       BSDF.Kd = Graphic3d_Vec3 (0.482353f, 0.482353f, 0.482353f);
+
       break;
     case Graphic3d_NOM_SILVER:
       MaterialType = Graphic3d_MATERIAL_PHYSIC;
@@ -261,6 +265,7 @@ RawMaterial::RawMaterial (Graphic3d_NameOfMaterial theName, const char* theStrin
 
       BSDF.Kd = Graphic3d_Vec3 (0.243137f, 0.243137f, 0.243137f);
       BSDF.Ks = Graphic3d_Vec4 (0.00392157f, 0.00392157f, 0.00392157f, 0.5f);
+
       break;
     case Graphic3d_NOM_CHROME:
       MaterialType = Graphic3d_MATERIAL_PHYSIC;
@@ -418,6 +423,7 @@ RawMaterial::RawMaterial (Graphic3d_NameOfMaterial theName, const char* theStrin
       Colors[Graphic3d_TOR_EMISSION] = Quantity_Color (Graphic3d_Vec3 (0.0f));
       break;
   }
+  PBRMaterial.SetBSDF (BSDF);
 }
 
 // =======================================================================
@@ -447,8 +453,9 @@ Graphic3d_MaterialAspect::Graphic3d_MaterialAspect (const Graphic3d_NameOfMateri
 void Graphic3d_MaterialAspect::init (const Graphic3d_NameOfMaterial theName)
 {
   const RawMaterial& aMat = THE_MATERIALS[theName];
-  myBSDF       = aMat.BSDF;
-  myStringName = aMat.StringName;
+  myBSDF        = aMat.BSDF;
+  myPBRMaterial = aMat.PBRMaterial;
+  myStringName  = aMat.StringName;
   myColors[Graphic3d_TOR_AMBIENT]     = aMat.Colors[Graphic3d_TOR_AMBIENT];
   myColors[Graphic3d_TOR_DIFFUSE]     = aMat.Colors[Graphic3d_TOR_DIFFUSE];
   myColors[Graphic3d_TOR_SPECULAR]    = aMat.Colors[Graphic3d_TOR_SPECULAR];
@@ -499,6 +506,8 @@ void Graphic3d_MaterialAspect::SetColor (const Quantity_Color& theColor)
     return;
   }
 
+  myPBRMaterial.SetColor (theColor);
+
   const RawMaterial& aSrcMat = THE_MATERIALS[myRequestedMaterialName];
   const Quantity_Color anAmbient((Graphic3d_Vec3 )theColor * aSrcMat.AmbientCoef);
   const Quantity_Color aDiffuse ((Graphic3d_Vec3 )theColor * aSrcMat.DiffuseCoef);
@@ -585,6 +594,7 @@ void Graphic3d_MaterialAspect::SetTransparency (const Standard_ShortReal theValu
   }
 
   myTransparencyCoef = theValue;
+  myPBRMaterial.SetAlpha (1.0f - theValue);
 }
 
 // =======================================================================
index 99d25ea..997b36e 100644 (file)
@@ -17,6 +17,7 @@
 #define _Graphic3d_MaterialAspect_HeaderFile
 
 #include <Graphic3d_BSDF.hxx>
+#include <Graphic3d_PBRMaterial.hxx>
 #include <Graphic3d_NameOfMaterial.hxx>
 #include <Graphic3d_TypeOfMaterial.hxx>
 #include <Graphic3d_TypeOfReflection.hxx>
@@ -170,6 +171,12 @@ public:
   //! Modifies the BSDF (bidirectional scattering distribution function).
   void SetBSDF (const Graphic3d_BSDF& theBSDF) { myBSDF = theBSDF; }
 
+  //! Returns physically based representation of material
+  const Graphic3d_PBRMaterial& PBRMaterial () const { return myPBRMaterial; }
+
+  //! Modifies the physically based representation of material
+  void SetPBRMaterial (const Graphic3d_PBRMaterial& thePBRMaterial) { myPBRMaterial = thePBRMaterial; }
+
   //! Returns TRUE if the reflection mode is active, FALSE otherwise.
   Standard_Boolean ReflectionMode (const Graphic3d_TypeOfReflection theType) const
   {
@@ -197,6 +204,7 @@ public:
     return myTransparencyCoef == theOther.myTransparencyCoef
         && myRefractionIndex  == theOther.myRefractionIndex
         && myBSDF             == theOther.myBSDF
+        && myPBRMaterial      == theOther.myPBRMaterial
         && myShininess        == theOther.myShininess
         && myColors[Graphic3d_TOR_AMBIENT]  == theOther.myColors[Graphic3d_TOR_AMBIENT]
         && myColors[Graphic3d_TOR_DIFFUSE]  == theOther.myColors[Graphic3d_TOR_DIFFUSE]
@@ -247,6 +255,7 @@ private:
 private:
 
   Graphic3d_BSDF           myBSDF;
+  Graphic3d_PBRMaterial    myPBRMaterial;
   TCollection_AsciiString  myStringName;
   Quantity_Color           myColors[Graphic3d_TypeOfReflection_NB];
   Standard_ShortReal       myTransparencyCoef;
diff --git a/src/Graphic3d/Graphic3d_PBRMaterial.cxx b/src/Graphic3d/Graphic3d_PBRMaterial.cxx
new file mode 100644 (file)
index 0000000..b1c20c5
--- /dev/null
@@ -0,0 +1,351 @@
+// Author: Ilya Khramov
+// Copyright (c) 2019 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.
+
+#include <Graphic3d_PBRMaterial.hxx>
+
+#include <Graphic3d_MaterialDefinitionError.hxx>
+
+#include <limits>
+
+// =======================================================================
+// function : RoughnessFromSpecular
+// purpose  :
+// =======================================================================
+Standard_ShortReal Graphic3d_PBRMaterial::RoughnessFromSpecular (const Quantity_Color& theSpecular,
+                                                                 const Standard_Real theShiness)
+{
+  Standard_Real aRoughnessFactor = 1.0 - theShiness;
+  //Standard_Real aSpecIntens = theSpecular.Light() * theSpecular;
+  const Standard_Real aSpecIntens = theSpecular.Red()   * 0.2125
+                                  + theSpecular.Green() * 0.7154
+                                  + theSpecular.Blue()  * 0.0721;
+  if (aSpecIntens < 0.1)
+  {
+    // low specular intensity should produce a rough material even if shininess is high
+    aRoughnessFactor *= (1.0 - aSpecIntens);
+  }
+  return (Standard_ShortReal )aRoughnessFactor;
+}
+
+// =======================================================================
+// function : Constructor
+// purpose  :
+// =======================================================================
+Graphic3d_PBRMaterial::Graphic3d_PBRMaterial ()
+: myColor     (0.f, 0.f, 0.f, 1.f),
+  myMetallic  (0.f),
+  myRoughness (1.f),
+  myEmission  (0.f),
+  myIOR       (1.5f)
+{}
+
+// =======================================================================
+// function : Constructor
+// purpose  :
+// =======================================================================
+Graphic3d_PBRMaterial::Graphic3d_PBRMaterial (const Graphic3d_BSDF& theBSDF)
+{
+  SetBSDF (theBSDF);
+}
+
+// =======================================================================
+// function : SetMetallic
+// purpose  :
+// =======================================================================
+void Graphic3d_PBRMaterial::SetMetallic (Standard_ShortReal theMetallic)
+{
+  Graphic3d_MaterialDefinitionError_Raise_if (theMetallic < 0.f || theMetallic > 1.f,
+    "'metallic' parameter of PBR material must be in range [0, 1]")
+  myMetallic = theMetallic;
+}
+
+// =======================================================================
+// function : Roughness
+// purpose  :
+// =======================================================================
+Standard_ShortReal Graphic3d_PBRMaterial::Roughness (Standard_ShortReal theNormalizedRoughness)
+{
+  return theNormalizedRoughness * (1.f - MinRoughness()) + MinRoughness();
+}
+
+// =======================================================================
+// function : SetRoughness
+// purpose  :
+// =======================================================================
+void Graphic3d_PBRMaterial::SetRoughness (Standard_ShortReal theRoughness)
+{
+  Graphic3d_MaterialDefinitionError_Raise_if (theRoughness < 0.f || theRoughness > 1.f,
+    "'roughness' parameter of PBR material must be in range [0, 1]")
+  myRoughness = theRoughness;
+}
+
+// =======================================================================
+// function : SetIOR
+// purpose  :
+// =======================================================================
+void Graphic3d_PBRMaterial::SetIOR (Standard_ShortReal theIOR)
+{
+  Graphic3d_MaterialDefinitionError_Raise_if (theIOR < 1.f || theIOR > 3.f,
+    "'IOR' parameter of PBR material must be in range [1, 3]")
+  myIOR = theIOR;
+}
+
+// =======================================================================
+// function : SetColor
+// purpose  :
+// =======================================================================
+void Graphic3d_PBRMaterial::SetColor (const Quantity_ColorRGBA& theColor)
+{
+  myColor.SetRGB (theColor.GetRGB());
+  SetAlpha (theColor.Alpha());
+}
+
+// =======================================================================
+// function : SetColor
+// purpose  :
+// =======================================================================
+void Graphic3d_PBRMaterial::SetColor (const Quantity_Color& theColor)
+{
+  myColor.SetRGB (theColor);
+}
+
+// =======================================================================
+// function : SetAlpha
+// purpose  :
+// =======================================================================
+void Graphic3d_PBRMaterial::SetAlpha (Standard_ShortReal theAlpha)
+{
+  Graphic3d_MaterialDefinitionError_Raise_if (theAlpha < 0.f || theAlpha > 1.f,
+    "'alpha' parameter of PBR material must be in range [0, 1]")
+  myColor.SetAlpha (theAlpha);
+}
+
+// =======================================================================
+// function : SetEmission
+// purpose  :
+// =======================================================================
+void Graphic3d_PBRMaterial::SetEmission (const Graphic3d_Vec3& theEmission)
+{
+  Graphic3d_MaterialDefinitionError_Raise_if (theEmission.r() < 0.f
+                                           || theEmission.g() < 0.f
+                                           || theEmission.b() < 0.f,
+    "all components of 'emission' parameter of PBR material must be greater than 0")
+  myEmission = theEmission;
+}
+
+// =======================================================================
+// function : SetBSDF
+// purpose  :
+// =======================================================================
+void Graphic3d_PBRMaterial::SetBSDF (const Graphic3d_BSDF& theBSDF)
+{
+  SetEmission (theBSDF.Le);
+
+  if (theBSDF.Absorption != Graphic3d_Vec4(0.f))
+  {
+    SetMetallic (0.f);
+    SetColor (Quantity_Color (theBSDF.Absorption.rgb()));
+    if (theBSDF.FresnelCoat.FresnelType() == Graphic3d_FM_DIELECTRIC)
+    {
+      SetIOR (theBSDF.FresnelCoat.Serialize().y());
+      SetRoughness (0.f);
+      SetAlpha (theBSDF.Absorption.a() * 4.f);
+    }
+    return;
+  }
+
+  if (theBSDF.FresnelBase.FresnelType() == Graphic3d_FM_CONSTANT
+   && theBSDF.Kt != Graphic3d_Vec3(0.f))
+  {
+    SetIOR (1.f);
+    SetRoughness (1.f);
+    SetMetallic (0.f);
+    SetColor (Quantity_Color (theBSDF.Kt));
+    SetAlpha (1.f - (theBSDF.Kt.r() + theBSDF.Kt.g() + theBSDF.Kt.b()) / 3.f);
+    return;
+  }
+
+  SetRoughness(sqrtf (theBSDF.Ks.w()));
+  if (theBSDF.FresnelBase.FresnelType() == Graphic3d_FM_DIELECTRIC
+   || theBSDF.FresnelBase.FresnelType() == Graphic3d_FM_CONSTANT)
+  {
+    SetIOR (1.5f);
+    SetColor (Quantity_Color (theBSDF.Kd));
+    SetMetallic (0.f);
+  }
+  else if (theBSDF.FresnelBase.FresnelType() == Graphic3d_FM_SCHLICK)
+  {
+    SetColor (Quantity_Color (theBSDF.FresnelBase.Serialize().rgb()));
+    SetMetallic (1.f);
+  }
+  else
+  {
+    SetColor (Quantity_Color (theBSDF.Ks.rgb()));
+    SetMetallic (1.f);
+  }
+}
+
+// =======================================================================
+// function : GenerateEnvLUT
+// purpose  :
+// =======================================================================
+void Graphic3d_PBRMaterial::GenerateEnvLUT (const Handle(Image_PixMap)& theLUT,
+                                            unsigned int theNbIntegralSamples)
+{
+  if (theLUT->Format() != Image_Format_RGF)
+  {
+    throw Standard_ProgramError("LUT pix map format for PBR LUT generation must be Image_Format_RGF");
+  }
+
+  for (unsigned int y = 0; y < theLUT->SizeY(); ++y)
+  {
+    Standard_ShortReal aRoughness = Roughness(y / Standard_ShortReal(theLUT->SizeY() - 1));
+
+    for (unsigned int x = 0; x < theLUT->SizeX(); ++x)
+    {
+      Standard_ShortReal aCosV = x / Standard_ShortReal(theLUT->SizeX() - 1);
+      Graphic3d_Vec3 aView = lutGenView (aCosV);
+      unsigned int aCount = 0;
+      Graphic3d_Vec2 aResult = Graphic3d_Vec2 (0.f);
+      for (unsigned int i = 0; i < theNbIntegralSamples; ++i)
+      {
+        Graphic3d_Vec2 aHammersleyPoint = lutGenHammersley (i, theNbIntegralSamples);
+        Graphic3d_Vec3 aHalf = lutGenImportanceSample (aHammersleyPoint, aRoughness);
+        Graphic3d_Vec3 aLight = lutGenReflect (aView, aHalf);
+        if (aLight.z() >= 0.f)
+        {
+          ++aCount;
+          Standard_ShortReal aCosVH = aView.Dot (aHalf);
+          Standard_ShortReal aGeometryFactor = lutGenGeometryFactor (aLight.z(),
+                                                                     aCosV,
+                                                                     aRoughness);
+          Standard_ShortReal anIntermediateResult = 1.f - aCosVH;
+          anIntermediateResult *= anIntermediateResult;
+          anIntermediateResult *= anIntermediateResult;
+          anIntermediateResult *= 1.f - aCosVH;
+
+          aResult.x() += aGeometryFactor * (aCosVH / aHalf.z()) * (1.f - anIntermediateResult);
+          aResult.y() += aGeometryFactor * (aCosVH / aHalf.z()) * anIntermediateResult;
+        }
+      }
+
+      aResult = aResult / Standard_ShortReal(theNbIntegralSamples);
+      theLUT->ChangeValue<Graphic3d_Vec2> (theLUT->SizeY() - 1 - y, x) = aResult;
+    }
+  }
+}
+
+// =======================================================================
+// function : SpecIBLMapSamplesFactor
+// purpose  :
+// =======================================================================
+Standard_ShortReal Graphic3d_PBRMaterial::SpecIBLMapSamplesFactor (Standard_ShortReal theProbability,
+                                                                   Standard_ShortReal theRoughness)
+{
+  return acosf (lutGenImportanceSampleCosTheta (theProbability, theRoughness)) * 2.f / Standard_ShortReal(M_PI);
+}
+
+// =======================================================================
+// function : lutGenGeometryFactor
+// purpose  :
+// =======================================================================
+Standard_ShortReal Graphic3d_PBRMaterial::lutGenGeometryFactor (Standard_ShortReal theCosL,
+                                                                Standard_ShortReal theCosV,
+                                                                Standard_ShortReal theRoughness)
+{
+  Standard_ShortReal aK = theRoughness * theRoughness * 0.5f;
+
+  Standard_ShortReal aGeometryFactor = theCosL;
+  aGeometryFactor /= theCosL * (1.f - aK) + aK;
+  aGeometryFactor /= theCosV * (1.f - aK) + aK;
+
+  return aGeometryFactor;
+}
+
+// =======================================================================
+// function : lutGenHammersley
+// purpose  :
+// =======================================================================
+Graphic3d_Vec2 Graphic3d_PBRMaterial::lutGenHammersley (unsigned int theNumber, unsigned int theCount)
+{
+  Standard_ShortReal aPhi2 = 0.f;
+  for (unsigned int i = 0; i < sizeof(unsigned int) * 8; ++i)
+  {
+    if ((theNumber >> i) == 0)
+    {
+      break;
+    }
+    aPhi2 += ((theNumber >> i) & 1) / Standard_ShortReal(1 << (i + 1));
+  }
+
+  return Graphic3d_Vec2(theNumber / Standard_ShortReal(theCount), aPhi2);
+}
+
+// =======================================================================
+// function : lutGenImportanceSampleCosTheta
+// purpose  :
+// =======================================================================
+Standard_ShortReal Graphic3d_PBRMaterial::lutGenImportanceSampleCosTheta (Standard_ShortReal theHammersleyPointComponent,
+                                                                          Standard_ShortReal theRoughness)
+{
+  Standard_ShortReal aQuadRoughness = theRoughness * theRoughness;
+  aQuadRoughness *= aQuadRoughness;
+
+  Standard_ShortReal aTmp = 1.f + (aQuadRoughness - 1.f) * theHammersleyPointComponent;
+
+  if (aTmp != 0.f)
+  {
+    return sqrtf ((1.f - theHammersleyPointComponent) / aTmp);
+  }
+  else
+  {
+    return 0.f;
+  }
+}
+
+// =======================================================================
+// function : lutGenImportanceSample
+// purpose  :
+// =======================================================================
+Graphic3d_Vec3 Graphic3d_PBRMaterial::lutGenImportanceSample (const Graphic3d_Vec2 &theHammerslayPoint,
+                                                              Standard_ShortReal   theRoughness)
+{
+  Standard_ShortReal aPhi = 2.f * Standard_ShortReal(M_PI) * theHammerslayPoint.y();
+
+  Standard_ShortReal aCosTheta = lutGenImportanceSampleCosTheta (theHammerslayPoint.x(), theRoughness);
+  Standard_ShortReal aSinTheta = sqrtf (1.f - aCosTheta * aCosTheta);
+
+  return Graphic3d_Vec3(aSinTheta * cosf (aPhi),
+                        aSinTheta * sinf (aPhi),
+                        aCosTheta);
+}
+
+// =======================================================================
+// function : lutGenView
+// purpose  :
+// =======================================================================
+Graphic3d_Vec3 Graphic3d_PBRMaterial::lutGenView (Standard_ShortReal theCosV)
+{
+  return Graphic3d_Vec3(0.f, sqrtf(1.f - theCosV * theCosV), theCosV);
+}
+
+// =======================================================================
+// function : lutGenReflect
+// purpose  :
+// =======================================================================
+Graphic3d_Vec3 Graphic3d_PBRMaterial::lutGenReflect (const Graphic3d_Vec3 &theVector,
+                                                     const Graphic3d_Vec3 &theAxis)
+{
+  return theAxis * theAxis.Dot(theVector) * 2.f - theVector;
+}
diff --git a/src/Graphic3d/Graphic3d_PBRMaterial.hxx b/src/Graphic3d/Graphic3d_PBRMaterial.hxx
new file mode 100644 (file)
index 0000000..25eff91
--- /dev/null
@@ -0,0 +1,198 @@
+// Author: Ilya Khramov
+// Copyright (c) 2019 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_PBRMaterial_HeaderFile
+#define _Graphic3d_PBRMaterial_HeaderFile
+
+#include <Image_PixMap.hxx>
+#include <Graphic3d_BSDF.hxx>
+#include <Graphic3d_Vec2.hxx>
+#include <Graphic3d_Vec3.hxx>
+#include <Graphic3d_Vec4.hxx>
+#include <Quantity_Color.hxx>
+
+//! Class implementing Metallic-Roughness physically based material definition
+class Graphic3d_PBRMaterial
+{
+public:
+
+  //! Creates new physically based material in Metallic-Roughness system.
+  //! 'metallic' parameter is 0 by default.
+  //! 'roughness' parameter is 1 by default.
+  //! 'color' parameter is (0, 0, 0) by default.
+  //! 'alpha' parameter is 1 by default.
+  //! 'IOR' parameter is 1.5 by default.
+  //! 'emission' parameter is (0, 0, 0) by default.
+  Standard_EXPORT Graphic3d_PBRMaterial();
+
+  //! Creates new physically based material in Metallic-Roughness system from Graphic3d_BSDF.
+  Standard_EXPORT Graphic3d_PBRMaterial (const Graphic3d_BSDF& theBSDF);
+
+  //! Returns material's metallic coefficient in [0, 1] range.
+  //! 1 for metals and 0 for dielectrics.
+  //! It is preferable to be exactly 0 or 1. Average values are needed for textures mixing in shader.
+  Standard_ShortReal Metallic() const { return myMetallic; }
+
+  //! Modifies metallic coefficient of material in [0, 1] range.
+  Standard_EXPORT void SetMetallic (Standard_ShortReal theMetallic);
+
+  //! Maps roughness from [0, 1] to [MinRoughness, 1] for calculations.
+  Standard_EXPORT static Standard_ShortReal Roughness(Standard_ShortReal theNormalizedRoughness);
+
+  //! Returns real value of roughness in [MinRoughness, 1] range for calculations.
+  Standard_ShortReal Roughness() const { return Roughness(myRoughness); }
+
+  //! Returns roughness mapping parameter in [0, 1] range.
+  //! Roughness is defined in [0, 1] for handful material settings
+  //! and is mapped to [MinRoughness, 1] for calculations.
+  Standard_ShortReal NormalizedRoughness() const { return myRoughness; }
+
+  //! Modifies roughness coefficient of material in [0, 1] range.
+  Standard_EXPORT void SetRoughness (Standard_ShortReal theRoughness);
+
+  //! Returns index of refraction in [1, 3] range.
+  Standard_ShortReal IOR() const { return myIOR; }
+
+  //! Modifies index of refraction in [1, 3] range.
+  //! In practice affects only on non-metal materials reflection possibilities.
+  Standard_EXPORT void SetIOR (Standard_ShortReal theIOR);
+
+  //! Returns albedo color with alpha component of material.
+  const Quantity_ColorRGBA& Color() const { return myColor; }
+
+  //! Modifies albedo color with alpha component.
+  Standard_EXPORT void SetColor (const Quantity_ColorRGBA& theColor);
+
+  //! Modifies only albedo color.
+  Standard_EXPORT void SetColor (const Quantity_Color& theColor);
+
+  //! Returns alpha component in range [0, 1].
+  Standard_ShortReal Alpha() const { return myColor.Alpha(); };
+
+  //! Modifies alpha component.
+  Standard_EXPORT void SetAlpha (Standard_ShortReal theAlpha);
+
+  //! Returns light intensity emitted by material.
+  //! Values are greater or equal 0.
+  Graphic3d_Vec3 Emission() const { return myEmission; }
+
+  //! Modifies light intensity emitted by material.
+  Standard_EXPORT void SetEmission (const Graphic3d_Vec3& theEmission);
+
+  //! Generates material in Metallic-Roughness system from Graphic3d_BSDF.
+  Standard_EXPORT void SetBSDF (const Graphic3d_BSDF& theBSDF);
+
+public:
+
+  //! PBR materials comparison operator.
+  Standard_Boolean operator== (const Graphic3d_PBRMaterial& theOther) const
+  {
+    return (myMetallic == theOther.myMetallic)
+        && (myRoughness == theOther.myRoughness)
+        && (myIOR == theOther.myIOR)
+        && (myColor == theOther.myColor)
+        && (myEmission == theOther.myEmission);
+  }
+
+public:
+
+  //! Generates 2D look up table of scale and bias for fresnell zero coefficient.
+  //! It is needed for calculation reflectance part of environment lighting.
+  //! @param [out] theLUT table storage (must be Image_Format_RGF).
+  //! @param [in] theIntegralSamplesCount number of importance samples in hemisphere integral calculation for every table item.
+  Standard_EXPORT static void GenerateEnvLUT (const Handle(Image_PixMap)& theLUT,
+                                              unsigned int                theNbIntegralSamples = 1024);
+
+  //! Compute material roughness from common material (specular color + shininess).
+  //! @param theSpecular [in] specular color
+  //! @param theShiness  [in] normalized shininess coefficient within [0..1] range
+  //! @return roughness within [0..1] range
+  Standard_EXPORT static Standard_ShortReal RoughnessFromSpecular (const Quantity_Color& theSpecular,
+                                                                   const Standard_Real theShiness);
+
+  //! Compute material metallicity from common material (specular color).
+  //! @param theSpecular [in] specular color
+  //! @return metallicity within [0..1] range
+  static Standard_ShortReal MetallicFromSpecular (const Quantity_Color& theSpecular)
+  {
+    return ((Graphic3d_Vec3 )theSpecular).maxComp();
+  }
+
+public:
+
+  //! Roughness cannot be 0 in real calculations, so it returns minimal achievable level of roughness in practice
+  static Standard_ShortReal MinRoughness() { return 0.01f; }
+
+public:
+
+  //! Shows how much times less samples can be used in certain roughness value specular IBL map generation
+  //! in compare with samples number for map with roughness of 1.
+  //! Specular IBL maps with less roughness values have higher resolution but require less samples for the same quality of baking.
+  //! So that reducing samples number is good strategy to improve performance of baking.
+  //! The samples number for specular IBL map with roughness of 1 (the maximum possible samples number) is expected to be defined as baking parameter.
+  //! Samples number for other roughness values can be calculated by multiplication origin samples number by this factor.
+  //! @param theProbability value from 0 to 1 controlling strength of samples reducing.
+  //! Bigger values result in slower reduction to provide better quality but worse performance.
+  //! Value of 1 doesn't affect at all so that 1 will be returned (it can be used to disable reduction strategy).
+  //! @param theRoughness roughness value of current generated specular IBL map (from 0 to 1).
+  //! @return factor to calculate number of samples for current specular IBL map baking.
+  //! Be aware! It has no obligation to return 1 in case of roughness of 1.
+  //! Be aware! It produces poor quality with small number of origin samples. In that case it is recommended to be disabled.
+  Standard_EXPORT static Standard_ShortReal SpecIBLMapSamplesFactor (Standard_ShortReal theProbability,
+                                                                     Standard_ShortReal theRoughness);
+
+private:
+
+  //! Calculates geometry factor of Cook-Torrance BRDF using Smith formula.
+  static Standard_ShortReal lutGenGeometryFactor (Standard_ShortReal theCosL,
+                                                  Standard_ShortReal theCosV,
+                                                  Standard_ShortReal theRoughness);
+
+  //! Generates quasi-random point from Hammersley set.
+  //! @param theNumber number of point
+  //! @param theCount size of Hammersley set
+  static Graphic3d_Vec2 lutGenHammersley (unsigned int theNumber, unsigned int theCount);
+
+  //! Generates only cosine theta of direction in spherical coordinates system
+  //! according to micro facet distribution function from Cook-Torrance BRDF.
+  static Standard_ShortReal lutGenImportanceSampleCosTheta (Standard_ShortReal theHammerslayPointComponent,
+                                                            Standard_ShortReal theRoughness);
+
+  //! Generates direction using point from Hammersley set
+  //! according to micro facet distribution function from Cook-Torrance BRDF.
+  static Graphic3d_Vec3 lutGenImportanceSample (const Graphic3d_Vec2 &theHammerslayPoint,
+                                                Standard_ShortReal    theRoughness);
+
+  //! Generates vector using cosine of angle between up vector (normal in hemisphere)
+  //! and desired vector.
+  //! x component for resulting vector will be zero.
+  static Graphic3d_Vec3 lutGenView (Standard_ShortReal theCosV);
+
+  //! Returns reflected vector according axis.
+  //! @param theVector vector is needed to be reflected.
+  //! @param theAxis axis of reflection.
+  static Graphic3d_Vec3 lutGenReflect (const Graphic3d_Vec3 &theVector,
+                                       const Graphic3d_Vec3 &theAxis);
+
+private:
+
+  Quantity_ColorRGBA myColor;     //!< albedo color with alpha component [0, 1]
+  Standard_ShortReal myMetallic;  //!< metallic coefficient of material [0, 1]
+  Standard_ShortReal myRoughness; //!< roughness coefficient of material [0, 1]
+  Graphic3d_Vec3     myEmission;  //!< light intensity emitted by material [>= 0]
+  Standard_ShortReal myIOR;       //!< index of refraction [1, 3]
+
+};
+
+#endif // _Graphic3d_PBRMaterial_HeaderFile
index 17bd259..a437d3a 100644 (file)
@@ -95,6 +95,13 @@ public:
   : Method                      (Graphic3d_RM_RASTERIZATION),
     TransparencyMethod          (Graphic3d_RTM_BLEND_UNORDERED),
     LineFeather                 (1.0f),
+    // PBR parameters
+    PbrEnvPow2Size              (9),
+    PbrEnvSpecMapNbLevels       (6),
+    PbrEnvBakingDiffNbSamples   (1024),
+    PbrEnvBakingSpecNbSamples   (256),
+    PbrEnvBakingProbability     (0.99f),
+    //
     OitDepthFactor              (0.0f),
     NbMsaaSamples               (0),
     RenderResolutionScale       (1.0f),
@@ -171,6 +178,15 @@ public:
   Graphic3d_RenderTransparentMethod TransparencyMethod;          //!< specifies rendering method for transparent graphics
   Standard_ShortReal                LineFeather;                 //!< line feater width in pixels (> 0.0), 1.0 by default;
                                                                  //!  high values produce blurred results, small values produce sharp (aliased) edges
+
+  Standard_Integer                  PbrEnvPow2Size;              //!< size of IBL maps side can be calculated as 2^PbrEnvPow2Size (> 0), 9 by default
+  Standard_Integer                  PbrEnvSpecMapNbLevels;       //!< number of levels used in specular IBL map (> 1), 6 by default
+  Standard_Integer                  PbrEnvBakingDiffNbSamples;   //!< number of samples used in Monte-Carlo integration during diffuse IBL map's
+                                                                 //!  spherical harmonics coefficients generation (> 0), 1024 by default
+  Standard_Integer                  PbrEnvBakingSpecNbSamples;   //!< number of samples used in Monte-Carlo integration during specular IBL map's generation (> 0), 256 by default
+  Standard_ShortReal                PbrEnvBakingProbability;     //!< controls strength of samples reducing strategy during specular IBL map's generation
+                                                                 //!  (see 'SpecIBLMapSamplesFactor' function for detail explanation) [0.0, 1.0], 0.99 by default
+
   Standard_ShortReal                OitDepthFactor;              //!< scalar factor [0-1] controlling influence of depth of a fragment to its final coverage
   Standard_Integer                  NbMsaaSamples;               //!< number of MSAA samples (should be within 0..GL_MAX_SAMPLES, power-of-two number), 0 by default
   Standard_ShortReal                RenderResolutionScale;       //!< rendering resolution scale factor, 1 by default;
index 5e5d4c7..e08774d 100755 (executable)
@@ -82,7 +82,8 @@ Graphic3d_ShaderProgram::Graphic3d_ShaderProgram()
   myNbFragOutputs (THE_NB_FRAG_OUTPUTS),
   myHasDefSampler (true),
   myHasAlphaTest (false),
-  myHasWeightOitOutput (false)
+  myHasWeightOitOutput (false),
+  myIsPBR (false)
 {
   myID = TCollection_AsciiString ("Graphic3d_ShaderProgram_")
        + TCollection_AsciiString (Standard_Atomic_Increment (&THE_PROGRAM_OBJECT_COUNTER));
index c44ba12..2aa7f19 100755 (executable)
@@ -151,6 +151,13 @@ public:
   //! Note that weighted OIT also requires at least 2 Fragment Outputs (color + coverage).
   void SetWeightOitOutput (Standard_Boolean theOutput) { myHasWeightOitOutput = theOutput; }
 
+  //! Return TRUE if standard program header should define functions and variables used in PBR pipeline.
+  //! FALSE by default
+  Standard_Boolean IsPBR() const { return myIsPBR; }
+
+  //! Sets whether standard program header should define functions and variables used in PBR pipeline.
+  void SetPBR (Standard_Boolean theIsPBR) { myIsPBR = theIsPBR; }
+
   //! Pushes custom uniform variable to the program.
   //! The list of pushed variables is automatically cleared after applying to GLSL program.
   //! Thus after program recreation even unchanged uniforms should be pushed anew.
@@ -204,6 +211,7 @@ private:
   Standard_Boolean              myHasDefSampler; //!< flag indicating that program defines default texture sampler occSampler0
   Standard_Boolean              myHasAlphaTest;       //!< flag indicating that Fragment Shader performs alpha test
   Standard_Boolean              myHasWeightOitOutput; //!< flag indicating that Fragment Shader includes weighted OIT coverage
+  Standard_Boolean              myIsPBR;         //!< flag indicating that program defines functions and variables used in PBR pipeline
 
 };
 
index 1eacf67..3c537cc 100644 (file)
@@ -29,6 +29,8 @@ Graphic3d_TextureParams::Graphic3d_TextureParams()
   myFilter     (Graphic3d_TOTF_NEAREST),
   myAnisoLevel (Graphic3d_LOTA_OFF),
   myGenMode    (Graphic3d_TOTM_MANUAL),
+  myBaseLevel  (0),
+  myMaxLevel   (1000),
   myRotAngle   (0.0f),
   myToModulate (Standard_False),
   myToRepeat   (Standard_False)
index 06fd0f1..e2c44b2 100644 (file)
@@ -106,6 +106,21 @@ public:
   //! Setup texture coordinates generation mode.
   Standard_EXPORT void SetGenMode (const Graphic3d_TypeOfTextureMode theMode, const Graphic3d_Vec4 thePlaneS, const Graphic3d_Vec4 thePlaneT);
 
+  //! @return base texture mipmap level; 0 by default.
+  Standard_Integer BaseLevel() const { return myBaseLevel; }
+
+  //! @return maximum texture mipmap array level; 1000 by default.
+  Standard_Integer MaxLevel() const { return myMaxLevel; }
+
+  //! Setups texture mipmap array levels range.
+  //! The lowest value will be the base level.
+  //! The remaining one will be the maximum level.
+  void SetLevelsRange (Standard_Integer theFirstLevel, Standard_Integer theSecondLevel = 0)
+  {
+    myMaxLevel  = theFirstLevel > theSecondLevel ? theFirstLevel : theSecondLevel;
+    myBaseLevel = theFirstLevel > theSecondLevel ? theSecondLevel : theFirstLevel;
+  }
+
   //! Return modification counter of parameters related to sampler state.
   unsigned int SamplerRevision() const { return mySamplerRevision; }
 
@@ -125,6 +140,8 @@ private:
   Graphic3d_TypeOfTextureFilter      myFilter;          //!< texture filter, Graphic3d_TOTF_NEAREST by default
   Graphic3d_LevelOfTextureAnisotropy myAnisoLevel;      //!< level of anisotropy filter, Graphic3d_LOTA_OFF by default
   Graphic3d_TypeOfTextureMode        myGenMode;         //!< texture coordinates generation mode, Graphic3d_TOTM_MANUAL by default
+  Standard_Integer                   myBaseLevel;       //!< base texture mipmap level (0 by default)
+  Standard_Integer                   myMaxLevel;        //!< maximum texture mipmap array level (1000 by default)
   Standard_ShortReal                 myRotAngle;        //!< texture coordinates rotation angle in degrees, 0 by default
   Standard_Boolean                   myToModulate;      //!< flag to modulate texture with material color, FALSE by default
   Standard_Boolean                   myToRepeat;        //!< flag to repeat (true) or wrap (false) texture coordinates out of [0,1] range
index 097c538..4cb85fc 100644 (file)
@@ -25,6 +25,7 @@ enum Graphic3d_TypeOfLimit
   Graphic3d_TypeOfLimit_MaxViewDumpSizeY,               //!< maximum height for image dump
   Graphic3d_TypeOfLimit_MaxCombinedTextureUnits,        //!< maximum number of combined texture units for multitexturing
   Graphic3d_TypeOfLimit_MaxMsaa,                        //!< maximum number of MSAA samples
+  Graphic3d_TypeOfLimit_HasPBR,                         //!< indicates whether PBR metallic-roughness shading model is supported
   Graphic3d_TypeOfLimit_HasRayTracing,                  //!< indicates whether ray tracing is supported
   Graphic3d_TypeOfLimit_HasRayTracingTextures,          //!< indicates whether ray tracing textures are supported
   Graphic3d_TypeOfLimit_HasRayTracingAdaptiveSampling,  //!< indicates whether adaptive screen sampling is supported
index 77e322c..01b5605 100644 (file)
@@ -46,6 +46,12 @@ enum Graphic3d_TypeOfShadingModel
   //! Shading model requires normals to be defined within vertex attributes.
   Graphic3d_TOSM_FRAGMENT,
 
+  //! Metallic-roughness physically based (PBR) illumination system.
+  Graphic3d_TOSM_PBR,
+
+  //! Same as Graphic3d_TOSM_PBR but using flat per-triangle normal.
+  Graphic3d_TOSM_PBR_FACET,
+
   // obsolete aliases
   Graphic3d_TOSM_NONE = Graphic3d_TOSM_UNLIT,
   V3d_COLOR   = Graphic3d_TOSM_NONE,
@@ -57,7 +63,7 @@ enum Graphic3d_TypeOfShadingModel
 enum
 {
   //! Auxiliary value defining the overall number of values in enumeration Graphic3d_TypeOfShadingModel
-  Graphic3d_TypeOfShadingModel_NB = Graphic3d_TOSM_FRAGMENT + 1
+  Graphic3d_TypeOfShadingModel_NB = Graphic3d_TOSM_PBR_FACET + 1
 };
 
 #endif // _Graphic3d_TypeOfShadingModel_HeaderFile
index acdfced..fa2184f 100644 (file)
@@ -266,6 +266,31 @@ public:
 
 };
 
+//! POD structure for packed float RG color value (2 floats)
+struct Image_ColorRGF
+{
+  //! Component type.
+  typedef Standard_ShortReal ComponentType_t;
+
+  //! Returns the number of components.
+  static Standard_Integer Length() { return 2; }
+
+  //! Alias to 1st component (red intensity).
+  Standard_ShortReal r() const { return v[0]; }
+
+  //! Alias to 2nd component (green intensity).
+  Standard_ShortReal g() const { return v[1]; }
+
+  //! Alias to 1st component (red intensity).
+  Standard_ShortReal& r() { return v[0]; }
+
+  //! Alias to 2nd component (green intensity).
+  Standard_ShortReal& g() { return v[1]; }
+
+public:
+  Standard_ShortReal v[2];
+};
+
 //! POD structure for packed float RGB color value (3 floats)
 struct Image_ColorRGBF
 {
index 6a72b05..5842625 100644 (file)
@@ -28,6 +28,7 @@ enum Image_Format
   Image_Format_BGRA,        //!< same as RGBA but with different components order
   Image_Format_GrayF,       //!< 1 float  (4-bytes) per pixel (1-component plane), intensity of the color
   Image_Format_AlphaF,      //!< 1 float  (4-bytes) per pixel (1-component plane), transparency
+  Image_Format_RGF,         //!< 2 floats (8-bytes) RG image plane
   Image_Format_RGBF,        //!< 3 floats (12-bytes) RGB image plane
   Image_Format_BGRF,        //!< same as RGBF but with different components order
   Image_Format_RGBAF,       //!< 4 floats (16-bytes) RGBA image plane
index ffbac02..57f76f1 100644 (file)
@@ -47,6 +47,8 @@ Standard_Size Image_PixMap::SizePixelBytes (const Image_Format thePixelFormat)
     case Image_Format_GrayF:
     case Image_Format_AlphaF:
       return sizeof(float);
+    case Image_Format_RGF:
+      return sizeof(float) * 2;
     case Image_Format_RGBAF:
     case Image_Format_BGRAF:
       return sizeof(float) * 4;
@@ -214,6 +216,11 @@ Quantity_ColorRGBA Image_PixMap::PixelColor (const Standard_Integer theX,
       const Standard_ShortReal& aPixel = Value<Standard_ShortReal> (theY, theX);
       return Quantity_ColorRGBA (NCollection_Vec4<float> (1.0f, 1.0f, 1.0f, aPixel));
     }
+    case Image_Format_RGF:
+    {
+      const Image_ColorRGF& aPixel = Value<Image_ColorRGF> (theY, theX);
+      return Quantity_ColorRGBA (NCollection_Vec4<float> (aPixel.r(), aPixel.g(), 0.0f, 1.0f));
+    }
     case Image_Format_RGBAF:
     {
       const Image_ColorRGBAF& aPixel = Value<Image_ColorRGBAF> (theY, theX);
@@ -339,6 +346,13 @@ void Image_PixMap::SetPixelColor (const Standard_Integer theX,
       ChangeValue<Standard_ShortReal> (theY, theX) = aColor.a();
       return;
     }
+    case Image_Format_RGF:
+    {
+      Image_ColorRGF& aPixel = ChangeValue<Image_ColorRGF> (theY, theX);
+      aPixel.r() = aColor.r();
+      aPixel.g() = aColor.g();
+      return;
+    }
     case Image_Format_RGBAF:
     {
       Image_ColorRGBAF& aPixel = ChangeValue<Image_ColorRGBAF> (theY, theX);
index 3641fb4..f0ad43e 100644 (file)
@@ -92,6 +92,7 @@ int Media_Frame::FormatOcct2FFmpeg (Image_Format theFormat)
       return AV_PIX_FMT_GRAY8;
     case Image_Format_GrayF:
     case Image_Format_AlphaF:
+    case Image_Format_RGF:
     case Image_Format_RGBAF:
     case Image_Format_RGBF:
     case Image_Format_BGRAF:
index 57b56c0..bc44d75 100755 (executable)
@@ -105,6 +105,8 @@ OpenGl_GraphicDriver.hxx
 OpenGl_IndexBuffer.cxx
 OpenGl_IndexBuffer.hxx
 OpenGl_Layer.hxx
+OpenGl_PBREnvironment.cxx
+OpenGl_PBREnvironment.hxx
 OpenGl_RenderFilter.hxx
 OpenGl_Sampler.cxx
 OpenGl_Sampler.hxx
index 40ec4b5..f71c55e 100644 (file)
@@ -144,6 +144,7 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
   hasUintIndex(Standard_True),
   hasTexRGBA8(Standard_True),
 #endif
+  hasTexFloatLinear (Standard_False),
   hasTexSRGB (Standard_False),
   hasFboSRGB (Standard_False),
   hasSRGBControl (Standard_False),
@@ -208,6 +209,10 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
   myHasRayTracingTextures (Standard_False),
   myHasRayTracingAdaptiveSampling (Standard_False),
   myHasRayTracingAdaptiveSamplingAtomic (Standard_False),
+  myHasPBR (Standard_False),
+  myPBREnvLUTTexUnit       (Graphic3d_TextureUnit_0),
+  myPBRDiffIBLMapSHTexUnit (Graphic3d_TextureUnit_0),
+  myPBRSpecIBLMapTexUnit   (Graphic3d_TextureUnit_0),
   myFrameStats (new OpenGl_FrameStats()),
 #if !defined(GL_ES_VERSION_2_0)
   myPointSpriteOrig (GL_UPPER_LEFT),
@@ -1485,6 +1490,8 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
 
   arbTexFloat = IsGlGreaterEqual (3, 0)
              && FindProcShort (glTexImage3D);
+  hasTexFloatLinear = arbTexFloat
+                   && CheckExtension ("GL_OES_texture_float_linear");
 
   const Standard_Boolean hasTexBuffer32  = IsGlGreaterEqual (3, 2) && FindProcShort (glTexBuffer);
   const Standard_Boolean hasExtTexBuffer = CheckExtension ("GL_EXT_texture_buffer") && FindProc ("glTexBufferEXT", myFuncs->glTexBuffer);
@@ -1581,6 +1588,7 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
   arbNPTW          = CheckExtension ("GL_ARB_texture_non_power_of_two");
   arbTexFloat      = IsGlGreaterEqual (3, 0)
                   || CheckExtension ("GL_ARB_texture_float");
+  hasTexFloatLinear = arbTexFloat;
   arbSampleShading = CheckExtension ("GL_ARB_sample_shading");
   extBgra          = CheckExtension ("GL_EXT_bgra");
   extAnis          = CheckExtension ("GL_EXT_texture_filter_anisotropic");
@@ -2933,6 +2941,23 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
                                          "Check OpenGL window creation parameters for optimal performance.", Message_Trace);
     }
   }
+
+  // check whether PBR shading model is supported
+  myHasPBR = arbFBO != NULL
+          && myMaxTexCombined >= 4
+          && arbTexRG
+          && arbTexFloat
+          && (IsGlGreaterEqual (3, 0)
+        #if !defined(GL_ES_VERSION_2_0)
+          || (IsGlGreaterEqual (2, 1) && CheckExtension ("GL_EXT_gpu_shader4"))
+        #endif
+             );
+  if (myHasPBR)
+  {
+    myPBREnvLUTTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined - 3);
+    myPBRDiffIBLMapSHTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined - 2);
+    myPBRSpecIBLMapTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined - 1);
+  }
 }
 
 // =======================================================================
@@ -3547,8 +3572,11 @@ void OpenGl_Context::SetShadingMaterial (const OpenGl_Aspects* theAspect,
   Standard_ShortReal anAlphaBack  = 1.0f;
   if (CheckIsTransparent (theAspect, theHighlight, anAlphaFront, anAlphaBack))
   {
-    myMatFront.Diffuse.a() = anAlphaFront;
-    myMatBack .Diffuse.a() = anAlphaBack;
+    myMatFront.Common.Diffuse.a() = anAlphaFront;
+    myMatBack .Common.Diffuse.a() = anAlphaBack;
+
+    myMatFront.Pbr.BaseColor.a() = anAlphaFront;
+    myMatBack .Pbr.BaseColor.a() = anAlphaBack;
   }
 
   // do not update material properties in case of zero reflection mode,
index 747c872..127ecfe 100644 (file)
@@ -587,6 +587,25 @@ public:
     return Quantity_ColorRGBA::Convert_LinearRGB_To_sRGB (theColor);
   }
 
+  //! Returns TRUE if PBR shading model is supported.
+  //! Basically, feature requires OpenGL 3.0+ / OpenGL ES 3.0+ hardware; more precisely:
+  //! - Graphics hardware with moderate capabilities for compiling long enough GLSL program.
+  //! - FBO (e.g. for baking environment).
+  //! - Multi-texturing with >= 4 units (LUT and IBL textures).
+  //! - GL_RG32F texture format (arbTexRG + arbTexFloat)
+  //! - Cubemap texture lookup textureCubeLod()/textureLod() with LOD index within Fragment Shader,
+  //!   which requires GLSL OpenGL 3.0+ / OpenGL ES 3.0+ or OpenGL 2.1 + GL_EXT_gpu_shader4 extension.
+  Standard_Boolean HasPBR() const { return myHasPBR; }
+
+  //! Returns texture unit where Environment Lookup Table is expected to be bound, or 0 if PBR is unavailable.
+  Graphic3d_TextureUnit PBREnvLUTTexUnit() const { return myPBREnvLUTTexUnit; }
+
+  //! Returns texture unit where Diffuse (irradiance) IBL map's spherical harmonics coefficients is expected to be bound, or 0 if PBR is unavailable.
+  Graphic3d_TextureUnit PBRDiffIBLMapSHTexUnit() const { return myPBRDiffIBLMapSHTexUnit; }
+
+  //! Returns texture unit where Specular IBL map is expected to be bound, or 0 if PBR is unavailable.
+  Graphic3d_TextureUnit PBRSpecIBLMapTexUnit() const { return myPBRSpecIBLMapTexUnit; }
+
   //! Returns true if VBO is supported and permitted.
   inline bool ToUseVbo() const
   {
@@ -956,6 +975,7 @@ public: //! @name extensions
   Standard_Boolean       hasHighp;           //!< highp in GLSL ES fragment shader is supported
   Standard_Boolean       hasUintIndex;       //!< GLuint for index buffer is supported (always available on desktop; on OpenGL ES - since 3.0 or as extension GL_OES_element_index_uint)
   Standard_Boolean       hasTexRGBA8;        //!< always available on desktop; on OpenGL ES - since 3.0 or as extension GL_OES_rgb8_rgba8
+  Standard_Boolean       hasTexFloatLinear;  //!< texture-filterable state for 32-bit floating texture formats (always on desktop, GL_OES_texture_float_linear within OpenGL ES)
   Standard_Boolean       hasTexSRGB;         //!< sRGB texture    formats (desktop OpenGL 2.0, OpenGL ES 3.0 or GL_EXT_texture_sRGB)
   Standard_Boolean       hasFboSRGB;         //!< sRGB FBO render targets (desktop OpenGL 2.1, OpenGL ES 3.0)
   Standard_Boolean       hasSRGBControl;     //!< sRGB write control (any desktop OpenGL, OpenGL ES + GL_EXT_sRGB_write_control extension)
@@ -969,7 +989,7 @@ public: //! @name extensions
   Standard_Boolean       arbDrawBuffers;     //!< GL_ARB_draw_buffers
   Standard_Boolean       arbNPTW;            //!< GL_ARB_texture_non_power_of_two
   Standard_Boolean       arbTexRG;           //!< GL_ARB_texture_rg
-  Standard_Boolean       arbTexFloat;        //!< GL_ARB_texture_float (on desktop OpenGL - since 3.0 or as extension GL_ARB_texture_float; on OpenGL ES - since 3.0)
+  Standard_Boolean       arbTexFloat;        //!< GL_ARB_texture_float (on desktop OpenGL - since 3.0 or as extension GL_ARB_texture_float; on OpenGL ES - since 3.0); @sa hasTexFloatLinear for linear filtering support
   OpenGl_ArbSamplerObject* arbSamplerObject; //!< GL_ARB_sampler_objects (on desktop OpenGL - since 3.3 or as extension GL_ARB_sampler_objects; on OpenGL ES - since 3.0)
   OpenGl_ArbTexBindless* arbTexBindless;     //!< GL_ARB_bindless_texture
   OpenGl_ArbTBO*         arbTBO;             //!< GL_ARB_texture_buffer_object
@@ -1056,6 +1076,12 @@ private: // context info
   Standard_Boolean myHasRayTracingAdaptiveSampling; //! indicates whether adaptive screen sampling in ray tracing mode is supported
   Standard_Boolean myHasRayTracingAdaptiveSamplingAtomic; //! indicates whether atomic adaptive screen sampling in ray tracing mode is supported
 
+  Standard_Boolean myHasPBR;                      //!< indicates whether PBR shading model is supported
+  Graphic3d_TextureUnit myPBREnvLUTTexUnit;       //!< texture unit where environment lookup table is expected to be binded (0 if PBR is not supported)
+  Graphic3d_TextureUnit myPBRDiffIBLMapSHTexUnit; //!< texture unit where diffuse (irradiance) IBL map's spherical harmonics coefficients is expected to  be binded
+                                                  //!  (0 if PBR is not supported)
+  Graphic3d_TextureUnit myPBRSpecIBLMapTexUnit;   //!< texture unit where specular IBL map is expected to  be binded (0 if PBR is not supported)
+
   Handle(OpenGl_ShaderManager) myShaderManager; //! support object for managing shader programs
 
 private: //! @name fields tracking current state
index e9344f9..3380c17 100644 (file)
@@ -786,6 +786,10 @@ Standard_Boolean OpenGl_FrameBuffer::BufferDump (const Handle(OpenGl_Context)& t
       aFormat = GL_DEPTH_COMPONENT;
       aType   = GL_FLOAT;
       break;
+    case Image_Format_RGF:
+      aFormat = GL_RG;
+      aType   = GL_FLOAT;
+      break;
     case Image_Format_RGB:
       aFormat = GL_RGB;
       aType   = GL_UNSIGNED_BYTE;
@@ -812,6 +816,7 @@ Standard_Boolean OpenGl_FrameBuffer::BufferDump (const Handle(OpenGl_Context)& t
     case Image_Format_GrayF:
     case Image_Format_BGRF:
     case Image_Format_BGRAF:
+    case Image_Format_RGF:
       return Standard_False;
     case Image_Format_BGRA:
     case Image_Format_BGR32:
index ec2f93d..dee15c7 100644 (file)
@@ -80,6 +80,9 @@
   // adds GL_FRAMEBUFFER_SRGB_EXT flag as on desktop OpenGL
   #define GL_FRAMEBUFFER_SRGB 0x8DB9
 
+  #define GL_TEXTURE_BASE_LEVEL 0x813C
+  #define GL_TEXTURE_MAX_LEVEL  0x813D
+
   // OpenGL ES 3.1+
   #define GL_TEXTURE_2D_MULTISAMPLE 0x9100
   #define GL_MAX_SAMPLES  0x8D57
index 1694e17..15218a6 100644 (file)
@@ -400,6 +400,8 @@ Standard_Integer OpenGl_GraphicDriver::InquireLimit (const Graphic3d_TypeOfLimit
       return !aCtx.IsNull() ? aCtx->MaxDumpSizeX() : 1024;
     case Graphic3d_TypeOfLimit_MaxViewDumpSizeY:
       return !aCtx.IsNull() ? aCtx->MaxDumpSizeY() : 1024;
+    case Graphic3d_TypeOfLimit_HasPBR:
+      return (!aCtx.IsNull() && aCtx->HasPBR()) ? 1 : 0;
     case Graphic3d_TypeOfLimit_HasRayTracing:
       return (!aCtx.IsNull() && aCtx->HasRayTracing()) ? 1 : 0;
     case Graphic3d_TypeOfLimit_HasRayTracingTextures:
index 0e46b23..b312644 100644 (file)
@@ -594,7 +594,7 @@ void OpenGl_LayerList::renderLayer (const Handle(OpenGl_Workspace)& theWorkspace
   if (hasOwnLights)
   {
     aLayerSettings.Lights()->UpdateRevision();
-    aManager->UpdateLightSourceStateTo (aLayerSettings.Lights());
+    aManager->UpdateLightSourceStateTo (aLayerSettings.Lights(), theWorkspace->View()->SpecIBLMapLevels());
   }
 
   const Handle(Graphic3d_Camera)& aWorldCamera = theWorkspace->View()->Camera();
@@ -665,7 +665,7 @@ void OpenGl_LayerList::renderLayer (const Handle(OpenGl_Workspace)& theWorkspace
 
   if (hasOwnLights)
   {
-    aManager->UpdateLightSourceStateTo (aLightsBack);
+    aManager->UpdateLightSourceStateTo (aLightsBack, theWorkspace->View()->SpecIBLMapLevels());
   }
   if (hasLocalCS)
   {
@@ -732,7 +732,7 @@ void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace,
       if (aPassIter == 0)
       {
         aCtx->SetColorMask (false);
-        aCtx->ShaderManager()->UpdateLightSourceStateTo (Handle(Graphic3d_LightSet)());
+        aCtx->ShaderManager()->UpdateLightSourceStateTo (Handle(Graphic3d_LightSet)(), theWorkspace->View()->SpecIBLMapLevels());
         aDefaultSettings.DepthFunc = aPrevSettings.DepthFunc;
         aDefaultSettings.DepthMask = GL_TRUE;
       }
@@ -743,13 +743,13 @@ void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace,
           continue;
         }
         aCtx->SetColorMask (true);
-        aCtx->ShaderManager()->UpdateLightSourceStateTo (aLightsBack);
+        aCtx->ShaderManager()->UpdateLightSourceStateTo (aLightsBack, theWorkspace->View()->SpecIBLMapLevels());
         aDefaultSettings = aPrevSettings;
       }
       else if (aPassIter == 2)
       {
         aCtx->SetColorMask (true);
-        aCtx->ShaderManager()->UpdateLightSourceStateTo (aLightsBack);
+        aCtx->ShaderManager()->UpdateLightSourceStateTo (aLightsBack, theWorkspace->View()->SpecIBLMapLevels());
         if (toPerformDepthPrepass)
         {
           aDefaultSettings.DepthFunc = GL_EQUAL;
index 79ef066..f2bbec4 100644 (file)
@@ -22,7 +22,7 @@
 class OpenGl_Context;
 
 //! OpenGL material definition
-struct OpenGl_Material
+struct OpenGl_MaterialCommon
 {
 
   OpenGl_Vec4 Ambient;  //!< ambient reflection coefficient
@@ -37,31 +37,58 @@ struct OpenGl_Material
   float  Transparency() const { return Params.y(); }
   float& ChangeTransparency() { return Params.y(); }
 
+  //! Empty constructor.
+  OpenGl_MaterialCommon() : Ambient (1.0f), Diffuse (1.0f), Specular (1.0f), Emission (1.0f), Params (1.0f, 0.0f, 0.0f, 0.0f) {}
+
+  //! Returns packed (serialized) representation of material properties
+  const OpenGl_Vec4* Packed() const { return reinterpret_cast<const OpenGl_Vec4*> (this); }
+  static Standard_Integer NbOfVec4() { return 5; }
+
+};
+
+//! OpenGL material definition
+struct OpenGl_MaterialPBR
+{
+
+  OpenGl_Vec4 BaseColor;   //!< base color of PBR material with alpha component
+  OpenGl_Vec4 EmissionIOR; //!< light intensity which is emitted by PBR material and index of refraction
+  OpenGl_Vec4 Params;      //!< extra packed parameters
+
+  float  Metallic()  const { return Params.b(); }
+  float& ChangeMetallic()  { return Params.b(); }
+
+  float  Roughness() const { return Params.g(); }
+  float& ChangeRoughness() { return Params.g(); }
+
+  //! Empty constructor.
+  OpenGl_MaterialPBR() : BaseColor (1.0f), EmissionIOR (1.0f), Params  (1.0f, 1.0f, 1.0f, 1.0f) {}
+
+  //! Returns packed (serialized) representation of material properties
+  const OpenGl_Vec4* Packed() const { return reinterpret_cast<const OpenGl_Vec4*> (this); }
+  static Standard_Integer NbOfVec4() { return 3; }
+
+};
+
+//! OpenGL material definition
+struct OpenGl_Material
+{
+  OpenGl_MaterialCommon Common;
+  OpenGl_MaterialPBR    Pbr;
+
   //! Set material color.
   void SetColor (const OpenGl_Vec4& theColor)
   {
     // apply the same formula as in Graphic3d_MaterialAspect::SetColor()
-    Ambient.SetValues (theColor.rgb() * 0.25f, Ambient.a());
-    Diffuse.SetValues (theColor.rgb(), Diffuse.a());
+    Common.Ambient.SetValues (theColor.rgb() * 0.25f, Common.Ambient.a());
+    Common.Diffuse.SetValues (theColor.rgb(), Common.Diffuse.a());
+    Pbr .BaseColor.SetValues (theColor.rgb(), Pbr.BaseColor.a());
   }
 
-  //! Empty constructor.
-  OpenGl_Material()
-  : Ambient (1.0f),
-    Diffuse (1.0f),
-    Specular(1.0f),
-    Emission(1.0f),
-    Params  (1.0f, 0.0f, 0.0f, 0.0f) {}
-
   //! Initialize material
   void Init (const OpenGl_Context& theCtx,
              const Graphic3d_MaterialAspect& theProp,
              const Quantity_Color& theInteriorColor);
 
-  //! Returns packed (serialized) representation of material properties
-  const OpenGl_Vec4* Packed() const { return reinterpret_cast<const OpenGl_Vec4*> (this); }
-  static Standard_Integer NbOfVec4() { return 5; }
-
   //! Check this material for equality with another material (without tolerance!).
   bool IsEqual (const OpenGl_Material& theOther) const
   {
diff --git a/src/OpenGl/OpenGl_PBREnvironment.cxx b/src/OpenGl/OpenGl_PBREnvironment.cxx
new file mode 100644 (file)
index 0000000..ca6e1d3
--- /dev/null
@@ -0,0 +1,487 @@
+// Author: Ilya Khramov
+// Copyright (c) 2019 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.
+
+#include <OpenGl_PBREnvironment.hxx>
+
+#include <Graphic3d_PBRMaterial.hxx>
+#include <OpenGl_ArbFBO.hxx>
+#include <OpenGl_FrameBuffer.hxx>
+#include <OpenGl_ShaderManager.hxx>
+#include <OSD_Timer.hxx>
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
+
+#include <algorithm>
+
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_PBREnvironment, OpenGl_NamedResource)
+
+//! Constructor of this class saves necessary OpenGL states components which can be changed by OpenGl_PBREnvironment.
+//! Destructor restores state back.
+class OpenGl_PBREnvironmentSentry
+{
+public:
+
+  OpenGl_PBREnvironmentSentry (const Handle(OpenGl_Context)& theCtx)
+  : myContext (theCtx)
+  {
+    backup();
+    prepare();
+  }
+
+  ~OpenGl_PBREnvironmentSentry()
+  {
+    restore();
+  }
+
+private:
+
+  void backup()
+  {
+    myContext->core11fwd->glGetIntegerv (GL_FRAMEBUFFER_BINDING, &myFBO);
+    myShaderProgram = myContext->ActiveProgram();
+    for (unsigned int i = 0; i < 4; ++i)
+    {
+      myViewport[i] = myContext->Viewport()[i];
+    }
+    myContext->core11fwd->glGetFloatv (GL_COLOR_CLEAR_VALUE, myClearColor);
+
+    GLboolean aStatus = GL_TRUE;
+    myContext->core11fwd->glGetBooleanv (GL_DEPTH_TEST, &aStatus);
+    myDepthTestWasEnabled = aStatus ? Standard_True : Standard_False;
+    myContext->core11fwd->glGetBooleanv (GL_DEPTH_WRITEMASK, &aStatus);
+    myDepthWrirtingWasEnablig = aStatus ? Standard_True : Standard_False;
+    myContext->core11fwd->glGetBooleanv (GL_SCISSOR_TEST, &aStatus);
+    myScissorTestWasEnabled = aStatus ? Standard_True : Standard_False;
+    myContext->core11fwd->glGetIntegerv (GL_SCISSOR_BOX, myScissorBox);
+  }
+
+  void prepare()
+  {
+    myContext->BindDefaultVao();
+    myContext->core11fwd->glDisable (GL_DEPTH_TEST);
+    myContext->core11fwd->glDepthMask (GL_FALSE);
+    myContext->core11fwd->glDisable (GL_BLEND);
+    myContext->core11fwd->glDisable (GL_SCISSOR_TEST);
+  }
+
+  void restore()
+  {
+    myContext->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, myFBO);
+    myContext->BindProgram (myShaderProgram);
+    myContext->ResizeViewport (myViewport);
+    myContext->core11fwd->glClearColor (myClearColor.r(), myClearColor.g(), myClearColor.b(), myClearColor.a());
+    if (myDepthTestWasEnabled)
+    {
+      myContext->core11fwd->glEnable (GL_DEPTH_TEST);
+    }
+    else
+    {
+      myContext->core11fwd->glDisable (GL_DEPTH_TEST);
+    }
+    myContext->core11fwd->glDepthMask (myDepthWrirtingWasEnablig ? GL_TRUE : GL_FALSE);
+    if (myScissorTestWasEnabled)
+    {
+      myContext->core11fwd->glEnable (GL_SCISSOR_TEST);
+    }
+    else
+    {
+      myContext->core11fwd->glDisable (GL_SCISSOR_TEST);
+    }
+    myContext->core11fwd->glScissor (myScissorBox[0], myScissorBox[1], myScissorBox[2], myScissorBox[3]);
+  }
+
+private:
+
+  OpenGl_PBREnvironmentSentry            (const OpenGl_PBREnvironmentSentry& );
+  OpenGl_PBREnvironmentSentry& operator= (const OpenGl_PBREnvironmentSentry& );
+
+private:
+
+  const Handle(OpenGl_Context) myContext;
+  GLint                        myFBO;
+  Handle(OpenGl_ShaderProgram) myShaderProgram;
+  Standard_Boolean             myDepthTestWasEnabled;
+  Standard_Boolean             myDepthWrirtingWasEnablig;
+  Standard_Boolean             myScissorTestWasEnabled;
+  Standard_Integer             myScissorBox[4];
+  Standard_Integer             myViewport[4];
+  Graphic3d_Vec4               myClearColor;
+
+};
+
+// =======================================================================
+// function : Create
+// purpose  :
+// =======================================================================
+Handle(OpenGl_PBREnvironment) OpenGl_PBREnvironment::Create (const Handle(OpenGl_Context)&  theCtx,
+                                                             unsigned int                   thePow2Size,
+                                                             unsigned int                   theLevelsNumber,
+                                                             const TCollection_AsciiString& theId)
+{
+  if (theCtx->arbFBO == NULL)
+  {
+    return Handle(OpenGl_PBREnvironment)();
+  }
+
+  Handle(OpenGl_PBREnvironment) anEnvironment = new OpenGl_PBREnvironment (theCtx, thePow2Size, theLevelsNumber, theId);
+  if (!anEnvironment->IsComplete())
+  {
+    theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_MEDIUM,
+                         "Warning: PBR environment is not created. PBR material system will be ignored.");
+    anEnvironment->Release (theCtx.get());
+    anEnvironment.Nullify();
+  }
+
+  return anEnvironment;
+}
+
+// =======================================================================
+// function : OpenGl_PBREnvironment
+// purpose  :
+// =======================================================================
+OpenGl_PBREnvironment::OpenGl_PBREnvironment (const Handle(OpenGl_Context)&  theCtx,
+                                              unsigned int                   thePowOf2Size,
+                                              unsigned int                   theSpecMapLevelsNumber,
+                                              const TCollection_AsciiString& theId)
+: OpenGl_NamedResource (theId),
+  myPow2Size (std::max (1u, thePowOf2Size)),
+  mySpecMapLevelsNumber (std::max (2u, std::min (theSpecMapLevelsNumber, std::max (1u, thePowOf2Size) + 1))),
+  myFBO (OpenGl_FrameBuffer::NO_FRAMEBUFFER),
+  myIsComplete (Standard_False),
+  myIsNeededToBeBound (Standard_True)
+{
+  OpenGl_PBREnvironmentSentry aSentry (theCtx);
+
+  myIsComplete = initVAO (theCtx)
+              && initTextures (theCtx)
+              && initFBO (theCtx);
+
+  if (myIsComplete)
+  {
+    clear (theCtx);
+  }
+}
+
+// =======================================================================
+// function : Bind
+// purpose  :
+// =======================================================================
+void OpenGl_PBREnvironment::Bind (const Handle(OpenGl_Context)& theCtx)
+{
+  myIBLMaps[OpenGl_TypeOfIBLMap_DiffuseSH].Bind (theCtx);
+  myIBLMaps[OpenGl_TypeOfIBLMap_Specular] .Bind (theCtx);
+  myIsNeededToBeBound = Standard_False;
+}
+
+// =======================================================================
+// function : Unbind
+// purpose  :
+// =======================================================================
+void OpenGl_PBREnvironment::Unbind (const Handle(OpenGl_Context)& theCtx)
+{
+  myIBLMaps[OpenGl_TypeOfIBLMap_DiffuseSH].Unbind (theCtx);
+  myIBLMaps[OpenGl_TypeOfIBLMap_Specular] .Unbind (theCtx);
+  myIsNeededToBeBound = Standard_True;
+}
+
+// =======================================================================
+// function : Clear
+// purpose  :
+// =======================================================================
+void OpenGl_PBREnvironment::Clear (const Handle(OpenGl_Context)& theCtx,
+                                   const Graphic3d_Vec3&         theColor)
+{
+  OpenGl_PBREnvironmentSentry aSentry (theCtx);
+  clear (theCtx, theColor);
+}
+
+// =======================================================================
+// function : Bake
+// purpose  :
+// =======================================================================
+void OpenGl_PBREnvironment::Bake (const Handle(OpenGl_Context)& theCtx,
+                                  const Handle(OpenGl_Texture)& theEnvMap,
+                                  Standard_Boolean              theZIsInverted,
+                                  Standard_Boolean              theIsTopDown,
+                                  Standard_Size                 theDiffMapNbSamples,
+                                  Standard_Size                 theSpecMapNbSamples,
+                                  Standard_ShortReal            theProbability)
+{
+  Standard_ProgramError_Raise_if (theEnvMap.IsNull(), "'Bake' function of 'OpenGl_PBREnvironment' can't work without source environment map")
+  Standard_RangeError_Raise_if (theProbability > 1.f || theProbability < 0.f, "'probability' parameter in 'Bake' function of 'OpenGl_PBREnvironment' must be in range [0, 1]")
+  Unbind (theCtx);
+  OpenGl_PBREnvironmentSentry aSentry (theCtx);
+  bake (theCtx, theEnvMap, theZIsInverted, theIsTopDown, theDiffMapNbSamples, theSpecMapNbSamples, theProbability);
+}
+
+// =======================================================================
+// function : SizesAreDifferent
+// purpose  :
+// =======================================================================
+bool OpenGl_PBREnvironment::SizesAreDifferent (unsigned int thePow2Size,
+                                               unsigned int theSpecMapLevelsNumber) const
+{
+  thePow2Size = std::max (1u, thePow2Size);
+  theSpecMapLevelsNumber = std::max (2u, std::min (theSpecMapLevelsNumber, std::max (1u, thePow2Size) + 1));
+  return myPow2Size != thePow2Size
+      || mySpecMapLevelsNumber != theSpecMapLevelsNumber;
+}
+
+// =======================================================================
+// function : Release
+// purpose  :
+// =======================================================================
+void OpenGl_PBREnvironment::Release (OpenGl_Context* theCtx)
+{
+  if (myFBO != OpenGl_FrameBuffer::NO_FRAMEBUFFER)
+  {
+    if (theCtx != NULL
+     && theCtx->IsValid())
+    {
+      theCtx->arbFBO->glDeleteFramebuffers (1, &myFBO);
+    }
+    myFBO = OpenGl_FrameBuffer::NO_FRAMEBUFFER;
+  }
+  myIBLMaps[OpenGl_TypeOfIBLMap_DiffuseSH].Release(theCtx);
+  myIBLMaps[OpenGl_TypeOfIBLMap_Specular] .Release (theCtx);
+  myVBO.Release (theCtx);
+}
+
+// =======================================================================
+// function : ~OpenGl_PBREnvironment
+// purpose  :
+// =======================================================================
+OpenGl_PBREnvironment::~OpenGl_PBREnvironment()
+{
+  Release (NULL);
+}
+
+// =======================================================================
+// function : initTextures
+// purpose  :
+// =======================================================================
+bool OpenGl_PBREnvironment::initTextures (const Handle(OpenGl_Context)& theCtx)
+{
+  myIBLMaps[OpenGl_TypeOfIBLMap_Specular] .Sampler()->Parameters()->SetTextureUnit (theCtx->PBRSpecIBLMapTexUnit());
+  myIBLMaps[OpenGl_TypeOfIBLMap_DiffuseSH].Sampler()->Parameters()->SetTextureUnit (theCtx->PBRDiffIBLMapSHTexUnit());
+  myIBLMaps[OpenGl_TypeOfIBLMap_Specular] .Sampler()->Parameters()->SetFilter (Graphic3d_TOTF_TRILINEAR);
+  myIBLMaps[OpenGl_TypeOfIBLMap_DiffuseSH].Sampler()->Parameters()->SetFilter(Graphic3d_TOTF_NEAREST);
+  myIBLMaps[OpenGl_TypeOfIBLMap_Specular] .Sampler()->Parameters()->SetLevelsRange (mySpecMapLevelsNumber - 1);
+
+  // NVIDIA's driver didn't work properly with 3 channel texture for diffuse SH coefficients so that alpha channel has been added
+  return myIBLMaps[OpenGl_TypeOfIBLMap_DiffuseSH].Init (theCtx,
+                                                        OpenGl_TextureFormat::FindFormat (theCtx, Image_Format_RGBAF, false),
+                                                        Graphic3d_Vec2i (9, 1),
+                                                        Graphic3d_TOT_2D)
+      && myIBLMaps[OpenGl_TypeOfIBLMap_Specular].InitCubeMap (theCtx, Handle(Graphic3d_CubeMap)(),
+                                                              Standard_Size(1) << myPow2Size, Image_Format_RGB, true, false);
+}
+
+// =======================================================================
+// function : initVAO
+// purpose  :
+// =======================================================================
+bool OpenGl_PBREnvironment::initVAO (const Handle(OpenGl_Context)& theCtx)
+{
+  const float aVertexPos[] =
+  {
+    -1.f, -1.f, 0.f, 0.f,
+     1.f, -1.f, 0.f, 0.f,
+    -1.f,  1.f, 0.f, 0.f,
+     1.f,  1.f, 0.f, 0.f
+  };
+  return myVBO.Init (theCtx, 4, 4, aVertexPos);
+}
+
+// =======================================================================
+// function : initFBO
+// purpose  :
+// =======================================================================
+bool OpenGl_PBREnvironment::initFBO (const Handle(OpenGl_Context)& theCtx)
+{
+  theCtx->arbFBO->glGenFramebuffers (1, &myFBO);
+  return checkFBOComplentess (theCtx);
+}
+
+// =======================================================================
+// function : processDiffIBLMap
+// purpose  :
+// =======================================================================
+bool OpenGl_PBREnvironment::processDiffIBLMap (const Handle(OpenGl_Context)& theCtx,
+                                               Standard_Boolean              theIsDrawAction,
+                                               Standard_Size                 theNbSamples)
+{
+  theCtx->arbFBO->glFramebufferTexture2D (GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+                                          myIBLMaps[OpenGl_TypeOfIBLMap_DiffuseSH].TextureId(), 0);
+  const Standard_Integer aViewport[4] = { 0, 0, 9, 1 };
+  theCtx->ResizeViewport(aViewport);
+  if (theIsDrawAction)
+  {
+    theCtx->ActiveProgram()->SetUniform(theCtx, "occNbSpecIBLLevels", 0);
+    theCtx->ActiveProgram()->SetUniform(theCtx, "uSamplesNum", static_cast<Standard_Integer>(theNbSamples));
+
+    theCtx->core11fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
+  }
+  else
+  {
+    theCtx->core11fwd->glClear (GL_COLOR_BUFFER_BIT);
+
+    theCtx->core11fwd->glEnable (GL_SCISSOR_TEST);
+    theCtx->core11fwd->glClearColor (0.f, 0.f, 0.f, 1.f);
+    theCtx->core11fwd->glScissor (1, 0, 8, 1);
+    theCtx->core11fwd->glClear (GL_COLOR_BUFFER_BIT);
+  }
+
+  return true;
+}
+
+// =======================================================================
+// function : processSpecIBLMap
+// purpose  :
+// =======================================================================
+bool OpenGl_PBREnvironment::processSpecIBLMap (const Handle(OpenGl_Context)& theCtx,
+                                               Standard_Boolean              theIsDrawAction,
+                                               Standard_Integer              theEnvMapSize,
+                                               Standard_Size                 theNbSamples,
+                                               Standard_ShortReal            theProbability)
+{
+  if (theIsDrawAction)
+  {
+    theCtx->ActiveProgram()->SetUniform (theCtx, "occNbSpecIBLLevels", Standard_Integer(mySpecMapLevelsNumber));
+    theCtx->ActiveProgram()->SetUniform (theCtx, "uEnvMapSize", theEnvMapSize);
+  }
+
+  for (int aLevelIter = mySpecMapLevelsNumber - 1;; --aLevelIter)
+  {
+    const Standard_Integer aSize = 1 << (myPow2Size - aLevelIter);
+    const Standard_Integer aViewport[4] = { 0, 0, aSize, aSize };
+    theCtx->ResizeViewport (aViewport);
+    if (theIsDrawAction)
+    {
+      Standard_Integer aNbSamples = static_cast<Standard_Integer>(Graphic3d_PBRMaterial::SpecIBLMapSamplesFactor (theProbability, aLevelIter / float (mySpecMapLevelsNumber - 1)) * theNbSamples);
+      theCtx->ActiveProgram()->SetUniform (theCtx, "uSamplesNum", static_cast<Standard_Integer>(aNbSamples));
+      theCtx->ActiveProgram()->SetUniform (theCtx, "uCurrentLevel", aLevelIter);
+    }
+
+    for (Standard_Integer aSideIter = 0; aSideIter < 6; ++aSideIter)
+    {
+      theCtx->arbFBO->glFramebufferTexture2D (GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + aSideIter,
+                                              myIBLMaps[OpenGl_TypeOfIBLMap_Specular].TextureId(), aLevelIter);
+      if (theIsDrawAction)
+      {
+        theCtx->ActiveProgram()->SetUniform(theCtx, "uCurrentSide", aSideIter);
+        theCtx->core11fwd->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+      }
+      else
+      {
+        theCtx->core11fwd->glClear(GL_COLOR_BUFFER_BIT);
+      }
+    }
+
+    if (aLevelIter == 0)
+    {
+      break;
+    }
+  }
+
+  return true;
+}
+
+// =======================================================================
+// function : checkFBOCompletness
+// purpose  :
+// =======================================================================
+bool OpenGl_PBREnvironment::checkFBOComplentess (const Handle(OpenGl_Context)& theCtx) const
+{
+  theCtx->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, myFBO);
+  theCtx->arbFBO->glFramebufferTexture2D (GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+                                          myIBLMaps[OpenGl_TypeOfIBLMap_DiffuseSH].TextureId(), 0);
+  if (theCtx->arbFBO->glCheckFramebufferStatus (GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
+  {
+    return false;
+  }
+  for (Standard_Integer aSideIter = 0; aSideIter < 6; ++aSideIter)
+  {
+    for (unsigned int aLevel = 0; aLevel < mySpecMapLevelsNumber; ++aLevel)
+    {
+      theCtx->arbFBO->glFramebufferTexture2D (GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + aSideIter,
+                                              myIBLMaps[OpenGl_TypeOfIBLMap_Specular].TextureId(), aLevel);
+      if (theCtx->arbFBO->glCheckFramebufferStatus (GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
+      {
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+// =======================================================================
+// function : bake
+// purpose  :
+// =======================================================================
+void OpenGl_PBREnvironment::bake (const Handle(OpenGl_Context)& theCtx,
+                                  const Handle(OpenGl_Texture)& theEnvMap,
+                                  Standard_Boolean              theZIsInverted,
+                                  Standard_Boolean              theIsTopDown,
+                                  Standard_Size                 theDiffNbSamples,
+                                  Standard_Size                 theSpecNbSamples,
+                                  Standard_ShortReal            theProbability)
+{
+  myIsNeededToBeBound = Standard_True;
+  if (!theCtx->ShaderManager()->BindPBREnvBakingProgram())
+  {
+    return;
+  }
+  theEnvMap->Bind (theCtx, theCtx->PBRSpecIBLMapTexUnit());
+  theCtx->ActiveProgram()->SetSampler (theCtx, "uEnvMap", theCtx->PBRSpecIBLMapTexUnit());
+  theCtx->ActiveProgram()->SetUniform (theCtx, "uZCoeff", theZIsInverted ? -1 : 1);
+  theCtx->ActiveProgram()->SetUniform (theCtx, "uYCoeff", theIsTopDown ? 1 : -1);
+  theCtx->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, myFBO);
+  myVBO.BindAttribute (theCtx, Graphic3d_TOA_POS);
+
+  OSD_Timer aTimer;
+  aTimer.Start();
+  if (processSpecIBLMap (theCtx, true, theEnvMap->SizeX(), theSpecNbSamples, theProbability)
+   && processDiffIBLMap (theCtx, true, theDiffNbSamples))
+  {
+    Message::DefaultMessenger()->Send(TCollection_AsciiString()
+      + "IBL " + myIBLMaps[OpenGl_TypeOfIBLMap_Specular].SizeX() + "x" + myIBLMaps[OpenGl_TypeOfIBLMap_Specular].SizeY()
+      + " is baked in " + aTimer.ElapsedTime() + " s", Message_Trace);
+  }
+  else
+  {
+    theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PERFORMANCE, 0, GL_DEBUG_SEVERITY_HIGH,
+      TCollection_AsciiString("Error: baking PBR environment ") + myIBLMaps[OpenGl_TypeOfIBLMap_Specular].SizeX()
+      + "x" + myIBLMaps[OpenGl_TypeOfIBLMap_Specular].SizeY() + " takes too much time!.");
+    clear (theCtx, Graphic3d_Vec3(1.0f));
+  }
+
+  myVBO.UnbindAttribute (theCtx, Graphic3d_TOA_POS);
+  theEnvMap->Unbind (theCtx, theCtx->PBREnvLUTTexUnit());
+}
+
+// =======================================================================
+// function : clear
+// purpose  :
+// =======================================================================
+void OpenGl_PBREnvironment::clear (const Handle(OpenGl_Context)& theCtx,
+                                   const Graphic3d_Vec3&         theColor)
+{
+  myIsNeededToBeBound = Standard_True;
+  theCtx->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, myFBO);
+  theCtx->core11fwd->glClearColor (theColor.r(), theColor.g(), theColor.b(), 1.f);
+
+  processSpecIBLMap (theCtx, false);
+  processDiffIBLMap (theCtx, false);
+}
diff --git a/src/OpenGl/OpenGl_PBREnvironment.hxx b/src/OpenGl/OpenGl_PBREnvironment.hxx
new file mode 100644 (file)
index 0000000..986883b
--- /dev/null
@@ -0,0 +1,206 @@
+// Author: Ilya Khramov
+// Copyright (c) 2019 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 _OpenGl_PBREnvironment_HeaderFile
+#define _OpenGl_PBREnvironment_HeaderFile
+
+#include <OpenGl_Texture.hxx>
+#include <OpenGl_VertexBuffer.hxx>
+
+//! This class contains specular and diffuse maps required for Image Base Lighting (IBL) in PBR shading model with it's generation methods.
+class OpenGl_PBREnvironment : public OpenGl_NamedResource
+{
+  DEFINE_STANDARD_RTTIEXT(OpenGl_PBREnvironment, OpenGl_NamedResource)
+public:
+
+  //! Creates and initializes new PBR environment. It is the only way to create OpenGl_PBREnvironment.
+  //! @param theCtx OpenGL context where environment will be created
+  //! @param thePow2Size final size of texture's sides can be calculated as 2^thePow2Size;
+  //!                    if thePow2Size less than 1 it will be set to 1
+  //! @param theSpecMapLevelsNum number of mipmap levels used in specular IBL map;
+  //!                            if theSpecMapLevelsNum less than 2 or less than Pow2Size + 1 it will be set to the corresponding values.
+  //! @param theId OpenGl_Resource name
+  //! @return handle to created PBR environment or NULL handle in case of fail
+  Standard_EXPORT static Handle(OpenGl_PBREnvironment) Create (const Handle(OpenGl_Context)&  theCtx,
+                                                               unsigned int                   thePow2Size = 9,
+                                                               unsigned int                   theSpecMapLevelsNum = 6,
+                                                               const TCollection_AsciiString& theId = "PBREnvironment");
+
+public:
+
+  //! Binds diffuse and specular IBL maps to the corresponding texture units.
+  Standard_EXPORT void Bind (const Handle(OpenGl_Context)& theCtx);
+
+  //! Unbinds diffuse and specular IBL maps.
+  Standard_EXPORT void Unbind (const Handle(OpenGl_Context)& theCtx);
+
+  //! Fills all mipmaps of specular IBL map and diffuse IBL map with one color.
+  //! So that environment illumination will be constant.
+  Standard_EXPORT void Clear (const Handle(OpenGl_Context)& theCtx,
+                              const Graphic3d_Vec3&         theColor = Graphic3d_Vec3 (1.f));
+
+  //! Generates specular and diffuse (irradiance) IBL maps.
+  //! @param theCtx OpenGL context
+  //! @param theEnvMap source environment map
+  //! @param theZIsInverted flags indicates whether environment cubemap has inverted Z axis or not
+  //! @param theIsTopDown flags indicates whether environment cubemap has top-down memory layout or not
+  //! @param theDiffMapNbSamples number of samples in Monte-Carlo integration for diffuse IBL spherical harmonics calculation
+  //! @param theSpecMapNbSamples number of samples in Monte-Carlo integration for specular IBL map generation
+  //! @param theProbability controls strength of samples number reducing strategy during specular IBL map baking (see 'SpecIBLMapSamplesFactor' for details)
+  //! theZIsInverted and theIsTopDown can be taken from Graphic3d_CubeMap source of environment cubemap.
+  //! theDiffMapNbSamples and theSpecMapNbSamples is the main parameter directly affected to performance.
+  Standard_EXPORT void Bake (const Handle(OpenGl_Context)& theCtx,
+                             const Handle(OpenGl_Texture)& theEnvMap,
+                             Standard_Boolean              theZIsInverted = Standard_False,
+                             Standard_Boolean              theIsTopDown = Standard_True,
+                             Standard_Size                 theDiffMapNbSamples = 1024,
+                             Standard_Size                 theSpecMapNbSamples = 256,
+                             Standard_ShortReal            theProbability = 0.99f);
+
+  //! Returns number of mipmap levels used in specular IBL map.
+  //! It can be different from value passed to creation method.
+  unsigned int SpecMapLevelsNumber() const { return mySpecMapLevelsNumber; }
+
+  //! Returns size of IBL maps sides as power of 2.
+  //! So that the real size can be calculated as 2^Pow2Size()
+  unsigned int Pow2Size() const { return myPow2Size; }
+
+  //! Checks whether the given sizes affects to the current ones.
+  //! It can be imagined as creation of new PBR environment.
+  //! If creation method with this values returns the PBR environment having real sizes which are equals to current ones
+  //! then this method will return false.
+  //! It is handful when sizes are required to be changed.
+  //! If this method returns false there is no reason to recreate PBR environment in order to change sizes.
+  Standard_EXPORT bool SizesAreDifferent (unsigned int thePow2Size,
+                                          unsigned int theSpecMapLevelsNumber) const;
+
+  //! Indicates whether IBL map's textures have to be bound or it is not obligate.
+  bool IsNeededToBeBound() const
+  {
+    return myIsNeededToBeBound;
+  }
+
+  //! Releases all OpenGL resources.
+  //! It must be called before destruction.
+  Standard_EXPORT virtual void Release (OpenGl_Context* theCtx) Standard_OVERRIDE;
+
+  //! Returns estimated GPU memory usage for holding data without considering overheads and allocation alignment rules.
+  virtual Standard_Size EstimatedDataSize() const Standard_OVERRIDE
+  {
+    unsigned int aDiffIBLMapSidePixelsCount = 1 << myPow2Size;
+    aDiffIBLMapSidePixelsCount *= aDiffIBLMapSidePixelsCount;
+    Standard_Size anEstimatedDataSize = aDiffIBLMapSidePixelsCount;
+    for (unsigned int i = 0; i < mySpecMapLevelsNumber; ++i)
+    {
+      anEstimatedDataSize += aDiffIBLMapSidePixelsCount >> (2 * i);
+    }
+    anEstimatedDataSize *= 6; // cubemap sides
+    anEstimatedDataSize *= 3; // channels
+    return anEstimatedDataSize;
+  }
+
+  //! Checks completeness of PBR environment.
+  //! Creation method returns only completed objects or null handles otherwise.
+  Standard_Boolean IsComplete() const { return myIsComplete; }
+
+  //! Destructor.
+  //! Warning! 'Release' method must be called before destruction.
+  //! Otherwise unhandled critical error will be generated.
+  Standard_EXPORT virtual ~OpenGl_PBREnvironment();
+
+private:
+
+  //! Creates new PBR environment.
+  //! Parameters and logic are described in 'Create' method documentation.
+  Standard_EXPORT OpenGl_PBREnvironment (const Handle(OpenGl_Context)&  theCtx,
+                                         unsigned int                   thePowOf2Size = 9,
+                                         unsigned int                   theSpecMapLevelsNumber = 6,
+                                         const TCollection_AsciiString& theId = "PBREnvironment");
+
+private:
+
+  //! Enum classified the type of IBL map
+  enum OpenGl_TypeOfIBLMap
+  {
+    OpenGl_TypeOfIBLMap_DiffuseSH,
+    OpenGl_TypeOfIBLMap_Specular
+  };
+
+  //! Initializes all textures.
+  //! @return false in case of failed texture initialization
+  //! Warning! Requires using of OpenGl_PBREnvironmentSentry.
+  bool initTextures (const Handle(OpenGl_Context)& theCtx);
+
+  //! Creates frame buffer object for IBL maps generation.
+  //! @return false in case of failed FBO initialization
+  //! Warning! Requires using of OpenGl_PBREnvironmentSentry.
+  bool initFBO (const Handle(OpenGl_Context)& theCtx);
+
+  //! Initializes vertex buffer object of screen rectangle.
+  //! @return false in case of failed creation
+  //! Warning! Requires using of OpenGl_PBREnvironmentSentry.
+  bool initVAO (const Handle(OpenGl_Context)& theCtx);
+
+  //! Responses for diffuse (irradiance) IBL map processing.
+  //! @return false in case of failed baking or clearing
+  //! Warning! Requires using of OpenGl_PBREnvironmentSentry.
+  bool processDiffIBLMap (const Handle(OpenGl_Context)& theCtx,
+                          Standard_Boolean      theIsDrawAction,
+                          Standard_Size         theNbSamples = 0);
+
+  //! Responses for specular IBL map processing.
+  //! @return false in case of failed baking or clearing
+  //! Warning! Requires using of OpenGl_PBREnvironmentSentry.
+  bool processSpecIBLMap (const Handle(OpenGl_Context)& theCtx,
+                          Standard_Boolean   theIsDrawAction,
+                          Standard_Integer   theEnvMapSize = 1024,
+                          Standard_Size      theNbSamples = 0,
+                          Standard_ShortReal theProbability = 1.f);
+
+  //! Checks completeness of frame buffer object for all targets
+  //! (all cube map sides and levels of IBL maps).
+  //! @return false in case of uncompleted frame buffer object.
+  //! Warning! Requires using of OpenGl_PBREnvironmentSentry.
+  bool checkFBOComplentess (const Handle(OpenGl_Context)& theCtx) const;
+
+  //! Version of 'Bake' without OpenGl_PBREnvironmentSetnry.
+  //! Warning! Requires using of OpenGl_PBREnvironmentSentry.
+  void bake (const Handle(OpenGl_Context)& theCtx,
+             const Handle(OpenGl_Texture)& theEnvMap,
+             Standard_Boolean              theZIsInverted = Standard_False,
+             Standard_Boolean              theIsTopDown = Standard_True,
+             Standard_Size                 theDiffMapNbSamples = 1024,
+             Standard_Size                 theSpecMapNbSamples = 256,
+             Standard_ShortReal            theProbability = 1.f);
+
+  //! Version of 'Clear' without OpenGl_PBREnvironmentSetnry.
+  //! Warning! Requires using of OpenGl_PBREnvironmentSentry.
+  void clear (const Handle(OpenGl_Context)& theCtx,
+              const Graphic3d_Vec3&         theColor = Graphic3d_Vec3 (1.f));
+
+private:
+
+  unsigned int        myPow2Size;            //!< size of IBL maps sides (real size can be calculated as 2^myPow2Size)
+  unsigned int        mySpecMapLevelsNumber; //!< number of mipmap levels used in specular IBL map
+
+  OpenGl_Texture      myIBLMaps[2];          //!< IBL maps
+  OpenGl_VertexBuffer myVBO;                 //!< vertex buffer object of screen rectangular
+  GLuint              myFBO;                 //!< frame buffer object to generate or clear IBL maps
+
+  Standard_Boolean    myIsComplete;          //!< completeness of PBR environment
+  Standard_Boolean    myIsNeededToBeBound;   //!< indicates whether IBL map's textures have to be bound or it is not obligate
+
+};
+
+#endif // _OpenGl_PBREnvironment_HeaderFile
index 54c1e25..4fcfca4 100644 (file)
@@ -223,7 +223,8 @@ void OpenGl_Sampler::applySamplerParams (const Handle(OpenGl_Context)& theCtx,
   }
 #endif
   setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_WRAP_T, aWrapMode);
-  if (theTarget == GL_TEXTURE_3D)
+  if (theTarget == GL_TEXTURE_3D
+   || theTarget == GL_TEXTURE_CUBE_MAP)
   {
     setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_WRAP_R, aWrapMode);
     return;
@@ -261,6 +262,13 @@ void OpenGl_Sampler::applySamplerParams (const Handle(OpenGl_Context)& theCtx,
 
     setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
   }
+
+  if (theCtx->IsGlGreaterEqual(1, 2) &&
+      (theSampler == NULL || !theSampler->isValidSampler()))
+  {
+    setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_BASE_LEVEL, theParams->BaseLevel());
+    setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_MAX_LEVEL,  theParams->MaxLevel());
+  }
 }
 
 // =======================================================================
index c7328ce..dcb2080 100644 (file)
 #include <OpenGl_Aspects.hxx>
 #include <OpenGl_ClippingIterator.hxx>
 #include <OpenGl_Context.hxx>
+#include <Graphic3d_CubeMapPacked.hxx>
 #include <OpenGl_ShaderManager.hxx>
 #include <OpenGl_ShaderProgram.hxx>
 #include <OpenGl_VertexBufferCompat.hxx>
 #include <OpenGl_PointSprite.hxx>
 #include <OpenGl_Workspace.hxx>
-
 #include <TCollection_ExtendedString.hxx>
 
+#include "../Shaders/Shaders_PBRDistribution_glsl.pxx"
+#include "../Shaders/Shaders_PBRGeometry_glsl.pxx"
+#include "../Shaders/Shaders_PBRFresnel_glsl.pxx"
+#include "../Shaders/Shaders_PBRCookTorrance_glsl.pxx"
+#include "../Shaders/Shaders_PBRIllumination_glsl.pxx"
+#include "../Shaders/Shaders_PBREnvBaking_fs.pxx"
+#include "../Shaders/Shaders_PBREnvBaking_vs.pxx"
+
 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderManager,Standard_Transient)
 
 namespace
@@ -57,8 +65,8 @@ const char THE_VARY_TexCoord_Trsf[] =
 //! Auxiliary function to flip gl_PointCoord vertically
 #define THE_VEC2_glPointCoord "vec2 (gl_PointCoord.x, 1.0 - gl_PointCoord.y)"
 
-//! Auxiliary function to transform normal
-const char THE_FUNC_transformNormal[] =
+//! Auxiliary function to transform normal from model to view coordinate system.
+const char THE_FUNC_transformNormal_view[] =
   EOL"vec3 transformNormal (in vec3 theNormal)"
   EOL"{"
   EOL"  vec4 aResult = occWorldViewMatrixInverseTranspose"
@@ -67,12 +75,31 @@ const char THE_FUNC_transformNormal[] =
   EOL"  return normalize (aResult.xyz);"
   EOL"}";
 
+//! The same function as THE_FUNC_transformNormal but is used in PBR pipeline.
+//! The normals are expected to be in world coordinate system in PBR pipeline.
+const char THE_FUNC_transformNormal_world[] =
+  EOL"vec3 transformNormal (in vec3 theNormal)"
+  EOL"{"
+  EOL"  vec4 aResult = occModelWorldMatrixInverseTranspose"
+  EOL"               * vec4 (theNormal, 0.0);"
+  EOL"  return normalize (aResult.xyz);"
+  EOL"}";
+
 //! Global shader variable for color definition with lighting enabled.
 const char THE_FUNC_lightDef[] =
   EOL"vec3 Ambient;"   //!< Ambient  contribution of light sources
   EOL"vec3 Diffuse;"   //!< Diffuse  contribution of light sources
   EOL"vec3 Specular;"; //!< Specular contribution of light sources
 
+//! Global shader variable for color definition with lighting enabled.
+const char THE_FUNC_PBR_lightDef[] =
+  EOL"vec3  DirectLighting;" //!< Accumulator of direct lighting from light sources
+  EOL"vec4  BaseColor;"      //!< Base color (albedo) of material for PBR
+  EOL"float Metallic;"       //!< Metallic coefficient of material
+  EOL"float Roughness;"      //!< Roughness coefficient of material
+  EOL"vec3  Emission;"       //!< Light intensity emitted by material
+  EOL"float IOR;";           //!< Material's index of refraction
+
 //! Function computes contribution of isotropic point light source
 const char THE_FUNC_pointLight[] =
   EOL"void pointLight (in int  theId,"
@@ -82,7 +109,7 @@ const char THE_FUNC_pointLight[] =
   EOL"                 in bool theIsFront)"
   EOL"{"
   EOL"  vec3 aLight = occLight_Position (theId).xyz;"
-  EOL"  if (occLight_IsHeadlight (theId) == 0)"
+  EOL"  if (!occLight_IsHeadlight (theId))"
   EOL"  {"
   EOL"    aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 1.0));"
   EOL"  }"
@@ -110,6 +137,38 @@ const char THE_FUNC_pointLight[] =
   EOL"  Specular += occLight_Specular (theId).rgb * aSpecl * anAtten;"
   EOL"}";
 
+//! Function computes contribution of isotropic point light source
+const char THE_FUNC_PBR_pointLight[] =
+  EOL"void pointLight (in int  theId,"
+  EOL"                 in vec3 theNormal,"
+  EOL"                 in vec3 theView,"
+  EOL"                 in vec3 thePoint,"
+  EOL"                 in bool theIsFront)"
+  EOL"{"
+  EOL"  vec3 aLight = occLight_Position (theId).xyz;"
+  EOL"  if (occLight_IsHeadlight (theId))"
+  EOL"  {"
+  EOL"    aLight = vec3 (occWorldViewMatrixInverse * vec4 (aLight, 1.0));"
+  EOL"  }"
+  EOL"  aLight -= thePoint;"
+  EOL
+  EOL"  float aDist = length (aLight);"
+  EOL"  aLight /= aDist;"
+  EOL
+  EOL"  float anAtten = 1.0 / max (aDist * aDist, 0.01);"
+  EOL
+  EOL"  theNormal = theIsFront ? theNormal : -theNormal;"
+  EOL"  DirectLighting += occPBRIllumination (theView,"
+  EOL"                                        aLight,"
+  EOL"                                        theNormal,"
+  EOL"                                        BaseColor,"
+  EOL"                                        Metallic,"
+  EOL"                                        Roughness,"
+  EOL"                                        IOR,"
+  EOL"                                        occLight_Specular(theId).rgb,"
+  EOL"                                        occLight_Intensity(theId) * anAtten);"
+  EOL"}";
+
 //! Function computes contribution of spotlight source
 const char THE_FUNC_spotLight[] =
   EOL"void spotLight (in int  theId,"
@@ -120,7 +179,7 @@ const char THE_FUNC_spotLight[] =
   EOL"{"
   EOL"  vec3 aLight   = occLight_Position      (theId).xyz;"
   EOL"  vec3 aSpotDir = occLight_SpotDirection (theId).xyz;"
-  EOL"  if (occLight_IsHeadlight (theId) == 0)"
+  EOL"  if (!occLight_IsHeadlight (theId))"
   EOL"  {"
   EOL"    aLight   = vec3 (occWorldViewMatrix * vec4 (aLight,   1.0));"
   EOL"    aSpotDir = vec3 (occWorldViewMatrix * vec4 (aSpotDir, 0.0));"
@@ -162,6 +221,53 @@ const char THE_FUNC_spotLight[] =
   EOL"  Specular += occLight_Specular (theId).rgb * aSpecl * anAtten;"
   EOL"}";
 
+//! Function computes contribution of spotlight source
+  const char THE_FUNC_PBR_spotLight[] =
+  EOL"void spotLight (in int  theId,"
+  EOL"                in vec3 theNormal,"
+  EOL"                in vec3 theView,"
+  EOL"                in vec3 thePoint,"
+  EOL"                in bool theIsFront)"
+  EOL"{"
+  EOL"  vec3 aLight   = occLight_Position      (theId).xyz;"
+  EOL"  vec3 aSpotDir = occLight_SpotDirection (theId).xyz;"
+  EOL"  if (occLight_IsHeadlight (theId))"
+  EOL"  {"
+  EOL"    aLight   = vec3 (occWorldViewMatrixInverse * vec4 (aLight,   1.0));"
+  EOL"    aSpotDir = vec3 (occWorldViewMatrixInverse * vec4 (aSpotDir, 0.0));"
+  EOL"  }"
+  EOL"  aLight -= thePoint;"
+  EOL
+  EOL"  float aDist = length (aLight);"
+  EOL"  aLight /= aDist;"
+  EOL
+  EOL"  aSpotDir = normalize (aSpotDir);"
+  // light cone
+  EOL"  float aCosA = dot (aSpotDir, -aLight);"
+  EOL"  if (aCosA >= 1.0 || aCosA < cos (occLight_SpotCutOff (theId)))"
+  EOL"  {"
+  EOL"    return;"
+  EOL"  }"
+  EOL
+  EOL"  float anExponent = occLight_SpotExponent (theId);"
+  EOL"  float anAtten    = 1.0 / max (aDist * aDist, 0.01);"
+  EOL"  if (anExponent > 0.0)"
+  EOL"  {"
+  EOL"    anAtten *= pow (aCosA, anExponent * 128.0);"
+  EOL"  }"
+  EOL
+  EOL"  theNormal = theIsFront ? theNormal : -theNormal;"
+  EOL"  DirectLighting += occPBRIllumination (theView,"
+  EOL"                                        aLight,"
+  EOL"                                        theNormal,"
+  EOL"                                        BaseColor,"
+  EOL"                                        Metallic,"
+  EOL"                                        Roughness,"
+  EOL"                                        IOR,"
+  EOL"                                        occLight_Specular(theId).rgb,"
+  EOL"                                        occLight_Intensity(theId) * anAtten);"
+  EOL"}";
+
 //! Function computes contribution of directional light source
 const char THE_FUNC_directionalLight[] =
   EOL"void directionalLight (in int  theId,"
@@ -170,7 +276,7 @@ const char THE_FUNC_directionalLight[] =
   EOL"                       in bool theIsFront)"
   EOL"{"
   EOL"  vec3 aLight = normalize (occLight_Position (theId).xyz);"
-  EOL"  if (occLight_IsHeadlight (theId) == 0)"
+  EOL"  if (!occLight_IsHeadlight (theId))"
   EOL"  {"
   EOL"    aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 0.0));"
   EOL"  }"
@@ -191,6 +297,31 @@ const char THE_FUNC_directionalLight[] =
   EOL"  Specular += occLight_Specular (theId).rgb * aSpecl;"
   EOL"}";
 
+//! Function computes contribution of directional light source
+const char THE_FUNC_PBR_directionalLight[] =
+  EOL"void directionalLight (in int  theId,"
+  EOL"                       in vec3 theNormal,"
+  EOL"                       in vec3 theView,"
+  EOL"                       in bool theIsFront)"
+  EOL"{"
+  EOL"  vec3 aLight = normalize (occLight_Position (theId).xyz);"
+  EOL"  if (occLight_IsHeadlight (theId))"
+  EOL"  {"
+  EOL"    aLight = vec3 (occWorldViewMatrixInverse * vec4 (aLight, 0.0));"
+  EOL"  }"
+  EOL
+  EOL"  theNormal = theIsFront ? theNormal : -theNormal;"
+  EOL"  DirectLighting += occPBRIllumination (theView,"
+  EOL"                                        aLight,"
+  EOL"                                        theNormal,"
+  EOL"                                        BaseColor,"
+  EOL"                                        Metallic,"
+  EOL"                                        Roughness,"
+  EOL"                                        IOR,"
+  EOL"                                        occLight_Specular(theId).rgb,"
+  EOL"                                        occLight_Intensity(theId));"
+  EOL"}";
+
 //! The same as THE_FUNC_directionalLight but for the light with zero index
 //! (avoids limitations on some mobile devices).
 const char THE_FUNC_directionalLightFirst[] =
@@ -199,7 +330,7 @@ const char THE_FUNC_directionalLightFirst[] =
   EOL"                            in bool theIsFront)"
   EOL"{"
   EOL"  vec3 aLight = normalize (occLightSources[1].xyz);"
-  EOL"  if (occLight_IsHeadlight (0) == 0)"
+  EOL"  if (!occLight_IsHeadlight (0))"
   EOL"  {"
   EOL"    aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 0.0));"
   EOL"  }"
@@ -220,6 +351,18 @@ const char THE_FUNC_directionalLightFirst[] =
   EOL"  Specular += occLightSources[0].rgb * aSpecl;"
   EOL"}";
 
+//! Returns the real cubemap fetching direction considering sides orientation, memory layout and vertical flip.
+const char THE_FUNC_cubemap_vector_transform[] =
+  EOL"vec3 cubemapVectorTransform (in vec3 theVector,"
+  EOL"                             in int  theYCoeff,"
+  EOL"                             in int  theZCoeff)"
+  EOL"{"
+  EOL"  theVector = theVector.yzx;"
+  EOL"  theVector.y *= float(theYCoeff);"
+  EOL"  theVector.z *= float(theZCoeff);"
+  EOL"  return theVector;"
+  EOL"}";
+
 //! Process clipping planes in Fragment Shader.
 //! Should be added at the beginning of the main() function.
 const char THE_FRAG_CLIP_PLANES_N[] =
@@ -422,6 +565,10 @@ OpenGl_ShaderManager::OpenGl_ShaderManager (OpenGl_Context* theContext)
 OpenGl_ShaderManager::~OpenGl_ShaderManager()
 {
   myProgramList.Clear();
+  if (!myPBREnvironment.IsNull())
+  {
+    myPBREnvironment->Release (myContext);
+  }
 }
 
 // =======================================================================
@@ -585,9 +732,11 @@ void OpenGl_ShaderManager::UpdateSRgbState()
 // function : UpdateLightSourceStateTo
 // purpose  : Updates state of OCCT light sources
 // =======================================================================
-void OpenGl_ShaderManager::UpdateLightSourceStateTo (const Handle(Graphic3d_LightSet)& theLights)
+void OpenGl_ShaderManager::UpdateLightSourceStateTo (const Handle(Graphic3d_LightSet)& theLights,
+                                                     Standard_Integer                  theSpecIBLMapLevels)
 {
   myLightSourceState.Set (theLights);
+  myLightSourceState.SetSpecIBLMapLevels (theSpecIBLMapLevels);
   myLightSourceState.Update();
   switchLightPrograms();
 }
@@ -768,6 +917,7 @@ void OpenGl_ShaderManager::pushLightSourceState (const Handle(OpenGl_ShaderProgr
     aLightType.Type        = aLight.Type();
     aLightType.IsHeadlight = aLight.IsHeadlight();
     aLightParams.Color     = aLight.PackedColor();
+    aLightParams.Color.a() = aLight.Intensity(); // used by PBR and ignored by old shading model
     if (aLight.Type() == Graphic3d_TOLS_DIRECTIONAL)
     {
       aLightParams.Position = -aLight.PackedDirection();
@@ -813,6 +963,11 @@ void OpenGl_ShaderManager::pushLightSourceState (const Handle(OpenGl_ShaderProgr
                             aLightsNb * OpenGl_ShaderLightParameters::NbOfVec4(),
                             myLightParamsArray.First().Packed());
   }
+
+  if (const OpenGl_ShaderUniformLocation aLocation = theProgram->GetStateLocation (OpenGl_OCCT_NB_SPEC_IBL_LEVELS))
+  {
+    theProgram->SetUniform (myContext, aLocation, myLightSourceState.SpecIBLMapLevels());
+  }
 }
 
 // =======================================================================
@@ -1164,18 +1319,18 @@ void OpenGl_ShaderManager::pushMaterialState (const Handle(OpenGl_ShaderProgram)
     }
 
     const GLenum aFrontFace = myMaterialState.ToDistinguish() ? GL_FRONT : GL_FRONT_AND_BACK;
-    myContext->core11->glMaterialfv(aFrontFace, GL_AMBIENT,   aFrontMat.Ambient.GetData());
-    myContext->core11->glMaterialfv(aFrontFace, GL_DIFFUSE,   aFrontMat.Diffuse.GetData());
-    myContext->core11->glMaterialfv(aFrontFace, GL_SPECULAR,  aFrontMat.Specular.GetData());
-    myContext->core11->glMaterialfv(aFrontFace, GL_EMISSION,  aFrontMat.Emission.GetData());
-    myContext->core11->glMaterialf (aFrontFace, GL_SHININESS, aFrontMat.Shine());
+    myContext->core11->glMaterialfv(aFrontFace, GL_AMBIENT,   aFrontMat.Common.Ambient.GetData());
+    myContext->core11->glMaterialfv(aFrontFace, GL_DIFFUSE,   aFrontMat.Common.Diffuse.GetData());
+    myContext->core11->glMaterialfv(aFrontFace, GL_SPECULAR,  aFrontMat.Common.Specular.GetData());
+    myContext->core11->glMaterialfv(aFrontFace, GL_EMISSION,  aFrontMat.Common.Emission.GetData());
+    myContext->core11->glMaterialf (aFrontFace, GL_SHININESS, aFrontMat.Common.Shine());
     if (myMaterialState.ToDistinguish())
     {
-      myContext->core11->glMaterialfv(GL_BACK, GL_AMBIENT,   aBackMat.Ambient.GetData());
-      myContext->core11->glMaterialfv(GL_BACK, GL_DIFFUSE,   aBackMat.Diffuse.GetData());
-      myContext->core11->glMaterialfv(GL_BACK, GL_SPECULAR,  aBackMat.Specular.GetData());
-      myContext->core11->glMaterialfv(GL_BACK, GL_EMISSION,  aBackMat.Emission.GetData());
-      myContext->core11->glMaterialf (GL_BACK, GL_SHININESS, aBackMat.Shine());
+      myContext->core11->glMaterialfv(GL_BACK, GL_AMBIENT,   aBackMat.Common.Ambient.GetData());
+      myContext->core11->glMaterialfv(GL_BACK, GL_DIFFUSE,   aBackMat.Common.Diffuse.GetData());
+      myContext->core11->glMaterialfv(GL_BACK, GL_SPECULAR,  aBackMat.Common.Specular.GetData());
+      myContext->core11->glMaterialfv(GL_BACK, GL_EMISSION,  aBackMat.Common.Emission.GetData());
+      myContext->core11->glMaterialf (GL_BACK, GL_SHININESS, aBackMat.Common.Shine());
     }
   #endif
     return;
@@ -1191,15 +1346,25 @@ void OpenGl_ShaderManager::pushMaterialState (const Handle(OpenGl_ShaderProgram)
                           theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE),
                           myMaterialState.ToDistinguish() ? 1 : 0);
 
-  if (const OpenGl_ShaderUniformLocation aLocFront = theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL))
+  if (const OpenGl_ShaderUniformLocation& aLocPbrFront = theProgram->GetStateLocation (OpenGl_OCCT_PBR_FRONT_MATERIAL))
   {
-    theProgram->SetUniform (myContext, aLocFront, OpenGl_Material::NbOfVec4(),
-                            aFrontMat.Packed());
+    theProgram->SetUniform (myContext, aLocPbrFront, OpenGl_MaterialPBR::NbOfVec4(),
+                            aFrontMat.Pbr.Packed());
   }
-  if (const OpenGl_ShaderUniformLocation aLocBack = theProgram->GetStateLocation (OpenGl_OCCT_BACK_MATERIAL))
+  if (const OpenGl_ShaderUniformLocation aLocPbrBack = theProgram->GetStateLocation (OpenGl_OCCT_PBR_BACK_MATERIAL))
   {
-    theProgram->SetUniform (myContext, aLocBack,  OpenGl_Material::NbOfVec4(),
-                            aBackMat.Packed());
+    theProgram->SetUniform (myContext, aLocPbrBack,  OpenGl_MaterialPBR::NbOfVec4(),
+                            aBackMat.Pbr.Packed());
+  }
+  if (const OpenGl_ShaderUniformLocation aLocFront = theProgram->GetStateLocation (OpenGl_OCCT_COMMON_FRONT_MATERIAL))
+  {
+    theProgram->SetUniform (myContext, aLocFront, OpenGl_MaterialCommon::NbOfVec4(),
+                            aFrontMat.Common.Packed());
+  }
+  if (const OpenGl_ShaderUniformLocation aLocBack = theProgram->GetStateLocation (OpenGl_OCCT_COMMON_BACK_MATERIAL))
+  {
+    theProgram->SetUniform (myContext, aLocBack,  OpenGl_MaterialCommon::NbOfVec4(),
+                            aBackMat.Common.Packed());
   }
 }
 
@@ -1614,7 +1779,8 @@ int OpenGl_ShaderManager::defaultGlslVersion (const Handle(Graphic3d_ShaderProgr
   }
   else
   {
-    if ((theBits & OpenGl_PO_StippleLine) != 0)
+    if ((theBits & OpenGl_PO_StippleLine) != 0
+     || theProgram->IsPBR())
     {
       if (myContext->IsGlGreaterEqual (3, 0))
       {
@@ -1654,6 +1820,11 @@ int OpenGl_ShaderManager::defaultGlslVersion (const Handle(Graphic3d_ShaderProgr
   }
   else
   {
+    if (theProgram->IsPBR()
+     && myContext->IsGlGreaterEqual (3, 0))
+    {
+      theProgram->SetHeader ("#version 300 es");
+    }
     if ((theBits & OpenGl_PO_WriteOit) != 0
      || (theBits & OpenGl_PO_StippleLine) != 0)
     {
@@ -1863,7 +2034,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramUnlit (Handle(OpenGl_Sha
     }
     else if ((theBits & OpenGl_PO_TextureEnv) != 0)
     {
-      aSrcVertExtraFunc = THE_FUNC_transformNormal;
+      aSrcVertExtraFunc = THE_FUNC_transformNormal_view;
 
       aSrcVertExtraMain +=
         EOL"  vec4 aPosition = occWorldViewMatrix * occModelWorldMatrix * occVertex;"
@@ -2046,7 +2217,8 @@ TCollection_AsciiString OpenGl_ShaderManager::pointSpriteShadingSrc (const TColl
 // purpose  :
 // =======================================================================
 TCollection_AsciiString OpenGl_ShaderManager::stdComputeLighting (Standard_Integer& theNbLights,
-                                                                  Standard_Boolean  theHasVertColor)
+                                                                  Standard_Boolean  theHasVertColor,
+                                                                  Standard_Boolean  theIsPBR)
 {
   TCollection_AsciiString aLightsFunc, aLightsLoop;
   theNbLights = 0;
@@ -2122,8 +2294,19 @@ TCollection_AsciiString OpenGl_ShaderManager::stdComputeLighting (Standard_Integ
       }
       aLightsLoop += EOL"    }";
     }
+
+    if (theIsPBR)
+    {
+      aLightsFunc += Shaders_PBRDistribution_glsl;
+      aLightsFunc += Shaders_PBRGeometry_glsl;
+      aLightsFunc += Shaders_PBRFresnel_glsl;
+      aLightsFunc += Shaders_PBRCookTorrance_glsl;
+      aLightsFunc += Shaders_PBRIllumination_glsl;
+    }
+
     if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_DIRECTIONAL) == 1
-     && theNbLights == 1)
+     && theNbLights == 1
+     && !theIsPBR)
     {
       // use the version with hard-coded first index
       aLightsLoop = EOL"    directionalLightFirst(theNormal, theView, theIsFront);";
@@ -2131,15 +2314,15 @@ TCollection_AsciiString OpenGl_ShaderManager::stdComputeLighting (Standard_Integ
     }
     else if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_DIRECTIONAL) > 0)
     {
-      aLightsFunc += THE_FUNC_directionalLight;
+      aLightsFunc += theIsPBR ? THE_FUNC_PBR_directionalLight : THE_FUNC_directionalLight;
     }
     if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_POSITIONAL) > 0)
     {
-      aLightsFunc += THE_FUNC_pointLight;
+      aLightsFunc += theIsPBR ? THE_FUNC_PBR_pointLight : THE_FUNC_pointLight;
     }
     if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_SPOT) > 0)
     {
-      aLightsFunc += THE_FUNC_spotLight;
+      aLightsFunc += theIsPBR ? THE_FUNC_PBR_spotLight : THE_FUNC_spotLight;
     }
   }
 
@@ -2151,7 +2334,9 @@ TCollection_AsciiString OpenGl_ShaderManager::stdComputeLighting (Standard_Integ
     aGetMatDiffuse = "getVertColor();";
   }
 
-  return TCollection_AsciiString()
+  if (!theIsPBR)
+  {
+    return TCollection_AsciiString()
     + THE_FUNC_lightDef
     + aLightsFunc
     + EOL
@@ -2175,6 +2360,42 @@ TCollection_AsciiString OpenGl_ShaderManager::stdComputeLighting (Standard_Integ
       EOL"                         + aMatEmission.rgb;"
       EOL"  return vec4 (aColor, aMatDiffuse.a);"
       EOL"}";
+  }
+  else
+  {
+    return TCollection_AsciiString()
+    + THE_FUNC_PBR_lightDef
+    + aLightsFunc
+    + EOL
+      EOL"vec4 computeLighting (in vec3 theNormal,"
+      EOL"                      in vec3 theView,"
+      EOL"                      in vec4 thePoint,"
+      EOL"                      in bool theIsFront)"
+      EOL"{"
+      EOL"  DirectLighting = vec3(0.0);"
+      EOL"  BaseColor = " + (theHasVertColor ? "getVertColor();" : "getBaseColor (theIsFront);")
+    + EOL"  Metallic  = theIsFront ? occPBRFrontMaterial_Metallic()  : occPBRBackMaterial_Metallic();"
+      EOL"  Roughness = theIsFront ? occPBRFrontMaterial_Roughness() : occPBRBackMaterial_Roughness();"
+      EOL"  IOR       = theIsFront ? occPBRFrontMaterial_IOR()       : occPBRBackMaterial_IOR();"
+      EOL"  Emission  = theIsFront ? occPBRFrontMaterial_Emission()  : occPBRBackMaterial_Emission();"
+      EOL"  vec3 aPoint = thePoint.xyz / thePoint.w;"
+    + aLightsLoop
+    + EOL"  vec3 aColor = DirectLighting;"
+      EOL"  vec3 anIndirectLightingSpec = occPBRFresnel (BaseColor.rgb, Metallic, IOR);"
+      EOL"  Roughness = theIsFront ? occPBRFrontMaterial_NormalizedRoughness() : occPBRBackMaterial_NormalizedRoughness();"
+      EOL"  vec2 aCoeff = occTexture2D (occEnvLUT, vec2(abs(dot(theView, theNormal)), Roughness)).xy;"
+      EOL"  anIndirectLightingSpec *= aCoeff.x;"
+      EOL"  anIndirectLightingSpec += aCoeff.y;"
+      EOL"  anIndirectLightingSpec *= occTextureCubeLod (occSpecIBLMap, -reflect (theView, theNormal), Roughness * float (occNbSpecIBLLevels - 1)).rgb;"
+      EOL"  vec3 aRefractionCoeff = 1.0 - occPBRFresnel (BaseColor.rgb, Metallic, Roughness, IOR, abs(dot(theView, theNormal)));"
+      EOL"  aRefractionCoeff *= (1.0 - Metallic);"
+      EOL"  vec3 anIndirectLightingDiff = aRefractionCoeff * BaseColor.rgb * BaseColor.a;"
+      EOL"  anIndirectLightingDiff *= occDiffIBLMap (theNormal).rgb;"
+      EOL"  aColor += occLightAmbient.rgb * (anIndirectLightingDiff + anIndirectLightingSpec);"
+      EOL"  aColor += Emission;"
+      EOL"  return vec4 (aColor, mix(1.0, BaseColor.a, aRefractionCoeff.x));"
+      EOL"}";
+  }
 }
 
 // =======================================================================
@@ -2278,9 +2499,9 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_S
   aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 BackColor",  Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
 
   Standard_Integer aNbLights = 0;
-  const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, !aSrcVertColor.IsEmpty());
+  const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, !aSrcVertColor.IsEmpty(), false);
   aSrcVert = TCollection_AsciiString()
-    + THE_FUNC_transformNormal
+    + THE_FUNC_transformNormal_view
     + EOL
     + aSrcVertColor
     + aLights
@@ -2334,9 +2555,12 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_S
 // =======================================================================
 Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_ShaderProgram)& theProgram,
                                                                const Standard_Integer        theBits,
-                                                               const Standard_Boolean        theIsFlatNormal)
+                                                               const Standard_Boolean        theIsFlatNormal,
+                                                               const Standard_Boolean        theIsPBR)
 {
-  #define thePhongCompLight "computeLighting (normalize (Normal), normalize (View), Position, gl_FrontFacing)"
+  TCollection_AsciiString aPosition = theIsPBR ? "PositionWorld" : "Position";
+  TCollection_AsciiString aPhongCompLight = TCollection_AsciiString() +
+    "computeLighting (normalize (Normal), normalize (View), " + aPosition + ", gl_FrontFacing)";
   const bool isFlatNormal = theIsFlatNormal
                          && myContext->hasFlatShading != OpenGl_FeatureNotAvailable;
   const char* aDFdxSignReversion = "";
@@ -2357,9 +2581,16 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
   }
 #endif
   Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
+  aProgramSrc->SetPBR (theIsPBR);
+
   TCollection_AsciiString aSrcVert, aSrcVertExtraFunc, aSrcVertExtraMain;
   TCollection_AsciiString aSrcFrag, aSrcFragExtraOut, aSrcFragGetVertColor, aSrcFragExtraMain;
-  TCollection_AsciiString aSrcFragGetColor = EOL"vec4 getColor(void) { return " thePhongCompLight "; }";
+  TCollection_AsciiString aSrcFragGetColor = TCollection_AsciiString() + EOL"vec4 getColor(void) { return " + aPhongCompLight +  "; }";
+  TCollection_AsciiString aSrcFragPBRGetBaseColor = TCollection_AsciiString() +
+    EOL"vec4 getBaseColor(in bool theIsFront)"
+    EOL"{"
+    EOL"  return theIsFront ? occPBRFrontMaterial_Color() : occPBRBackMaterial_Color();"
+    EOL"}";
   OpenGl_ShaderObject::ShaderVariableList aUniforms, aStageInOuts;
   if ((theBits & OpenGl_PO_IsPoint) != 0)
   {
@@ -2378,7 +2609,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
     #endif
 
       aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerPointSprite", Graphic3d_TOS_FRAGMENT));
-      aSrcFragGetColor = pointSpriteShadingSrc (thePhongCompLight, theBits);
+      aSrcFragGetColor = pointSpriteShadingSrc (aPhongCompLight, theBits);
     }
 
     if ((theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureRGB
@@ -2399,12 +2630,24 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
       aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 TexCoord", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
       aSrcVertExtraMain += THE_VARY_TexCoord_Trsf;
 
-      aSrcFragGetColor =
-        EOL"vec4 getColor(void)"
-        EOL"{"
-        EOL"  vec4 aColor = " thePhongCompLight ";"
-        EOL"  return occTexture2D(occSamplerBaseColor, TexCoord.st / TexCoord.w) * aColor;"
-        EOL"}";
+      if (!theIsPBR)
+      {
+        aSrcFragGetColor = TCollection_AsciiString() +
+          EOL"vec4 getColor(void)"
+          EOL"{"
+          EOL"  vec4 aColor = " + aPhongCompLight + ";"
+          EOL"  return occTexture2D(occSamplerBaseColor, TexCoord.st / TexCoord.w) * aColor;"
+          EOL"}";
+      }
+      else
+      {
+        aSrcFragPBRGetBaseColor = TCollection_AsciiString() +
+          EOL"vec4 getBaseColor (in bool theIsFront)"
+          EOL"{"
+          EOL"  return occTexture2D(occSamplerBaseColor, TexCoord.st / TexCoord.w) *"
+          EOL"         (theIsFront ? occPBRFrontMaterial_Color() : occPBRBackMaterial_Color());"
+          EOL"}";
+      }
     }
   }
 
@@ -2448,13 +2691,13 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
   {
     aSrcFragExtraOut  += EOL"vec3 Normal;";
     aSrcFragExtraMain += TCollection_AsciiString()
-      + EOL"  Normal = " + aDFdxSignReversion + "normalize (cross (dFdx (Position.xyz / Position.w), dFdy (Position.xyz / Position.w)));"
+      + EOL"  Normal = " + aDFdxSignReversion + "normalize (cross (dFdx (" + aPosition + ".xyz / " + aPosition + ".w), dFdy (" + aPosition + ".xyz / " + aPosition + ".w)));"
         EOL"  if (!gl_FrontFacing) { Normal = -Normal; }";
   }
   else
   {
     aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec3 Normal", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
-    aSrcVertExtraFunc += THE_FUNC_transformNormal;
+    aSrcVertExtraFunc += theIsPBR ? THE_FUNC_transformNormal_world : THE_FUNC_transformNormal_view;
     aSrcVertExtraMain += EOL"  Normal = transformNormal (occNormal);";
   }
 
@@ -2468,7 +2711,15 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
       EOL"{"
       EOL"  PositionWorld = occModelWorldMatrix * occVertex;"
       EOL"  Position      = occWorldViewMatrix * PositionWorld;"
-    + EOL"  View          = vec3 (0.0, 0.0, 1.0);"
+      EOL"  if (occProjectionMatrix[3][3] == 1.0)"
+      EOL"  {"
+      EOL"    View = vec3(0.0, 0.0, 1.0);"
+      EOL"  }"
+      EOL"  else"
+      EOL"  {"
+      EOL"    View = -Position.xyz;"
+      EOL"  }"
+    + (theIsPBR ? EOL"  View = (occWorldViewMatrixInverse * vec4(View, 0.0)).xyz;" : "")
     + aSrcVertExtraMain
     + THE_VERT_gl_Position
     + EOL"}";
@@ -2479,11 +2730,12 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
     : EOL"#define getFinalColor getColor";
 
   Standard_Integer aNbLights = 0;
-  const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, !aSrcFragGetVertColor.IsEmpty());
+  const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, !aSrcFragGetVertColor.IsEmpty(), theIsPBR);
   aSrcFrag = TCollection_AsciiString()
     + EOL
     + aSrcFragExtraOut
     + aSrcFragGetVertColor
+    + (theIsPBR ? aSrcFragPBRGetBaseColor : "")
     + aLights
     + aSrcFragGetColor
     + EOL
@@ -2493,12 +2745,13 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
     + EOL"  occSetFragColor (getFinalColor());"
     + EOL"}";
 
-  const TCollection_AsciiString aProgId = TCollection_AsciiString (theIsFlatNormal ? "flat-" : "phong-") + genLightKey (myLightSourceState.LightSources()) + "-";
+  const TCollection_AsciiString aProgId = TCollection_AsciiString (theIsFlatNormal ? "flat-" : "phong-") + (theIsPBR ? "pbr-" : "") + genLightKey (myLightSourceState.LightSources()) + "-";
   defaultGlslVersion (aProgramSrc, aProgId, theBits, isFlatNormal);
   aProgramSrc->SetDefaultSampler (false);
   aProgramSrc->SetNbLightsMax (aNbLights);
   aProgramSrc->SetNbClipPlanesMax (aNbClipPlanes);
   aProgramSrc->SetAlphaTest ((theBits & OpenGl_PO_AlphaTest) != 0);
+
   const Standard_Integer aNbGeomInputVerts = !aSrcGeom.IsEmpty() ? 3 : 0;
   aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX,   aUniforms, aStageInOuts, "", "", aNbGeomInputVerts));
   aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcGeom, Graphic3d_TOS_GEOMETRY, aUniforms, aStageInOuts, "geomIn", "geomOut", aNbGeomInputVerts));
@@ -2788,6 +3041,48 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramBoundBox()
 }
 
 // =======================================================================
+// function : preparePBREnvBakingProgram
+// purpose  :
+// =======================================================================
+Standard_Boolean OpenGl_ShaderManager::preparePBREnvBakingProgram()
+{
+  Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
+  OpenGl_ShaderObject::ShaderVariableList aUniforms, aStageInOuts;
+
+  TCollection_AsciiString aSrcVert = TCollection_AsciiString()
+  + THE_FUNC_cubemap_vector_transform
+  + Shaders_PBREnvBaking_vs;
+
+  TCollection_AsciiString aSrcFrag = TCollection_AsciiString()
+  + THE_FUNC_cubemap_vector_transform
+  + Shaders_PBRDistribution_glsl
+  + Shaders_PBREnvBaking_fs;
+
+  // constant array definition requires OpenGL 2.1+ or OpenGL ES 3.0+
+#if defined(GL_ES_VERSION_2_0)
+  aProgramSrc->SetHeader ("#version 300 es");
+#else
+  aProgramSrc->SetHeader ("#version 120");
+#endif
+
+  defaultGlslVersion (aProgramSrc, "pbr_env_baking", 0);
+  aProgramSrc->SetDefaultSampler (false);
+  aProgramSrc->SetNbLightsMax (0);
+  aProgramSrc->SetNbClipPlanesMax (0);
+  aProgramSrc->SetPBR (true);
+  aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX,   aUniforms, aStageInOuts));
+  aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
+  TCollection_AsciiString aKey;
+  if (!Create (aProgramSrc, aKey, myPBREnvBakingProgram))
+  {
+    myPBREnvBakingProgram = new OpenGl_ShaderProgram(); // just mark as invalid
+    return Standard_False;
+  }
+
+  return Standard_True;
+}
+
+// =======================================================================
 // function : GetBgCubeMapProgram
 // purpose  :
 // =======================================================================
@@ -2795,24 +3090,23 @@ const Handle(Graphic3d_ShaderProgram)& OpenGl_ShaderManager::GetBgCubeMapProgram
 {
   if (myBgCubeMapProgram.IsNull())
   {
-    myBgCubeMapProgram = new Graphic3d_ShaderProgram;
+    myBgCubeMapProgram = new Graphic3d_ShaderProgram();
 
     OpenGl_ShaderObject::ShaderVariableList aUniforms, aStageInOuts;
     aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable("vec3 ViewDirection", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
-    aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("int uZCoeff", Graphic3d_TOS_VERTEX)); // defines orientation of Z axis to make horizontal flip
-    aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("int uYCoeff", Graphic3d_TOS_VERTEX)); // defines orientation of Y axis to make vertical flip
     aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("samplerCube occSampler0", Graphic3d_TOS_FRAGMENT));
+    aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("int uYCoeff", Graphic3d_TOS_VERTEX));
+    aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("int uZCoeff", Graphic3d_TOS_VERTEX));
 
-    TCollection_AsciiString aSrcVert =
-      EOL"void main()"
+    TCollection_AsciiString aSrcVert = TCollection_AsciiString()
+    + THE_FUNC_cubemap_vector_transform
+    + EOL"void main()"
       EOL"{"
       EOL"  vec4 aViewDirection = occProjectionMatrixInverse * vec4(occVertex.xy, 0.0, 1.0);"
       EOL"  aViewDirection /= aViewDirection.w;"
       EOL"  aViewDirection.w = 0.0;"
       EOL"  ViewDirection = normalize((occWorldViewMatrixInverse * aViewDirection).xyz);"
-      EOL"  ViewDirection = ViewDirection.yzx;" // is needed to sync horizon and frontal camera position
-      EOL"  ViewDirection.y *= uYCoeff;"
-      EOL"  ViewDirection.z *= uZCoeff;"
+      EOL"  ViewDirection = cubemapVectorTransform (ViewDirection, uYCoeff, uZCoeff);"
       EOL"  gl_Position = vec4(occVertex.xy, 0.0, 1.0);"
       EOL"}";
 
@@ -2820,15 +3114,15 @@ const Handle(Graphic3d_ShaderProgram)& OpenGl_ShaderManager::GetBgCubeMapProgram
       EOL"#define occEnvCubemap occSampler0"
       EOL"void main()"
       EOL"{"
-      EOL"  occSetFragColor (vec4(texture(occEnvCubemap, ViewDirection).rgb, 1.0));"
+      EOL"  occSetFragColor (vec4(occTextureCube (occEnvCubemap, ViewDirection).rgb, 1.0));"
       EOL"}";
 
-    defaultGlslVersion(myBgCubeMapProgram, "background_cubemap", 0);
-    myBgCubeMapProgram->SetDefaultSampler(false);
-    myBgCubeMapProgram->SetNbLightsMax(0);
-    myBgCubeMapProgram->SetNbClipPlanesMax(0);
-    myBgCubeMapProgram->AttachShader(OpenGl_ShaderObject::CreateFromSource(aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts));
-    myBgCubeMapProgram->AttachShader(OpenGl_ShaderObject::CreateFromSource(aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
+    defaultGlslVersion (myBgCubeMapProgram, "background_cubemap", 0);
+    myBgCubeMapProgram->SetDefaultSampler (false);
+    myBgCubeMapProgram->SetNbLightsMax (0);
+    myBgCubeMapProgram->SetNbClipPlanesMax (0);
+    myBgCubeMapProgram->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts));
+    myBgCubeMapProgram->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
   }
 
   return myBgCubeMapProgram;
index 46ddd18..793ac51 100644 (file)
@@ -22,6 +22,7 @@
 #include <NCollection_DataMap.hxx>
 #include <NCollection_Sequence.hxx>
 
+#include <OpenGl_PBREnvironment.hxx>
 #include <OpenGl_SetOfShaderPrograms.hxx>
 #include <OpenGl_ShaderStates.hxx>
 #include <OpenGl_Aspects.hxx>
@@ -249,16 +250,44 @@ public:
   //! Returns bounding box vertex buffer.
   const Handle(OpenGl_VertexBuffer)& BoundBoxVertBuffer() const { return myBoundBoxVertBuffer; }
 
+  //! Bind program for IBL maps generation in PBR pipeline.
+  Standard_Boolean BindPBREnvBakingProgram()
+  {
+    if (myPBREnvBakingProgram.IsNull())
+    {
+      preparePBREnvBakingProgram();
+    }
+    return myContext->BindProgram (myPBREnvBakingProgram);
+  }
+
   //! Generates shader program to render environment cubemap as background.
   Standard_EXPORT const Handle(Graphic3d_ShaderProgram)& GetBgCubeMapProgram ();
 
+  //! Resets PBR shading models to corresponding non-PBR ones if PBR is not allowed.
+  static Graphic3d_TypeOfShadingModel PBRShadingModelFallback (Graphic3d_TypeOfShadingModel theShadingModel,
+                                                               Standard_Boolean             theIsPbrAllowed = Standard_False)
+  {
+    if (theIsPbrAllowed)
+    {
+      return theShadingModel;
+    }
+
+    switch (theShadingModel)
+    {
+      case Graphic3d_TOSM_PBR:       return Graphic3d_TOSM_FRAGMENT;
+      case Graphic3d_TOSM_PBR_FACET: return Graphic3d_TOSM_FACET;
+      default: return theShadingModel;
+    }
+  }
+
 public:
 
   //! Returns current state of OCCT light sources.
   const OpenGl_LightSourceState& LightSourceState() const { return myLightSourceState; }
 
   //! Updates state of OCCT light sources.
-  Standard_EXPORT void UpdateLightSourceStateTo (const Handle(Graphic3d_LightSet)& theLights);
+  Standard_EXPORT void UpdateLightSourceStateTo (const Handle(Graphic3d_LightSet)& theLights,
+                                                 Standard_Integer                  theSpecIBLMapLevels = 0);
 
   //! Invalidate state of OCCT light sources.
   Standard_EXPORT void UpdateLightSourceState();
@@ -443,6 +472,7 @@ public:
 
   //! Choose Shading Model for filled primitives.
   //! Fallbacks to FACET model if there are no normal attributes.
+  //! Fallbacks to corresponding non-PBR models if PBR is unavailable.
   Graphic3d_TypeOfShadingModel ChooseFaceShadingModel (Graphic3d_TypeOfShadingModel theCustomModel,
                                                        bool theHasNodalNormals) const
   {
@@ -460,12 +490,17 @@ public:
       case Graphic3d_TOSM_VERTEX:
       case Graphic3d_TOSM_FRAGMENT:
         return theHasNodalNormals ? aModel : Graphic3d_TOSM_FACET;
+      case Graphic3d_TOSM_PBR:
+        return PBRShadingModelFallback (theHasNodalNormals ? aModel : Graphic3d_TOSM_PBR_FACET, IsPbrAllowed());
+      case Graphic3d_TOSM_PBR_FACET:
+        return PBRShadingModelFallback (aModel, IsPbrAllowed());
     }
     return Graphic3d_TOSM_UNLIT;
   }
 
   //! Choose Shading Model for line primitives.
   //! Fallbacks to UNLIT model if there are no normal attributes.
+  //! Fallbacks to corresponding non-PBR models if PBR is unavailable.
   Graphic3d_TypeOfShadingModel ChooseLineShadingModel (Graphic3d_TypeOfShadingModel theCustomModel,
                                                        bool theHasNodalNormals) const
   {
@@ -483,6 +518,10 @@ public:
       case Graphic3d_TOSM_VERTEX:
       case Graphic3d_TOSM_FRAGMENT:
         return theHasNodalNormals ? aModel : Graphic3d_TOSM_UNLIT;
+      case Graphic3d_TOSM_PBR:
+        return PBRShadingModelFallback (theHasNodalNormals ? aModel : Graphic3d_TOSM_UNLIT, IsPbrAllowed());
+      case Graphic3d_TOSM_PBR_FACET:
+        return Graphic3d_TOSM_UNLIT;
     }
     return Graphic3d_TOSM_UNLIT;
   }
@@ -648,11 +687,13 @@ protected:
   {
     switch (theShadingModel)
     {
-      case Graphic3d_TOSM_UNLIT:    return prepareStdProgramUnlit  (theProgram, theBits, false);
-      case Graphic3d_TOSM_FACET:    return prepareStdProgramPhong  (theProgram, theBits, true);
-      case Graphic3d_TOSM_VERTEX:   return prepareStdProgramGouraud(theProgram, theBits);
+      case Graphic3d_TOSM_UNLIT:     return prepareStdProgramUnlit  (theProgram, theBits, false);
+      case Graphic3d_TOSM_FACET:     return prepareStdProgramPhong  (theProgram, theBits, true);
+      case Graphic3d_TOSM_VERTEX:    return prepareStdProgramGouraud(theProgram, theBits);
       case Graphic3d_TOSM_DEFAULT:
-      case Graphic3d_TOSM_FRAGMENT: return prepareStdProgramPhong  (theProgram, theBits, false);
+      case Graphic3d_TOSM_FRAGMENT:  return prepareStdProgramPhong  (theProgram, theBits, false);
+      case Graphic3d_TOSM_PBR:       return prepareStdProgramPhong  (theProgram, theBits, false, true);
+      case Graphic3d_TOSM_PBR_FACET: return prepareStdProgramPhong  (theProgram, theBits, true, true);
     }
     return false;
   }
@@ -663,15 +704,19 @@ protected:
 
   //! Prepare standard GLSL program with per-pixel lighting.
   //! @param theIsFlatNormal when TRUE, the Vertex normals will be ignored and Face normal will be computed instead
+  //! @param theIsPBR when TRUE, the PBR pipeline will be activated
   Standard_EXPORT Standard_Boolean prepareStdProgramPhong (Handle(OpenGl_ShaderProgram)& theProgram,
                                                            const Standard_Integer        theBits,
-                                                           const Standard_Boolean        theIsFlatNormal = false);
+                                                           const Standard_Boolean        theIsFlatNormal = false,
+                                                           const Standard_Boolean        theIsPBR = false);
 
   //! Define computeLighting GLSL function depending on current lights configuration
   //! @param theNbLights     [out] number of defined light sources
   //! @param theHasVertColor [in]  flag to use getVertColor() instead of Ambient and Diffuse components of active material
+  //! @param theIsPBR        [in]  flag to activate PBR pipeline
   Standard_EXPORT TCollection_AsciiString stdComputeLighting (Standard_Integer& theNbLights,
-                                                              Standard_Boolean  theHasVertColor);
+                                                              Standard_Boolean  theHasVertColor,
+                                                              Standard_Boolean  theIsPBR);
 
   //! Bind specified program to current context and apply state.
   Standard_EXPORT Standard_Boolean bindProgramWithState (const Handle(OpenGl_ShaderProgram)& theProgram);
@@ -697,6 +742,13 @@ protected:
                                                               OpenGl_ShaderObject::ShaderVariableList& theStageInOuts,
                                                               Standard_Integer theBits);
 
+  //! Prepare GLSL source for IBL generation used in PBR pipeline.
+  Standard_EXPORT Standard_Boolean preparePBREnvBakingProgram();
+
+  //! Checks whether one of PBR shading models is set as default model.
+  Standard_Boolean IsPbrAllowed() const { return myShadingModel == Graphic3d_TOSM_PBR
+                                              || myShadingModel == Graphic3d_TOSM_PBR_FACET; }
+
 protected:
 
   //! Packed properties of light source
@@ -769,12 +821,15 @@ protected:
   Handle(OpenGl_ShaderProgram)       myOitCompositingProgram[2]; //!< standard program for OIT compositing (default and MSAA).
   OpenGl_MapOfShaderPrograms         myMapOfLightPrograms; //!< map of lighting programs depending on lights configuration
 
+  Handle(OpenGl_ShaderProgram)       myPBREnvBakingProgram;//!< program for IBL maps generation used in PBR pipeline
   Handle(Graphic3d_ShaderProgram)    myBgCubeMapProgram;   //!< program for background cubemap rendering
 
   Handle(OpenGl_ShaderProgram)       myStereoPrograms[Graphic3d_StereoMode_NB]; //!< standard stereo programs
 
   Handle(OpenGl_VertexBuffer)        myBoundBoxVertBuffer; //!< bounding box vertex buffer
 
+  mutable Handle(OpenGl_PBREnvironment) myPBREnvironment;  //!< manager of IBL maps used in PBR pipeline
+
   OpenGl_Context*                    myContext;            //!< OpenGL context
   Standard_Boolean                   mySRgbState;          //!< track sRGB state
 
index b7cb81d..68b3af2 100755 (executable)
@@ -56,38 +56,42 @@ Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] =
   "occWorldViewMatrixInverseTranspose",  // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE
   "occProjectionMatrixInverseTranspose", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE
 
-  "occClipPlaneEquations", // OpenGl_OCC_CLIP_PLANE_EQUATIONS
-  "occClipPlaneChains",    // OpenGl_OCC_CLIP_PLANE_CHAINS
-  "occClipPlaneCount",     // OpenGl_OCC_CLIP_PLANE_COUNT
-
-  "occLightSourcesCount",  // OpenGl_OCC_LIGHT_SOURCE_COUNT
-  "occLightSourcesTypes",  // OpenGl_OCC_LIGHT_SOURCE_TYPES
-  "occLightSources",       // OpenGl_OCC_LIGHT_SOURCE_PARAMS
-  "occLightAmbient",       // OpenGl_OCC_LIGHT_AMBIENT
-
-  "occTextureEnable",      // OpenGl_OCCT_TEXTURE_ENABLE
-  "occDistinguishingMode", // OpenGl_OCCT_DISTINGUISH_MODE
-  "occFrontMaterial",      // OpenGl_OCCT_FRONT_MATERIAL
-  "occBackMaterial",       // OpenGl_OCCT_BACK_MATERIAL
-  "occAlphaCutoff",        // OpenGl_OCCT_ALPHA_CUTOFF
-  "occColor",              // OpenGl_OCCT_COLOR
-
-  "occOitOutput",          // OpenGl_OCCT_OIT_OUTPUT
-  "occOitDepthFactor",     // OpenGl_OCCT_OIT_DEPTH_FACTOR
-
-  "occTexTrsf2d",          // OpenGl_OCCT_TEXTURE_TRSF2D
-  "occPointSize",          // OpenGl_OCCT_POINT_SIZE
-
-  "occViewport",           // OpenGl_OCCT_VIEWPORT
-  "occLineWidth",          // OpenGl_OCCT_LINE_WIDTH
-  "occLineFeather",        // OpenGl_OCCT_LINE_FEATHER
-  "occStipplePattern",     // OpenGl_OCCT_LINE_STIPPLE_PATTERN
-  "occStippleFactor",      // OpenGl_OCCT_LINE_STIPPLE_FACTOR
-  "occWireframeColor",     // OpenGl_OCCT_WIREFRAME_COLOR
-  "occIsQuadMode",         // OpenGl_OCCT_QUAD_MODE_STATE
-
-  "occOrthoScale",         // OpenGl_OCCT_ORTHO_SCALE
-  "occSilhouetteThickness" // OpenGl_OCCT_SILHOUETTE_THICKNESS
+  "occClipPlaneEquations",  // OpenGl_OCC_CLIP_PLANE_EQUATIONS
+  "occClipPlaneChains",     // OpenGl_OCC_CLIP_PLANE_CHAINS
+  "occClipPlaneCount",      // OpenGl_OCC_CLIP_PLANE_COUNT
+
+  "occLightSourcesCount",   // OpenGl_OCC_LIGHT_SOURCE_COUNT
+  "occLightSourcesTypes",   // OpenGl_OCC_LIGHT_SOURCE_TYPES
+  "occLightSources",        // OpenGl_OCC_LIGHT_SOURCE_PARAMS
+  "occLightAmbient",        // OpenGl_OCC_LIGHT_AMBIENT
+
+  "occTextureEnable",       // OpenGl_OCCT_TEXTURE_ENABLE
+  "occDistinguishingMode",  // OpenGl_OCCT_DISTINGUISH_MODE
+  "occPbrFrontMaterial",    // OpenGl_OCCT_PBR_FRONT_MATERIAL
+  "occPbrBackMaterial",     // OpenGl_OCCT_PBR_BACK_MATERIAL
+  "occFrontMaterial",       // OpenGl_OCCT_COMMON_FRONT_MATERIAL
+  "occBackMaterial",        // OpenGl_OCCT_COMMON_BACK_MATERIAL
+  "occAlphaCutoff",         // OpenGl_OCCT_ALPHA_CUTOFF
+  "occColor",               // OpenGl_OCCT_COLOR
+
+  "occOitOutput",           // OpenGl_OCCT_OIT_OUTPUT
+  "occOitDepthFactor",      // OpenGl_OCCT_OIT_DEPTH_FACTOR
+
+  "occTexTrsf2d",           // OpenGl_OCCT_TEXTURE_TRSF2D
+  "occPointSize",           // OpenGl_OCCT_POINT_SIZE
+
+  "occViewport",            // OpenGl_OCCT_VIEWPORT
+  "occLineWidth",           // OpenGl_OCCT_LINE_WIDTH
+  "occLineFeather",         // OpenGl_OCCT_LINE_FEATHER
+  "occStipplePattern",      // OpenGl_OCCT_LINE_STIPPLE_PATTERN
+  "occStippleFactor",       // OpenGl_OCCT_LINE_STIPPLE_FACTOR
+  "occWireframeColor",      // OpenGl_OCCT_WIREFRAME_COLOR
+  "occIsQuadMode",          // OpenGl_OCCT_QUAD_MODE_STATE
+
+  "occOrthoScale",          // OpenGl_OCCT_ORTHO_SCALE
+  "occSilhouetteThickness", // OpenGl_OCCT_SILHOUETTE_THICKNESS
+
+  "occNbSpecIBLLevels"      // OpenGl_OCCT_NB_SPEC_IBL_LEVELS
 };
 
 namespace
@@ -409,6 +413,11 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
     {
       aHeaderConstants += "#define THE_HAS_DEFAULT_SAMPLER\n";
     }
+    if (!myProxy.IsNull()
+      && myProxy->IsPBR())
+    {
+      aHeaderConstants += "#define THE_IS_PBR\n";
+    }
 
     const TCollection_AsciiString aSource = aHeaderVer                     // #version   - header defining GLSL version, should be first
                                           + (!aHeaderVer.IsEmpty() ? "\n" : "")
@@ -488,6 +497,18 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
   {
     SetUniform (theCtx, aLocSampler, GLint(theCtx->SpriteTextureUnit()));
   }
+  if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occDiffIBLMapSHCoeffs"))
+  {
+    SetUniform (theCtx, aLocSampler, GLint(theCtx->PBRDiffIBLMapSHTexUnit()));
+  }
+  if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occSpecIBLMap"))
+  {
+    SetUniform (theCtx, aLocSampler, GLint(theCtx->PBRSpecIBLMapTexUnit()));
+  }
+  if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occEnvLUT"))
+  {
+    SetUniform (theCtx, aLocSampler, GLint(theCtx->PBREnvLUTTexUnit()));
+  }
 
   const TCollection_AsciiString aSamplerNamePrefix ("occSampler");
   const Standard_Integer aNbUnitsMax = Max (theCtx->MaxCombinedTextureUnits(), Graphic3d_TextureUnit_NB);
index 8016c6e..93252bb 100755 (executable)
@@ -62,8 +62,10 @@ enum OpenGl_StateVariable
   // Material state
   OpenGl_OCCT_TEXTURE_ENABLE,
   OpenGl_OCCT_DISTINGUISH_MODE,
-  OpenGl_OCCT_FRONT_MATERIAL,
-  OpenGl_OCCT_BACK_MATERIAL,
+  OpenGl_OCCT_PBR_FRONT_MATERIAL,
+  OpenGl_OCCT_PBR_BACK_MATERIAL,
+  OpenGl_OCCT_COMMON_FRONT_MATERIAL,
+  OpenGl_OCCT_COMMON_BACK_MATERIAL,
   OpenGl_OCCT_ALPHA_CUTOFF,
   OpenGl_OCCT_COLOR,
 
@@ -88,6 +90,9 @@ enum OpenGl_StateVariable
   OpenGl_OCCT_ORTHO_SCALE,
   OpenGl_OCCT_SILHOUETTE_THICKNESS,
 
+  // PBR state
+  OpenGl_OCCT_NB_SPEC_IBL_LEVELS,
+
   // DON'T MODIFY THIS ITEM (insert new items before it)
   OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES
 };
index eaa5abe..bebd349 100755 (executable)
@@ -122,7 +122,7 @@ class OpenGl_LightSourceState : public OpenGl_StateInterface
 public:
 
   //! Creates uninitialized state of light sources.
-  OpenGl_LightSourceState() {}
+  OpenGl_LightSourceState() : mySpecIBLMapLevels (0) {}
 
   //! Sets new light sources.
   void Set (const Handle(Graphic3d_LightSet)& theLightSources) { myLightSources = theLightSources; }
@@ -130,9 +130,17 @@ public:
   //! Returns current list of light sources.
   const Handle(Graphic3d_LightSet)& LightSources() const { return myLightSources; }
 
+  //! Returns number of mipmap levels used in specular IBL map.
+  //! 0 by default or in case of using non-PBR shading model.
+  Standard_Integer SpecIBLMapLevels() const { return mySpecIBLMapLevels; }
+
+  //! Sets number of mipmap levels used in specular IBL map.
+  void SetSpecIBLMapLevels(Standard_Integer theSpecIBLMapLevels) { mySpecIBLMapLevels = theSpecIBLMapLevels; }
+
 private:
 
-  Handle(Graphic3d_LightSet) myLightSources; //!< List of OCCT light sources
+  Handle(Graphic3d_LightSet) myLightSources;     //!< List of OCCT light sources
+  Standard_Integer           mySpecIBLMapLevels; //!< Number of mipmap levels used in specular IBL map (0 by default or in case of using non-PBR shading model)
 
 };
 
index a6553ac..aa01fac 100644 (file)
@@ -563,7 +563,7 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)&       theCtx,
   {
     case Graphic3d_TOT_CUBEMAP:
     {
-      return initCubeMap (theCtx, Handle(Graphic3d_CubeMap)::DownCast(theTextureMap),
+      return InitCubeMap (theCtx, Handle(Graphic3d_CubeMap)::DownCast(theTextureMap),
                           0, Image_Format_RGB, false, theTextureMap->IsColorMap());
     }
     default:
@@ -793,10 +793,10 @@ bool OpenGl_Texture::Init3D (const Handle(OpenGl_Context)& theCtx,
 }
 
 // =======================================================================
-// function : initCubeMap
+// function : InitCubeMap
 // purpose  :
 // =======================================================================
-bool OpenGl_Texture::initCubeMap (const Handle(OpenGl_Context)&    theCtx,
+bool OpenGl_Texture::InitCubeMap (const Handle(OpenGl_Context)&    theCtx,
                                   const Handle(Graphic3d_CubeMap)& theCubeMap,
                                   Standard_Size    theSize,
                                   Image_Format     theFormat,
@@ -811,6 +811,7 @@ bool OpenGl_Texture::initCubeMap (const Handle(OpenGl_Context)&    theCtx,
 
   if (!theCubeMap.IsNull())
   {
+    theToGenMipmap = theCubeMap->HasMipmaps();
     if (Handle(Image_PixMap) anImage = theCubeMap->Reset().Value())
     {
       theSize   = anImage->SizeX();
@@ -836,6 +837,8 @@ bool OpenGl_Texture::initCubeMap (const Handle(OpenGl_Context)&    theCtx,
   myTarget = GL_TEXTURE_CUBE_MAP;
   myHasMipmaps = theToGenMipmap;
   myNbSamples = 1;
+  mySizeX = (GLsizei )theSize;
+  mySizeY = (GLsizei )theSize;
   Bind (theCtx);
   applyDefaultSamplerParams (theCtx);
 
@@ -991,6 +994,10 @@ Standard_Size OpenGl_Texture::EstimatedDataSize() const
   {
     aSize *= Standard_Size(mySizeZ);
   }
+  if (myTarget == GL_TEXTURE_CUBE_MAP)
+  {
+    aSize *= 6; // cube sides
+  }
   if (myHasMipmaps)
   {
     aSize = aSize + aSize / 3;
index a9520d3..0841286 100644 (file)
@@ -245,11 +245,6 @@ public:
     return Init3D (theCtx, aFormat, Graphic3d_Vec3i (theSizeX, theSizeY, theSizeZ), thePixels);
   }
 
-protected:
-
-  //! Apply default sampler parameters after texture creation.
-  Standard_EXPORT void applyDefaultSamplerParams (const Handle(OpenGl_Context)& theCtx);
-
   //! Initializes 6 sides of cubemap.
   //! If theCubeMap is not NULL then size and format will be taken from it and corresponding arguments will be ignored.
   //! Otherwise this parametres will be taken from arguments.
@@ -259,7 +254,7 @@ protected:
   //! @param theFormat      [in] image format
   //! @param theToGenMipmap [in] flag to generate mipmaped cubemap
   //! @param theIsColorMap  [in] flag indicating cubemap storing color values
-  Standard_EXPORT bool initCubeMap (const Handle(OpenGl_Context)&    theCtx,
+  Standard_EXPORT bool InitCubeMap (const Handle(OpenGl_Context)&    theCtx,
                                     const Handle(Graphic3d_CubeMap)& theCubeMap,
                                     Standard_Size    theSize,
                                     Image_Format     theFormat,
@@ -268,6 +263,11 @@ protected:
 
 protected:
 
+  //! Apply default sampler parameters after texture creation.
+  Standard_EXPORT void applyDefaultSamplerParams (const Handle(OpenGl_Context)& theCtx);
+
+protected:
+
   Handle(OpenGl_Sampler) mySampler; //!< texture sampler
   Standard_Size    myRevision;   //!< revision of associated data source
   GLuint           myTextureId;  //!< GL resource ID
index 851032b..30c7018 100644 (file)
@@ -31,7 +31,7 @@ OpenGl_TextureFormat OpenGl_TextureFormat::FindFormat (const Handle(OpenGl_Conte
       aFormat.SetNbComponents (1);
       if (theCtx->core11 == NULL)
       {
-        aFormat.SetInternalFormat (GL_R8); // GL_R32F
+        aFormat.SetInternalFormat (theCtx->arbTexFloat ? GL_R32F : GL_R8);
         aFormat.SetPixelFormat (GL_RED);
       }
       else
@@ -51,7 +51,7 @@ OpenGl_TextureFormat OpenGl_TextureFormat::FindFormat (const Handle(OpenGl_Conte
       aFormat.SetNbComponents (1);
       if (theCtx->core11 == NULL)
       {
-        aFormat.SetInternalFormat (GL_R8);  // GL_R32F
+        aFormat.SetInternalFormat (theCtx->arbTexFloat ? GL_R32F : GL_R8);
         aFormat.SetPixelFormat (GL_RED);
       }
       else
@@ -66,10 +66,22 @@ OpenGl_TextureFormat OpenGl_TextureFormat::FindFormat (const Handle(OpenGl_Conte
       aFormat.SetDataType (GL_FLOAT);
       return aFormat;
     }
+    case Image_Format_RGF:
+    {
+      if (!theCtx->arbTexRG)
+      {
+        return OpenGl_TextureFormat();
+      }
+      aFormat.SetNbComponents (2);
+      aFormat.SetInternalFormat (theCtx->arbTexFloat ? GL_RG32F : GL_RG8);
+      aFormat.SetPixelFormat (GL_RG);
+      aFormat.SetDataType (GL_FLOAT);
+      return aFormat;
+    }
     case Image_Format_RGBAF:
     {
       aFormat.SetNbComponents (4);
-      aFormat.SetInternalFormat (GL_RGBA8); // GL_RGBA32F
+      aFormat.SetInternalFormat (theCtx->arbTexFloat ? GL_RGBA32F : GL_RGBA8);
       aFormat.SetPixelFormat (GL_RGBA);
       aFormat.SetDataType (GL_FLOAT);
       return aFormat;
@@ -81,7 +93,7 @@ OpenGl_TextureFormat OpenGl_TextureFormat::FindFormat (const Handle(OpenGl_Conte
         return OpenGl_TextureFormat();
       }
       aFormat.SetNbComponents (4);
-      aFormat.SetInternalFormat (GL_RGBA8); // GL_RGBA32F
+      aFormat.SetInternalFormat (theCtx->arbTexFloat ? GL_RGBA32F : GL_RGBA8);
       aFormat.SetPixelFormat (GL_BGRA_EXT); // equals to GL_BGRA
       aFormat.SetDataType (GL_FLOAT);
       return aFormat;
@@ -89,7 +101,7 @@ OpenGl_TextureFormat OpenGl_TextureFormat::FindFormat (const Handle(OpenGl_Conte
     case Image_Format_RGBF:
     {
       aFormat.SetNbComponents (3);
-      aFormat.SetInternalFormat (GL_RGB8); // GL_RGB32F
+      aFormat.SetInternalFormat (theCtx->arbTexFloat ? GL_RGB32F : GL_RGB8);
       aFormat.SetPixelFormat (GL_RGB);
       aFormat.SetDataType (GL_FLOAT);
       return aFormat;
@@ -98,7 +110,7 @@ OpenGl_TextureFormat OpenGl_TextureFormat::FindFormat (const Handle(OpenGl_Conte
     {
     #if !defined(GL_ES_VERSION_2_0)
       aFormat.SetNbComponents (3);
-      aFormat.SetInternalFormat (GL_RGB8); // GL_RGB32F
+      aFormat.SetInternalFormat (theCtx->arbTexFloat ? GL_RGB32F : GL_RGB8);
       aFormat.SetPixelFormat (GL_BGR);     // equals to GL_BGR_EXT
       aFormat.SetDataType (GL_FLOAT);
       return aFormat;
index 4179fa2..b5d5c23 100644 (file)
@@ -72,6 +72,8 @@ OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr,
   myTextureParams   (new OpenGl_Aspects()),
   myCubeMapParams   (new OpenGl_Aspects()),
   myBackgroundType  (Graphic3d_TOB_NONE),
+  myPBREnvState     (OpenGl_PBREnvState_NONEXISTENT),
+  myPBREnvRequest   (OpenGl_PBREnvRequest_NONE),
   // ray-tracing fields initialization
   myRaytraceInitStatus     (OpenGl_RT_NONE),
   myIsRaytraceDataValid    (Standard_False),
@@ -202,6 +204,11 @@ void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
   releaseSrgbResources (theCtx);
 
   releaseRaytraceResources (theCtx);
+
+  if (!myPBREnvironment.IsNull())
+  {
+    myPBREnvironment->Release (theCtx.get());
+  }
 }
 
 // =======================================================================
@@ -530,37 +537,56 @@ Handle(Graphic3d_CubeMap) OpenGl_View::BackgroundCubeMap() const
 {
   return myBackgroundCubeMap;
 }
+
+// =======================================================================
+// function : SpecIBLMapLevels
+// purpose  :
+// =======================================================================
+unsigned int OpenGl_View::SpecIBLMapLevels() const
+{
+  return myPBREnvironment.IsNull() ? 0 : myPBREnvironment->SpecMapLevelsNumber();
+}
  
 // =======================================================================
 // function : SetBackgroundCubeMap
 // purpose  :
 // =======================================================================
-void OpenGl_View::SetBackgroundCubeMap (const Handle(Graphic3d_CubeMap)& theCubeMap)
+void OpenGl_View::SetBackgroundCubeMap (const Handle(Graphic3d_CubeMap)& theCubeMap,
+                                        Standard_Boolean theToUpdatePBREnv)
 {
   myBackgroundCubeMap = theCubeMap;
-  Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d;
-  Handle(Graphic3d_TextureSet) aTextureSet = new Graphic3d_TextureSet (myBackgroundCubeMap);
+  if (theCubeMap.IsNull())
+  {
+    if (theToUpdatePBREnv)
+    {
+      myPBREnvRequest = OpenGl_PBREnvRequest_CLEAR;
+    }
+    if (myBackgroundType == Graphic3d_TOB_CUBEMAP)
+    {
+      myBackgroundType = Graphic3d_TOB_NONE;
+    }
+    return;
+  }
 
-  anAspect->SetInteriorStyle(Aspect_IS_SOLID);
-  anAspect->SetSuppressBackFaces(false);
-  anAspect->SetTextureSet(aTextureSet);
+  theCubeMap ->SetMipmapsGeneration (Standard_True);
+  Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
+  Handle(Graphic3d_TextureSet) aTextureSet = new Graphic3d_TextureSet (myBackgroundCubeMap);
+  anAspect->SetInteriorStyle (Aspect_IS_SOLID);
+  anAspect->SetSuppressBackFaces (false);
+  anAspect->SetTextureSet (aTextureSet);
 
   const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext();
   if (!aCtx.IsNull())
   {
     anAspect->SetShaderProgram (aCtx->ShaderManager()->GetBgCubeMapProgram());
   }
+  anAspect->SetTextureMapOn (theCubeMap->IsDone());
+  myCubeMapParams->SetAspect (anAspect);
 
-  if (theCubeMap->IsDone())
+  if (theToUpdatePBREnv)
   {
-    anAspect->SetTextureMapOn();
-  }
-  else
-  {
-    anAspect->SetTextureMapOff();
+    myPBREnvRequest = OpenGl_PBREnvRequest_BAKE;
   }
-
-  myCubeMapParams->SetAspect(anAspect);
   const OpenGl_Aspects* anAspectsBackup = myWorkspace->SetAspects (myCubeMapParams);
   myWorkspace->ApplyAspects();
   myWorkspace->SetAspects (anAspectsBackup);
index daf3f8a..ddf1b53 100644 (file)
@@ -57,6 +57,7 @@ struct OpenGl_Matrix;
 
 class Graphic3d_StructureManager;
 class OpenGl_GraphicDriver;
+class OpenGl_PBREnvironment;
 class OpenGl_StateCounter;
 class OpenGl_TriangleSet;
 class OpenGl_Workspace;
@@ -226,7 +227,27 @@ public:
   Standard_EXPORT Handle(Graphic3d_CubeMap) BackgroundCubeMap() const Standard_OVERRIDE;
 
   //! Sets environment cubemap as background.
-  Standard_EXPORT virtual void SetBackgroundCubeMap (const Handle(Graphic3d_CubeMap)& theCubeMap) Standard_OVERRIDE;
+  //! @param theCubeMap cubemap source to be set as background
+  //! @param theToUpdatePBREnv defines whether IBL maps will be generated or not (see 'GeneratePBREnvironment')
+  Standard_EXPORT virtual void SetBackgroundCubeMap (const Handle(Graphic3d_CubeMap)& theCubeMap,
+                                                     Standard_Boolean theToUpdatePBREnv = Standard_True) Standard_OVERRIDE;
+
+  //! Generates PBR specular probe and irradiance map
+  //! in order to provide environment indirect illumination in PBR shading model (Image Based Lighting).
+  //! The source of environment data is background cubemap.
+  //! If PBR is unavailable it does nothing.
+  //! If PBR is available but there is no cubemap being set to background it clears all IBL maps (see 'ClearPBREnvironment').
+  virtual void GeneratePBREnvironment() Standard_OVERRIDE { myPBREnvRequest = OpenGl_PBREnvRequest_BAKE; }
+
+  //! Fills PBR specular probe and irradiance map with white color.
+  //! So that environment indirect illumination will be constant
+  //! and will be fully controlled by ambient light sources.
+  //! If PBR is unavailable it does nothing.
+  virtual void ClearPBREnvironment() Standard_OVERRIDE { myPBREnvRequest = OpenGl_PBREnvRequest_CLEAR; }
+
+  //! Returns number of mipmap levels used in specular IBL map.
+  //! 0 if PBR environment is not created.
+  Standard_EXPORT unsigned int SpecIBLMapLevels() const;
 
   //! Returns environment texture set for the view.
   virtual Handle(Graphic3d_TextureEnv) TextureEnv() const Standard_OVERRIDE { return myTextureEnvData; }
@@ -518,10 +539,48 @@ protected: //! @name Background parameters
 
   OpenGl_Aspects*            myTextureParams;                     //!< Stores texture and its parameters for textured background
   OpenGl_Aspects*            myCubeMapParams;                     //!< Stores cubemap and its parameters for cubemap background
-  Handle(Graphic3d_CubeMap)  myBackgroundCubeMap;                 //!< Cubemap has been setted as background
-  Graphic3d_TypeOfBackground myBackgroundType;                    //!< Current typy of background
+  Handle(Graphic3d_CubeMap)  myBackgroundCubeMap;                 //!< Cubemap has been set as background
+  Graphic3d_TypeOfBackground myBackgroundType;                    //!< Current type of background
   OpenGl_BackgroundArray*    myBackgrounds[Graphic3d_TypeOfBackground_NB]; //!< Array of primitive arrays of different background types
 
+protected: //! @name methods related to PBR
+
+  //! Checks whether PBR is available.
+  Standard_EXPORT Standard_Boolean checkPBRAvailability() const;
+
+  //! Generates IBL maps used in PBR pipeline.
+  //! If background cubemap is not set clears all IBL maps.
+  Standard_EXPORT void bakePBREnvironment (const Handle(OpenGl_Context)& theCtx);
+
+  //! Fills all IBL maps with white color.
+  //! So that environment lighting is considered to be constant and is completely controls by ambient light sources.
+  Standard_EXPORT void clearPBREnvironment (const Handle(OpenGl_Context)& theCtx);
+
+  //! Process requests to generate or to clear PBR environment.
+  Standard_EXPORT void processPBREnvRequest (const Handle(OpenGl_Context)& theCtx);
+
+protected: //! @name fields and types related to PBR
+
+  //! State of PBR environment.
+  enum PBREnvironmentState
+  {
+    OpenGl_PBREnvState_NONEXISTENT,
+    OpenGl_PBREnvState_UNAVAILABLE, // indicates failed try to create PBR environment
+    OpenGl_PBREnvState_CREATED
+  };
+
+  //! Type of action which can be done with PBR environment.
+  enum PBREnvironmentRequest
+  {
+    OpenGl_PBREnvRequest_NONE,
+    OpenGl_PBREnvRequest_BAKE,
+    OpenGl_PBREnvRequest_CLEAR
+  };
+
+  Handle(OpenGl_PBREnvironment) myPBREnvironment; //!< manager of IBL maps used in PBR pipeline
+  PBREnvironmentState           myPBREnvState;    //!< state of PBR environment
+  PBREnvironmentRequest         myPBREnvRequest;  //!< type of action is requested to be done with PBR environment
+
 protected: //! @name data types related to ray-tracing
 
   //! Result of OpenGL shaders initialization.
index 98354d4..d46bc85 100644 (file)
@@ -39,6 +39,8 @@
 #include <OpenGl_Structure.hxx>
 #include <OpenGl_ArbFBO.hxx>
 
+#include "../Textures/Textures_EnvLUT.pxx"
+
 namespace
 {
   //! Format Frame Buffer format for logging messages.
@@ -344,6 +346,65 @@ void OpenGl_View::Redraw()
     }
   }
 
+  // process PBR environment
+  if (myShadingModel == Graphic3d_TOSM_PBR
+   || myShadingModel == Graphic3d_TOSM_PBR_FACET)
+  {
+    if (!myPBREnvironment.IsNull()
+      && myPBREnvironment->SizesAreDifferent (myRenderParams.PbrEnvPow2Size,
+                                              myRenderParams.PbrEnvSpecMapNbLevels))
+    {
+      myPBREnvironment->Release (aCtx.get());
+      myPBREnvironment.Nullify();
+      myPBREnvState = OpenGl_PBREnvState_NONEXISTENT;
+      myPBREnvRequest = OpenGl_PBREnvRequest_BAKE;
+      ++myLightsRevision;
+    }
+
+    if (myPBREnvState == OpenGl_PBREnvState_NONEXISTENT
+     && aCtx->HasPBR())
+    {
+      myPBREnvironment = OpenGl_PBREnvironment::Create (aCtx, myRenderParams.PbrEnvPow2Size, myRenderParams.PbrEnvSpecMapNbLevels);
+      myPBREnvState = myPBREnvironment.IsNull() ? OpenGl_PBREnvState_UNAVAILABLE : OpenGl_PBREnvState_CREATED;
+      if (myPBREnvState == OpenGl_PBREnvState_CREATED)
+      {
+        Handle(OpenGl_Texture) anEnvLUT;
+        static const TCollection_AsciiString THE_SHARED_ENV_LUT_KEY("EnvLUT");
+        if (!aCtx->GetResource (THE_SHARED_ENV_LUT_KEY, anEnvLUT))
+        {
+          Handle(Graphic3d_TextureParams) aParams = new Graphic3d_TextureParams();
+          aParams->SetFilter (Graphic3d_TOTF_BILINEAR);
+          aParams->SetRepeat (Standard_False);
+          aParams->SetTextureUnit (aCtx->PBREnvLUTTexUnit());
+          anEnvLUT = new OpenGl_Texture(THE_SHARED_ENV_LUT_KEY, aParams);
+          Handle(Image_PixMap) aPixMap = new Image_PixMap();
+          aPixMap->InitWrapper (Image_Format_RGF, (Standard_Byte*)Textures_EnvLUT, Textures_EnvLUTSize, Textures_EnvLUTSize);
+          OpenGl_TextureFormat aTexFormat = OpenGl_TextureFormat::FindFormat (aCtx, aPixMap->Format(), false);
+        #if defined(GL_ES_VERSION_2_0)
+          // GL_RG32F is not texture-filterable format on OpenGL ES without OES_texture_float_linear extension.
+          // GL_RG16F is texture-filterable since OpenGL ES 3.0 and can be initialized from 32-bit floats.
+          // Note that it is expected that GL_RG16F has enough precision for this table, so that it can be used also on desktop OpenGL.
+          //if (!aCtx->hasTexFloatLinear)
+          aTexFormat.SetInternalFormat (GL_RG16F);
+        #endif
+          if (!aTexFormat.IsValid()
+           || !anEnvLUT->Init (aCtx, aTexFormat, Graphic3d_Vec2i((Standard_Integer)Textures_EnvLUTSize), Graphic3d_TOT_2D, aPixMap.get()))
+          {
+            aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, "Failed allocation of LUT for PBR");
+            anEnvLUT.Nullify();
+          }
+          aCtx->ShareResource (THE_SHARED_ENV_LUT_KEY, anEnvLUT);
+        }
+        if (!anEnvLUT.IsNull())
+        {
+          anEnvLUT->Bind (aCtx);
+        }
+        myWorkspace->ApplyAspects();
+      }
+    }
+    processPBREnvRequest (aCtx);
+  }
+
   // create color and coverage accumulation buffers required for OIT algorithm
   if (toUseOit)
   {
@@ -938,7 +999,7 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection,
    || aLightsRevision != myLightsRevision)
   {
     myLightsRevision = aLightsRevision;
-    aManager->UpdateLightSourceStateTo (aLights);
+    aManager->UpdateLightSourceStateTo (aLights, SpecIBLMapLevels());
     myLastLightSourceState = StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index());
   }
 
@@ -1020,7 +1081,7 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection,
   }
 #endif
 
-  aManager->SetShadingModel (myShadingModel);
+  aManager->SetShadingModel (OpenGl_ShaderManager::PBRShadingModelFallback (myShadingModel, checkPBRAvailability()));
 
   // Redraw 3d scene
   if (theProjection == Graphic3d_Camera::Projection_MonoLeftEye)
@@ -1848,3 +1909,64 @@ bool OpenGl_View::chooseOitColorConfiguration (const Handle(OpenGl_Context)& the
   }
   return false; // color combination does not exist
 }
+
+// =======================================================================
+// function : checkPBRAvailability
+// purpose  :
+// =======================================================================
+Standard_Boolean OpenGl_View::checkPBRAvailability() const
+{
+  return myWorkspace->GetGlContext()->HasPBR()
+      && !myPBREnvironment.IsNull();
+}
+
+// =======================================================================
+// function : bakePBREnvironment
+// purpose  :
+// =======================================================================
+void OpenGl_View::bakePBREnvironment (const Handle(OpenGl_Context)& theCtx)
+{
+  const Handle(OpenGl_TextureSet)& aTextureSet = myCubeMapParams->TextureSet (theCtx);
+  if (!aTextureSet.IsNull()
+   && !aTextureSet->IsEmpty())
+  {
+    myPBREnvironment->Bake (theCtx,
+                            aTextureSet->First(),
+                            myBackgroundCubeMap->ZIsInverted(),
+                            myBackgroundCubeMap->IsTopDown(),
+                            myRenderParams.PbrEnvBakingDiffNbSamples,
+                            myRenderParams.PbrEnvBakingSpecNbSamples,
+                            myRenderParams.PbrEnvBakingProbability);
+  }
+  else
+  {
+    myPBREnvironment->Clear (theCtx);
+  }
+}
+
+// =======================================================================
+// function : clearPBREnvironment
+// purpose  :
+// =======================================================================
+void OpenGl_View::clearPBREnvironment (const Handle(OpenGl_Context)& theCtx)
+{
+  myPBREnvironment->Clear (theCtx);
+}
+
+// =======================================================================
+// function : clearPBREnvironment
+// purpose  :
+// =======================================================================
+void OpenGl_View::processPBREnvRequest (const Handle(OpenGl_Context)& theCtx)
+{
+  if (myPBREnvState == OpenGl_PBREnvState_CREATED)
+  {
+    switch (myPBREnvRequest)
+    {
+      case OpenGl_PBREnvRequest_NONE:  return;
+      case OpenGl_PBREnvRequest_BAKE:  bakePBREnvironment  (theCtx); break;
+      case OpenGl_PBREnvRequest_CLEAR: clearPBREnvironment (theCtx); break;
+    }
+  }
+  myPBREnvRequest = OpenGl_PBREnvRequest_NONE;
+}
index edfe12b..22f1449 100644 (file)
@@ -58,36 +58,42 @@ void OpenGl_Material::Init (const OpenGl_Context& theCtx,
                             const Graphic3d_MaterialAspect& theMat,
                             const Quantity_Color& theInteriorColor)
 {
-  ChangeShine()        = 128.0f * theMat.Shininess();
-  ChangeTransparency() = theMat.Alpha();
+  Common.ChangeShine()        = 128.0f * theMat.Shininess();
+  Common.ChangeTransparency() = theMat.Alpha();
+
+  Pbr.ChangeMetallic()  = theMat.PBRMaterial().Metallic();
+  Pbr.ChangeRoughness() = theMat.PBRMaterial().NormalizedRoughness();
+  Pbr.EmissionIOR = Graphic3d_Vec4 (theMat.PBRMaterial().Emission(), theMat.PBRMaterial().IOR());
 
   const OpenGl_Vec3& aSrcAmb = theMat.AmbientColor();
   const OpenGl_Vec3& aSrcDif = theMat.DiffuseColor();
   const OpenGl_Vec3& aSrcSpe = theMat.SpecularColor();
   const OpenGl_Vec3& aSrcEms = theMat.EmissiveColor();
-  Specular.SetValues (aSrcSpe, 1.0f); // interior color is ignored for Specular
+  Common.Specular.SetValues (aSrcSpe, 1.0f); // interior color is ignored for Specular
   switch (theMat.MaterialType())
   {
     case Graphic3d_MATERIAL_ASPECT:
     {
-      Ambient .SetValues (aSrcAmb * theInteriorColor, 1.0f);
-      Diffuse .SetValues (aSrcDif * theInteriorColor, 1.0f);
-      Emission.SetValues (aSrcEms * theInteriorColor, 1.0f);
+      Common.Ambient .SetValues (aSrcAmb * theInteriorColor, 1.0f);
+      Common.Diffuse .SetValues (aSrcDif * theInteriorColor, 1.0f);
+      Common.Emission.SetValues (aSrcEms * theInteriorColor, 1.0f);
+      Pbr  .BaseColor.SetValues (theInteriorColor, theMat.Alpha());
       break;
     }
     case Graphic3d_MATERIAL_PHYSIC:
     {
-      Ambient .SetValues (aSrcAmb, 1.0f);
-      Diffuse .SetValues (aSrcDif, 1.0f);
-      Emission.SetValues (aSrcEms, 1.0f);
+      Common.Ambient .SetValues (aSrcAmb, 1.0f);
+      Common.Diffuse .SetValues (aSrcDif, 1.0f);
+      Common.Emission.SetValues (aSrcEms, 1.0f);
+      Pbr.BaseColor = theMat.PBRMaterial().Color();
       break;
     }
   }
 
-  Ambient  = theCtx.Vec4FromQuantityColor (Ambient);
-  Diffuse  = theCtx.Vec4FromQuantityColor (Diffuse);
-  Specular = theCtx.Vec4FromQuantityColor (Specular);
-  Emission = theCtx.Vec4FromQuantityColor (Emission);
+  Common.Ambient  = theCtx.Vec4FromQuantityColor (Common.Ambient);
+  Common.Diffuse  = theCtx.Vec4FromQuantityColor (Common.Diffuse);
+  Common.Specular = theCtx.Vec4FromQuantityColor (Common.Specular);
+  Common.Emission = theCtx.Vec4FromQuantityColor (Common.Emission);
 }
 
 // =======================================================================
@@ -310,6 +316,14 @@ const OpenGl_Aspects* OpenGl_Workspace::ApplyAspects()
     myGlContext->BindTextures (myEnvironmentTexture);
   }
 
+  if ((myView->myShadingModel == Graphic3d_TOSM_PBR
+    || myView->myShadingModel == Graphic3d_TOSM_PBR_FACET)
+   && !myView->myPBREnvironment.IsNull()
+   &&  myView->myPBREnvironment->IsNeededToBeBound())
+  {
+    myView->myPBREnvironment->Bind (myGlContext);
+  }
+
   myAspectsApplied = myAspectsSet->Aspect();
   return myAspectsSet;
 }
index d0c4f1e..53a45bc 100644 (file)
@@ -21,6 +21,8 @@
   #define occTexture1D   texture
   #define occTexture2D   texture
   #define occTexture3D   texture
+  #define occTextureCube texture
+  #define occTextureCubeLod textureLod
 #else
   #define THE_ATTRIBUTE  attribute
   #define THE_SHADER_IN  varying
   #define occTexture1D   texture1D
   #define occTexture2D   texture2D
   #define occTexture3D   texture3D
+  #define occTextureCube textureCube
+  #define occTextureCubeLod textureCubeLod
 #endif
 
 #ifdef GL_ES
-  #define THE_PREC_ENUM lowp // enumerations should fit into lowp range
+#if (__VERSION__ >= 300)
+  #define THE_PREC_ENUM highp // lowp should be enough for enums but triggers driver bugs
+#else
+  #define THE_PREC_ENUM lowp
+#endif
 #else
   #define THE_PREC_ENUM
 #endif
   void occSetFragColor (in vec4 theColor);
 #endif
 
+// Pi number definitions
+#define PI       3.141592654
+#define PI_2     6.283185307
+#define PI_DIV_2 1.570796327
+#define PI_DIV_3 1.047197551
+#define PI_DIV_4 0.785398163
+#define INV_PI   0.318309886
+#define INV_PI_2 0.159154943
+
 // Matrix state
 uniform mat4 occWorldViewMatrix;  //!< World-view  matrix
 uniform mat4 occProjectionMatrix; //!< Projection  matrix
@@ -102,6 +119,15 @@ uniform mat4 occWorldViewMatrixInverseTranspose;  //!< Transpose of the inverse
 uniform mat4 occProjectionMatrixInverseTranspose; //!< Transpose of the inverse of the projection  matrix
 uniform mat4 occModelWorldMatrixInverseTranspose; //!< Transpose of the inverse of the model-world matrix
 
+#if defined(THE_IS_PBR)
+uniform sampler2D   occEnvLUT;             //!< Environment Lookup Table
+uniform sampler2D   occDiffIBLMapSHCoeffs; //!< Packed diffuse (irradiance) IBL map's spherical harmonics coefficients
+uniform samplerCube occSpecIBLMap;         //!< Specular IBL map
+uniform int         occNbSpecIBLLevels;    //!< Number of mipmap levels used in occSpecIBLMap to store different roughness values maps
+
+vec3 occDiffIBLMap (in vec3 theNormal); //!< Unpacks spherical harmonics coefficients to diffuse IBL map's values
+#endif
+
 // light type enumeration (same as Graphic3d_TypeOfLightSource)
 const int OccLightType_Direct = 1; //!< directional     light source
 const int OccLightType_Point  = 2; //!< isotropic point light source
@@ -116,7 +142,7 @@ uniform THE_PREC_ENUM int  occLightSourcesCount; //!< Total number of light sour
 #define occLight_Type(theId)              occLightSourcesTypes[theId].x
 
 //! Is light a headlight, int?
-#define occLight_IsHeadlight(theId)       occLightSourcesTypes[theId].y
+#define occLight_IsHeadlight(theId)       (occLightSourcesTypes[theId].y != 0)
 
 //! Specular intensity (equals to diffuse), vec4.
 #define occLight_Specular(theId)          occLightSources[theId * 4 + 0]
@@ -133,6 +159,11 @@ uniform THE_PREC_ENUM int  occLightSourcesCount; //!< Total number of light sour
 //! Attenuation of the spot light intensity (from 0 to 1), float.
 #define occLight_SpotExponent(theId)      occLightSources[theId * 4 + 3].w
 
+#if defined(THE_IS_PBR)
+//! Intensity of light source (>= 0), float.
+#define occLight_Intensity(theId)         occLightSources[theId * 4 + 0].a
+#else
+
 //! Diffuse intensity (equals to Specular), vec4.
 #define occLight_Diffuse(theId)           occLightSources[theId * 4 + 0]
 
@@ -142,22 +173,44 @@ uniform THE_PREC_ENUM int  occLightSourcesCount; //!< Total number of light sour
 //! Linear attenuation factor of positional light source, float.
 #define occLight_LinearAttenuation(theId) occLightSources[theId * 4 + 3].y
 #endif
+#endif
+
+// Converts roughness value from range [0, 1] to real value for calculations
+float occRoughness (in float theNormalizedRoughness);
 
 // Front material properties accessors
-vec4  occFrontMaterial_Emission(void);     //!< Emission color
-vec4  occFrontMaterial_Ambient(void);      //!< Ambient  reflection
-vec4  occFrontMaterial_Diffuse(void);      //!< Diffuse  reflection
-vec4  occFrontMaterial_Specular(void);     //!< Specular reflection
-float occFrontMaterial_Shininess(void);    //!< Specular exponent
-float occFrontMaterial_Transparency(void); //!< Transparency coefficient
+#if !defined(THE_IS_PBR)
+vec4  occFrontMaterial_Emission(void);            //!< Emission color
+vec4  occFrontMaterial_Ambient(void);             //!< Ambient  reflection
+vec4  occFrontMaterial_Diffuse(void);             //!< Diffuse  reflection
+vec4  occFrontMaterial_Specular(void);            //!< Specular reflection
+float occFrontMaterial_Shininess(void);           //!< Specular exponent
+float occFrontMaterial_Transparency(void);        //!< Transparency coefficient
+#else
+vec4  occPBRFrontMaterial_Color(void);               //!< Base color of PBR material
+float occPBRFrontMaterial_Metallic(void);            //!< Metallic coefficient
+float occPBRFrontMaterial_Roughness(void);           //!< Roughness coefficient
+float occPBRFrontMaterial_NormalizedRoughness(void); //!< Normalized roughness coefficient
+vec3  occPBRFrontMaterial_Emission(void);            //!< Light intensity emitted by material
+float occPBRFrontMaterial_IOR(void);                 //!< Index of refraction
+#endif
 
 // Back material properties accessors
-vec4  occBackMaterial_Emission(void);      //!< Emission color
-vec4  occBackMaterial_Ambient(void);       //!< Ambient  reflection
-vec4  occBackMaterial_Diffuse(void);       //!< Diffuse  reflection
-vec4  occBackMaterial_Specular(void);      //!< Specular reflection
-float occBackMaterial_Shininess(void);     //!< Specular exponent
-float occBackMaterial_Transparency(void);  //!< Transparency coefficient
+#if !defined(THE_IS_PBR)
+vec4  occBackMaterial_Emission(void);            //!< Emission color
+vec4  occBackMaterial_Ambient(void);             //!< Ambient  reflection
+vec4  occBackMaterial_Diffuse(void);             //!< Diffuse  reflection
+vec4  occBackMaterial_Specular(void);            //!< Specular reflection
+float occBackMaterial_Shininess(void);           //!< Specular exponent
+float occBackMaterial_Transparency(void);        //!< Transparency coefficient
+#else
+vec4  occPBRBackMaterial_Color(void);               //!< Base color of PBR material
+float occPBRBackMaterial_Metallic(void);            //!< Metallic coefficient
+float occPBRBackMaterial_Roughness(void);           //!< Roughness coefficient
+float occPBRBackMaterial_NormalizedRoughness(void); //!< Normalized roughness coefficient
+vec3  occPBRBackMaterial_Emission(void);            //!< Light intensity emitted by material
+float occPBRBackMaterial_IOR(void);                 //!< Index of refraction
+#endif
 
 #ifdef THE_HAS_DEFAULT_SAMPLER
 #define occActiveSampler    occSampler0                //!< alias for backward compatibility
index 37ac72b..047c159 100644 (file)
@@ -19,15 +19,59 @@ void occSetFragColor (in vec4 theColor)
 
 #if defined(THE_MAX_LIGHTS) && (THE_MAX_LIGHTS > 0)
 // arrays of light sources
-uniform THE_PREC_ENUM ivec2 occLightSourcesTypes[THE_MAX_LIGHTS]; //!< packed light sources types
 uniform               vec4  occLightSources[THE_MAX_LIGHTS * 4];  //!< packed light sources parameters
+uniform THE_PREC_ENUM ivec2 occLightSourcesTypes[THE_MAX_LIGHTS]; //!< packed light sources types
+#endif
+
+#if defined(THE_IS_PBR)
+vec3 occDiffIBLMap (in vec3 theNormal)
+{
+  vec3 aSHCoeffs[9];
+  for (int i = 0; i < 9; ++i)
+  {
+    aSHCoeffs[i] = occTexture2D (occDiffIBLMapSHCoeffs, vec2 ((float(i) + 0.5) / 9.0, 0.0)).rgb;
+  }
+  return aSHCoeffs[0]
+
+       + aSHCoeffs[1] * theNormal.x
+          + aSHCoeffs[2] * theNormal.y
+          + aSHCoeffs[3] * theNormal.z
+
+          + aSHCoeffs[4] * theNormal.x * theNormal.z
+          + aSHCoeffs[5] * theNormal.y * theNormal.z
+          + aSHCoeffs[6] * theNormal.x * theNormal.y
+
+          + aSHCoeffs[7] * (3.0 * theNormal.z * theNormal.z - 1.0)
+          + aSHCoeffs[8] * (theNormal.x * theNormal.x - theNormal.y * theNormal.y);
+}
 #endif
 
-// material state
+// front and back material properties accessors
+#if defined(THE_IS_PBR)
+uniform vec4 occPbrFrontMaterial[3];
+uniform vec4 occPbrBackMaterial[3];
+
+#define MIN_ROUGHNESS 0.01
+// Converts roughness value from range [0, 1] to real value for calculations
+float occRoughness (in float theNormalizedRoughness) { return theNormalizedRoughness * (1.0 - MIN_ROUGHNESS) + MIN_ROUGHNESS; }
+
+vec4  occPBRFrontMaterial_Color(void)     { return occPbrFrontMaterial[0]; }
+vec3  occPBRFrontMaterial_Emission(void)  { return occPbrFrontMaterial[1].rgb; }
+float occPBRFrontMaterial_IOR(void)       { return occPbrFrontMaterial[1].w; }
+float occPBRFrontMaterial_Metallic(void)  { return occPbrFrontMaterial[2].b; }
+float occPBRFrontMaterial_Roughness(void) { return occRoughness (occPbrFrontMaterial[2].g); }
+float occPBRFrontMaterial_NormalizedRoughness(void) { return occPbrFrontMaterial[2].g; }
+
+vec4  occPBRBackMaterial_Color(void)     { return occPbrBackMaterial[0]; }
+vec3  occPBRBackMaterial_Emission(void)  { return occPbrBackMaterial[1].rgb; }
+float occPBRBackMaterial_IOR(void)       { return occPbrBackMaterial[1].w; }
+float occPBRBackMaterial_Metallic(void)  { return occPbrBackMaterial[2].b; }
+float occPBRBackMaterial_Roughness(void) { return occRoughness (occPbrBackMaterial[2].g); }
+float occPBRBackMaterial_NormalizedRoughness(void) { return occPbrBackMaterial[2].g; }
+#else
 uniform vec4 occFrontMaterial[5];
 uniform vec4 occBackMaterial[5];
 
-// front material properties accessors
 vec4  occFrontMaterial_Ambient(void)      { return occFrontMaterial[0]; }
 vec4  occFrontMaterial_Diffuse(void)      { return occFrontMaterial[1]; }
 vec4  occFrontMaterial_Specular(void)     { return occFrontMaterial[2]; }
@@ -35,13 +79,13 @@ vec4  occFrontMaterial_Emission(void)     { return occFrontMaterial[3]; }
 float occFrontMaterial_Shininess(void)    { return occFrontMaterial[4].x; }
 float occFrontMaterial_Transparency(void) { return occFrontMaterial[4].y; }
 
-// back material properties accessors
 vec4  occBackMaterial_Ambient(void)       { return occBackMaterial[0]; }
 vec4  occBackMaterial_Diffuse(void)       { return occBackMaterial[1]; }
 vec4  occBackMaterial_Specular(void)      { return occBackMaterial[2]; }
 vec4  occBackMaterial_Emission(void)      { return occBackMaterial[3]; }
 float occBackMaterial_Shininess(void)     { return occBackMaterial[4].x; }
 float occBackMaterial_Transparency(void)  { return occBackMaterial[4].y; }
+#endif
 
 // 2D texture coordinates transformation
 vec2  occTextureTrsf_Translation(void) { return occTexTrsf2d[0].xy; }
index ebccc1e..327206a 100644 (file)
@@ -1,5 +1,12 @@
 srcinc:::Declarations.glsl
 srcinc:::DeclarationsImpl.glsl
+srcinc:::PBRCookTorrance.glsl
+srcinc:::PBRDistribution.glsl
+srcinc:::PBREnvBaking.fs
+srcinc:::PBREnvBaking.vs
+srcinc:::PBRFresnel.glsl
+srcinc:::PBRGeometry.glsl
+srcinc:::PBRIllumination.glsl
 srcinc:::PhongShading.fs
 srcinc:::PhongShading.vs
 srcinc:::Display.fs
@@ -11,6 +18,13 @@ srcinc:::RaytraceSmooth.fs
 Shaders_Declarations_glsl.pxx
 Shaders_DeclarationsImpl_glsl.pxx
 Shaders_Display_fs.pxx
+Shaders_PBRCookTorrance_glsl.pxx
+Shaders_PBRDistribution_glsl.pxx
+Shaders_PBREnvBaking_fs.pxx
+Shaders_PBREnvBaking_vs.pxx
+Shaders_PBRFresnel_glsl.pxx
+Shaders_PBRGeometry_glsl.pxx
+Shaders_PBRIllumination_glsl.pxx
 Shaders_RaytraceBase_fs.pxx
 Shaders_RaytraceRender_fs.pxx
 Shaders_PathtraceBase_fs.pxx
diff --git a/src/Shaders/PBRCookTorrance.glsl b/src/Shaders/PBRCookTorrance.glsl
new file mode 100644 (file)
index 0000000..3d86363
--- /dev/null
@@ -0,0 +1,20 @@
+//! Calculates Cook-Torrance BRDF.
+vec3 occPBRCookTorrance (in vec3  theView,
+                         in vec3  theLight,
+                         in vec3  theNormal,
+                         in vec3  theBaseColor,
+                         in float theMetallic,
+                         in float theRoughness,
+                         in float theIOR)
+{
+  vec3 aHalf = normalize (theView + theLight);
+  float aCosV = max(dot(theView, theNormal), 0.0);
+  float aCosL = max(dot(theLight, theNormal), 0.0);
+  float aCosH = max(dot(aHalf, theNormal), 0.0);
+  float aCosVH = max(dot(aHalf, theView), 0.0);
+  vec3 aCookTorrance = occPBRDistribution (aCosH, theRoughness)
+                     * occPBRGeometry     (aCosV, aCosL, theRoughness)
+                     * occPBRFresnel      (theBaseColor, theMetallic, theIOR, aCosVH);
+  aCookTorrance /= 4.0;
+  return aCookTorrance;
+}
diff --git a/src/Shaders/PBRDistribution.glsl b/src/Shaders/PBRDistribution.glsl
new file mode 100644 (file)
index 0000000..dc5a64e
--- /dev/null
@@ -0,0 +1,9 @@
+//! Calculates micro facet normals distribution.
+float occPBRDistribution (in float theCosH,
+                          in float theRoughness)
+{
+  float aDistribution = theRoughness * theRoughness;
+  aDistribution = aDistribution / (theCosH * theCosH * (aDistribution * aDistribution - 1.0) + 1.0);
+  aDistribution = INV_PI * aDistribution * aDistribution;
+  return aDistribution;
+}
diff --git a/src/Shaders/PBREnvBaking.fs b/src/Shaders/PBREnvBaking.fs
new file mode 100644 (file)
index 0000000..e795c46
--- /dev/null
@@ -0,0 +1,162 @@
+THE_SHADER_IN vec3 ViewDirection; //!< direction of fetching from environment cubemap
+
+uniform int uSamplesNum;     //!< number of samples in Monte-Carlo integration
+uniform int uCurrentLevel;   //!< current level of specular IBL map (ignored in case of diffuse map's processing)
+uniform int uEnvMapSize;     //!< one edge's size of source environtment map's zero mipmap level
+uniform int uYCoeff;         //!< coefficient of Y controlling horizontal flip of cubemap
+uniform int uZCoeff;         //!< coefficient of Z controlling vertical flip of cubemap
+uniform samplerCube uEnvMap; //!< source of baking (environment cubemap)
+
+//! Returns coordinates of point theNumber from Hammersley point set having size theSize.
+vec2 hammersley (in int theNumber,
+                 in int theSize)
+{
+  int aDenominator = 2;
+  int aNumber = theNumber;
+  float aVanDerCorput = 0.0;
+  for (int i = 0; i < 32; ++i)
+  {
+    if (aNumber > 0)
+    {
+      aVanDerCorput += float(aNumber % 2) / float(aDenominator);
+      aNumber /= 2;
+      aDenominator *= 2;
+    }
+  }
+  return vec2(float(theNumber) / float(theSize), aVanDerCorput);
+}
+
+//! This function does importance sampling on hemisphere surface using GGX normal distribution function
+//! in tangent space (positive z axis is surface normal direction).
+vec3 importanceSample (in vec2  theHammersleyPoint,
+                       in float theRoughness)
+{
+  float aPhi = PI_2 * theHammersleyPoint.x;
+  theRoughness *= theRoughness;
+  theRoughness *= theRoughness;
+  float aCosTheta = sqrt((1.0 - theHammersleyPoint.y) / (1.0 + (theRoughness - 1.0) * theHammersleyPoint.y));
+  float aSinTheta = sqrt(1.0 - aCosTheta * aCosTheta);
+  return vec3(aSinTheta * cos(aPhi),
+              aSinTheta * sin(aPhi),
+              aCosTheta);
+}
+
+//! This function uniformly generates samples on whole sphere.
+vec3 sphereUniformSample (in vec2 theHammersleyPoint)
+{
+  float aPhi = PI_2 * theHammersleyPoint.x;
+  float aCosTheta = 2.0 * theHammersleyPoint.y - 1.0;
+  float aSinTheta = sqrt(1.0 - aCosTheta * aCosTheta);
+  return vec3(aSinTheta * cos(aPhi),
+              aSinTheta * sin(aPhi),
+              aCosTheta);
+}
+
+//! Transforms resulted sampled direction from tangent space to world space considering the surface normal.
+vec3 fromTangentSpace (in vec3 theVector,
+                       in vec3 theNormal)
+{
+  vec3 anUp = (abs(theNormal.z) < 0.999) ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
+  vec3 anX = normalize(cross(anUp, theNormal));
+  vec3 anY = cross(theNormal, anX);
+  return anX * theVector.x + anY * theVector.y + theNormal * theVector.z;
+}
+
+const float aSHBasisFuncCoeffs[9] = float[9]
+(
+  0.282095 * 0.282095,
+  0.488603 * 0.488603,
+  0.488603 * 0.488603,
+  0.488603 * 0.488603,
+  1.092548 * 1.092548,
+  1.092548 * 1.092548,
+  1.092548 * 1.092548,
+  0.315392 * 0.315392,
+  0.546274 * 0.546274
+);
+
+const float aSHCosCoeffs[9] = float[9]
+(
+  3.141593,
+  2.094395,
+  2.094395,
+  2.094395,
+  0.785398,
+  0.785398,
+  0.785398,
+  0.785398,
+  0.785398
+);
+
+//! Bakes diffuse IBL map's spherical harmonics coefficients.
+vec3 bakeDiffuseSH()
+{
+  int anIndex = int(gl_FragCoord.x);
+  vec3 aResult = vec3 (0.0);
+  for (int aSampleIter = 0; aSampleIter < uSamplesNum; ++aSampleIter)
+  {
+    vec2 aHammersleyPoint = hammersley (aSampleIter, uSamplesNum);
+    vec3 aDirection = sphereUniformSample (aHammersleyPoint);
+
+    vec3 aValue = occTextureCube (uEnvMap, cubemapVectorTransform (aDirection, uYCoeff, uZCoeff)).rgb;
+
+    float aBasisFunc[9];
+    aBasisFunc[0] = 1.0;
+
+    aBasisFunc[1] = aDirection.x;
+    aBasisFunc[2] = aDirection.y;
+    aBasisFunc[3] = aDirection.z;
+
+    aBasisFunc[4] = aDirection.x * aDirection.z;
+    aBasisFunc[5] = aDirection.y * aDirection.z;
+    aBasisFunc[6] = aDirection.x * aDirection.y;
+
+    aBasisFunc[7] = 3.0 * aDirection.z * aDirection.z - 1.0;
+    aBasisFunc[8] = aDirection.x * aDirection.x - aDirection.y * aDirection.y;
+
+    aResult += aValue * aBasisFunc[anIndex];
+  }
+
+  aResult *= 4.0 * aSHCosCoeffs[anIndex] * aSHBasisFuncCoeffs[anIndex] / float(uSamplesNum);
+  return aResult;
+}
+
+//! Bakes specular IBL map.
+vec3 bakeSpecularMap (in vec3  theNormal,
+                      in float theRoughness)
+{
+  vec3 aResult = vec3(0.0);
+  float aWeightSum = 0.0;
+  int aSamplesNum = (theRoughness == 0.0) ? 1 : uSamplesNum;
+  float aSolidAngleSource = 4.0 * PI / (6.0 * float(uEnvMapSize * uEnvMapSize));
+  for (int aSampleIter = 0; aSampleIter < aSamplesNum; ++aSampleIter)
+  {
+    vec2 aHammersleyPoint = hammersley (aSampleIter, aSamplesNum);
+    vec3 aHalf = importanceSample (aHammersleyPoint, occRoughness (theRoughness));
+    float aHdotV = aHalf.z;
+    aHalf = fromTangentSpace (aHalf, theNormal);
+    vec3  aLight = -reflect (theNormal, aHalf);
+    float aNdotL = dot (aLight, theNormal);
+    if (aNdotL > 0.0)
+    {
+      float aSolidAngleSample = 1.0 / (float(aSamplesNum) * (occPBRDistribution (aHdotV, theRoughness) * 0.25 + 0.0001) + 0.0001);
+      float aLod = (theRoughness == 0.0) ? 0.0 : 0.5 * log2 (aSolidAngleSample / aSolidAngleSource);
+      aResult += occTextureCubeLod (uEnvMap, aLight, aLod).rgb * aNdotL;
+      aWeightSum += aNdotL;
+    }
+  }
+  return aResult / aWeightSum;
+}
+
+void main()
+{
+  vec3 aViewDirection = normalize (ViewDirection);
+  if (occNbSpecIBLLevels == 0)
+  {
+    occSetFragColor (vec4 (bakeDiffuseSH (), 1.0));
+  }
+  else
+  {
+    occSetFragColor (vec4 (bakeSpecularMap (aViewDirection, float(uCurrentLevel) / float(occNbSpecIBLLevels - 1)), 1.0));
+  }
+}
diff --git a/src/Shaders/PBREnvBaking.vs b/src/Shaders/PBREnvBaking.vs
new file mode 100644 (file)
index 0000000..d9339ae
--- /dev/null
@@ -0,0 +1,35 @@
+THE_SHADER_OUT vec3 ViewDirection; //!< direction of fetching from environment cubemap
+
+uniform int uCurrentSide; //!< current side of cubemap
+uniform int uYCoeff;      //!< coefficient of Y controlling horizontal flip of cubemap
+uniform int uZCoeff;      //!< coefficient of Z controlling vertical flip of cubemap
+
+const mat2 cubemapDirectionMatrices[6] = mat2[]
+(
+  mat2 ( 0, -1, -1,  0),
+  mat2 ( 0,  1, -1,  0),
+  mat2 ( 0,  1,  1,  0),
+  mat2 ( 0,  1, -1,  0),
+  mat2 ( 1,  0,  0, -1),
+  mat2 (-1,  0,  0, -1)
+);
+
+//! Generates environment map fetching direction considering current index of side.
+vec3 cubemapBakingViewDirection (in int theSide,
+                                 in vec2 theScreenCoord)
+{
+  int anAxis = theSide / 2;
+  vec3 aDirection = vec3(0.0);
+  aDirection[anAxis] = float(-(int(theSide) % 2) * 2 + 1);
+  theScreenCoord = cubemapDirectionMatrices[theSide] * theScreenCoord;
+  aDirection[(anAxis + 1) % 3] = theScreenCoord.x;
+  aDirection[(anAxis + 2) % 3] = theScreenCoord.y;
+  return aDirection;
+}
+
+void main()
+{
+  ViewDirection = cubemapBakingViewDirection (uCurrentSide, occVertex.xy);
+  ViewDirection = cubemapVectorTransform (ViewDirection, uYCoeff, uZCoeff);
+  gl_Position = vec4 (occVertex.xy, 0.0, 1.0);
+}
diff --git a/src/Shaders/PBRFresnel.glsl b/src/Shaders/PBRFresnel.glsl
new file mode 100644 (file)
index 0000000..53c3d70
--- /dev/null
@@ -0,0 +1,36 @@
+//! Functions to calculate fresnel coefficient and approximate zero fresnel value.
+vec3 occPBRFresnel (in vec3  theBaseColor,
+                    in float theMetallic,
+                    in float theIOR)
+{
+  theIOR = (1.0 - theIOR) / (1.0 + theIOR);
+  theIOR *= theIOR;
+  vec3 f0 = vec3(theIOR);
+  f0 = mix (f0, theBaseColor.rgb, theMetallic);
+  return f0;
+}
+
+vec3 occPBRFresnel (in vec3  theBaseColor,
+                    in float theMetallic,
+                    in float theIOR,
+                    in float theCosVH)
+{
+  vec3 f0 = occPBRFresnel (theBaseColor, theMetallic, theIOR);
+  theCosVH = 1.0 - theCosVH;
+  theCosVH *= theCosVH;
+  theCosVH *= theCosVH * theCosVH * theCosVH * theCosVH;
+  return f0 + (vec3 (1.0) - f0) * theCosVH;
+}
+
+vec3 occPBRFresnel (in vec3  theBaseColor,
+                    in float theMetallic,
+                    in float theRoughness,
+                    in float theIOR,
+                    in float theCosV)
+{
+  vec3 f0 = occPBRFresnel (theBaseColor, theMetallic, theIOR);
+  theCosV = 1.0 - theCosV;
+  theCosV *= theCosV;
+  theCosV *= theCosV * theCosV * theCosV * theCosV;
+  return f0 + (max(vec3(1.0 - theRoughness), f0) - f0) * theCosV;
+}
diff --git a/src/Shaders/PBRGeometry.glsl b/src/Shaders/PBRGeometry.glsl
new file mode 100644 (file)
index 0000000..18987e7
--- /dev/null
@@ -0,0 +1,13 @@
+//! Calculates geometry factor for Cook-Torrance BRDF.
+float occPBRGeometry (in float theCosV,
+                      in float theCosL,
+                      in float theRoughness)
+{
+  float k = theRoughness + 1.0;
+  k *= 0.125 * k;
+  float g1 = 1.0;
+  g1 /= theCosV * (1.0 - k) + k;
+  float g2 = 1.0;
+  g2 /= theCosL * (1.0 - k) + k;
+  return g1 * g2;
+}
diff --git a/src/Shaders/PBRIllumination.glsl b/src/Shaders/PBRIllumination.glsl
new file mode 100644 (file)
index 0000000..9ccbfc9
--- /dev/null
@@ -0,0 +1,28 @@
+//! Calculates direct illumination using Cook-Torrance BRDF.
+vec3 occPBRIllumination (in vec3  theView,
+                         in vec3  theLight,
+                         in vec3  theNormal,
+                         in vec4  theBaseColor,
+                         in float theMetallic,
+                         in float theRoughness,
+                         in float theIOR,
+                         in vec3  theLightColor,
+                         in float theLightIntensity)
+{
+  vec3 aHalf = normalize (theView + theLight);
+  float aCosVH = max(dot(theView, aHalf), 0.0);
+  vec3 aFresnel = occPBRFresnel (theBaseColor.rgb, theMetallic, theIOR, aCosVH);
+  vec3 aSpecular = occPBRCookTorrance (theView,
+                                       theLight,
+                                       theNormal,
+                                       theBaseColor.rgb,
+                                       theMetallic,
+                                       theRoughness,
+                                       theIOR);
+  vec3 aDiffuse = vec3(1.0) - aFresnel;
+  aDiffuse *= 1.0 - theMetallic;
+  aDiffuse *= INV_PI;
+  aDiffuse *= theBaseColor.rgb;
+  aDiffuse = mix (vec3(0.0), aDiffuse, theBaseColor.a);
+  return (aDiffuse + aSpecular) * theLightColor * theLightIntensity * max(0.0, dot(theLight, theNormal));
+}
index d102812..1e52cbe 100755 (executable)
@@ -29,7 +29,7 @@ void pointLight (in int  theId,
                  in vec3 thePoint)
 {
   vec3 aLight = occLight_Position (theId).xyz;
-  if (occLight_IsHeadlight (theId) == 0)
+  if (!occLight_IsHeadlight (theId))
   {
     aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 1.0));
   }
index 71a6b03..3b31ea9 100644 (file)
@@ -22,15 +22,59 @@ static const char Shaders_DeclarationsImpl_glsl[] =
   "\n"
   "#if defined(THE_MAX_LIGHTS) && (THE_MAX_LIGHTS > 0)\n"
   "// arrays of light sources\n"
-  "uniform THE_PREC_ENUM ivec2 occLightSourcesTypes[THE_MAX_LIGHTS]; //!< packed light sources types\n"
   "uniform               vec4  occLightSources[THE_MAX_LIGHTS * 4];  //!< packed light sources parameters\n"
+  "uniform THE_PREC_ENUM ivec2 occLightSourcesTypes[THE_MAX_LIGHTS]; //!< packed light sources types\n"
+  "#endif\n"
+  "\n"
+  "#if defined(THE_IS_PBR)\n"
+  "vec3 occDiffIBLMap (in vec3 theNormal)\n"
+  "{\n"
+  "  vec3 aSHCoeffs[9];\n"
+  "  for (int i = 0; i < 9; ++i)\n"
+  "  {\n"
+  "    aSHCoeffs[i] = occTexture2D (occDiffIBLMapSHCoeffs, vec2 ((float(i) + 0.5) / 9.0, 0.0)).rgb;\n"
+  "  }\n"
+  "  return aSHCoeffs[0]\n"
+  "\n"
+  "       + aSHCoeffs[1] * theNormal.x\n"
+  "       + aSHCoeffs[2] * theNormal.y\n"
+  "       + aSHCoeffs[3] * theNormal.z\n"
+  "\n"
+  "       + aSHCoeffs[4] * theNormal.x * theNormal.z\n"
+  "       + aSHCoeffs[5] * theNormal.y * theNormal.z\n"
+  "       + aSHCoeffs[6] * theNormal.x * theNormal.y\n"
+  "\n"
+  "       + aSHCoeffs[7] * (3.0 * theNormal.z * theNormal.z - 1.0)\n"
+  "       + aSHCoeffs[8] * (theNormal.x * theNormal.x - theNormal.y * theNormal.y);\n"
+  "}\n"
   "#endif\n"
   "\n"
-  "// material state\n"
+  "// front and back material properties accessors\n"
+  "#if defined(THE_IS_PBR)\n"
+  "uniform vec4 occPbrFrontMaterial[3];\n"
+  "uniform vec4 occPbrBackMaterial[3];\n"
+  "\n"
+  "#define MIN_ROUGHNESS 0.01\n"
+  "// Converts roughness value from range [0, 1] to real value for calculations\n"
+  "float occRoughness (in float theNormalizedRoughness) { return theNormalizedRoughness * (1.0 - MIN_ROUGHNESS) + MIN_ROUGHNESS; }\n"
+  "\n"
+  "vec4  occPBRFrontMaterial_Color(void)     { return occPbrFrontMaterial[0]; }\n"
+  "vec3  occPBRFrontMaterial_Emission(void)  { return occPbrFrontMaterial[1].rgb; }\n"
+  "float occPBRFrontMaterial_IOR(void)       { return occPbrFrontMaterial[1].w; }\n"
+  "float occPBRFrontMaterial_Metallic(void)  { return occPbrFrontMaterial[2].b; }\n"
+  "float occPBRFrontMaterial_Roughness(void) { return occRoughness (occPbrFrontMaterial[2].g); }\n"
+  "float occPBRFrontMaterial_NormalizedRoughness(void) { return occPbrFrontMaterial[2].g; }\n"
+  "\n"
+  "vec4  occPBRBackMaterial_Color(void)     { return occPbrBackMaterial[0]; }\n"
+  "vec3  occPBRBackMaterial_Emission(void)  { return occPbrBackMaterial[1].rgb; }\n"
+  "float occPBRBackMaterial_IOR(void)       { return occPbrBackMaterial[1].w; }\n"
+  "float occPBRBackMaterial_Metallic(void)  { return occPbrBackMaterial[2].b; }\n"
+  "float occPBRBackMaterial_Roughness(void) { return occRoughness (occPbrBackMaterial[2].g); }\n"
+  "float occPBRBackMaterial_NormalizedRoughness(void) { return occPbrBackMaterial[2].g; }\n"
+  "#else\n"
   "uniform vec4 occFrontMaterial[5];\n"
   "uniform vec4 occBackMaterial[5];\n"
   "\n"
-  "// front material properties accessors\n"
   "vec4  occFrontMaterial_Ambient(void)      { return occFrontMaterial[0]; }\n"
   "vec4  occFrontMaterial_Diffuse(void)      { return occFrontMaterial[1]; }\n"
   "vec4  occFrontMaterial_Specular(void)     { return occFrontMaterial[2]; }\n"
@@ -38,13 +82,13 @@ static const char Shaders_DeclarationsImpl_glsl[] =
   "float occFrontMaterial_Shininess(void)    { return occFrontMaterial[4].x; }\n"
   "float occFrontMaterial_Transparency(void) { return occFrontMaterial[4].y; }\n"
   "\n"
-  "// back material properties accessors\n"
   "vec4  occBackMaterial_Ambient(void)       { return occBackMaterial[0]; }\n"
   "vec4  occBackMaterial_Diffuse(void)       { return occBackMaterial[1]; }\n"
   "vec4  occBackMaterial_Specular(void)      { return occBackMaterial[2]; }\n"
   "vec4  occBackMaterial_Emission(void)      { return occBackMaterial[3]; }\n"
   "float occBackMaterial_Shininess(void)     { return occBackMaterial[4].x; }\n"
   "float occBackMaterial_Transparency(void)  { return occBackMaterial[4].y; }\n"
+  "#endif\n"
   "\n"
   "// 2D texture coordinates transformation\n"
   "vec2  occTextureTrsf_Translation(void) { return occTexTrsf2d[0].xy; }\n"
index 12af3c4..586183a 100644 (file)
@@ -24,6 +24,8 @@ static const char Shaders_Declarations_glsl[] =
   "  #define occTexture1D   texture\n"
   "  #define occTexture2D   texture\n"
   "  #define occTexture3D   texture\n"
+  "  #define occTextureCube texture\n"
+  "  #define occTextureCubeLod textureLod\n"
   "#else\n"
   "  #define THE_ATTRIBUTE  attribute\n"
   "  #define THE_SHADER_IN  varying\n"
@@ -32,10 +34,16 @@ static const char Shaders_Declarations_glsl[] =
   "  #define occTexture1D   texture1D\n"
   "  #define occTexture2D   texture2D\n"
   "  #define occTexture3D   texture3D\n"
+  "  #define occTextureCube textureCube\n"
+  "  #define occTextureCubeLod textureCubeLod\n"
   "#endif\n"
   "\n"
   "#ifdef GL_ES\n"
-  "  #define THE_PREC_ENUM lowp // enumerations should fit into lowp range\n"
+  "#if (__VERSION__ >= 300)\n"
+  "  #define THE_PREC_ENUM highp // lowp should be enough for enums but triggers driver bugs\n"
+  "#else\n"
+  "  #define THE_PREC_ENUM lowp\n"
+  "#endif\n"
   "#else\n"
   "  #define THE_PREC_ENUM\n"
   "#endif\n"
@@ -88,6 +96,15 @@ static const char Shaders_Declarations_glsl[] =
   "  void occSetFragColor (in vec4 theColor);\n"
   "#endif\n"
   "\n"
+  "// Pi number definitions\n"
+  "#define PI       3.141592654\n"
+  "#define PI_2     6.283185307\n"
+  "#define PI_DIV_2 1.570796327\n"
+  "#define PI_DIV_3 1.047197551\n"
+  "#define PI_DIV_4 0.785398163\n"
+  "#define INV_PI   0.318309886\n"
+  "#define INV_PI_2 0.159154943\n"
+  "\n"
   "// Matrix state\n"
   "uniform mat4 occWorldViewMatrix;  //!< World-view  matrix\n"
   "uniform mat4 occProjectionMatrix; //!< Projection  matrix\n"
@@ -105,6 +122,15 @@ static const char Shaders_Declarations_glsl[] =
   "uniform mat4 occProjectionMatrixInverseTranspose; //!< Transpose of the inverse of the projection  matrix\n"
   "uniform mat4 occModelWorldMatrixInverseTranspose; //!< Transpose of the inverse of the model-world matrix\n"
   "\n"
+  "#if defined(THE_IS_PBR)\n"
+  "uniform sampler2D   occEnvLUT;             //!< Environment Lookup Table\n"
+  "uniform sampler2D   occDiffIBLMapSHCoeffs; //!< Packed diffuse (irradiance) IBL map's spherical harmonics coefficients\n"
+  "uniform samplerCube occSpecIBLMap;         //!< Specular IBL map\n"
+  "uniform int         occNbSpecIBLLevels;    //!< Number of mipmap levels used in occSpecIBLMap to store different roughness values maps\n"
+  "\n"
+  "vec3 occDiffIBLMap (in vec3 theNormal); //!< Unpacks spherical harmonics coefficients to diffuse IBL map's values\n"
+  "#endif\n"
+  "\n"
   "// light type enumeration (same as Graphic3d_TypeOfLightSource)\n"
   "const int OccLightType_Direct = 1; //!< directional     light source\n"
   "const int OccLightType_Point  = 2; //!< isotropic point light source\n"
@@ -119,7 +145,7 @@ static const char Shaders_Declarations_glsl[] =
   "#define occLight_Type(theId)              occLightSourcesTypes[theId].x\n"
   "\n"
   "//! Is light a headlight, int?\n"
-  "#define occLight_IsHeadlight(theId)       occLightSourcesTypes[theId].y\n"
+  "#define occLight_IsHeadlight(theId)       (occLightSourcesTypes[theId].y != 0)\n"
   "\n"
   "//! Specular intensity (equals to diffuse), vec4.\n"
   "#define occLight_Specular(theId)          occLightSources[theId * 4 + 0]\n"
@@ -136,6 +162,11 @@ static const char Shaders_Declarations_glsl[] =
   "//! Attenuation of the spot light intensity (from 0 to 1), float.\n"
   "#define occLight_SpotExponent(theId)      occLightSources[theId * 4 + 3].w\n"
   "\n"
+  "#if defined(THE_IS_PBR)\n"
+  "//! Intensity of light source (>= 0), float.\n"
+  "#define occLight_Intensity(theId)         occLightSources[theId * 4 + 0].a\n"
+  "#else\n"
+  "\n"
   "//! Diffuse intensity (equals to Specular), vec4.\n"
   "#define occLight_Diffuse(theId)           occLightSources[theId * 4 + 0]\n"
   "\n"
@@ -145,22 +176,44 @@ static const char Shaders_Declarations_glsl[] =
   "//! Linear attenuation factor of positional light source, float.\n"
   "#define occLight_LinearAttenuation(theId) occLightSources[theId * 4 + 3].y\n"
   "#endif\n"
+  "#endif\n"
+  "\n"
+  "// Converts roughness value from range [0, 1] to real value for calculations\n"
+  "float occRoughness (in float theNormalizedRoughness);\n"
   "\n"
   "// Front material properties accessors\n"
-  "vec4  occFrontMaterial_Emission(void);     //!< Emission color\n"
-  "vec4  occFrontMaterial_Ambient(void);      //!< Ambient  reflection\n"
-  "vec4  occFrontMaterial_Diffuse(void);      //!< Diffuse  reflection\n"
-  "vec4  occFrontMaterial_Specular(void);     //!< Specular reflection\n"
-  "float occFrontMaterial_Shininess(void);    //!< Specular exponent\n"
-  "float occFrontMaterial_Transparency(void); //!< Transparency coefficient\n"
+  "#if !defined(THE_IS_PBR)\n"
+  "vec4  occFrontMaterial_Emission(void);            //!< Emission color\n"
+  "vec4  occFrontMaterial_Ambient(void);             //!< Ambient  reflection\n"
+  "vec4  occFrontMaterial_Diffuse(void);             //!< Diffuse  reflection\n"
+  "vec4  occFrontMaterial_Specular(void);            //!< Specular reflection\n"
+  "float occFrontMaterial_Shininess(void);           //!< Specular exponent\n"
+  "float occFrontMaterial_Transparency(void);        //!< Transparency coefficient\n"
+  "#else\n"
+  "vec4  occPBRFrontMaterial_Color(void);               //!< Base color of PBR material\n"
+  "float occPBRFrontMaterial_Metallic(void);            //!< Metallic coefficient\n"
+  "float occPBRFrontMaterial_Roughness(void);           //!< Roughness coefficient\n"
+  "float occPBRFrontMaterial_NormalizedRoughness(void); //!< Normalized roughness coefficient\n"
+  "vec3  occPBRFrontMaterial_Emission(void);            //!< Light intensity emitted by material\n"
+  "float occPBRFrontMaterial_IOR(void);                 //!< Index of refraction\n"
+  "#endif\n"
   "\n"
   "// Back material properties accessors\n"
-  "vec4  occBackMaterial_Emission(void);      //!< Emission color\n"
-  "vec4  occBackMaterial_Ambient(void);       //!< Ambient  reflection\n"
-  "vec4  occBackMaterial_Diffuse(void);       //!< Diffuse  reflection\n"
-  "vec4  occBackMaterial_Specular(void);      //!< Specular reflection\n"
-  "float occBackMaterial_Shininess(void);     //!< Specular exponent\n"
-  "float occBackMaterial_Transparency(void);  //!< Transparency coefficient\n"
+  "#if !defined(THE_IS_PBR)\n"
+  "vec4  occBackMaterial_Emission(void);            //!< Emission color\n"
+  "vec4  occBackMaterial_Ambient(void);             //!< Ambient  reflection\n"
+  "vec4  occBackMaterial_Diffuse(void);             //!< Diffuse  reflection\n"
+  "vec4  occBackMaterial_Specular(void);            //!< Specular reflection\n"
+  "float occBackMaterial_Shininess(void);           //!< Specular exponent\n"
+  "float occBackMaterial_Transparency(void);        //!< Transparency coefficient\n"
+  "#else\n"
+  "vec4  occPBRBackMaterial_Color(void);               //!< Base color of PBR material\n"
+  "float occPBRBackMaterial_Metallic(void);            //!< Metallic coefficient\n"
+  "float occPBRBackMaterial_Roughness(void);           //!< Roughness coefficient\n"
+  "float occPBRBackMaterial_NormalizedRoughness(void); //!< Normalized roughness coefficient\n"
+  "vec3  occPBRBackMaterial_Emission(void);            //!< Light intensity emitted by material\n"
+  "float occPBRBackMaterial_IOR(void);                 //!< Index of refraction\n"
+  "#endif\n"
   "\n"
   "#ifdef THE_HAS_DEFAULT_SAMPLER\n"
   "#define occActiveSampler    occSampler0                //!< alias for backward compatibility\n"
diff --git a/src/Shaders/Shaders_PBRCookTorrance_glsl.pxx b/src/Shaders/Shaders_PBRCookTorrance_glsl.pxx
new file mode 100644 (file)
index 0000000..c2c8f88
--- /dev/null
@@ -0,0 +1,23 @@
+// This file has been automatically generated from resource file src/Shaders/PBRCookTorrance.glsl
+
+static const char Shaders_PBRCookTorrance_glsl[] =
+  "//! Calculates Cook-Torrance BRDF.\n"
+  "vec3 occPBRCookTorrance (in vec3  theView,\n"
+  "                         in vec3  theLight,\n"
+  "                         in vec3  theNormal,\n"
+  "                         in vec3  theBaseColor,\n"
+  "                         in float theMetallic,\n"
+  "                         in float theRoughness,\n"
+  "                         in float theIOR)\n"
+  "{\n"
+  "  vec3 aHalf = normalize (theView + theLight);\n"
+  "  float aCosV = max(dot(theView, theNormal), 0.0);\n"
+  "  float aCosL = max(dot(theLight, theNormal), 0.0);\n"
+  "  float aCosH = max(dot(aHalf, theNormal), 0.0);\n"
+  "  float aCosVH = max(dot(aHalf, theView), 0.0);\n"
+  "  vec3 aCookTorrance = occPBRDistribution (aCosH, theRoughness)\n"
+  "                     * occPBRGeometry     (aCosV, aCosL, theRoughness)\n"
+  "                     * occPBRFresnel      (theBaseColor, theMetallic, theIOR, aCosVH);\n"
+  "  aCookTorrance /= 4.0;\n"
+  "  return aCookTorrance;\n"
+  "}\n";
diff --git a/src/Shaders/Shaders_PBRDistribution_glsl.pxx b/src/Shaders/Shaders_PBRDistribution_glsl.pxx
new file mode 100644 (file)
index 0000000..66f1cf8
--- /dev/null
@@ -0,0 +1,12 @@
+// This file has been automatically generated from resource file src/Shaders/PBRDistribution.glsl
+
+static const char Shaders_PBRDistribution_glsl[] =
+  "//! Calculates micro facet normals distribution.\n"
+  "float occPBRDistribution (in float theCosH,\n"
+  "                          in float theRoughness)\n"
+  "{\n"
+  "  float aDistribution = theRoughness * theRoughness;\n"
+  "  aDistribution = aDistribution / (theCosH * theCosH * (aDistribution * aDistribution - 1.0) + 1.0);\n"
+  "  aDistribution = INV_PI * aDistribution * aDistribution;\n"
+  "  return aDistribution;\n"
+  "}\n";
diff --git a/src/Shaders/Shaders_PBREnvBaking_fs.pxx b/src/Shaders/Shaders_PBREnvBaking_fs.pxx
new file mode 100644 (file)
index 0000000..bc995ac
--- /dev/null
@@ -0,0 +1,165 @@
+// This file has been automatically generated from resource file src/Shaders/PBREnvBaking.fs
+
+static const char Shaders_PBREnvBaking_fs[] =
+  "THE_SHADER_IN vec3 ViewDirection; //!< direction of fetching from environment cubemap\n"
+  "\n"
+  "uniform int uSamplesNum;     //!< number of samples in Monte-Carlo integration\n"
+  "uniform int uCurrentLevel;   //!< current level of specular IBL map (ignored in case of diffuse map's processing)\n"
+  "uniform int uEnvMapSize;     //!< one edge's size of source environtment map's zero mipmap level\n"
+  "uniform int uYCoeff;         //!< coefficient of Y controlling horizontal flip of cubemap\n"
+  "uniform int uZCoeff;         //!< coefficient of Z controlling vertical flip of cubemap\n"
+  "uniform samplerCube uEnvMap; //!< source of baking (environment cubemap)\n"
+  "\n"
+  "//! Returns coordinates of point theNumber from Hammersley point set having size theSize.\n"
+  "vec2 hammersley (in int theNumber,\n"
+  "                 in int theSize)\n"
+  "{\n"
+  "  int aDenominator = 2;\n"
+  "  int aNumber = theNumber;\n"
+  "  float aVanDerCorput = 0.0;\n"
+  "  for (int i = 0; i < 32; ++i)\n"
+  "  {\n"
+  "    if (aNumber > 0)\n"
+  "    {\n"
+  "      aVanDerCorput += float(aNumber % 2) / float(aDenominator);\n"
+  "      aNumber /= 2;\n"
+  "      aDenominator *= 2;\n"
+  "    }\n"
+  "  }\n"
+  "  return vec2(float(theNumber) / float(theSize), aVanDerCorput);\n"
+  "}\n"
+  "\n"
+  "//! This function does importance sampling on hemisphere surface using GGX normal distribution function\n"
+  "//! in tangent space (positive z axis is surface normal direction).\n"
+  "vec3 importanceSample (in vec2  theHammersleyPoint,\n"
+  "                       in float theRoughness)\n"
+  "{\n"
+  "  float aPhi = PI_2 * theHammersleyPoint.x;\n"
+  "  theRoughness *= theRoughness;\n"
+  "  theRoughness *= theRoughness;\n"
+  "  float aCosTheta = sqrt((1.0 - theHammersleyPoint.y) / (1.0 + (theRoughness - 1.0) * theHammersleyPoint.y));\n"
+  "  float aSinTheta = sqrt(1.0 - aCosTheta * aCosTheta);\n"
+  "  return vec3(aSinTheta * cos(aPhi),\n"
+  "              aSinTheta * sin(aPhi),\n"
+  "              aCosTheta);\n"
+  "}\n"
+  "\n"
+  "//! This function uniformly generates samples on whole sphere.\n"
+  "vec3 sphereUniformSample (in vec2 theHammersleyPoint)\n"
+  "{\n"
+  "  float aPhi = PI_2 * theHammersleyPoint.x;\n"
+  "  float aCosTheta = 2.0 * theHammersleyPoint.y - 1.0;\n"
+  "  float aSinTheta = sqrt(1.0 - aCosTheta * aCosTheta);\n"
+  "  return vec3(aSinTheta * cos(aPhi),\n"
+  "              aSinTheta * sin(aPhi),\n"
+  "              aCosTheta);\n"
+  "}\n"
+  "\n"
+  "//! Transforms resulted sampled direction from tangent space to world space considering the surface normal.\n"
+  "vec3 fromTangentSpace (in vec3 theVector,\n"
+  "                       in vec3 theNormal)\n"
+  "{\n"
+  "  vec3 anUp = (abs(theNormal.z) < 0.999) ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);\n"
+  "  vec3 anX = normalize(cross(anUp, theNormal));\n"
+  "  vec3 anY = cross(theNormal, anX);\n"
+  "  return anX * theVector.x + anY * theVector.y + theNormal * theVector.z;\n"
+  "}\n"
+  "\n"
+  "const float aSHBasisFuncCoeffs[9] = float[9]\n"
+  "(\n"
+  "  0.282095 * 0.282095,\n"
+  "  0.488603 * 0.488603,\n"
+  "  0.488603 * 0.488603,\n"
+  "  0.488603 * 0.488603,\n"
+  "  1.092548 * 1.092548,\n"
+  "  1.092548 * 1.092548,\n"
+  "  1.092548 * 1.092548,\n"
+  "  0.315392 * 0.315392,\n"
+  "  0.546274 * 0.546274\n"
+  ");\n"
+  "\n"
+  "const float aSHCosCoeffs[9] = float[9]\n"
+  "(\n"
+  "  3.141593,\n"
+  "  2.094395,\n"
+  "  2.094395,\n"
+  "  2.094395,\n"
+  "  0.785398,\n"
+  "  0.785398,\n"
+  "  0.785398,\n"
+  "  0.785398,\n"
+  "  0.785398\n"
+  ");\n"
+  "\n"
+  "//! Bakes diffuse IBL map's spherical harmonics coefficients.\n"
+  "vec3 bakeDiffuseSH()\n"
+  "{\n"
+  "  int anIndex = int(gl_FragCoord.x);\n"
+  "  vec3 aResult = vec3 (0.0);\n"
+  "  for (int aSampleIter = 0; aSampleIter < uSamplesNum; ++aSampleIter)\n"
+  "  {\n"
+  "    vec2 aHammersleyPoint = hammersley (aSampleIter, uSamplesNum);\n"
+  "    vec3 aDirection = sphereUniformSample (aHammersleyPoint);\n"
+  "\n"
+  "    vec3 aValue = occTextureCube (uEnvMap, cubemapVectorTransform (aDirection, uYCoeff, uZCoeff)).rgb;\n"
+  "\n"
+  "    float aBasisFunc[9];\n"
+  "    aBasisFunc[0] = 1.0;\n"
+  "\n"
+  "    aBasisFunc[1] = aDirection.x;\n"
+  "    aBasisFunc[2] = aDirection.y;\n"
+  "    aBasisFunc[3] = aDirection.z;\n"
+  "\n"
+  "    aBasisFunc[4] = aDirection.x * aDirection.z;\n"
+  "    aBasisFunc[5] = aDirection.y * aDirection.z;\n"
+  "    aBasisFunc[6] = aDirection.x * aDirection.y;\n"
+  "\n"
+  "    aBasisFunc[7] = 3.0 * aDirection.z * aDirection.z - 1.0;\n"
+  "    aBasisFunc[8] = aDirection.x * aDirection.x - aDirection.y * aDirection.y;\n"
+  "\n"
+  "    aResult += aValue * aBasisFunc[anIndex];\n"
+  "  }\n"
+  "\n"
+  "  aResult *= 4.0 * aSHCosCoeffs[anIndex] * aSHBasisFuncCoeffs[anIndex] / float(uSamplesNum);\n"
+  "  return aResult;\n"
+  "}\n"
+  "\n"
+  "//! Bakes specular IBL map.\n"
+  "vec3 bakeSpecularMap (in vec3  theNormal,\n"
+  "                      in float theRoughness)\n"
+  "{\n"
+  "  vec3 aResult = vec3(0.0);\n"
+  "  float aWeightSum = 0.0;\n"
+  "  int aSamplesNum = (theRoughness == 0.0) ? 1 : uSamplesNum;\n"
+  "  float aSolidAngleSource = 4.0 * PI / (6.0 * float(uEnvMapSize * uEnvMapSize));\n"
+  "  for (int aSampleIter = 0; aSampleIter < aSamplesNum; ++aSampleIter)\n"
+  "  {\n"
+  "    vec2 aHammersleyPoint = hammersley (aSampleIter, aSamplesNum);\n"
+  "    vec3 aHalf = importanceSample (aHammersleyPoint, occRoughness (theRoughness));\n"
+  "    float aHdotV = aHalf.z;\n"
+  "    aHalf = fromTangentSpace (aHalf, theNormal);\n"
+  "    vec3  aLight = -reflect (theNormal, aHalf);\n"
+  "    float aNdotL = dot (aLight, theNormal);\n"
+  "    if (aNdotL > 0.0)\n"
+  "    {\n"
+  "      float aSolidAngleSample = 1.0 / (float(aSamplesNum) * (occPBRDistribution (aHdotV, theRoughness) * 0.25 + 0.0001) + 0.0001);\n"
+  "      float aLod = (theRoughness == 0.0) ? 0.0 : 0.5 * log2 (aSolidAngleSample / aSolidAngleSource);\n"
+  "      aResult += occTextureCubeLod (uEnvMap, aLight, aLod).rgb * aNdotL;\n"
+  "      aWeightSum += aNdotL;\n"
+  "    }\n"
+  "  }\n"
+  "  return aResult / aWeightSum;\n"
+  "}\n"
+  "\n"
+  "void main()\n"
+  "{\n"
+  "  vec3 aViewDirection = normalize (ViewDirection);\n"
+  "  if (occNbSpecIBLLevels == 0)\n"
+  "  {\n"
+  "    occSetFragColor (vec4 (bakeDiffuseSH (), 1.0));\n"
+  "  }\n"
+  "  else\n"
+  "  {\n"
+  "    occSetFragColor (vec4 (bakeSpecularMap (aViewDirection, float(uCurrentLevel) / float(occNbSpecIBLLevels - 1)), 1.0));\n"
+  "  }\n"
+  "}\n";
diff --git a/src/Shaders/Shaders_PBREnvBaking_vs.pxx b/src/Shaders/Shaders_PBREnvBaking_vs.pxx
new file mode 100644 (file)
index 0000000..89a37cb
--- /dev/null
@@ -0,0 +1,38 @@
+// This file has been automatically generated from resource file src/Shaders/PBREnvBaking.vs
+
+static const char Shaders_PBREnvBaking_vs[] =
+  "THE_SHADER_OUT vec3 ViewDirection; //!< direction of fetching from environment cubemap\n"
+  "\n"
+  "uniform int uCurrentSide; //!< current side of cubemap\n"
+  "uniform int uYCoeff;      //!< coefficient of Y controlling horizontal flip of cubemap\n"
+  "uniform int uZCoeff;      //!< coefficient of Z controlling vertical flip of cubemap\n"
+  "\n"
+  "const mat2 cubemapDirectionMatrices[6] = mat2[]\n"
+  "(\n"
+  "  mat2 ( 0, -1, -1,  0),\n"
+  "  mat2 ( 0,  1, -1,  0),\n"
+  "  mat2 ( 0,  1,  1,  0),\n"
+  "  mat2 ( 0,  1, -1,  0),\n"
+  "  mat2 ( 1,  0,  0, -1),\n"
+  "  mat2 (-1,  0,  0, -1)\n"
+  ");\n"
+  "\n"
+  "//! Generates environment map fetching direction considering current index of side.\n"
+  "vec3 cubemapBakingViewDirection (in int theSide,\n"
+  "                                 in vec2 theScreenCoord)\n"
+  "{\n"
+  "  int anAxis = theSide / 2;\n"
+  "  vec3 aDirection = vec3(0.0);\n"
+  "  aDirection[anAxis] = float(-(int(theSide) % 2) * 2 + 1);\n"
+  "  theScreenCoord = cubemapDirectionMatrices[theSide] * theScreenCoord;\n"
+  "  aDirection[(anAxis + 1) % 3] = theScreenCoord.x;\n"
+  "  aDirection[(anAxis + 2) % 3] = theScreenCoord.y;\n"
+  "  return aDirection;\n"
+  "}\n"
+  "\n"
+  "void main()\n"
+  "{\n"
+  "  ViewDirection = cubemapBakingViewDirection (uCurrentSide, occVertex.xy);\n"
+  "  ViewDirection = cubemapVectorTransform (ViewDirection, uYCoeff, uZCoeff);\n"
+  "  gl_Position = vec4 (occVertex.xy, 0.0, 1.0);\n"
+  "}\n";
diff --git a/src/Shaders/Shaders_PBRFresnel_glsl.pxx b/src/Shaders/Shaders_PBRFresnel_glsl.pxx
new file mode 100644 (file)
index 0000000..3612829
--- /dev/null
@@ -0,0 +1,39 @@
+// This file has been automatically generated from resource file src/Shaders/PBRFresnel.glsl
+
+static const char Shaders_PBRFresnel_glsl[] =
+  "//! Functions to calculate fresnel coefficient and approximate zero fresnel value.\n"
+  "vec3 occPBRFresnel (in vec3  theBaseColor,\n"
+  "                    in float theMetallic,\n"
+  "                    in float theIOR)\n"
+  "{\n"
+  "  theIOR = (1.0 - theIOR) / (1.0 + theIOR);\n"
+  "  theIOR *= theIOR;\n"
+  "  vec3 f0 = vec3(theIOR);\n"
+  "  f0 = mix (f0, theBaseColor.rgb, theMetallic);\n"
+  "  return f0;\n"
+  "}\n"
+  "\n"
+  "vec3 occPBRFresnel (in vec3  theBaseColor,\n"
+  "                    in float theMetallic,\n"
+  "                    in float theIOR,\n"
+  "                    in float theCosVH)\n"
+  "{\n"
+  "  vec3 f0 = occPBRFresnel (theBaseColor, theMetallic, theIOR);\n"
+  "  theCosVH = 1.0 - theCosVH;\n"
+  "  theCosVH *= theCosVH;\n"
+  "  theCosVH *= theCosVH * theCosVH * theCosVH * theCosVH;\n"
+  "  return f0 + (vec3 (1.0) - f0) * theCosVH;\n"
+  "}\n"
+  "\n"
+  "vec3 occPBRFresnel (in vec3  theBaseColor,\n"
+  "                    in float theMetallic,\n"
+  "                    in float theRoughness,\n"
+  "                    in float theIOR,\n"
+  "                    in float theCosV)\n"
+  "{\n"
+  "  vec3 f0 = occPBRFresnel (theBaseColor, theMetallic, theIOR);\n"
+  "  theCosV = 1.0 - theCosV;\n"
+  "  theCosV *= theCosV;\n"
+  "  theCosV *= theCosV * theCosV * theCosV * theCosV;\n"
+  "  return f0 + (max(vec3(1.0 - theRoughness), f0) - f0) * theCosV;\n"
+  "}\n";
diff --git a/src/Shaders/Shaders_PBRGeometry_glsl.pxx b/src/Shaders/Shaders_PBRGeometry_glsl.pxx
new file mode 100644 (file)
index 0000000..7ade3af
--- /dev/null
@@ -0,0 +1,16 @@
+// This file has been automatically generated from resource file src/Shaders/PBRGeometry.glsl
+
+static const char Shaders_PBRGeometry_glsl[] =
+  "//! Calculates geometry factor for Cook-Torrance BRDF.\n"
+  "float occPBRGeometry (in float theCosV,\n"
+  "                      in float theCosL,\n"
+  "                      in float theRoughness)\n"
+  "{\n"
+  "  float k = theRoughness + 1.0;\n"
+  "  k *= 0.125 * k;\n"
+  "  float g1 = 1.0;\n"
+  "  g1 /= theCosV * (1.0 - k) + k;\n"
+  "  float g2 = 1.0;\n"
+  "  g2 /= theCosL * (1.0 - k) + k;\n"
+  "  return g1 * g2;\n"
+  "}\n";
diff --git a/src/Shaders/Shaders_PBRIllumination_glsl.pxx b/src/Shaders/Shaders_PBRIllumination_glsl.pxx
new file mode 100644 (file)
index 0000000..d7a2760
--- /dev/null
@@ -0,0 +1,31 @@
+// This file has been automatically generated from resource file src/Shaders/PBRIllumination.glsl
+
+static const char Shaders_PBRIllumination_glsl[] =
+  "//! Calculates direct illumination using Cook-Torrance BRDF.\n"
+  "vec3 occPBRIllumination (in vec3  theView,\n"
+  "                         in vec3  theLight,\n"
+  "                         in vec3  theNormal,\n"
+  "                         in vec4  theBaseColor,\n"
+  "                         in float theMetallic,\n"
+  "                         in float theRoughness,\n"
+  "                         in float theIOR,\n"
+  "                         in vec3  theLightColor,\n"
+  "                         in float theLightIntensity)\n"
+  "{\n"
+  "  vec3 aHalf = normalize (theView + theLight);\n"
+  "  float aCosVH = max(dot(theView, aHalf), 0.0);\n"
+  "  vec3 aFresnel = occPBRFresnel (theBaseColor.rgb, theMetallic, theIOR, aCosVH);\n"
+  "  vec3 aSpecular = occPBRCookTorrance (theView,\n"
+  "                                       theLight,\n"
+  "                                       theNormal,\n"
+  "                                       theBaseColor.rgb,\n"
+  "                                       theMetallic,\n"
+  "                                       theRoughness,\n"
+  "                                       theIOR);\n"
+  "  vec3 aDiffuse = vec3(1.0) - aFresnel;\n"
+  "  aDiffuse *= 1.0 - theMetallic;\n"
+  "  aDiffuse *= INV_PI;\n"
+  "  aDiffuse *= theBaseColor.rgb;\n"
+  "  aDiffuse = mix (vec3(0.0), aDiffuse, theBaseColor.a);\n"
+  "  return (aDiffuse + aSpecular) * theLightColor * theLightIntensity * max(0.0, dot(theLight, theNormal));\n"
+  "}\n";
index 40b9c55..e1ffb54 100755 (executable)
@@ -29,3 +29,4 @@ icon:::env_pearl.rgb
 icon:::env_road.rgb
 icon:::env_sky1.rgb
 icon:::env_sky2.rgb
+Textures_EnvLUT.pxx
diff --git a/src/Textures/Textures_EnvLUT.pxx b/src/Textures/Textures_EnvLUT.pxx
new file mode 100644 (file)
index 0000000..97aea55
--- /dev/null
@@ -0,0 +1,3461 @@
+//this file has been generated by vgenenvlut draw command
+static unsigned int Textures_EnvLUTSize = 128;
+
+static float Textures_EnvLUT[] =
+{
+0.f,0.f, 0.0382714f,0.949235f, 0.0758239f,0.917965f, 0.112197f,0.88368f, 0.147415f,0.84953f,
+0.181504f,0.816054f, 0.214496f,0.783493f, 0.246415f,0.751876f, 0.277286f,0.721232f, 0.307141f,0.691546f,
+0.335999f,0.662837f, 0.363891f,0.635065f, 0.390836f,0.608214f, 0.416849f,0.582274f, 0.44198f,0.557216f,
+0.466225f,0.533021f, 0.489626f,0.509675f, 0.512206f,0.487152f, 0.533968f,0.465424f, 0.554953f,0.444486f,
+0.57517f,0.424293f, 0.594646f,0.404846f, 0.613403f,0.386116f, 0.631465f,0.368093f, 0.648841f,0.350738f,
+0.665546f,0.334045f, 0.68162f,0.317993f, 0.697066f,0.302564f, 0.71191f,0.28774f, 0.726152f,0.273502f,
+0.739848f,0.259838f, 0.752975f,0.246719f, 0.765564f,0.234135f, 0.777648f,0.222076f, 0.789204f,0.210511f,
+0.800294f,0.199436f, 0.810913f,0.188832f, 0.821063f,0.178685f, 0.830796f,0.168977f, 0.840084f,0.159698f,
+0.848952f,0.150828f, 0.857425f,0.142358f, 0.865535f,0.134272f, 0.873243f,0.126558f, 0.880614f,0.119203f,
+0.887631f,0.112196f, 0.8943f,0.10552f, 0.900652f,0.0991651f, 0.906722f,0.0931193f, 0.912472f,0.087374f,
+0.917921f,0.0819166f, 0.923109f,0.0767335f, 0.928039f,0.0718161f, 0.932694f,0.0671546f, 0.937131f,0.0627394f,
+0.9413f,0.0585586f, 0.945264f,0.0546035f, 0.949021f,0.0508651f, 0.95256f,0.0473339f, 0.955875f,0.0440025f,
+0.959033f,0.0408606f, 0.961987f,0.0379014f, 0.964782f,0.0351159f, 0.967406f,0.032497f, 0.96986f,0.0300355f,
+0.972171f,0.027727f, 0.974353f,0.0255618f, 0.976379f,0.0235343f, 0.978272f,0.0216371f, 0.980045f,0.019865f,
+0.981701f,0.0182105f, 0.983262f,0.0166683f, 0.984683f,0.0152321f, 0.986024f,0.0138969f, 0.987259f,0.0126571f,
+0.988416f,0.0115071f, 0.989498f,0.0104425f, 0.990478f,0.00945815f, 0.991393f,0.00854934f, 0.992236f,0.00771189f,
+0.992993f,0.00694133f, 0.993713f,0.00623369f, 0.99437f,0.00558503f, 0.994946f,0.00499139f, 0.995495f,0.00444938f,
+0.995986f,0.00395558f, 0.996456f,0.0035066f, 0.996841f,0.00309926f, 0.997238f,0.00273078f, 0.997559f,0.00239817f,
+0.997864f,0.0020988f, 0.99812f,0.0018301f, 0.998364f,0.00158966f, 0.998593f,0.00137519f, 0.998779f,0.0011845f,
+0.998959f,0.00101559f, 0.999096f,0.000866519f, 0.999222f,0.00073548f, 0.999341f,0.000620806f, 0.999451f,0.000520908f,
+0.999527f,0.000434302f, 0.999622f,0.000359617f, 0.999691f,0.000295579f, 0.999744f,0.000241008f, 0.999771f,0.000194807f,
+0.999818f,0.000155985f, 0.999866f,0.000123613f, 0.999879f,9.68558e-05f, 0.999893f,7.49452e-05f, 0.999935f,5.71916e-05f,
+0.999939f,4.2975e-05f, 0.999943f,3.17377e-05f, 0.999953f,2.29845e-05f, 0.999985f,1.62785e-05f, 0.999988f,1.12382e-05f,
+0.999988f,7.53158e-06f, 0.999996f,4.87458e-06f, 0.999996f,3.02678e-06f, 0.999997f,1.78729e-06f, 0.999997f,9.91806e-07f,
+0.999999f,5.08708e-07f, 0.999999f,2.35362e-07f, 0.999999f,9.4587e-08f, 1.f,3.09939e-08f, 1.f,7.35508e-09f,
+1.f,9.6856e-10f, 1.f,3.02675e-11f, 1.f,0.f,
+
+0.00481949f,0.82372f, 0.0374275f,0.923088f, 0.0748831f,0.90541f, 0.111238f,0.875679f, 0.146459f,0.843787f,
+0.180562f,0.811688f, 0.213569f,0.78002f, 0.245505f,0.749041f, 0.276395f,0.718868f, 0.306267f,0.689558f,
+0.335143f,0.661128f, 0.36305f,0.633588f, 0.390011f,0.606933f, 0.416051f,0.581151f, 0.441195f,0.556231f,
+0.465464f,0.532154f, 0.488881f,0.508903f, 0.511473f,0.486461f, 0.533256f,0.46481f, 0.554254f,0.44393f,
+0.574492f,0.4238f, 0.593985f,0.404402f, 0.612758f,0.385718f, 0.63083f,0.367726f, 0.648221f,0.35041f,
+0.664948f,0.333749f, 0.681032f,0.317726f, 0.696492f,0.302323f, 0.711348f,0.287522f, 0.725614f,0.273306f,
+0.73931f,0.259655f, 0.752456f,0.246555f, 0.765063f,0.233988f, 0.777151f,0.221938f, 0.788735f,0.210389f,
+0.799834f,0.199326f, 0.810459f,0.188731f, 0.820629f,0.178593f, 0.830356f,0.168894f, 0.839657f,0.159621f,
+0.848544f,0.150759f, 0.857034f,0.142295f, 0.865135f,0.134216f, 0.872867f,0.126507f, 0.880239f,0.119157f,
+0.887264f,0.112152f, 0.893956f,0.10548f, 0.900324f,0.0991298f, 0.906384f,0.0930889f, 0.912143f,0.087346f,
+0.917617f,0.0818899f, 0.922813f,0.0767099f, 0.92774f,0.0717956f, 0.932417f,0.0671361f, 0.936845f,0.0627218f,
+0.941037f,0.0585426f, 0.945003f,0.0545894f, 0.948754f,0.0508526f, 0.952295f,0.047323f, 0.955639f,0.0439924f,
+0.95879f,0.0408519f, 0.961759f,0.0378933f, 0.964556f,0.0351086f, 0.967185f,0.0324902f, 0.969655f,0.0300303f,
+0.971972f,0.0277217f, 0.974146f,0.0255573f, 0.976183f,0.0235303f, 0.978086f,0.0216339f, 0.979867f,0.0198618f,
+0.981531f,0.0182078f, 0.983081f,0.0166658f, 0.984524f,0.0152301f, 0.985867f,0.0138951f, 0.987115f,0.0126554f,
+0.988272f,0.0115058f, 0.989344f,0.0104413f, 0.990333f,0.00945706f, 0.991248f,0.00854854f, 0.992093f,0.00771118f,
+0.992868f,0.00694076f, 0.993585f,0.00623319f, 0.994238f,0.00558451f, 0.994838f,0.00499103f, 0.995387f,0.00444909f,
+0.995885f,0.0039553f, 0.996339f,0.00350634f, 0.996753f,0.00309912f, 0.997127f,0.00273063f, 0.997464f,0.00239807f,
+0.997769f,0.00209872f, 0.998043f,0.00183004f, 0.998288f,0.00158962f, 0.998506f,0.00137515f, 0.998703f,0.00118448f,
+0.998874f,0.00101557f, 0.999028f,0.000866506f, 0.999165f,0.000735482f, 0.999285f,0.000620809f, 0.999387f,0.000520908f,
+0.999479f,0.000434303f, 0.999559f,0.00035962f, 0.999626f,0.000295584f, 0.999684f,0.000241013f, 0.999732f,0.000194816f,
+0.999776f,0.000155992f, 0.999813f,0.00012362f, 0.999843f,9.686e-05f, 0.999868f,7.49491e-05f, 0.999889f,5.71958e-05f,
+0.999906f,4.29784e-05f, 0.99992f,3.17402e-05f, 0.999934f,2.29864e-05f, 0.999942f,1.62802e-05f, 0.99995f,1.12393e-05f,
+0.999959f,7.53244e-06f, 0.999965f,4.87528e-06f, 0.999969f,3.02721e-06f, 0.999972f,1.78758e-06f, 0.999977f,9.92001e-07f,
+0.999979f,5.08818e-07f, 0.999981f,2.3542e-07f, 0.999987f,9.46147e-08f, 0.99999f,3.10055e-08f, 0.999992f,7.35861e-09f,
+0.999996f,9.69246e-10f, 0.999998f,3.03082e-11f, 1.f,8.57764e-25f,
+
+0.00793899f,0.795161f, 0.0363458f,0.883401f, 0.0735482f,0.88601f, 0.109812f,0.862934f, 0.14504f,0.834928f,
+0.179147f,0.80492f, 0.212168f,0.77464f, 0.244123f,0.744647f, 0.275037f,0.715208f, 0.304933f,0.686462f,
+0.333835f,0.658481f, 0.361768f,0.631302f, 0.388757f,0.604942f, 0.414824f,0.579408f, 0.439994f,0.554694f,
+0.46429f,0.530795f, 0.487735f,0.507696f, 0.510351f,0.485387f, 0.532161f,0.463849f, 0.553186f,0.443068f,
+0.573447f,0.423026f, 0.592966f,0.403707f, 0.611762f,0.38509f, 0.629858f,0.36716f, 0.647271f,0.349898f,
+0.664021f,0.333287f, 0.680129f,0.317307f, 0.695612f,0.301944f, 0.710488f,0.287178f, 0.724776f,0.272993f,
+0.738494f,0.259371f, 0.751658f,0.246297f, 0.764286f,0.233753f, 0.776393f,0.221725f, 0.787997f,0.210195f,
+0.799114f,0.199149f, 0.809758f,0.188571f, 0.819945f,0.178447f, 0.82969f,0.168761f, 0.839008f,0.1595f,
+0.847912f,0.15065f, 0.856417f,0.142196f, 0.864535f,0.134125f, 0.872283f,0.126425f, 0.87967f,0.119082f,
+0.88671f,0.112085f, 0.893416f,0.105419f, 0.899799f,0.0990744f, 0.905872f,0.0930387f, 0.911645f,0.0873007f,
+0.917132f,0.081849f, 0.922341f,0.076673f, 0.927283f,0.071762f, 0.931969f,0.067106f, 0.93641f,0.0626946f,
+0.940615f,0.0585183f, 0.944593f,0.0545674f, 0.948353f,0.0508327f, 0.951905f,0.0473054f, 0.95526f,0.0439765f,
+0.958422f,0.0408377f, 0.961402f,0.0378807f, 0.964207f,0.0350974f, 0.966845f,0.0324801f, 0.969326f,0.0300214f,
+0.971653f,0.0277138f, 0.973836f,0.0255503f, 0.975881f,0.023524f, 0.977795f,0.0216284f, 0.979585f,0.019857f,
+0.981256f,0.0182035f, 0.982814f,0.0166621f, 0.984265f,0.0152269f, 0.985616f,0.0138923f, 0.986871f,0.012653f,
+0.988036f,0.0115037f, 0.989114f,0.0104395f, 0.990114f,0.00945551f, 0.991035f,0.00854717f, 0.991886f,0.00771002f,
+0.992669f,0.00693978f, 0.99339f,0.00623235f, 0.99405f,0.00558383f, 0.994656f,0.00499045f, 0.995211f,0.00444862f,
+0.995716f,0.0039549f, 0.996176f,0.00350602f, 0.996595f,0.00309886f, 0.996974f,0.00273043f, 0.997318f,0.00239791f,
+0.997628f,0.0020986f, 0.997907f,0.00182995f, 0.998157f,0.00158955f, 0.998381f,0.0013751f, 0.998581f,0.00118445f,
+0.998759f,0.00101555f, 0.998918f,0.000866497f, 0.999058f,0.00073548f, 0.999181f,0.000620813f, 0.99929f,0.000520916f,
+0.999385f,0.000434313f, 0.999469f,0.000359632f, 0.99954f,0.000295596f, 0.999603f,0.000241025f, 0.999657f,0.000194828f,
+0.999704f,0.000156003f, 0.999743f,0.00012363f, 0.999777f,9.68692e-05f, 0.999807f,7.49571e-05f, 0.999832f,5.72027e-05f,
+0.999853f,4.29842e-05f, 0.999872f,3.17449e-05f, 0.999887f,2.29902e-05f, 0.9999f,1.62832e-05f, 0.999912f,1.12417e-05f,
+0.999922f,7.53418e-06f, 0.999931f,4.87653e-06f, 0.999939f,3.02809e-06f, 0.999946f,1.78816e-06f, 0.999953f,9.9237e-07f,
+0.999961f,5.09037e-07f, 0.999966f,2.3554e-07f, 0.999973f,9.46727e-08f, 0.999977f,3.10294e-08f, 0.999982f,7.36613e-09f,
+0.99999f,9.70726e-10f, 0.999994f,3.04003e-11f, 1.f,4.49891e-22f,
+
+0.0136761f,0.785272f, 0.0355416f,0.832397f, 0.0720802f,0.859307f, 0.108175f,0.846411f, 0.143282f,0.822624f,
+0.177329f,0.795319f, 0.210375f,0.767286f, 0.242339f,0.738646f, 0.273269f,0.710208f, 0.303187f,0.682232f,
+0.332115f,0.654859f, 0.360077f,0.628172f, 0.387095f,0.602217f, 0.413194f,0.57702f, 0.438397f,0.552591f,
+0.462725f,0.528934f, 0.486203f,0.506044f, 0.508852f,0.483913f, 0.530694f,0.462532f, 0.551751f,0.441888f,
+0.572045f,0.421967f, 0.591595f,0.402754f, 0.610424f,0.384231f, 0.62855f,0.366385f, 0.645993f,0.349198f,
+0.662774f,0.332653f, 0.678912f,0.316734f, 0.694423f,0.301424f, 0.709328f,0.286707f, 0.723644f,0.272565f,
+0.737389f,0.258983f, 0.75058f,0.245944f, 0.763235f,0.233434f, 0.775367f,0.221434f, 0.786998f,0.209931f,
+0.798139f,0.198909f, 0.808807f,0.188353f, 0.819019f,0.178249f, 0.828787f,0.168582f, 0.838127f,0.159337f,
+0.847054f,0.150501f, 0.855581f,0.142061f, 0.863722f,0.134003f, 0.871489f,0.126314f, 0.878897f,0.118982f,
+0.885957f,0.111993f, 0.892682f,0.105337f, 0.899085f,0.099f, 0.905177f,0.0929714f, 0.910969f,0.0872398f,
+0.916472f,0.0817942f, 0.921699f,0.0766235f, 0.926659f,0.0717175f, 0.931362f,0.0670659f, 0.935819f,0.0626585f,
+0.940039f,0.0584859f, 0.944034f,0.0545383f, 0.94781f,0.0508068f, 0.951377f,0.0472821f, 0.954745f,0.0439558f,
+0.957922f,0.0408192f, 0.960916f,0.0378642f, 0.963735f,0.0350828f, 0.966388f,0.0324672f, 0.96888f,0.0300099f,
+0.97122f,0.0277037f, 0.973417f,0.0255414f, 0.975474f,0.0235162f, 0.977399f,0.0216215f, 0.9792f,0.019851f,
+0.980883f,0.0181983f, 0.982451f,0.0166576f, 0.983913f,0.015223f, 0.985276f,0.0138889f, 0.986542f,0.0126501f,
+0.987715f,0.0115012f, 0.988805f,0.0104374f, 0.989812f,0.00945375f, 0.990744f,0.00854569f, 0.991605f,0.00770878f,
+0.992397f,0.00693876f, 0.993126f,0.00623153f, 0.993796f,0.00558316f, 0.99441f,0.00498991f, 0.994971f,0.0044482f,
+0.995487f,0.00395458f, 0.995954f,0.00350579f, 0.996381f,0.00309869f, 0.996768f,0.00273032f, 0.997118f,0.00239784f,
+0.997436f,0.00209857f, 0.997721f,0.00182995f, 0.997978f,0.00158957f, 0.998209f,0.00137514f, 0.998417f,0.0011845f,
+0.998602f,0.00101561f, 0.998767f,0.000866557f, 0.998914f,0.000735544f, 0.999043f,0.000620878f, 0.999158f,0.000520978f,
+0.999258f,0.000434373f, 0.999348f,0.000359687f, 0.999426f,0.000295647f, 0.999493f,0.000241071f, 0.999553f,0.000194869f,
+0.999605f,0.00015604f, 0.999651f,0.000123662f, 0.999689f,9.68967e-05f, 0.999723f,7.49804e-05f, 0.999755f,5.72222e-05f,
+0.99978f,4.30002e-05f, 0.999804f,3.17579e-05f, 0.999823f,2.30004e-05f, 0.999841f,1.62912e-05f, 0.999857f,1.12477e-05f,
+0.999873f,7.53867e-06f, 0.999886f,4.87976e-06f, 0.999898f,3.03034e-06f, 0.999911f,1.78966e-06f, 0.999921f,9.93318e-07f,
+0.999932f,5.096e-07f, 0.999942f,2.35847e-07f, 0.999951f,9.48222e-08f, 0.999962f,3.10912e-08f, 0.999971f,7.38587e-09f,
+0.999981f,9.74677e-10f, 0.99999f,3.06548e-11f, 1.f,1.08921e-19f,
+
+0.0202734f,0.767652f, 0.0352934f,0.775016f, 0.0707147f,0.827819f, 0.106351f,0.824625f, 0.141292f,0.807202f,
+0.17529f,0.783846f, 0.20824f,0.757732f, 0.240162f,0.730692f, 0.271095f,0.703627f, 0.301059f,0.676828f,
+0.33001f,0.650243f, 0.357998f,0.624184f, 0.385047f,0.598745f, 0.411179f,0.573977f, 0.436416f,0.549911f,
+0.460781f,0.526561f, 0.484295f,0.503936f, 0.506983f,0.482035f, 0.528862f,0.460854f, 0.549958f,0.440384f,
+0.570289f,0.420617f, 0.589878f,0.401539f, 0.608744f,0.383137f, 0.626908f,0.365398f, 0.644389f,0.348306f,
+0.661206f,0.331847f, 0.677379f,0.316004f, 0.692927f,0.300763f, 0.707866f,0.286107f, 0.722217f,0.272022f,
+0.735996f,0.25849f, 0.749221f,0.245497f, 0.761908f,0.233028f, 0.774074f,0.221065f, 0.785735f,0.209597f,
+0.796907f,0.198605f, 0.807606f,0.188078f, 0.817847f,0.177999f, 0.827645f,0.168354f, 0.837014f,0.159131f,
+0.845969f,0.150314f, 0.854523f,0.141892f, 0.86269f,0.13385f, 0.870485f,0.126176f, 0.877918f,0.118856f,
+0.885003f,0.11188f, 0.891753f,0.105234f, 0.898181f,0.0989071f, 0.904296f,0.0928876f, 0.910111f,0.0871642f,
+0.915638f,0.0817261f, 0.920887f,0.0765623f, 0.925868f,0.0716626f, 0.930591f,0.0670166f, 0.93507f,0.0626144f,
+0.939311f,0.0584464f, 0.943324f,0.0545031f, 0.94712f,0.0507752f, 0.950706f,0.0472541f, 0.954093f,0.0439309f,
+0.957289f,0.0407971f, 0.9603f,0.0378446f, 0.963136f,0.0350655f, 0.965805f,0.032452f, 0.968314f,0.0299965f,
+0.970671f,0.0276919f, 0.972882f,0.0255311f, 0.974956f,0.0235073f, 0.976897f,0.0216138f, 0.978712f,0.0198443f,
+0.980409f,0.0181926f, 0.981992f,0.0166527f, 0.983468f,0.0152188f, 0.984843f,0.0138854f, 0.986122f,0.0126471f,
+0.98731f,0.0114988f, 0.988411f,0.0104353f, 0.989432f,0.0094521f, 0.990375f,0.00854436f, 0.991247f,0.00770774f,
+0.992051f,0.00693795f, 0.992792f,0.00623091f, 0.993473f,0.00558273f, 0.994097f,0.00498962f, 0.99467f,0.00444803f,
+0.995194f,0.00395451f, 0.995672f,0.00350579f, 0.996109f,0.00309876f, 0.996505f,0.00273043f, 0.996864f,0.00239799f,
+0.997192f,0.00209874f, 0.997487f,0.00183014f, 0.997754f,0.00158977f, 0.997992f,0.00137534f, 0.998208f,0.0011847f,
+0.998403f,0.00101581f, 0.998575f,0.00086675f, 0.998729f,0.000735725f, 0.998867f,0.000621047f, 0.99899f,0.000521135f,
+0.999098f,0.000434515f, 0.999194f,0.000359816f, 0.999278f,0.000295763f, 0.999354f,0.000241173f, 0.999422f,0.000194959f,
+0.99948f,0.000156118f, 0.999532f,0.000123729f, 0.999578f,9.69535e-05f, 0.999619f,7.50279e-05f, 0.999656f,5.72615e-05f,
+0.999688f,4.30322e-05f, 0.999717f,3.17836e-05f, 0.999743f,2.30207e-05f, 0.999767f,1.63069e-05f, 0.99979f,1.12596e-05f,
+0.99981f,7.54744e-06f, 0.999828f,4.88606e-06f, 0.999846f,3.0347e-06f, 0.999864f,1.79256e-06f, 0.99988f,9.95152e-07f,
+0.999896f,5.10689e-07f, 0.999911f,2.36442e-07f, 0.999926f,9.51128e-08f, 0.999941f,3.12119e-08f, 0.999956f,7.42476e-09f,
+0.99997f,9.82586e-10f, 0.999984f,3.11885e-11f, 1.f,6.75637e-18f,
+
+0.028675f,0.762755f, 0.0361374f,0.717796f, 0.0697061f,0.790077f, 0.104705f,0.799813f, 0.139273f,0.788486f,
+0.172992f,0.768671f, 0.205906f,0.746194f, 0.237821f,0.721553f, 0.268707f,0.695857f, 0.298607f,0.669986f,
+0.327537f,0.644286f, 0.355514f,0.618955f, 0.382656f,0.594451f, 0.408824f,0.570238f, 0.434095f,0.546622f,
+0.458496f,0.523654f, 0.482049f,0.501354f, 0.504774f,0.479735f, 0.526695f,0.458798f, 0.547831f,0.438543f,
+0.568205f,0.418964f, 0.587835f,0.400053f, 0.606743f,0.381798f, 0.624949f,0.36419f, 0.642472f,0.347215f,
+0.659331f,0.330861f, 0.675546f,0.315112f, 0.691135f,0.299956f, 0.706115f,0.285376f, 0.720506f,0.271359f,
+0.734325f,0.257889f, 0.747588f,0.244952f, 0.760314f,0.232533f, 0.772518f,0.220617f, 0.784216f,0.20919f,
+0.795425f,0.198237f, 0.80616f,0.187743f, 0.816436f,0.177695f, 0.826269f,0.168079f, 0.835672f,0.158882f,
+0.84466f,0.150089f, 0.853247f,0.141688f, 0.861447f,0.133665f, 0.869273f,0.126009f, 0.876737f,0.118705f,
+0.883852f,0.111744f, 0.890632f,0.105111f, 0.897088f,0.0987965f, 0.903232f,0.0927881f, 0.909074f,0.0870748f,
+0.914628f,0.0816458f, 0.919904f,0.0764904f, 0.924912f,0.0715981f, 0.929661f,0.066959f, 0.934165f,0.0625629f,
+0.938429f,0.0584005f, 0.942468f,0.0544623f, 0.946287f,0.0507391f, 0.949896f,0.0472221f, 0.953305f,0.0439026f,
+0.956521f,0.0407722f, 0.959554f,0.0378228f, 0.962412f,0.0350464f, 0.965102f,0.0324353f, 0.967631f,0.029982f,
+0.970007f,0.0276794f, 0.972238f,0.0255203f, 0.974329f,0.023498f, 0.976289f,0.0216059f, 0.978121f,0.0198376f,
+0.979836f,0.018187f, 0.981436f,0.016648f, 0.982929f,0.0152149f, 0.98432f,0.0138823f, 0.985615f,0.0126446f,
+0.986818f,0.0114968f, 0.987934f,0.0104339f, 0.98897f,0.00945101f, 0.989928f,0.00854362f, 0.990815f,0.00770728f,
+0.991633f,0.00693773f, 0.992388f,0.0062309f, 0.993081f,0.00558286f, 0.99372f,0.00498989f, 0.994305f,0.00444839f,
+0.994841f,0.00395494f, 0.995332f,0.00350629f, 0.99578f,0.00309929f, 0.996188f,0.00273098f, 0.996561f,0.00239855f,
+0.996897f,0.0020993f, 0.997203f,0.00183069f, 0.997481f,0.0015903f, 0.997731f,0.00137585f, 0.997957f,0.00118518f,
+0.99816f,0.00101626f, 0.998344f,0.000867167f, 0.998508f,0.000736109f, 0.998654f,0.000621397f, 0.998787f,0.000521452f,
+0.998904f,0.000434801f, 0.999009f,0.000360071f, 0.999103f,0.000295988f, 0.999187f,0.000241371f, 0.999261f,0.000195131f,
+0.99933f,0.000156265f, 0.999389f,0.000123854f, 0.999443f,9.70592e-05f, 0.999492f,7.5116e-05f, 0.999536f,5.7334e-05f,
+0.999575f,4.3091e-05f, 0.999613f,3.18307e-05f, 0.999646f,2.30578e-05f, 0.999677f,1.63355e-05f, 0.999707f,1.12812e-05f,
+0.999734f,7.56339e-06f, 0.999759f,4.8975e-06f, 0.999784f,3.04263e-06f, 0.999809f,1.79784e-06f, 0.999831f,9.985e-07f,
+0.999854f,5.12682e-07f, 0.999875f,2.37536e-07f, 0.999896f,9.56505e-08f, 0.999918f,3.14374e-08f, 0.999938f,7.4985e-09f,
+0.999958f,9.98022e-10f, 0.999978f,3.23201e-11f, 1.f,2.2521e-16f,
+
+0.0378261f,0.750319f, 0.0381689f,0.665902f, 0.0692973f,0.749911f, 0.103245f,0.77066f, 0.137335f,0.767205f,
+0.170812f,0.752526f, 0.203425f,0.732312f, 0.235166f,0.70984f, 0.266048f,0.686441f, 0.295971f,0.662286f,
+0.324899f,0.637724f, 0.352883f,0.613287f, 0.379944f,0.589183f, 0.406101f,0.565531f, 0.431372f,0.542411f,
+0.455778f,0.519871f, 0.479466f,0.498247f, 0.502239f,0.476986f, 0.524203f,0.456348f, 0.545384f,0.436351f,
+0.565801f,0.416998f, 0.585477f,0.398285f, 0.604431f,0.380207f, 0.622682f,0.362756f, 0.640251f,0.345921f,
+0.657156f,0.329691f, 0.673416f,0.314054f, 0.689051f,0.298999f, 0.704078f,0.28451f, 0.718514f,0.270574f,
+0.732377f,0.257178f, 0.745685f,0.244308f, 0.758454f,0.231949f, 0.770701f,0.220088f, 0.782442f,0.20871f,
+0.793693f,0.197802f, 0.804469f,0.187349f, 0.814785f,0.177339f, 0.824658f,0.167757f, 0.834101f,0.15859f,
+0.843128f,0.149825f, 0.851753f,0.141449f, 0.859989f,0.13345f, 0.867852f,0.125814f, 0.875352f,0.11853f,
+0.882503f,0.111586f, 0.889317f,0.104969f, 0.895806f,0.0986689f, 0.901984f,0.0926736f, 0.90786f,0.0869722f,
+0.913444f,0.0815539f, 0.918751f,0.0764083f, 0.923788f,0.0715249f, 0.928569f,0.0668938f, 0.933101f,0.062505f,
+0.937395f,0.0583492f, 0.94146f,0.054417f, 0.945307f,0.0506991f, 0.948943f,0.0471869f, 0.952378f,0.0438718f,
+0.955621f,0.0407453f, 0.958679f,0.0377994f, 0.961561f,0.0350261f, 0.964274f,0.0324178f, 0.966827f,0.0299671f,
+0.969226f,0.0276666f, 0.971479f,0.0255096f, 0.973593f,0.023489f, 0.975573f,0.0215984f, 0.977428f,0.0198315f,
+0.979163f,0.018182f, 0.980783f,0.0166441f, 0.982295f,0.0152119f, 0.983706f,0.01388f, 0.98502f,0.012643f,
+0.986241f,0.0114958f, 0.987376f,0.0104333f, 0.988428f,0.00945086f, 0.989404f,0.00854381f, 0.990307f,0.00770774f,
+0.991141f,0.0069384f, 0.991911f,0.00623174f, 0.992622f,0.00558383f, 0.993275f,0.00499096f, 0.993875f,0.00444952f,
+0.994427f,0.00395611f, 0.994932f,0.00350746f, 0.995394f,0.00310046f, 0.995815f,0.00273214f, 0.996202f,0.00239967f,
+0.996552f,0.00210037f, 0.996871f,0.00183171f, 0.997161f,0.00159127f, 0.997424f,0.00137675f, 0.997662f,0.00118602f,
+0.997877f,0.00101704f, 0.998071f,0.000867883f, 0.998247f,0.000736761f, 0.998405f,0.000621987f, 0.998548f,0.000521983f,
+0.998676f,0.000435274f, 0.998792f,0.00036049f, 0.998897f,0.000296356f, 0.998991f,0.000241692f, 0.999076f,0.000195408f,
+0.999152f,0.000156503f, 0.999222f,0.000124056f, 0.999285f,9.7229e-05f, 0.999343f,7.52571e-05f, 0.999396f,5.74499e-05f,
+0.999445f,4.31851e-05f, 0.999491f,3.19058e-05f, 0.999532f,2.31168e-05f, 0.999573f,1.6381e-05f, 0.999609f,1.13157e-05f,
+0.999646f,7.58883e-06f, 0.999678f,4.91576e-06f, 0.999711f,3.05531e-06f, 0.999743f,1.80631e-06f, 0.999774f,1.00389e-06f,
+0.999802f,5.15902e-07f, 0.999831f,2.39315e-07f, 0.999861f,9.65325e-08f, 0.999889f,3.18121e-08f, 0.999916f,7.62378e-09f,
+0.999943f,1.02542e-09f, 0.999971f,3.46055e-11f, 1.f,4.11135e-15f,
+
+0.0484631f,0.740882f, 0.0417663f,0.623721f, 0.0698224f,0.708895f, 0.102352f,0.739251f, 0.135623f,0.742489f,
+0.168703f,0.733549f, 0.201039f,0.716987f, 0.232607f,0.697193f, 0.263254f,0.675234f, 0.293018f,0.652443f,
+0.321982f,0.629668f, 0.349984f,0.60649f, 0.377076f,0.583381f, 0.403248f,0.560464f, 0.428539f,0.53795f,
+0.452973f,0.515923f, 0.476566f,0.494436f, 0.499341f,0.473523f, 0.521316f,0.453205f, 0.542512f,0.433494f,
+0.563066f,0.41462f, 0.582812f,0.396193f, 0.601818f,0.378335f, 0.62012f,0.361073f, 0.637738f,0.344405f,
+0.654693f,0.328323f, 0.671003f,0.312819f, 0.686687f,0.297882f, 0.701762f,0.2835f, 0.716248f,0.26966f,
+0.73016f,0.256351f, 0.743517f,0.243559f, 0.756334f,0.231271f, 0.768629f,0.219475f, 0.780416f,0.208155f,
+0.791714f,0.197299f, 0.802536f,0.186895f, 0.812899f,0.176928f, 0.822815f,0.167385f, 0.832302f,0.158254f,
+0.841373f,0.149522f, 0.85004f,0.141176f, 0.858319f,0.133204f, 0.866223f,0.125593f, 0.873762f,0.118331f,
+0.880953f,0.111407f, 0.887807f,0.104809f, 0.894335f,0.0985254f, 0.900549f,0.0925453f, 0.906461f,0.0868577f,
+0.912083f,0.0814519f, 0.917425f,0.0763176f, 0.922498f,0.0714445f, 0.927311f,0.0668226f, 0.931878f,0.0624423f,
+0.936204f,0.058294f, 0.940301f,0.0543685f, 0.944179f,0.0506568f, 0.947847f,0.0471501f, 0.951313f,0.0438399f,
+0.954583f,0.0407179f, 0.95767f,0.0377759f, 0.96058f,0.0350062f, 0.963322f,0.032401f, 0.965901f,0.029953f,
+0.968327f,0.027655f, 0.970606f,0.0255001f, 0.972745f,0.0234815f, 0.97475f,0.0215926f, 0.97663f,0.0198271f,
+0.978387f,0.0181788f, 0.980031f,0.016642f, 0.981566f,0.0152107f, 0.982998f,0.0138796f, 0.984334f,0.0126433f,
+0.985576f,0.0114966f, 0.986732f,0.0104345f, 0.987804f,0.00945244f, 0.9888f,0.00854566f, 0.989722f,0.0077098f,
+0.990576f,0.00694062f, 0.991365f,0.00623405f, 0.992093f,0.0055862f, 0.992764f,0.00499334f, 0.993381f,0.0044519f,
+0.99395f,0.00395845f, 0.994472f,0.00350974f, 0.99495f,0.00310266f, 0.995388f,0.00273424f, 0.995788f,0.00240167f,
+0.996155f,0.00210227f, 0.996489f,0.00183349f, 0.996793f,0.00159292f, 0.99707f,0.00137829f, 0.997322f,0.00118744f,
+0.99755f,0.00101833f, 0.997758f,0.00086906f, 0.997948f,0.000737827f, 0.998118f,0.000622946f, 0.998274f,0.000522839f,
+0.998415f,0.000436035f, 0.998542f,0.000361161f, 0.998659f,0.000296943f, 0.998765f,0.000242202f, 0.998861f,0.000195848f,
+0.998949f,0.000156879f, 0.99903f,0.000124375f, 0.999103f,9.74968e-05f, 0.999172f,7.54795e-05f, 0.999235f,5.76324e-05f,
+0.999294f,4.3333e-05f, 0.999349f,3.20239e-05f, 0.999402f,2.32098e-05f, 0.999451f,1.64529e-05f, 0.999498f,1.137e-05f,
+0.999542f,7.62904e-06f, 0.999586f,4.94469e-06f, 0.999627f,3.07547e-06f, 0.999668f,1.81982e-06f, 0.999707f,1.01253e-06f,
+0.999745f,5.21106e-07f, 0.999783f,2.42216e-07f, 0.99982f,9.79909e-08f, 0.999857f,3.24446e-08f, 0.999892f,7.84256e-09f,
+0.999927f,1.07658e-09f, 0.999963f,3.97831e-11f, 1.f,5.32808e-14f,
+
+0.0599245f,0.728967f, 0.0468215f,0.591592f, 0.0714001f,0.669159f, 0.102144f,0.706529f, 0.134372f,0.716113f,
+0.16675f,0.711701f, 0.198778f,0.69991f, 0.230037f,0.682748f, 0.260559f,0.663376f, 0.290166f,0.642141f,
+0.318912f,0.620252f, 0.346772f,0.59803f, 0.373894f,0.576256f, 0.400075f,0.554296f, 0.425431f,0.532705f,
+0.449904f,0.511351f, 0.473528f,0.490392f, 0.496335f,0.469925f, 0.518345f,0.449991f, 0.53958f,0.430615f,
+0.560058f,0.411811f, 0.579799f,0.393587f, 0.598821f,0.375945f, 0.617144f,0.358882f, 0.634788f,0.342396f,
+0.651909f,0.32668f, 0.668299f,0.311373f, 0.684043f,0.296586f, 0.699174f,0.282332f, 0.713713f,0.268607f,
+0.727679f,0.2554f, 0.741088f,0.2427f, 0.753958f,0.230495f, 0.766304f,0.218772f, 0.778144f,0.20752f,
+0.789492f,0.196726f, 0.800364f,0.186377f, 0.810777f,0.17646f, 0.820743f,0.166964f, 0.830278f,0.157874f,
+0.839396f,0.14918f, 0.848111f,0.140868f, 0.856436f,0.132927f, 0.864385f,0.125344f, 0.871971f,0.118108f,
+0.879206f,0.111208f, 0.886103f,0.104631f, 0.892674f,0.0983663f, 0.898931f,0.0924037f, 0.904885f,0.0867318f,
+0.910547f,0.0813405f, 0.915928f,0.076219f, 0.92104f,0.0713575f, 0.925892f,0.0667463f, 0.930494f,0.0623754f,
+0.934858f,0.0582356f, 0.938991f,0.0543179f, 0.942905f,0.0506131f, 0.946607f,0.0471126f, 0.950106f,0.0438079f,
+0.953412f,0.0406908f, 0.956531f,0.0377531f, 0.959472f,0.0349873f, 0.962245f,0.0323856f, 0.964855f,0.0299407f,
+0.96731f,0.0276453f, 0.969619f,0.0254928f, 0.971785f,0.0234761f, 0.97382f,0.021589f, 0.975725f,0.019825f,
+0.977511f,0.018178f, 0.979181f,0.0166423f, 0.980741f,0.015212f, 0.982199f,0.0138816f, 0.983558f,0.0126459f,
+0.984824f,0.0114997f, 0.986004f,0.010438f, 0.9871f,0.0094562f, 0.988117f,0.00854963f, 0.989062f,0.0077139f,
+0.989936f,0.00694478f, 0.990746f,0.00623822f, 0.991495f,0.00559033f, 0.992186f,0.0049974f, 0.992824f,0.00445585f,
+0.993411f,0.00396226f, 0.993951f,0.00351339f, 0.994447f,0.00310614f, 0.994904f,0.00273754f, 0.995323f,0.00240478f,
+0.995706f,0.00210518f, 0.996056f,0.0018362f, 0.996378f,0.00159543f, 0.996671f,0.0013806f, 0.996938f,0.00118956f,
+0.997182f,0.00102026f, 0.997406f,0.000870812f, 0.997609f,0.000739407f, 0.997795f,0.000624363f, 0.997964f,0.000524102f,
+0.99812f,0.000437154f, 0.998261f,0.000362146f, 0.99839f,0.000297804f, 0.998509f,0.00024295f, 0.998619f,0.000196493f,
+0.998719f,0.00015743f, 0.998813f,0.000124842f, 0.998898f,9.78884e-05f, 0.998978f,7.58049e-05f, 0.999054f,5.78997e-05f,
+0.999125f,4.35498e-05f, 0.999191f,3.21974e-05f, 0.999254f,2.33464e-05f, 0.999314f,1.65587e-05f, 0.999372f,1.14504e-05f,
+0.999427f,7.68863e-06f, 0.999481f,4.98775e-06f, 0.999532f,3.10563e-06f, 0.999584f,1.84016e-06f, 0.999632f,1.02563e-06f,
+0.999679f,5.29084e-07f, 0.999727f,2.46727e-07f, 0.999773f,1.00303e-07f, 0.999819f,3.34768e-08f, 0.999865f,8.2171e-09f,
+0.999908f,1.17278e-09f, 0.999953f,5.23614e-11f, 1.f,4.9827e-13f,
+
+0.0724374f,0.716948f, 0.0533872f,0.567321f, 0.0742314f,0.632341f, 0.102793f,0.672933f, 0.133742f,0.688331f,
+0.165264f,0.688544f, 0.19667f,0.680214f, 0.227621f,0.66678f, 0.257859f,0.649714f, 0.287294f,0.630543f,
+0.315959f,0.610453f, 0.343706f,0.589405f, 0.370623f,0.568219f, 0.396674f,0.54697f, 0.421976f,0.526175f,
+0.446517f,0.505784f, 0.470155f,0.485469f, 0.493039f,0.465688f, 0.515114f,0.446287f, 0.536391f,0.42732f,
+0.556911f,0.408862f, 0.576695f,0.39094f, 0.595764f,0.373563f, 0.614134f,0.356737f, 0.631826f,0.340462f,
+0.648857f,0.324733f, 0.665246f,0.309548f, 0.681013f,0.2949f, 0.69617f,0.280779f, 0.71074f,0.267177f,
+0.724838f,0.254196f, 0.738373f,0.241685f, 0.751315f,0.229594f, 0.763724f,0.217966f, 0.775622f,0.206795f,
+0.787026f,0.196074f, 0.797954f,0.18579f, 0.808421f,0.175932f, 0.818441f,0.166488f, 0.828029f,0.157447f,
+0.8372f,0.148796f, 0.845967f,0.140524f, 0.854342f,0.132618f, 0.862341f,0.125068f, 0.869976f,0.117861f,
+0.87726f,0.110987f, 0.884205f,0.104435f, 0.890823f,0.0981922f, 0.897126f,0.0922494f, 0.903124f,0.0865956f,
+0.908832f,0.0812203f, 0.914257f,0.0761136f, 0.919412f,0.0712653f, 0.924306f,0.066666f, 0.928952f,0.0623058f,
+0.933355f,0.0581757f, 0.93753f,0.0542665f, 0.941482f,0.0505694f, 0.945222f,0.0470758f, 0.948758f,0.0437772f,
+0.9521f,0.0406655f, 0.955256f,0.0377327f, 0.958234f,0.0349711f, 0.961041f,0.0323731f, 0.963685f,0.0299315f,
+0.966173f,0.027639f, 0.968514f,0.0254888f, 0.970713f,0.0234744f, 0.972778f,0.021589f, 0.974715f,0.0198266f,
+0.97653f,0.0181809f, 0.97823f,0.0166462f, 0.979819f,0.0152167f, 0.981304f,0.0138871f, 0.982691f,0.0126519f,
+0.983984f,0.0115061f, 0.985189f,0.0104447f, 0.986311f,0.00946304f, 0.987353f,0.00855655f, 0.988322f,0.0077208f,
+0.989222f,0.00695162f, 0.990055f,0.00624493f, 0.990826f,0.00559688f, 0.991539f,0.00500373f, 0.9922f,0.00446192f,
+0.992809f,0.00396807f, 0.99337f,0.00351892f, 0.993887f,0.00311136f, 0.994364f,0.00274245f, 0.994801f,0.00240937f,
+0.995204f,0.00210946f, 0.995574f,0.00184017f, 0.995913f,0.00159909f, 0.996224f,0.00138396f, 0.996509f,0.00119263f,
+0.996771f,0.00102306f, 0.997011f,0.00087334f, 0.997231f,0.000741682f, 0.997434f,0.000626399f, 0.997619f,0.000525915f,
+0.997789f,0.000438759f, 0.997946f,0.000363557f, 0.998091f,0.000299038f, 0.998224f,0.000244021f, 0.998347f,0.000197416f,
+0.998462f,0.000158219f, 0.998569f,0.000125511f, 0.99867f,9.84504e-05f, 0.998762f,7.62722e-05f, 0.998851f,5.8284e-05f,
+0.998934f,4.38622e-05f, 0.999013f,3.24479e-05f, 0.99909f,2.35444e-05f, 0.999162f,1.67124e-05f, 0.999231f,1.15675e-05f,
+0.999298f,7.77596e-06f, 0.999364f,5.05121e-06f, 0.999426f,3.15039e-06f, 0.999487f,1.87062e-06f, 0.999547f,1.04547e-06f,
+0.999606f,5.41329e-07f, 0.999664f,2.53782e-07f, 0.999722f,1.04014e-07f, 0.999777f,3.51997e-08f, 0.999832f,8.88335e-09f,
+0.999887f,1.36587e-09f, 0.999942f,8.64521e-11f, 0.999999f,3.651e-12f,
+
+0.0856947f,0.703782f, 0.0613258f,0.549424f, 0.0783571f,0.599864f, 0.104453f,0.640229f, 0.133867f,0.660127f,
+0.16433f,0.664329f, 0.194981f,0.659417f, 0.225383f,0.648849f, 0.255235f,0.634349f, 0.284513f,0.617836f,
+0.312914f,0.59911f, 0.340551f,0.579639f, 0.367436f,0.559884f, 0.39342f,0.539617f, 0.418562f,0.519327f,
+0.442957f,0.499393f, 0.466494f,0.479583f, 0.489394f,0.460488f, 0.511545f,0.441789f, 0.532851f,0.42331f,
+0.553402f,0.405276f, 0.573315f,0.387885f, 0.592444f,0.370848f, 0.610866f,0.354304f, 0.628609f,0.338273f,
+0.645693f,0.322762f, 0.662135f,0.30777f, 0.677954f,0.293294f, 0.693167f,0.279328f, 0.707792f,0.265865f,
+0.721843f,0.252897f, 0.735342f,0.240414f, 0.748302f,0.228407f, 0.760738f,0.216866f, 0.772669f,0.20578f,
+0.784108f,0.195137f, 0.795208f,0.185041f, 0.805795f,0.175306f, 0.81589f,0.165938f, 0.825543f,0.156959f,
+0.834775f,0.148362f, 0.843598f,0.140136f, 0.852031f,0.132273f, 0.860085f,0.124761f, 0.867775f,0.117588f,
+0.875111f,0.110745f, 0.88211f,0.10422f, 0.888779f,0.0980024f, 0.895131f,0.0920822f, 0.901181f,0.0864488f,
+0.906938f,0.0810919f, 0.912411f,0.0760017f, 0.917613f,0.0711683f, 0.922554f,0.0665824f, 0.927245f,0.0622342f,
+0.931693f,0.0581148f, 0.935912f,0.0542153f, 0.939907f,0.0505267f, 0.943689f,0.0470407f, 0.947267f,0.0437489f,
+0.950651f,0.0406431f, 0.953846f,0.0377156f, 0.956862f,0.0349586f, 0.959708f,0.0323646f, 0.96239f,0.0299265f,
+0.964915f,0.027637f, 0.967291f,0.0254895f, 0.969526f,0.0234772f, 0.971625f,0.0215937f, 0.973596f,0.0198328f,
+0.975445f,0.0181884f, 0.977176f,0.0166547f, 0.978798f,0.015226f, 0.980313f,0.0138969f, 0.981731f,0.0126621f,
+0.983053f,0.0115166f, 0.984288f,0.0104554f, 0.985438f,0.00947372f, 0.986509f,0.00856713f, 0.987505f,0.00773123f,
+0.98843f,0.0069618f, 0.98929f,0.00625481f, 0.990086f,0.00560641f, 0.990825f,0.00501288f, 0.991509f,0.00447066f,
+0.992142f,0.00397637f, 0.992728f,0.00352676f, 0.993267f,0.00311874f, 0.993765f,0.00274937f, 0.994225f,0.00241582f,
+0.994649f,0.00211545f, 0.995039f,0.0018457f, 0.9954f,0.00160419f, 0.995731f,0.00138864f, 0.996036f,0.00119689f,
+0.996316f,0.00102693f, 0.996575f,0.000876839f, 0.996813f,0.000744829f, 0.997033f,0.000629215f, 0.997236f,0.000528422f,
+0.997423f,0.000440977f, 0.997598f,0.00036551f, 0.997758f,0.000300745f, 0.997909f,0.000245504f, 0.998049f,0.000198695f,
+0.998179f,0.000159314f, 0.9983f,0.000126441f, 0.998414f,9.92325e-05f, 0.998525f,7.69241e-05f, 0.998627f,5.88216e-05f,
+0.998724f,4.43003e-05f, 0.998818f,3.28005e-05f, 0.998906f,2.3824e-05f, 0.998992f,1.69307e-05f, 0.999075f,1.17348e-05f,
+0.999155f,7.90147e-06f, 0.999232f,5.14314e-06f, 0.999308f,3.21583e-06f, 0.999382f,1.91567e-06f, 0.999455f,1.07525e-06f,
+0.999525f,5.60054e-07f, 0.999595f,2.64839e-07f, 0.999664f,1.10033e-07f, 0.99973f,3.81371e-08f, 0.999797f,1.01137e-08f,
+0.999863f,1.77788e-09f, 0.999929f,1.85982e-10f, 0.999998f,2.18422e-11f,
+
+0.0996969f,0.69019f, 0.0705858f,0.536134f, 0.0838118f,0.571881f, 0.107243f,0.609282f, 0.134824f,0.63127f,
+0.164113f,0.639737f, 0.193835f,0.637765f, 0.223557f,0.629928f, 0.252956f,0.618122f, 0.281751f,0.603164f,
+0.309995f,0.586837f, 0.337486f,0.569065f, 0.364131f,0.55025f, 0.390031f,0.531196f, 0.415204f,0.512176f,
+0.439523f,0.492956f, 0.463018f,0.473812f, 0.485791f,0.455074f, 0.507783f,0.436616f, 0.529017f,0.418529f,
+0.549645f,0.401109f, 0.569598f,0.384176f, 0.588775f,0.367541f, 0.607227f,0.351315f, 0.625072f,0.335673f,
+0.642261f,0.320498f, 0.658771f,0.305751f, 0.67465f,0.291481f, 0.689922f,0.277696f, 0.704604f,0.264394f,
+0.718717f,0.25157f, 0.732273f,0.239217f, 0.74529f,0.227327f, 0.757787f,0.215891f, 0.769776f,0.2049f,
+0.781275f,0.194343f, 0.792297f,0.18421f, 0.802858f,0.174491f, 0.812973f,0.165174f, 0.822656f,0.156249f,
+0.831921f,0.147705f, 0.840781f,0.13953f, 0.849343f,0.131774f, 0.857564f,0.124381f, 0.86534f,0.117266f,
+0.872746f,0.110466f, 0.879807f,0.103977f, 0.886535f,0.0977906f, 0.892947f,0.0918976f, 0.899051f,0.0862882f,
+0.904861f,0.0809528f, 0.910388f,0.0758818f, 0.915642f,0.0710655f, 0.920634f,0.0664948f, 0.925374f,0.0621603f,
+0.929873f,0.0580531f, 0.934139f,0.0541643f, 0.938181f,0.0504854f, 0.94201f,0.0470079f, 0.945633f,0.0437236f,
+0.94906f,0.0406244f, 0.9523f,0.0377027f, 0.95536f,0.0349507f, 0.958247f,0.0323611f, 0.96097f,0.0299267f,
+0.963535f,0.0276405f, 0.965951f,0.0254957f, 0.968225f,0.0234856f, 0.970362f,0.021604f, 0.97237f,0.0198447f,
+0.974254f,0.0182015f, 0.976021f,0.0166687f, 0.977677f,0.0152407f, 0.979228f,0.0139121f, 0.980678f,0.0126776f,
+0.982034f,0.0115321f, 0.9833f,0.0104709f, 0.984481f,0.00948905f, 0.985583f,0.00858219f, 0.986608f,0.00774593f,
+0.987564f,0.00697606f, 0.988451f,0.00626857f, 0.989276f,0.00561961f, 0.990043f,0.00502549f, 0.990753f,0.00448265f,
+0.991412f,0.00398772f, 0.992022f,0.00353746f, 0.992587f,0.00312879f, 0.993109f,0.00275876f, 0.993594f,0.00242457f,
+0.994041f,0.00212355f, 0.994455f,0.00185319f, 0.994836f,0.00161108f, 0.995189f,0.00139494f, 0.995516f,0.00120264f,
+0.995818f,0.00103215f, 0.996097f,0.000881562f, 0.996356f,0.000749078f, 0.996595f,0.000633019f, 0.996818f,0.00053181f,
+0.997024f,0.000443979f, 0.997216f,0.000368154f, 0.997396f,0.000303061f, 0.997563f,0.000247518f, 0.997721f,0.000200435f,
+0.997869f,0.000160807f, 0.998007f,0.000127711f, 0.998138f,0.000100305f, 0.998262f,7.78208e-05f, 0.99838f,5.95639e-05f,
+0.998494f,4.49079e-05f, 0.998602f,3.32918e-05f, 0.998706f,2.42158e-05f, 0.998807f,1.72384e-05f, 0.998904f,1.19723e-05f,
+0.998998f,8.08123e-06f, 0.99909f,5.27614e-06f, 0.999179f,3.31167e-06f, 0.999266f,1.98263e-06f, 0.999352f,1.12033e-06f,
+0.999436f,5.89072e-07f, 0.999518f,2.82508e-07f, 0.999599f,1.20063e-07f, 0.999679f,4.33353e-08f, 0.999758f,1.25019e-08f,
+0.999836f,2.71252e-09f, 0.999914f,4.87336e-10f, 0.999997f,1.09682e-10f,
+
+0.114294f,0.675955f, 0.0810286f,0.525802f, 0.0905226f,0.548002f, 0.11119f,0.580711f, 0.136756f,0.603272f,
+0.16455f,0.613858f, 0.193328f,0.615713f, 0.222209f,0.610182f, 0.250991f,0.600673f, 0.279347f,0.587955f,
+0.307153f,0.573066f, 0.334337f,0.556833f, 0.360922f,0.53996f, 0.386698f,0.522151f, 0.41166f,0.503848f,
+0.435908f,0.485582f, 0.459429f,0.467445f, 0.48219f,0.449419f, 0.504143f,0.431499f, 0.525341f,0.413868f,
+0.545893f,0.396768f, 0.565692f,0.379975f, 0.584776f,0.363578f, 0.603286f,0.347797f, 0.621208f,0.332564f,
+0.638478f,0.317752f, 0.655031f,0.303271f, 0.670947f,0.289228f, 0.686331f,0.275738f, 0.701135f,0.262701f,
+0.715326f,0.250066f, 0.728951f,0.23787f, 0.742034f,0.226118f, 0.754595f,0.214805f, 0.766648f,0.203923f,
+0.778209f,0.193465f, 0.789294f,0.183421f, 0.799918f,0.173782f, 0.810095f,0.164538f, 0.819839f,0.155679f,
+0.829165f,0.147194f, 0.838087f,0.139073f, 0.846617f,0.131306f, 0.854769f,0.123883f, 0.862556f,0.116791f,
+0.869989f,0.110022f, 0.877081f,0.103566f, 0.883846f,0.097411f, 0.890293f,0.091548f, 0.896611f,0.0860532f,
+0.902544f,0.0807763f, 0.908151f,0.0757391f, 0.913472f,0.0709481f, 0.918526f,0.0663978f, 0.923325f,0.0620806f,
+0.927878f,0.0579883f, 0.932198f,0.0541125f, 0.936293f,0.0504449f, 0.940173f,0.0469772f, 0.943847f,0.0437015f,
+0.947323f,0.0406099f, 0.950611f,0.0376947f, 0.953716f,0.0349484f, 0.95665f,0.0323636f, 0.959417f,0.0299333f,
+0.962028f,0.0276505f, 0.964487f,0.0255086f, 0.966802f,0.023501f, 0.968981f,0.0216213f, 0.971029f,0.0198634f,
+0.972952f,0.0182214f, 0.97476f,0.0166895f, 0.976454f,0.0152621f, 0.978041f,0.0139338f, 0.979528f,0.0126994f,
+0.980919f,0.0115538f, 0.982221f,0.0104923f, 0.983435f,0.00951011f, 0.98457f,0.00860274f, 0.985629f,0.00776586f,
+0.986616f,0.00699531f, 0.987535f,0.00628707f, 0.98839f,0.00563731f, 0.989186f,0.00504234f, 0.989926f,0.00449864f,
+0.990614f,0.00400283f, 0.991251f,0.00355168f, 0.991844f,0.00314212f, 0.992394f,0.00277121f, 0.992904f,0.00243615f,
+0.993377f,0.00213429f, 0.993815f,0.0018631f, 0.994222f,0.00162019f, 0.9946f,0.00140329f, 0.994949f,0.00121026f,
+0.995274f,0.00103907f, 0.995577f,0.00088782f, 0.995856f,0.000754713f, 0.996119f,0.00063807f, 0.996361f,0.000536315f,
+0.996588f,0.000447975f, 0.996801f,0.000371681f, 0.997f,0.000306155f, 0.997187f,0.000250217f, 0.997362f,0.000202773f,
+0.997528f,0.000162818f, 0.997686f,0.000129429f, 0.997835f,0.000101759f, 0.997978f,7.90418e-05f, 0.998113f,6.05791e-05f,
+0.998243f,4.57433e-05f, 0.998367f,3.39712e-05f, 0.998488f,2.47613e-05f, 0.998605f,1.76701e-05f, 0.998718f,1.23086e-05f,
+0.998826f,8.33841e-06f, 0.998934f,5.46877e-06f, 0.999037f,3.45255e-06f, 0.999139f,2.08281e-06f, 0.99924f,1.18928e-06f,
+0.999338f,6.34693e-07f, 0.999434f,3.11301e-07f, 0.999528f,1.37209e-07f, 0.999623f,5.2837e-08f, 0.999715f,1.73181e-08f,
+0.999806f,4.90744e-09f, 0.999896f,1.38859e-09f, 0.999994f,4.70601e-10f,
+
+0.129435f,0.661419f, 0.0925656f,0.517375f, 0.0984476f,0.527661f, 0.116309f,0.55469f, 0.139714f,0.576341f,
+0.165897f,0.588571f, 0.193405f,0.592402f, 0.221484f,0.590127f, 0.249475f,0.582414f, 0.277295f,0.57185f,
+0.304619f,0.558604f, 0.331508f,0.544169f, 0.357684f,0.528224f, 0.383249f,0.511735f, 0.408202f,0.495004f,
+0.432353f,0.47773f, 0.455702f,0.460203f, 0.478378f,0.442891f, 0.500284f,0.425635f, 0.521613f,0.408911f,
+0.542122f,0.392234f, 0.5619f,0.375847f, 0.58098f,0.359825f, 0.599473f,0.344355f, 0.617267f,0.329226f,
+0.634396f,0.3145f, 0.650973f,0.300324f, 0.666986f,0.286639f, 0.682471f,0.273464f, 0.697324f,0.260644f,
+0.711559f,0.248198f, 0.725227f,0.23617f, 0.738368f,0.224584f, 0.751107f,0.213531f, 0.763257f,0.202806f,
+0.774897f,0.192473f, 0.786054f,0.182537f, 0.796748f,0.172993f, 0.806992f,0.163833f, 0.816803f,0.15505f,
+0.826196f,0.146633f, 0.835182f,0.138573f, 0.843777f,0.130862f, 0.851994f,0.123488f, 0.859843f,0.116442f,
+0.867338f,0.109714f, 0.874494f,0.103294f, 0.881319f,0.097173f, 0.887826f,0.0913401f, 0.894029f,0.085786f,
+0.899935f,0.0805013f, 0.905557f,0.0754768f, 0.910907f,0.070703f, 0.915992f,0.066171f, 0.920824f,0.0618718f,
+0.925415f,0.0577967f, 0.929972f,0.0540121f, 0.934185f,0.0503824f, 0.938144f,0.0469357f, 0.941885f,0.0436746f,
+0.945421f,0.0405943f, 0.948764f,0.037688f, 0.951925f,0.0349491f, 0.954911f,0.0323704f, 0.957727f,0.0299452f,
+0.960387f,0.0276666f, 0.962893f,0.0255281f, 0.965255f,0.0235233f, 0.96748f,0.0216458f, 0.969572f,0.0198896f,
+0.97154f,0.0182488f, 0.973387f,0.0167177f, 0.975123f,0.0152908f, 0.976752f,0.0139627f, 0.978278f,0.0127283f,
+0.979708f,0.0115825f, 0.981048f,0.0105205f, 0.982301f,0.0095377f, 0.983471f,0.00862958f, 0.984566f,0.00779185f,
+0.985587f,0.00702034f, 0.986541f,0.0063111f, 0.987429f,0.00566026f, 0.988258f,0.00506418f, 0.989029f,0.00451934f,
+0.989749f,0.00402238f, 0.990417f,0.00357007f, 0.991039f,0.00315936f, 0.991617f,0.00278731f, 0.992157f,0.00245114f,
+0.992657f,0.00214818f, 0.993123f,0.00187594f, 0.993556f,0.00163201f, 0.993959f,0.00141413f, 0.994335f,0.00122016f,
+0.994685f,0.00104807f, 0.995011f,0.000895973f, 0.995315f,0.000762066f, 0.9956f,0.000644673f, 0.995866f,0.000542215f,
+0.996116f,0.000453223f, 0.99635f,0.000376323f, 0.99657f,0.000310239f, 0.996778f,0.00025379f, 0.996975f,0.000205879f,
+0.997162f,0.000165501f, 0.997338f,0.000131729f, 0.997507f,0.000103717f, 0.997668f,8.06936e-05f, 0.997822f,6.19606e-05f,
+0.997971f,4.68873e-05f, 0.998113f,3.49085e-05f, 0.998251f,2.55201e-05f, 0.998384f,1.82764e-05f, 0.998515f,1.27859e-05f,
+0.998641f,8.70802e-06f, 0.998763f,5.74968e-06f, 0.998884f,3.66156e-06f, 0.999003f,2.23457e-06f, 0.999117f,1.29639e-06f,
+0.999231f,7.07838e-07f, 0.999342f,3.59345e-07f, 0.999452f,1.67349e-07f, 0.999561f,7.07501e-08f, 0.999667f,2.73224e-08f,
+0.999772f,1.01393e-08f, 0.999877f,3.98817e-09f, 0.99999f,1.76554e-09f,
+
+0.144963f,0.646512f, 0.105045f,0.509972f, 0.107477f,0.510285f, 0.122585f,0.531821f, 0.143736f,0.551196f,
+0.168165f,0.563979f, 0.194324f,0.569585f, 0.221279f,0.568989f, 0.248565f,0.564041f, 0.275638f,0.55492f,
+0.302502f,0.543743f, 0.328865f,0.530459f, 0.354781f,0.516241f, 0.380031f,0.50084f, 0.404653f,0.484917f,
+0.428624f,0.468682f, 0.452017f,0.452507f, 0.474626f,0.436026f, 0.496438f,0.419402f, 0.517605f,0.403071f,
+0.538099f,0.387006f, 0.557934f,0.371267f, 0.57712f,0.355868f, 0.595574f,0.340696f, 0.613355f,0.325874f,
+0.630491f,0.311442f, 0.647081f,0.297532f, 0.663045f,0.284003f, 0.678389f,0.270861f, 0.693146f,0.258135f,
+0.707458f,0.245963f, 0.721241f,0.234217f, 0.734562f,0.222942f, 0.747305f,0.211999f, 0.759497f,0.201409f,
+0.771184f,0.1912f, 0.782388f,0.181377f, 0.793221f,0.172009f, 0.803607f,0.163005f, 0.813513f,0.154329f,
+0.822987f,0.146f, 0.83205f,0.138015f, 0.840717f,0.13037f, 0.849002f,0.123054f, 0.856923f,0.11606f,
+0.864485f,0.109379f, 0.871707f,0.103001f, 0.878598f,0.0969176f, 0.885172f,0.0911186f, 0.891437f,0.0855949f,
+0.897407f,0.0803375f, 0.903091f,0.0753375f, 0.908502f,0.0705857f, 0.913648f,0.0660732f, 0.91854f,0.0617914f,
+0.923188f,0.0577318f, 0.927602f,0.053886f, 0.93179f,0.0502458f, 0.935763f,0.046803f, 0.939527f,0.0435498f,
+0.943093f,0.0404785f, 0.946468f,0.0375816f, 0.949661f,0.0348517f, 0.952882f,0.0323392f, 0.955827f,0.0299423f,
+0.958567f,0.0276775f, 0.961141f,0.0255473f, 0.963562f,0.0235481f, 0.965841f,0.0216746f, 0.967984f,0.0199213f,
+0.970001f,0.0182825f, 0.971899f,0.0167528f, 0.97368f,0.0153267f, 0.975354f,0.013999f, 0.976924f,0.0127646f,
+0.978397f,0.0116185f, 0.979778f,0.010556f, 0.981071f,0.0095724f, 0.982282f,0.00866337f, 0.983414f,0.00782457f,
+0.984474f,0.00705189f, 0.985464f,0.00634137f, 0.986389f,0.0056892f, 0.987253f,0.00509173f, 0.988059f,0.00454547f,
+0.988811f,0.00404706f, 0.989513f,0.00359332f, 0.990168f,0.00318117f, 0.990779f,0.0028077f, 0.991348f,0.00247013f,
+0.991878f,0.00216583f, 0.992374f,0.00189226f, 0.992835f,0.00164705f, 0.993267f,0.00142794f, 0.993671f,0.0012328f,
+0.994047f,0.00105959f, 0.9944f,0.000906434f, 0.99473f,0.000771525f, 0.99504f,0.000653187f, 0.995332f,0.000549846f,
+0.995604f,0.000460029f, 0.995862f,0.000382365f, 0.996107f,0.000315574f, 0.996336f,0.000258475f, 0.996556f,0.00020997f,
+0.996763f,0.00016905f, 0.996962f,0.000134787f, 0.997151f,0.000106334f, 0.997332f,8.2916e-05f, 0.997506f,6.3832e-05f,
+0.997675f,4.8449e-05f, 0.997837f,3.61988e-05f, 0.997993f,2.65748e-05f, 0.998146f,1.91283e-05f, 0.998294f,1.34649e-05f,
+0.998438f,9.24139e-06f, 0.998579f,6.16184e-06f, 0.998717f,3.97422e-06f, 0.998851f,2.46686e-06f, 0.998984f,1.46494e-06f,
+0.999113f,8.2688e-07f, 0.999242f,4.40876e-07f, 0.999366f,2.21275e-07f, 0.999491f,1.05058e-07f, 0.999613f,4.82674e-08f,
+0.999734f,2.24437e-08f, 0.999855f,1.10559e-08f, 0.999984f,5.865e-09f,
+
+0.160753f,0.631274f, 0.118321f,0.503019f, 0.117501f,0.49541f, 0.129884f,0.511008f, 0.148783f,0.527861f,
+0.171357f,0.540262f, 0.196043f,0.546972f, 0.221822f,0.548032f, 0.248109f,0.544646f, 0.274564f,0.537992f,
+0.300713f,0.527978f, 0.32663f,0.516469f, 0.352096f,0.503454f, 0.376962f,0.489176f, 0.401408f,0.474673f,
+0.42509f,0.459241f, 0.448188f,0.443709f, 0.470644f,0.428076f, 0.492545f,0.412646f, 0.513694f,0.397083f,
+0.534084f,0.381495f, 0.55382f,0.366169f, 0.572941f,0.351189f, 0.591376f,0.336449f, 0.609278f,0.322209f,
+0.626519f,0.308249f, 0.643093f,0.294584f, 0.659045f,0.281282f, 0.674403f,0.268371f, 0.689221f,0.255905f,
+0.703535f,0.243897f, 0.717256f,0.232234f, 0.730435f,0.220958f, 0.743104f,0.210088f, 0.755384f,0.199711f,
+0.767175f,0.189707f, 0.778583f,0.180147f, 0.78949f,0.170909f, 0.799893f,0.161982f, 0.809843f,0.153393f,
+0.819365f,0.145148f, 0.828478f,0.137241f, 0.837302f,0.129734f, 0.845731f,0.122533f, 0.85375f,0.115618f,
+0.8614f,0.108998f, 0.868701f,0.102673f, 0.875668f,0.0966351f, 0.882312f,0.0908761f, 0.888649f,0.085388f,
+0.894688f,0.0801623f, 0.90044f,0.0751901f, 0.905917f,0.0704631f, 0.911128f,0.0659728f, 0.916085f,0.0617107f,
+0.920795f,0.0576685f, 0.925271f,0.053838f, 0.92952f,0.0502112f, 0.933552f,0.0467803f, 0.937376f,0.0435375f,
+0.941f,0.0404752f, 0.944433f,0.037586f, 0.947682f,0.0348628f, 0.950756f,0.0322985f, 0.953661f,0.0298862f,
+0.956408f,0.0276191f, 0.958999f,0.0254909f, 0.961446f,0.023495f, 0.963753f,0.0216255f, 0.965927f,0.0198763f,
+0.968162f,0.0182825f, 0.9702f,0.016776f, 0.972068f,0.0153593f, 0.973808f,0.0140363f, 0.975437f,0.0128042f,
+0.976963f,0.0116593f, 0.978393f,0.0105971f, 0.979733f,0.00961326f, 0.980989f,0.00870357f, 0.982166f,0.00786382f,
+0.983267f,0.00708995f, 0.984298f,0.00637807f, 0.985264f,0.00572442f, 0.986167f,0.00512538f, 0.98701f,0.00457748f,
+0.987799f,0.0040774f, 0.988536f,0.00362195f, 0.989227f,0.00320811f, 0.989872f,0.00283295f, 0.990474f,0.00249371f,
+0.991038f,0.00218777f, 0.991565f,0.00191261f, 0.992059f,0.00166586f, 0.99252f,0.00144526f, 0.992953f,0.00124868f,
+0.993359f,0.00107411f, 0.99374f,0.000919654f, 0.994098f,0.000783514f, 0.994435f,0.000664016f, 0.994753f,0.000559585f,
+0.995053f,0.000468749f, 0.995336f,0.000390136f, 0.995605f,0.000322466f, 0.99586f,0.000264555f, 0.996102f,0.000215304f,
+0.996334f,0.000173704f, 0.996556f,0.000138822f, 0.996767f,0.000109809f, 0.996971f,8.58877e-05f, 0.997167f,6.6354e-05f,
+0.997356f,5.05718e-05f, 0.997539f,3.79698e-05f, 0.997716f,2.80379e-05f, 0.997888f,2.03243e-05f, 0.998056f,1.44313e-05f,
+0.998219f,1.00124e-05f, 0.998379f,6.76829e-06f, 0.998535f,4.44386e-06f, 0.998688f,2.8243e-06f, 0.998839f,1.73179e-06f,
+0.998985f,1.02188e-06f, 0.999131f,5.80049e-07f, 0.999273f,3.18081e-07f, 0.999414f,1.70595e-07f, 0.999553f,9.14716e-08f,
+0.999691f,5.03136e-08f, 0.999827f,2.88861e-08f, 0.999975f,1.73769e-08f,
+
+0.17675f,0.615851f, 0.132284f,0.496092f, 0.128413f,0.482152f, 0.138174f,0.49244f, 0.154843f,0.506568f,
+0.175518f,0.517999f, 0.198593f,0.524828f, 0.223093f,0.527114f, 0.248338f,0.525269f, 0.273879f,0.519986f,
+0.299494f,0.512275f, 0.324735f,0.501769f, 0.349696f,0.490037f, 0.374265f,0.477313f, 0.398243f,0.463499f,
+0.421714f,0.449298f, 0.444644f,0.434815f, 0.466841f,0.419826f, 0.488477f,0.404921f, 0.509491f,0.390053f,
+0.529955f,0.375438f, 0.549729f,0.360848f, 0.56879f,0.346327f, 0.587161f,0.33198f, 0.60497f,0.318033f,
+0.622195f,0.304449f, 0.63876f,0.291114f, 0.654863f,0.278307f, 0.670338f,0.265781f, 0.685197f,0.253563f,
+0.699483f,0.241702f, 0.713219f,0.230216f, 0.726424f,0.219112f, 0.739211f,0.208481f, 0.751471f,0.198192f,
+0.763221f,0.188251f, 0.77449f,0.178672f, 0.785306f,0.169459f, 0.795801f,0.160698f, 0.805794f,0.152222f,
+0.81551f,0.144183f, 0.82485f,0.136481f, 0.833703f,0.129029f, 0.842144f,0.12187f, 0.850204f,0.115011f,
+0.857902f,0.108448f, 0.865254f,0.102175f, 0.872348f,0.0962246f, 0.879162f,0.090564f, 0.885609f,0.0851365f,
+0.891741f,0.0799564f, 0.897575f,0.0750216f, 0.903129f,0.0703261f, 0.908414f,0.0658629f, 0.913443f,0.0616243f,
+0.918224f,0.0576026f, 0.922767f,0.05379f, 0.927083f,0.0501789f, 0.93118f,0.0467615f, 0.935068f,0.0435305f,
+0.938754f,0.0404784f, 0.942247f,0.0375979f, 0.945558f,0.0348822f, 0.94869f,0.0323241f, 0.951655f,0.029917f,
+0.954456f,0.0276543f, 0.957105f,0.0255295f, 0.959605f,0.0235364f, 0.961967f,0.0216689f, 0.964193f,0.0199212f,
+0.966292f,0.0182874f, 0.96827f,0.016762f, 0.970132f,0.0153396f, 0.971885f,0.014015f, 0.973533f,0.0127831f,
+0.975083f,0.0116391f, 0.976538f,0.0105781f, 0.978075f,0.00962403f, 0.97949f,0.0087337f, 0.980756f,0.00790057f,
+0.981926f,0.00712918f, 0.983014f,0.00641792f, 0.984029f,0.0057639f, 0.984979f,0.0051639f, 0.985868f,0.00461468f,
+0.9867f,0.00411305f, 0.987478f,0.00365591f, 0.988208f,0.00324028f, 0.988891f,0.00286328f, 0.98953f,0.00252219f,
+0.99013f,0.00221441f, 0.990691f,0.00193742f, 0.991219f,0.00168889f, 0.991715f,0.00146655f, 0.99218f,0.0012683f,
+0.992618f,0.00109212f, 0.993029f,0.000936111f, 0.993418f,0.000798502f, 0.993783f,0.00067761f, 0.99413f,0.000571866f,
+0.994457f,0.000479797f, 0.994769f,0.000400029f, 0.995064f,0.000331285f, 0.995346f,0.000272378f, 0.995614f,0.000222209f,
+0.995871f,0.000179764f, 0.996117f,0.000144112f, 0.996354f,0.000114398f, 0.996581f,8.98438e-05f, 0.9968f,6.97406e-05f,
+0.997012f,5.34495e-05f, 0.997216f,4.03956e-05f, 0.997415f,3.00655e-05f, 0.997608f,2.20033e-05f, 0.997797f,1.58077e-05f,
+0.997982f,1.11285e-05f, 0.998161f,7.66261e-06f, 0.998337f,5.1512e-06f, 0.99851f,3.3759e-06f, 0.998679f,2.15535e-06f,
+0.998845f,1.34175e-06f, 0.99901f,8.17332e-07f, 0.99917f,4.90851e-07f, 0.999329f,2.94067e-07f, 0.999486f,1.78228e-07f,
+0.999641f,1.1054e-07f, 0.999795f,7.06218e-08f, 0.999961f,4.64718e-08f,
+
+0.192897f,0.600379f, 0.146834f,0.489083f, 0.140129f,0.470325f, 0.147373f,0.47579f, 0.161853f,0.487154f,
+0.180589f,0.496928f, 0.202039f,0.50372f, 0.225156f,0.506668f, 0.24924f,0.505873f, 0.273845f,0.502023f,
+0.298594f,0.495432f, 0.323364f,0.487061f, 0.347715f,0.476328f, 0.371767f,0.46463f, 0.395441f,0.452192f,
+0.418588f,0.438969f, 0.441092f,0.425027f, 0.463194f,0.411228f, 0.48467f,0.397132f, 0.505446f,0.382783f,
+0.52569f,0.368642f, 0.545329f,0.35461f, 0.564399f,0.340801f, 0.582884f,0.327211f, 0.600717f,0.313777f,
+0.617867f,0.300493f, 0.634415f,0.287507f, 0.650423f,0.274901f, 0.665904f,0.262682f, 0.680762f,0.250725f,
+0.695197f,0.239261f, 0.709075f,0.22811f, 0.722376f,0.217255f, 0.735146f,0.206738f, 0.74741f,0.196575f,
+0.759188f,0.186768f, 0.770493f,0.177317f, 0.781467f,0.168316f, 0.791935f,0.159602f, 0.801955f,0.151211f,
+0.811552f,0.143148f, 0.82074f,0.13541f, 0.829661f,0.128069f, 0.838151f,0.120999f, 0.846317f,0.114252f,
+0.854259f,0.107869f, 0.861791f,0.10172f, 0.868936f,0.0958129f, 0.875735f,0.0901616f, 0.882216f,0.0847659f,
+0.888392f,0.0796209f, 0.894276f,0.0747203f, 0.899882f,0.0700568f, 0.905372f,0.0656842f, 0.910536f,0.0614994f,
+0.915419f,0.0575136f, 0.920051f,0.0537283f, 0.924447f,0.0501389f, 0.92862f,0.0467396f, 0.93258f,0.0435236f,
+0.936336f,0.0404842f, 0.939898f,0.0376144f, 0.943274f,0.0349076f, 0.946472f,0.032357f, 0.949498f,0.0299561f,
+0.952362f,0.0276984f, 0.955071f,0.0255776f, 0.957631f,0.0235876f, 0.96005f,0.0217225f, 0.962332f,0.0199764f,
+0.964488f,0.0183436f, 0.966519f,0.0168187f, 0.968435f,0.0153963f, 0.97024f,0.0140714f, 0.971939f,0.0128387f,
+0.973538f,0.0116936f, 0.975043f,0.0106314f, 0.976457f,0.00964745f, 0.977787f,0.00873749f, 0.979037f,0.0078973f,
+0.980211f,0.00712281f, 0.981314f,0.00641015f, 0.982348f,0.00575555f, 0.983318f,0.00515545f, 0.984407f,0.00462854f,
+0.985399f,0.00414097f, 0.986268f,0.0036881f, 0.987062f,0.00327354f, 0.987801f,0.00289621f, 0.988489f,0.00255409f,
+0.989134f,0.00224487f, 0.989738f,0.00196626f, 0.990305f,0.00171598f, 0.990837f,0.00149186f, 0.99134f,0.00129181f,
+0.991813f,0.00111386f, 0.992258f,0.000956127f, 0.99268f,0.00081685f, 0.993079f,0.000694359f, 0.993457f,0.000587089f,
+0.993815f,0.000493574f, 0.994155f,0.000412444f, 0.994481f,0.000342422f, 0.994791f,0.000282322f, 0.995087f,0.000231045f,
+0.995371f,0.000187578f, 0.995642f,0.000150984f, 0.995905f,0.000120409f, 0.996158f,9.50698e-05f, 0.996401f,7.42567e-05f,
+0.996638f,5.73263e-05f, 0.996866f,4.37003e-05f, 0.997088f,3.28613e-05f, 0.997306f,2.43497e-05f, 0.997516f,1.776e-05f,
+0.997723f,1.27378e-05f, 0.997924f,8.97613e-06f, 0.998122f,6.21186e-06f, 0.998314f,4.2226e-06f, 0.998504f,2.82303e-06f,
+0.998691f,1.8615e-06f, 0.998874f,1.21652e-06f, 0.999055f,7.93312e-07f, 0.999234f,5.20283e-07f, 0.999408f,3.45563e-07f,
+0.999583f,2.33477e-07f, 0.999756f,1.61011e-07f, 0.999942f,1.13074e-07f,
+
+0.209082f,0.58486f, 0.161831f,0.48183f, 0.152529f,0.459609f, 0.157379f,0.460816f, 0.16969f,0.46891f,
+0.186565f,0.477488f, 0.206348f,0.483734f, 0.228016f,0.486861f, 0.250902f,0.48703f, 0.27443f,0.484027f,
+0.29833f,0.478759f, 0.322266f,0.471283f, 0.346186f,0.462491f, 0.369712f,0.451862f, 0.392847f,0.440202f,
+0.415608f,0.427977f, 0.437929f,0.415307f, 0.459682f,0.40213f, 0.480805f,0.388557f, 0.501555f,0.375286f,
+0.521652f,0.361795f, 0.541068f,0.34818f, 0.559991f,0.33486f, 0.578317f,0.321677f, 0.596094f,0.308747f,
+0.613349f,0.296117f, 0.63001f,0.2837f, 0.646032f,0.271461f, 0.661441f,0.25946f, 0.676314f,0.247802f,
+0.690679f,0.236506f, 0.704561f,0.225587f, 0.717868f,0.214939f, 0.730749f,0.20471f, 0.743192f,0.194858f,
+0.755084f,0.18527f, 0.766483f,0.175996f, 0.777417f,0.167048f, 0.787903f,0.15843f, 0.797958f,0.150139f,
+0.807619f,0.142186f, 0.816971f,0.134613f, 0.825877f,0.127306f, 0.834389f,0.120289f, 0.842526f,0.113564f,
+0.850306f,0.107126f, 0.857822f,0.101013f, 0.865025f,0.0951773f, 0.871866f,0.0895815f, 0.878472f,0.0842771f,
+0.884924f,0.0792832f, 0.890978f,0.0744688f, 0.896709f,0.0698637f, 0.90215f,0.0654742f, 0.907324f,0.0612982f,
+0.912243f,0.0573305f, 0.91692f,0.0535651f, 0.921366f,0.0499953f, 0.925615f,0.0466232f, 0.929783f,0.0434727f,
+0.933667f,0.0404667f, 0.937328f,0.0376188f, 0.94079f,0.0349277f, 0.944066f,0.0323891f, 0.947168f,0.0299974f,
+0.950103f,0.027747f, 0.952879f,0.0256319f, 0.955504f,0.0236463f, 0.957987f,0.0217844f, 0.960332f,0.0200406f,
+0.962548f,0.0184093f, 0.964639f,0.0168852f, 0.966611f,0.015463f, 0.968472f,0.0141377f, 0.970227f,0.0129043f,
+0.97188f,0.0117581f, 0.973437f,0.0106944f, 0.974904f,0.00970873f, 0.976283f,0.00879686f, 0.977581f,0.00795455f,
+0.978804f,0.00717783f, 0.979953f,0.00646282f, 0.981033f,0.00580581f, 0.98205f,0.00520322f, 0.983005f,0.00465164f,
+0.983902f,0.00414778f, 0.984746f,0.00368849f, 0.98554f,0.00327078f, 0.986286f,0.00289177f, 0.986989f,0.00254872f,
+0.98765f,0.00223902f, 0.988509f,0.00198136f, 0.98921f,0.00173857f, 0.989825f,0.00151646f, 0.990388f,0.00131647f,
+0.990912f,0.00113772f, 0.991403f,0.000978763f, 0.991865f,0.000838053f, 0.992303f,0.000714041f, 0.992718f,0.000605226f,
+0.993111f,0.000510183f, 0.993486f,0.00042757f, 0.993843f,0.000356124f, 0.994185f,0.000294672f, 0.994511f,0.00024212f,
+0.994825f,0.000197459f, 0.995126f,0.000159755f, 0.995417f,0.000128153f, 0.995697f,0.00010187f, 0.995968f,8.01945e-05f,
+0.99623f,6.248e-05f, 0.996485f,4.81452e-05f, 0.996733f,3.66697e-05f, 0.996973f,2.75899e-05f, 0.997209f,2.04964e-05f,
+0.997438f,1.50306e-05f, 0.997664f,1.08812e-05f, 0.997883f,7.78088e-06f, 0.998099f,5.50284e-06f, 0.998311f,3.85748e-06f,
+0.998519f,2.6889e-06f, 0.998724f,1.87154e-06f, 0.998925f,1.30662e-06f, 0.999123f,9.18801e-07f, 0.999319f,6.52627e-07f,
+0.999513f,4.69084e-07f, 0.999705f,3.42033e-07f, 0.999913f,2.51928e-07f,
+
+0.225267f,0.569388f, 0.177185f,0.474263f, 0.165515f,0.449552f, 0.168112f,0.447274f, 0.178359f,0.452556f,
+0.193376f,0.459501f, 0.211456f,0.464636f, 0.231675f,0.467885f, 0.253258f,0.468411f, 0.275739f,0.466536f,
+0.298631f,0.461979f, 0.321796f,0.455748f, 0.344908f,0.447673f, 0.367978f,0.438631f, 0.390723f,0.428295f,
+0.412961f,0.41674f, 0.43486f,0.404848f, 0.456342f,0.392636f, 0.477315f,0.380085f, 0.497703f,0.367226f,
+0.517508f,0.35423f, 0.536944f,0.341577f, 0.555754f,0.328831f, 0.573892f,0.316025f, 0.591527f,0.303493f,
+0.608644f,0.291217f, 0.625217f,0.279179f, 0.641283f,0.267438f, 0.656787f,0.255925f, 0.671787f,0.244725f,
+0.686171f,0.233712f, 0.699992f,0.222964f, 0.713325f,0.212558f, 0.726184f,0.202495f, 0.738623f,0.192812f,
+0.750524f,0.183388f, 0.761969f,0.174293f, 0.773113f,0.165635f, 0.783743f,0.15722f, 0.793908f,0.149086f,
+0.803643f,0.141249f, 0.812967f,0.133712f, 0.821898f,0.126474f, 0.830449f,0.11953f, 0.838654f,0.112888f,
+0.846606f,0.106583f, 0.854159f,0.100514f, 0.861362f,0.0947019f, 0.868236f,0.0891451f, 0.874799f,0.0838397f,
+0.881063f,0.0787794f, 0.887171f,0.0740182f, 0.892945f,0.0694542f, 0.898422f,0.0651001f, 0.90372f,0.060991f,
+0.908931f,0.0571466f, 0.91378f,0.0534463f, 0.918353f,0.0499194f, 0.922684f,0.0465698f, 0.926789f,0.043395f,
+0.930684f,0.0403903f, 0.934379f,0.0375502f, 0.937885f,0.0348687f, 0.941207f,0.0323399f, 0.944388f,0.0299662f,
+0.947529f,0.0277625f, 0.950433f,0.0256699f, 0.953158f,0.0236977f, 0.955727f,0.0218445f, 0.95815f,0.0201065f,
+0.960437f,0.0184791f, 0.962598f,0.0169575f, 0.964636f,0.0155366f, 0.966561f,0.0142118f, 0.968375f,0.0129782f,
+0.970088f,0.0118312f, 0.971702f,0.0107663f, 0.973225f,0.00977899f, 0.97466f,0.00886518f, 0.976012f,0.00802067f,
+0.977286f,0.00724155f, 0.978486f,0.00652399f, 0.979616f,0.00586431f, 0.98068f,0.00525897f, 0.981682f,0.00470459f,
+0.982626f,0.00419791f, 0.983515f,0.0037358f, 0.984353f,0.00331528f, 0.985143f,0.0029335f, 0.985888f,0.00258773f,
+0.98659f,0.00227538f, 0.987253f,0.00199397f, 0.987877f,0.00174115f, 0.988469f,0.0015147f, 0.989028f,0.00131251f,
+0.989559f,0.00113256f, 0.990059f,0.00097298f, 0.990694f,0.000842747f, 0.99132f,0.000728294f, 0.991832f,0.000621962f,
+0.992291f,0.000527232f, 0.992719f,0.000444053f, 0.993121f,0.000371648f, 0.993504f,0.000309058f, 0.993868f,0.000255302f,
+0.994216f,0.000209432f, 0.994552f,0.000170549f, 0.994875f,0.00013782f, 0.995185f,0.000110473f, 0.995486f,8.78044e-05f,
+0.995777f,6.91709e-05f, 0.996061f,5.39926e-05f, 0.996337f,4.17482e-05f, 0.996604f,3.19725e-05f, 0.996866f,2.42534e-05f,
+0.99712f,1.82291e-05f, 0.99737f,1.35846e-05f, 0.997614f,1.00487e-05f, 0.997855f,7.39045e-06f, 0.99809f,5.41594e-06f,
+0.998321f,3.96502e-06f, 0.998548f,2.90783e-06f, 0.998772f,2.14144e-06f, 0.998992f,1.58643e-06f, 0.99921f,1.18347e-06f,
+0.999425f,8.89821e-07f, 0.999639f,6.75782e-07f, 0.999868f,5.1523e-07f,
+
+0.241391f,0.554007f, 0.192796f,0.466327f, 0.178991f,0.439998f, 0.179466f,0.434671f, 0.187739f,0.437387f,
+0.200909f,0.442336f, 0.217387f,0.44695f, 0.236096f,0.449732f, 0.256344f,0.45037f, 0.277641f,0.448964f,
+0.299608f,0.445615f, 0.321824f,0.440003f, 0.344237f,0.43313f, 0.366548f,0.424752f, 0.388771f,0.41558f,
+0.410711f,0.405468f, 0.432133f,0.394247f, 0.453184f,0.382691f, 0.473826f,0.370885f, 0.49404f,0.358948f,
+0.513708f,0.346773f, 0.532797f,0.334433f, 0.551336f,0.3221f, 0.569501f,0.310112f, 0.587111f,0.298183f,
+0.60404f,0.286203f, 0.620459f,0.274472f, 0.636449f,0.2631f, 0.651878f,0.251919f, 0.66681f,0.241018f,
+0.681282f,0.230438f, 0.69521f,0.220087f, 0.70868f,0.210054f, 0.721578f,0.20023f, 0.733958f,0.190673f,
+0.745877f,0.181431f, 0.757388f,0.172538f, 0.768499f,0.163984f, 0.779135f,0.155694f, 0.789318f,0.147682f,
+0.799205f,0.14005f, 0.808722f,0.132721f, 0.817787f,0.125629f, 0.826447f,0.118802f, 0.834732f,0.112246f,
+0.842656f,0.105959f, 0.850233f,0.0999379f, 0.857479f,0.094178f, 0.864405f,0.0886729f, 0.87115f,0.0834785f,
+0.877538f,0.0784902f, 0.883616f,0.0737232f, 0.889407f,0.0691775f, 0.894925f,0.0648491f, 0.900182f,0.0607321f,
+0.905238f,0.0568395f, 0.910127f,0.0531683f, 0.914728f,0.0496644f, 0.91909f,0.0463362f, 0.923269f,0.0431946f,
+0.927487f,0.0402968f, 0.931368f,0.0375103f, 0.935008f,0.0348622f, 0.938442f,0.0323563f, 0.941688f,0.0299906f,
+0.944761f,0.0277613f, 0.947669f,0.0256636f, 0.950422f,0.0236921f, 0.953027f,0.0218418f, 0.955492f,0.0201073f,
+0.957825f,0.0184835f, 0.960203f,0.0169989f, 0.962379f,0.0155951f, 0.964407f,0.014279f, 0.966309f,0.0130501f,
+0.968098f,0.0119054f, 0.969784f,0.0108412f, 0.971374f,0.00985371f, 0.972872f,0.00893887f, 0.974285f,0.0080928f,
+0.975617f,0.00731168f, 0.976874f,0.0065918f, 0.978059f,0.00592956f, 0.979177f,0.00532149f, 0.980231f,0.00476425f,
+0.981225f,0.00425462f, 0.982164f,0.00378952f, 0.983049f,0.003366f, 0.983886f,0.00298122f, 0.984676f,0.0026325f,
+0.985423f,0.00231723f, 0.986128f,0.00203298f, 0.986796f,0.0017774f, 0.987428f,0.00154828f, 0.988028f,0.0013435f,
+0.988597f,0.00116109f, 0.989137f,0.000999155f, 0.989651f,0.000855923f, 0.99014f,0.000729724f, 0.990606f,0.000618989f,
+0.991051f,0.000522247f, 0.991478f,0.000438125f, 0.991884f,0.000365338f, 0.992459f,0.000311657f, 0.993008f,0.000264633f,
+0.993451f,0.000220449f, 0.993851f,0.000181695f, 0.994225f,0.000148474f, 0.994579f,0.00012037f, 0.99492f,9.68374e-05f,
+0.995247f,7.73129e-05f, 0.995563f,6.12593e-05f, 0.995871f,4.8179e-05f, 0.996169f,3.76198e-05f, 0.99646f,2.91768e-05f,
+0.996743f,2.24909e-05f, 0.997022f,1.72476e-05f, 0.997293f,1.31746e-05f, 0.997559f,1.00387e-05f, 0.997821f,7.64307e-06f,
+0.998076f,5.82406e-06f, 0.998329f,4.44816e-06f, 0.998577f,3.40858e-06f, 0.998821f,2.62199e-06f, 0.999062f,2.02521e-06f,
+0.9993f,1.5717e-06f, 0.999537f,1.22792e-06f, 0.999788f,9.58068e-07f,
+
+0.257395f,0.538737f, 0.208569f,0.45801f, 0.192857f,0.430741f, 0.19136f,0.423018f, 0.197763f,0.423497f,
+0.20919f,0.426809f, 0.224062f,0.430473f, 0.241274f,0.43259f, 0.260202f,0.433318f, 0.280271f,0.432078f,
+0.301136f,0.429152f, 0.322514f,0.424706f, 0.344023f,0.418356f, 0.365669f,0.411048f, 0.387175f,0.402498f,
+0.408535f,0.393228f, 0.429669f,0.383362f, 0.450368f,0.372701f, 0.470548f,0.361399f, 0.490378f,0.350031f,
+0.509769f,0.338531f, 0.528731f,0.327019f, 0.547157f,0.315393f, 0.56501f,0.30369f, 0.582334f,0.292065f,
+0.599273f,0.280765f, 0.615753f,0.269674f, 0.631575f,0.258568f, 0.646849f,0.24764f, 0.661715f,0.237071f,
+0.676097f,0.226757f, 0.690005f,0.216715f, 0.703447f,0.206954f, 0.716423f,0.197467f, 0.728887f,0.188214f,
+0.740976f,0.17931f, 0.75253f,0.170614f, 0.763606f,0.162174f, 0.774231f,0.154009f, 0.784522f,0.146197f,
+0.794423f,0.138678f, 0.803923f,0.131433f, 0.813001f,0.124437f, 0.821711f,0.117721f, 0.830199f,0.111355f,
+0.838296f,0.105219f, 0.846004f,0.0993102f, 0.85336f,0.0936406f, 0.860387f,0.0882115f, 0.867099f,0.0830207f,
+0.873507f,0.0780633f, 0.879626f,0.0733341f, 0.885466f,0.0688267f, 0.891144f,0.0645792f, 0.89654f,0.0605252f,
+0.901657f,0.0566588f, 0.906524f,0.0529816f, 0.911152f,0.0494899f, 0.915554f,0.0461785f, 0.919742f,0.0430418f,
+0.923811f,0.0401015f, 0.927699f,0.0373243f, 0.931355f,0.0346875f, 0.934813f,0.032194f, 0.938107f,0.0298462f,
+0.941458f,0.0276921f, 0.944585f,0.025645f, 0.947488f,0.0237026f, 0.950212f,0.021871f, 0.952779f,0.0201493f,
+0.955203f,0.0185345f, 0.957492f,0.0170225f, 0.959656f,0.0156091f, 0.961701f,0.0142898f, 0.963633f,0.0130602f,
+0.96546f,0.0119158f, 0.967185f,0.0108524f, 0.96895f,0.00988602f, 0.970605f,0.0089867f, 0.972131f,0.00814765f,
+0.973552f,0.00736967f, 0.974888f,0.00665082f, 0.976144f,0.00598834f, 0.977328f,0.00537922f, 0.978445f,0.00482036f,
+0.979498f,0.00430873f, 0.980494f,0.00384137f, 0.981434f,0.0034154f, 0.982323f,0.00302807f, 0.983165f,0.00267672f,
+0.983961f,0.0023588f, 0.984715f,0.0020719f, 0.98543f,0.00181371f, 0.986109f,0.00158202f, 0.986753f,0.00137475f,
+0.987366f,0.00118991f, 0.987948f,0.00102565f, 0.988504f,0.00088019f, 0.989033f,0.000751867f, 0.989539f,0.000639117f,
+0.990023f,0.000540476f, 0.990486f,0.000454567f, 0.990931f,0.00038011f, 0.991357f,0.000315911f, 0.991769f,0.000260863f,
+0.992163f,0.000213941f, 0.992546f,0.0001742f, 0.992915f,0.00014077f, 0.993308f,0.000114178f, 0.993946f,0.000100259f,
+0.994394f,8.30396e-05f, 0.994785f,6.74749e-05f, 0.995149f,5.42282e-05f, 0.995493f,4.32345e-05f, 0.995825f,3.42496e-05f,
+0.996146f,2.69914e-05f, 0.996458f,2.11845e-05f, 0.996762f,1.65771e-05f, 0.997059f,1.29469e-05f, 0.997351f,1.01024e-05f,
+0.997637f,7.8818e-06f, 0.997918f,6.15151e-06f, 0.998193f,4.80329e-06f, 0.998464f,3.75168e-06f, 0.998732f,2.93084e-06f,
+0.998998f,2.29136e-06f, 0.999262f,1.79649e-06f, 0.99954f,1.40021e-06f,
+
+0.273267f,0.523649f, 0.224448f,0.449371f, 0.207048f,0.421689f, 0.203725f,0.412115f, 0.20836f,0.410656f,
+0.218099f,0.412278f, 0.231364f,0.414613f, 0.24719f,0.416623f, 0.264734f,0.416867f, 0.283642f,0.416046f,
+0.303387f,0.413384f, 0.323755f,0.409394f, 0.344516f,0.404181f, 0.365318f,0.397351f, 0.386213f,0.38979f,
+0.406939f,0.381192f, 0.427479f,0.371954f, 0.447831f,0.36235f, 0.467814f,0.352193f, 0.48725f,0.341357f,
+0.506293f,0.330394f, 0.524925f,0.319365f, 0.543132f,0.308336f, 0.560906f,0.297358f, 0.578157f,0.286354f,
+0.594847f,0.275335f, 0.611011f,0.264416f, 0.626782f,0.253801f, 0.642186f,0.243509f, 0.656982f,0.233257f,
+0.671197f,0.223125f, 0.684957f,0.213268f, 0.698394f,0.203814f, 0.711317f,0.194558f, 0.7238f,0.185573f,
+0.735879f,0.176889f, 0.747497f,0.168446f, 0.758649f,0.160242f, 0.769429f,0.152345f, 0.779776f,0.144696f,
+0.789672f,0.137282f, 0.799151f,0.130122f, 0.808297f,0.123265f, 0.817083f,0.116676f, 0.825573f,0.110381f,
+0.833657f,0.104304f, 0.841376f,0.0984619f, 0.84882f,0.0928939f, 0.856048f,0.0876139f, 0.862919f,0.0825335f,
+0.86945f,0.0776583f, 0.875674f,0.0729947f, 0.881609f,0.0685423f, 0.88727f,0.0642974f, 0.892669f,0.0602553f,
+0.897816f,0.0564105f, 0.90272f,0.0527571f, 0.907457f,0.0493125f, 0.912011f,0.0460563f, 0.916309f,0.0429557f,
+0.920384f,0.0400142f, 0.924253f,0.0372294f, 0.927928f,0.0345969f, 0.931418f,0.0321114f, 0.934731f,0.0297676f,
+0.937987f,0.0275887f, 0.941068f,0.0255329f, 0.943961f,0.0235906f, 0.946689f,0.0217628f, 0.949268f,0.0200466f,
+0.951868f,0.0184718f, 0.954406f,0.0170081f, 0.956739f,0.0156223f, 0.958909f,0.0143189f, 0.960943f,0.013099f,
+0.962856f,0.0119608f, 0.96466f,0.0109011f, 0.966363f,0.0099165f, 0.967971f,0.00900335f, 0.969488f,0.00815797f,
+0.970924f,0.0073767f, 0.97228f,0.00665599f, 0.973562f,0.00599238f, 0.974835f,0.00538958f, 0.976137f,0.00484667f,
+0.977309f,0.00434147f, 0.978394f,0.0038766f, 0.979407f,0.00345116f, 0.980361f,0.00306326f, 0.98126f,0.00271067f,
+0.982111f,0.00239113f, 0.982915f,0.00210236f, 0.983678f,0.00184215f, 0.984402f,0.00160838f, 0.985091f,0.001399f,
+0.985745f,0.00121209f, 0.986369f,0.00104578f, 0.986963f,0.000898339f, 0.987531f,0.000768115f, 0.988074f,0.000653556f,
+0.988592f,0.000553201f, 0.989091f,0.000465683f, 0.989569f,0.000389725f, 0.990029f,0.000324134f, 0.990472f,0.000267804f,
+0.9909f,0.000219709f, 0.991312f,0.000178902f, 0.99171f,0.00014451f, 0.992096f,0.000115735f, 0.992471f,9.18471e-05f,
+0.992835f,7.21841e-05f, 0.993189f,5.61465e-05f, 0.993533f,4.31953e-05f, 0.994014f,3.653e-05f, 0.994585f,3.30116e-05f,
+0.995009f,2.72111e-05f, 0.995385f,2.17837e-05f, 0.995736f,1.71621e-05f, 0.996072f,1.33606e-05f, 0.996397f,1.02873e-05f,
+0.996713f,7.82752e-06f, 0.997021f,5.87125e-06f, 0.997323f,4.32222e-06f, 0.99762f,3.10074e-06f, 0.997912f,2.14327e-06f,
+0.9982f,1.40063e-06f, 0.998486f,8.34573e-07f, 0.998784f,3.81846e-07f,
+
+0.288961f,0.508755f, 0.240356f,0.440463f, 0.221476f,0.41269f, 0.21647f,0.401713f, 0.219429f,0.398472f,
+0.227571f,0.398693f, 0.239324f,0.400019f, 0.25372f,0.401384f, 0.269968f,0.401448f, 0.287622f,0.400462f,
+0.306296f,0.398225f, 0.325639f,0.394591f, 0.345454f,0.389809f, 0.365572f,0.384062f, 0.385672f,0.376946f,
+0.40582f,0.369252f, 0.425783f,0.360696f, 0.445544f,0.351607f, 0.465104f,0.342224f, 0.48435f,0.332472f,
+0.503157f,0.322295f, 0.521415f,0.311685f, 0.539327f,0.301145f, 0.556821f,0.290611f, 0.573887f,0.280127f,
+0.590531f,0.269748f, 0.606667f,0.259401f, 0.62228f,0.249111f, 0.63737f,0.238927f, 0.652044f,0.229002f,
+0.666381f,0.219417f, 0.680248f,0.210016f, 0.693537f,0.200711f, 0.70632f,0.191601f, 0.718725f,0.182807f,
+0.73081f,0.174365f, 0.742422f,0.16613f, 0.753621f,0.158154f, 0.764463f,0.150475f, 0.774871f,0.14302f,
+0.784845f,0.135791f, 0.79445f,0.128828f, 0.803683f,0.122118f, 0.812541f,0.115651f, 0.821007f,0.109412f,
+0.82911f,0.103411f, 0.83696f,0.0976995f, 0.844502f,0.0922314f, 0.85172f,0.0869859f, 0.858593f,0.081946f,
+0.865148f,0.0771184f, 0.871496f,0.072543f, 0.877645f,0.0682077f, 0.883474f,0.0640475f, 0.889008f,0.0600675f,
+0.894271f,0.0562715f, 0.899282f,0.0526579f, 0.904055f,0.049223f, 0.9086f,0.045962f, 0.912928f,0.0428697f,
+0.917048f,0.0399407f, 0.920968f,0.0371693f, 0.924832f,0.0345891f, 0.928454f,0.0321336f, 0.931876f,0.0298096f,
+0.935117f,0.0276161f, 0.938193f,0.0255495f, 0.941109f,0.0236053f, 0.943874f,0.0217787f, 0.946497f,0.0200648f,
+0.949111f,0.0184857f, 0.951561f,0.0169992f, 0.953856f,0.0156021f, 0.956018f,0.0142944f, 0.958059f,0.0130735f,
+0.960136f,0.0119617f, 0.962063f,0.0109179f, 0.964007f,0.00996425f, 0.965772f,0.00906585f, 0.96741f,0.00822793f,
+0.968947f,0.00745019f, 0.970391f,0.00673066f, 0.971751f,0.0060667f, 0.973037f,0.00545544f, 0.974252f,0.00489394f,
+0.975402f,0.00437928f, 0.97649f,0.00390861f, 0.977519f,0.00347911f, 0.978496f,0.0030881f, 0.979424f,0.002733f,
+0.980475f,0.00242555f, 0.981423f,0.00214221f, 0.982288f,0.00188337f, 0.983093f,0.0016491f, 0.983852f,0.00143826f,
+0.984569f,0.00124936f, 0.98525f,0.0010808f, 0.985897f,0.000930967f, 0.986516f,0.000798312f, 0.987106f,0.000681337f,
+0.987671f,0.000578623f, 0.988214f,0.000488828f, 0.988734f,0.000410692f, 0.989235f,0.000343036f, 0.989717f,0.000284762f,
+0.990182f,0.000234847f, 0.990633f,0.000192346f, 0.991067f,0.000156389f, 0.991488f,0.000126175f, 0.991898f,0.000100971f,
+0.992296f,8.01104e-05f, 0.992682f,6.29904e-05f, 0.993057f,4.90666e-05f, 0.993425f,3.78515e-05f, 0.993782f,2.89116e-05f,
+0.994132f,2.18637e-05f, 0.994474f,1.63721e-05f, 0.994912f,1.40014e-05f, 0.995544f,1.49489e-05f, 0.995985f,1.27963e-05f,
+0.99637f,1.03665e-05f, 0.996729f,8.15043e-06f, 0.997074f,6.24587e-06f, 0.997407f,4.65062e-06f, 0.997733f,3.33596e-06f,
+0.998051f,2.26885e-06f, 0.998368f,1.41722e-06f, 0.998698f,6.92188e-07f,
+
+0.304447f,0.494077f, 0.256232f,0.431304f, 0.236075f,0.403791f, 0.229523f,0.391719f, 0.230916f,0.387019f,
+0.237541f,0.385978f, 0.247833f,0.386293f, 0.260797f,0.386678f, 0.275823f,0.386871f, 0.292245f,0.385635f,
+0.309804f,0.383565f, 0.328128f,0.380248f, 0.347005f,0.375901f, 0.366236f,0.370563f, 0.385695f,0.364443f,
+0.405111f,0.357222f, 0.424509f,0.349452f, 0.443737f,0.341034f, 0.462748f,0.332152f, 0.481506f,0.322944f,
+0.500031f,0.313597f, 0.518177f,0.303962f, 0.535821f,0.29397f, 0.552984f,0.283808f, 0.569784f,0.273747f,
+0.586189f,0.263774f, 0.602171f,0.253889f, 0.617749f,0.24415f, 0.632825f,0.234466f, 0.647433f,0.224912f,
+0.661525f,0.215464f, 0.675187f,0.20624f, 0.688505f,0.197326f, 0.701438f,0.188667f, 0.713884f,0.180167f,
+0.725813f,0.171821f, 0.737296f,0.163699f, 0.748476f,0.155914f, 0.75931f,0.148412f, 0.769732f,0.141136f,
+0.77977f,0.134102f, 0.789486f,0.127345f, 0.79881f,0.120808f, 0.807714f,0.114469f, 0.816311f,0.108395f,
+0.824509f,0.102521f, 0.832375f,0.0968777f, 0.839955f,0.0914809f, 0.847184f,0.0862894f, 0.854139f,0.0813346f,
+0.860819f,0.0766016f, 0.867279f,0.0721064f, 0.873411f,0.0677872f, 0.879243f,0.063653f, 0.884802f,0.0597057f,
+0.890205f,0.0559832f, 0.895425f,0.0524603f, 0.900371f,0.0490926f, 0.905054f,0.0458798f, 0.909503f,0.0428244f,
+0.913731f,0.0399247f, 0.917753f,0.037177f, 0.921578f,0.0345768f, 0.925216f,0.0321195f, 0.928676f,0.0297997f,
+0.931965f,0.0276124f, 0.935176f,0.0255743f, 0.938244f,0.0236581f, 0.941128f,0.0218479f, 0.943852f,0.0201445f,
+0.946431f,0.0185454f, 0.948874f,0.0170468f, 0.951191f,0.0156447f, 0.953385f,0.0143347f, 0.955466f,0.0131127f,
+0.957578f,0.0119988f, 0.959539f,0.0109529f, 0.961371f,0.00997561f, 0.963095f,0.0090665f, 0.964721f,0.00822318f,
+0.966399f,0.00746265f, 0.967953f,0.00675333f, 0.969428f,0.00609824f, 0.970929f,0.00550582f, 0.97229f,0.00495269f,
+0.973552f,0.00444153f, 0.974735f,0.00397171f, 0.975848f,0.00354151f, 0.9769f,0.00314883f, 0.977895f,0.00279142f,
+0.978839f,0.00246703f, 0.979735f,0.00217341f, 0.980588f,0.0019084f, 0.981397f,0.00166991f, 0.98217f,0.00145592f,
+0.982907f,0.00126453f, 0.983741f,0.00110182f, 0.984553f,0.000957295f, 0.985281f,0.000825999f, 0.985956f,0.000708679f,
+0.986593f,0.000604792f, 0.987196f,0.000513408f, 0.987773f,0.000433485f, 0.988324f,0.000363966f, 0.988855f,0.000303826f,
+0.989366f,0.000252091f, 0.989859f,0.000207844f, 0.990336f,0.000170231f, 0.990797f,0.000138464f, 0.991244f,0.000111818f,
+0.991679f,8.96267e-05f, 0.992101f,7.12883e-05f, 0.992513f,5.62566e-05f, 0.992913f,4.40412e-05f, 0.993305f,3.4204e-05f,
+0.993686f,2.63571e-05f, 0.994059f,2.01591e-05f, 0.994424f,1.53127e-05f, 0.994782f,1.15613e-05f, 0.995131f,8.68597e-06f,
+0.995474f,6.50242e-06f, 0.996177f,8.78935e-06f, 0.996683f,8.04499e-06f, 0.997098f,6.48301e-06f, 0.997479f,4.9016e-06f,
+0.997841f,3.48469e-06f, 0.998196f,2.27498e-06f, 0.998566f,1.17002e-06f,
+
+0.319718f,0.479644f, 0.272038f,0.42194f, 0.250789f,0.394937f, 0.242829f,0.382083f, 0.242763f,0.376187f,
+0.247949f,0.374043f, 0.256834f,0.373314f, 0.268474f,0.373116f, 0.282208f,0.372815f, 0.297479f,0.371613f,
+0.313868f,0.369317f, 0.331208f,0.366437f, 0.349115f,0.362345f, 0.367475f,0.357466f, 0.386105f,0.351755f,
+0.404891f,0.345374f, 0.423637f,0.338157f, 0.442287f,0.330363f, 0.460805f,0.322149f, 0.479072f,0.313481f,
+0.497093f,0.304564f, 0.514892f,0.29557f, 0.532347f,0.286372f, 0.549413f,0.277013f, 0.565938f,0.267363f,
+0.582056f,0.257737f, 0.597795f,0.248216f, 0.613158f,0.238831f, 0.628111f,0.229568f, 0.642682f,0.22048f,
+0.656766f,0.211468f, 0.67042f,0.202623f, 0.683572f,0.193887f, 0.696279f,0.185339f, 0.708644f,0.177078f,
+0.72071f,0.169129f, 0.732311f,0.161339f, 0.743481f,0.153744f, 0.754183f,0.146324f, 0.764477f,0.139128f,
+0.774522f,0.132265f, 0.78424f,0.125655f, 0.79359f,0.119267f, 0.802576f,0.113098f, 0.811265f,0.107182f,
+0.819622f,0.101487f, 0.827579f,0.0959688f, 0.835257f,0.0906905f, 0.842583f,0.0856036f, 0.849573f,0.0807113f,
+0.85625f,0.0760188f, 0.862695f,0.0715519f, 0.868867f,0.0672832f, 0.874828f,0.0632313f, 0.880545f,0.0593703f,
+0.886041f,0.0557003f, 0.891247f,0.0521852f, 0.896195f,0.0488319f, 0.900903f,0.0456405f, 0.905497f,0.0426449f,
+0.909919f,0.0398129f, 0.914122f,0.0371204f, 0.91809f,0.0345584f, 0.921851f,0.0321292f, 0.925421f,0.0298311f,
+0.928813f,0.0276607f, 0.932035f,0.025614f, 0.935097f,0.0236867f, 0.938007f,0.021874f, 0.940772f,0.0201716f,
+0.943411f,0.0185776f, 0.946036f,0.0171083f, 0.948483f,0.0157211f, 0.950784f,0.0144195f, 0.952959f,0.0132021f,
+0.955019f,0.0120661f, 0.95697f,0.011008f, 0.958819f,0.0100243f, 0.960571f,0.00911116f, 0.962235f,0.00826504f,
+0.963967f,0.00750434f, 0.965552f,0.0067914f, 0.967031f,0.00612976f, 0.968422f,0.00551872f, 0.969737f,0.00495624f,
+0.97112f,0.00445587f, 0.972403f,0.00399271f, 0.973589f,0.00356502f, 0.974753f,0.00317795f, 0.975946f,0.00283231f,
+0.977026f,0.00251264f, 0.97803f,0.00222044f, 0.97897f,0.00195506f, 0.979858f,0.00171519f, 0.980701f,0.00149921f,
+0.981502f,0.00130547f, 0.982266f,0.0011323f, 0.982996f,0.000978077f, 0.983693f,0.00084124f, 0.984361f,0.000720295f,
+0.985002f,0.000613829f, 0.985618f,0.000520504f, 0.986333f,0.00044434f, 0.98706f,0.000379081f, 0.987703f,0.000320057f,
+0.988298f,0.000268116f, 0.988861f,0.000223046f, 0.989398f,0.000184318f, 0.989912f,0.000151311f, 0.990408f,0.00012339f,
+0.990888f,9.99471e-05f, 0.991354f,8.04096e-05f, 0.991806f,6.4251e-05f, 0.992246f,5.09913e-05f, 0.992675f,4.01978e-05f,
+0.993092f,3.14841e-05f, 0.993501f,2.45078e-05f, 0.993899f,1.89691e-05f, 0.994289f,1.46072e-05f, 0.99467f,1.11987e-05f,
+0.995043f,8.55395e-06f, 0.995409f,6.5144e-06f, 0.995766f,4.94964e-06f, 0.996162f,4.15043e-06f, 0.996967f,5.96166e-06f,
+0.997455f,4.77293e-06f, 0.997877f,3.28805e-06f, 0.998302f,1.7248e-06f,
+
+0.334739f,0.465466f, 0.287719f,0.412409f, 0.265555f,0.386121f, 0.256317f,0.372704f, 0.254897f,0.365875f,
+0.258711f,0.362593f, 0.266273f,0.361083f, 0.276624f,0.360232f, 0.289076f,0.359229f, 0.303227f,0.358131f,
+0.318535f,0.355871f, 0.334781f,0.352871f, 0.351791f,0.34929f, 0.369236f,0.344659f, 0.387046f,0.339391f,
+0.405061f,0.333439f, 0.423164f,0.326879f, 0.441253f,0.319754f, 0.459173f,0.312009f, 0.477013f,0.304063f,
+0.494546f,0.29562f, 0.511865f,0.287033f, 0.528902f,0.278294f, 0.545685f,0.269533f, 0.562116f,0.260669f,
+0.578117f,0.251667f, 0.593586f,0.24248f, 0.608692f,0.233414f, 0.623414f,0.224461f, 0.637779f,0.215677f,
+0.651749f,0.207034f, 0.665362f,0.19859f, 0.678498f,0.19023f, 0.691251f,0.18207f, 0.703519f,0.174021f,
+0.715374f,0.166167f, 0.726856f,0.158547f, 0.738026f,0.151201f, 0.74888f,0.144115f, 0.759263f,0.137168f,
+0.769269f,0.130434f, 0.77886f,0.123887f, 0.788063f,0.117548f, 0.797067f,0.111526f, 0.805778f,0.105743f,
+0.814159f,0.100171f, 0.82219f,0.0947918f, 0.829939f,0.0896377f, 0.837436f,0.0847117f, 0.844555f,0.0799426f,
+0.851391f,0.0753753f, 0.85794f,0.0709989f, 0.864175f,0.0667947f, 0.870123f,0.0627684f, 0.875798f,0.0589203f,
+0.881216f,0.0552486f, 0.886449f,0.0517693f, 0.89156f,0.0484958f, 0.896461f,0.045387f, 0.901135f,0.0424271f,
+0.905555f,0.0396025f, 0.90975f,0.0369165f, 0.913737f,0.0343684f, 0.917643f,0.0319878f, 0.921378f,0.0297382f,
+0.924956f,0.0276157f, 0.928323f,0.025601f, 0.931508f,0.0236966f, 0.934527f,0.021901f, 0.937391f,0.0202113f,
+0.94011f,0.0186241f, 0.942691f,0.0171353f, 0.945145f,0.0157409f, 0.947473f,0.0144368f, 0.949685f,0.013219f,
+0.951882f,0.0121004f, 0.953975f,0.011058f, 0.955934f,0.0100823f, 0.957783f,0.00917339f, 0.959529f,0.0083291f,
+0.961183f,0.00754675f, 0.962753f,0.00682329f, 0.964242f,0.00615563f, 0.965654f,0.00554067f, 0.967033f,0.00497978f,
+0.968452f,0.00447702f, 0.969748f,0.00400945f, 0.970959f,0.0035791f, 0.972102f,0.00318514f, 0.973183f,0.00282589f,
+0.974361f,0.00251333f, 0.97544f,0.00222484f, 0.976436f,0.00196069f, 0.977371f,0.00172097f, 0.978339f,0.00151041f,
+0.979317f,0.0013242f, 0.980204f,0.001154f, 0.98103f,0.00100058f, 0.981807f,0.00086338f, 0.982545f,0.000741424f,
+0.983248f,0.00063358f, 0.983922f,0.000538681f, 0.984568f,0.000455574f, 0.985189f,0.000383153f, 0.985788f,0.000320363f,
+0.986365f,0.000266213f, 0.986923f,0.000219775f, 0.987463f,0.000180185f, 0.988177f,0.000152099f, 0.988824f,0.000126777f,
+0.989405f,0.000104134f, 0.989946f,8.46218e-05f, 0.99046f,6.81293e-05f, 0.990953f,5.43721e-05f, 0.991431f,4.3019e-05f,
+0.991892f,3.37389e-05f, 0.992341f,2.62211e-05f, 0.992778f,2.01829e-05f, 0.993204f,1.5373e-05f, 0.993619f,1.1572e-05f,
+0.994025f,8.59091e-06f, 0.994423f,6.27002e-06f, 0.994811f,4.47612e-06f, 0.99519f,3.10028e-06f, 0.99556f,2.05521e-06f,
+0.995997f,1.7266e-06f, 0.996891f,2.76144e-06f, 0.997446f,1.03993e-06f,
+
+0.349507f,0.45156f, 0.303246f,0.402757f, 0.280328f,0.377321f, 0.269939f,0.363544f, 0.267262f,0.355934f,
+0.269797f,0.351775f, 0.276106f,0.349583f, 0.285205f,0.347992f, 0.296482f,0.34666f, 0.309435f,0.345052f,
+0.323736f,0.343077f, 0.338958f,0.340085f, 0.354961f,0.336516f, 0.371576f,0.332388f, 0.38853f,0.327379f,
+0.405779f,0.321852f, 0.423187f,0.315774f, 0.440619f,0.309126f, 0.458081f,0.302164f, 0.475313f,0.294557f,
+0.492467f,0.286826f, 0.50935f,0.278723f, 0.525947f,0.270386f, 0.54232f,0.262016f, 0.558437f,0.253636f,
+0.574222f,0.245185f, 0.589678f,0.236737f, 0.604679f,0.22818f, 0.619172f,0.219523f, 0.633329f,0.211031f,
+0.6471f,0.202657f, 0.660536f,0.194475f, 0.673603f,0.186455f, 0.686321f,0.178627f, 0.698597f,0.170912f,
+0.71051f,0.163396f, 0.722002f,0.156031f, 0.733062f,0.148822f, 0.743725f,0.141803f, 0.754092f,0.135047f,
+0.76418f,0.128555f, 0.773934f,0.122275f, 0.783244f,0.116135f, 0.792176f,0.110183f, 0.800782f,0.104444f,
+0.809016f,0.0988927f, 0.817089f,0.0936368f, 0.824879f,0.0885916f, 0.832405f,0.0837585f, 0.839583f,0.0790893f,
+0.846523f,0.0746324f, 0.853236f,0.0703818f, 0.859623f,0.0662841f, 0.865705f,0.062347f, 0.871582f,0.0586047f,
+0.877161f,0.0550115f, 0.882472f,0.0515749f, 0.887534f,0.048296f, 0.892361f,0.045173f, 0.896964f,0.0422032f,
+0.901357f,0.0393832f, 0.90566f,0.0367422f, 0.9099f,0.0342727f, 0.9139f,0.0319176f, 0.917675f,0.0296761f,
+0.921247f,0.0275509f, 0.924639f,0.0255413f, 0.927974f,0.0236725f, 0.931128f,0.0219045f, 0.9342f,0.0202548f,
+0.93708f,0.018692f, 0.939795f,0.0172192f, 0.942365f,0.0158354f, 0.944801f,0.0145383f, 0.947111f,0.0133248f,
+0.949306f,0.0121916f, 0.951391f,0.011135f, 0.95337f,0.0101515f, 0.955251f,0.00923751f, 0.957072f,0.00839463f,
+0.958898f,0.00762701f, 0.960593f,0.00690942f, 0.962184f,0.00624348f, 0.963687f,0.00562797f, 0.965113f,0.00506078f,
+0.966465f,0.00453945f, 0.96775f,0.00406142f, 0.968972f,0.00362411f, 0.970136f,0.00322499f, 0.97133f,0.00286992f,
+0.972513f,0.00255027f, 0.973598f,0.002256f, 0.974617f,0.00198789f, 0.97558f,0.00174507f, 0.976512f,0.00152756f,
+0.977553f,0.00134277f, 0.978482f,0.0011718f, 0.979344f,0.00101699f, 0.980157f,0.000878232f, 0.980927f,0.000754712f,
+0.981805f,0.000652167f, 0.982635f,0.000560588f, 0.983393f,0.000478197f, 0.984104f,0.000405246f, 0.984777f,0.000341287f,
+0.985422f,0.000285642f, 0.986039f,0.000237559f, 0.986634f,0.000196277f, 0.987208f,0.000161062f, 0.987765f,0.000131221f,
+0.988304f,0.000106104f, 0.988827f,8.51148e-05f, 0.989336f,6.77048e-05f, 0.989996f,5.66068e-05f, 0.990649f,4.73829e-05f,
+0.991221f,3.86029e-05f, 0.991752f,3.09403e-05f, 0.992253f,2.44827e-05f, 0.992734f,1.9144e-05f, 0.993198f,1.47863e-05f,
+0.993648f,1.1263e-05f, 0.994087f,8.43655e-06f, 0.994513f,6.18518e-06f, 0.994927f,4.40499e-06f, 0.995332f,3.01025e-06f,
+0.995723f,1.93328e-06f, 0.996099f,1.12865e-06f, 0.997229f,1.63787e-06f,
+
+0.364005f,0.437936f, 0.318584f,0.39302f, 0.295059f,0.368512f, 0.28364f,0.354515f, 0.279807f,0.346346f,
+0.281147f,0.341474f, 0.286259f,0.338595f, 0.294192f,0.336482f, 0.304325f,0.334729f, 0.316155f,0.332749f,
+0.329413f,0.330764f, 0.343686f,0.327997f, 0.358719f,0.324439f, 0.374405f,0.320419f, 0.390591f,0.31591f,
+0.407036f,0.310642f, 0.423711f,0.304935f, 0.440519f,0.298817f, 0.457302f,0.292166f, 0.474133f,0.28536f,
+0.490732f,0.277988f, 0.507174f,0.270399f, 0.523454f,0.262688f, 0.539407f,0.25469f, 0.555092f,0.246613f,
+0.570525f,0.238538f, 0.585726f,0.230546f, 0.600554f,0.222488f, 0.615075f,0.214499f, 0.629135f,0.206437f,
+0.642707f,0.19833f, 0.655963f,0.19041f, 0.668829f,0.182603f, 0.681383f,0.175003f, 0.6936f,0.167587f,
+0.705469f,0.160349f, 0.716974f,0.153278f, 0.728075f,0.146353f, 0.738826f,0.139619f, 0.749145f,0.133018f,
+0.759111f,0.126616f, 0.768729f,0.120414f, 0.778061f,0.114447f, 0.787166f,0.108743f, 0.795915f,0.103208f,
+0.804263f,0.0978193f, 0.812247f,0.0925998f, 0.819924f,0.0875778f, 0.827311f,0.0827536f, 0.834515f,0.0781754f,
+0.841477f,0.0737973f, 0.848241f,0.0696304f, 0.854675f,0.0656076f, 0.860874f,0.0617668f, 0.86689f,0.0581201f,
+0.87264f,0.0546243f, 0.878088f,0.0512627f, 0.883337f,0.0480679f, 0.888344f,0.0450179f, 0.893101f,0.0421034f,
+0.897626f,0.0393267f, 0.901938f,0.036687f, 0.906044f,0.0341816f, 0.90996f,0.0318074f, 0.913698f,0.0295625f,
+0.917357f,0.0274653f, 0.920917f,0.0255012f, 0.924282f,0.0236377f, 0.927545f,0.0218888f, 0.930617f,0.0202337f,
+0.933525f,0.0186726f, 0.936394f,0.0172278f, 0.939084f,0.0158618f, 0.941723f,0.0145955f, 0.944207f,0.0134033f,
+0.946544f,0.0122828f, 0.948751f,0.011234f, 0.950841f,0.0102549f, 0.952824f,0.00934303f, 0.954707f,0.00849546f,
+0.956495f,0.0077092f, 0.958196f,0.00698119f, 0.959814f,0.00630838f, 0.961351f,0.00568778f, 0.962939f,0.00513134f,
+0.964429f,0.00461575f, 0.965823f,0.00413902f, 0.967138f,0.00370072f, 0.968385f,0.00329933f, 0.969571f,0.0029329f,
+0.970699f,0.00259935f, 0.971775f,0.00229658f, 0.972803f,0.00202252f, 0.973785f,0.00177516f, 0.974872f,0.00156371f,
+0.975877f,0.0013701f, 0.976809f,0.00119416f, 0.977689f,0.00103589f, 0.978524f,0.000894449f, 0.979428f,0.000774996f,
+0.980328f,0.000670291f, 0.981147f,0.000574993f, 0.981911f,0.000489991f, 0.982637f,0.000415004f, 0.98333f,0.000349375f,
+0.984063f,0.000294687f, 0.984871f,0.000250467f, 0.985591f,0.000210244f, 0.986262f,0.000174851f, 0.986896f,0.000144237f,
+0.987502f,0.000118062f, 0.988084f,9.58925e-05f, 0.988647f,7.72729e-05f, 0.989192f,6.17606e-05f, 0.989721f,4.89399e-05f,
+0.990237f,3.84283e-05f, 0.990737f,2.98799e-05f, 0.991224f,2.29856e-05f, 0.991983f,2.08553e-05f, 0.992594f,1.73559e-05f,
+0.99314f,1.38968e-05f, 0.993649f,1.08267e-05f, 0.994133f,8.21465e-06f, 0.994598f,6.04278e-06f, 0.995045f,4.26789e-06f,
+0.995476f,2.84503e-06f, 0.995887f,1.74547e-06f, 0.996818f,2.23186e-06f,
+
+0.378218f,0.424598f, 0.333703f,0.383233f, 0.309704f,0.359705f, 0.297374f,0.345656f, 0.292483f,0.337104f,
+0.292717f,0.331693f, 0.296686f,0.328089f, 0.303522f,0.325613f, 0.312545f,0.323373f, 0.323334f,0.321255f,
+0.335479f,0.318749f, 0.348827f,0.316244f, 0.36297f,0.312914f, 0.377744f,0.308955f, 0.39307f,0.304624f,
+0.408799f,0.299844f, 0.424726f,0.294421f, 0.440815f,0.288594f, 0.45704f,0.282517f, 0.473208f,0.275964f,
+0.489379f,0.269247f, 0.505373f,0.262149f, 0.521146f,0.254764f, 0.536809f,0.247383f, 0.55216f,0.239756f,
+0.567218f,0.23202f, 0.582019f,0.224291f, 0.596562f,0.216611f, 0.610857f,0.209023f, 0.624794f,0.201427f,
+0.638417f,0.193912f, 0.651589f,0.186362f, 0.664296f,0.178811f, 0.676702f,0.171453f, 0.688744f,0.164228f,
+0.700436f,0.157163f, 0.711856f,0.150327f, 0.722943f,0.143665f, 0.733703f,0.137183f, 0.744048f,0.130819f,
+0.754103f,0.124672f, 0.76378f,0.118675f, 0.773076f,0.112834f, 0.782023f,0.107168f, 0.790698f,0.101724f,
+0.799109f,0.0964957f, 0.807301f,0.0914974f, 0.815155f,0.0866552f, 0.822644f,0.0819558f, 0.8298f,0.0774161f,
+0.836644f,0.073044f, 0.843217f,0.0688525f, 0.849641f,0.0648855f, 0.855903f,0.0611243f, 0.861927f,0.0575274f,
+0.867735f,0.0540959f, 0.873273f,0.0508041f, 0.878654f,0.0476871f, 0.883845f,0.044724f, 0.888757f,0.0418778f,
+0.893431f,0.0391599f, 0.897948f,0.0365905f, 0.902225f,0.0341362f, 0.906287f,0.0318008f, 0.91015f,0.0295843f,
+0.913827f,0.0274848f, 0.917331f,0.0254995f, 0.920667f,0.023625f, 0.923851f,0.0218591f, 0.926997f,0.020221f,
+0.930059f,0.0186916f, 0.932929f,0.017242f, 0.93564f,0.0158755f, 0.938209f,0.0145917f, 0.940715f,0.0133981f,
+0.943227f,0.012303f, 0.945572f,0.0112698f, 0.947839f,0.0103109f, 0.950017f,0.009419f, 0.952055f,0.00858278f,
+0.953976f,0.00780281f, 0.955792f,0.00707784f, 0.957516f,0.00640586f, 0.959153f,0.00578452f, 0.960708f,0.00521133f,
+0.96219f,0.0046837f, 0.963601f,0.00419909f, 0.964946f,0.00375497f, 0.966316f,0.00335793f, 0.967651f,0.00299719f,
+0.968894f,0.00266475f, 0.970067f,0.00236086f, 0.971178f,0.00208448f, 0.972237f,0.0018341f, 0.973247f,0.0016081f,
+0.974215f,0.00140479f, 0.97514f,0.00122249f, 0.976028f,0.00105961f, 0.976969f,0.00092007f, 0.977923f,0.000798437f,
+0.978797f,0.000687769f, 0.979618f,0.000588826f, 0.980398f,0.000501235f, 0.981183f,0.000426119f, 0.982075f,0.000366079f,
+0.982867f,0.000310517f, 0.983602f,0.000261039f, 0.984298f,0.000217756f, 0.984963f,0.00018032f, 0.985603f,0.000148229f,
+0.986275f,0.000122341f, 0.987059f,0.000103271f, 0.987751f,8.54789e-05f, 0.988391f,6.9838e-05f, 0.988996f,5.64526e-05f,
+0.989576f,4.51821e-05f, 0.990133f,3.5805e-05f, 0.990673f,2.808e-05f, 0.991196f,2.17726e-05f, 0.991704f,1.66657e-05f,
+0.992197f,1.2565e-05f, 0.992769f,1.01286e-05f, 0.993518f,9.38787e-06f, 0.994117f,7.57201e-06f, 0.994653f,5.68456e-06f,
+0.995148f,3.99229e-06f, 0.995607f,2.59302e-06f, 0.995951f,1.87723e-06f,
+
+0.392141f,0.411556f, 0.348583f,0.373435f, 0.324233f,0.350911f, 0.311102f,0.336951f, 0.305245f,0.328125f,
+0.304443f,0.322243f, 0.307353f,0.318127f, 0.313129f,0.315218f, 0.321104f,0.312602f, 0.330863f,0.310194f,
+0.342028f,0.307597f, 0.354353f,0.304815f, 0.367639f,0.301781f, 0.381557f,0.297983f, 0.396022f,0.29374f,
+0.410957f,0.289206f, 0.426212f,0.284253f, 0.441619f,0.278759f, 0.457127f,0.272884f, 0.47277f,0.266875f,
+0.48834f,0.260458f, 0.503848f,0.253827f, 0.519274f,0.247049f, 0.534442f,0.23995f, 0.549447f,0.232795f,
+0.564254f,0.225591f, 0.578731f,0.218222f, 0.592924f,0.210825f, 0.606848f,0.203467f, 0.620525f,0.196206f,
+0.633956f,0.189053f, 0.647046f,0.181938f, 0.659826f,0.174915f, 0.67217f,0.16789f, 0.684068f,0.160888f,
+0.695671f,0.154073f, 0.706944f,0.147413f, 0.717831f,0.140869f, 0.728506f,0.134585f, 0.738856f,0.128463f,
+0.748905f,0.122525f, 0.758605f,0.116734f, 0.767968f,0.111104f, 0.777032f,0.105658f, 0.785724f,0.100349f,
+0.794099f,0.0952153f, 0.802151f,0.0902472f, 0.809953f,0.0854828f, 0.817536f,0.0809279f, 0.8249f,0.0765714f,
+0.831959f,0.0723636f, 0.838683f,0.0682904f, 0.845102f,0.0643648f, 0.851236f,0.0605927f, 0.857101f,0.0569759f,
+0.862774f,0.0535392f, 0.868348f,0.0503022f, 0.873766f,0.0472343f, 0.878968f,0.0443069f, 0.883951f,0.0415119f,
+0.888781f,0.0388675f, 0.893453f,0.0363627f, 0.897909f,0.0339733f, 0.902118f,0.0316869f, 0.906171f,0.029526f,
+0.910042f,0.0274755f, 0.913705f,0.0255259f, 0.917185f,0.0236782f, 0.920494f,0.0219314f, 0.923642f,0.0202832f,
+0.92664f,0.0187307f, 0.929495f,0.0172707f, 0.932215f,0.0158998f, 0.934949f,0.0146412f, 0.937589f,0.0134664f,
+0.940065f,0.0123575f, 0.942401f,0.0113166f, 0.944615f,0.0103428f, 0.946716f,0.00943434f, 0.948832f,0.00860641f,
+0.950812f,0.0078303f, 0.952774f,0.00711739f, 0.954739f,0.00646737f, 0.95656f,0.00585815f, 0.958267f,0.00529144f,
+0.959879f,0.00476681f, 0.961405f,0.00428289f, 0.962854f,0.00383788f, 0.964233f,0.0034298f, 0.965546f,0.0030566f,
+0.9668f,0.00271616f, 0.967997f,0.00240645f, 0.969206f,0.00213096f, 0.970426f,0.00188593f, 0.971554f,0.00166089f,
+0.972621f,0.00145647f, 0.973631f,0.00127199f, 0.974597f,0.00110634f, 0.975521f,0.000958238f, 0.976406f,0.000826371f,
+0.977258f,0.000709433f, 0.978078f,0.000606163f, 0.978919f,0.000517882f, 0.979839f,0.000445233f, 0.980673f,0.000378803f,
+0.981452f,0.000319745f, 0.982193f,0.000267988f, 0.982928f,0.000223972f, 0.983802f,0.000191491f, 0.984572f,0.000160727f,
+0.985286f,0.000133323f, 0.98596f,0.000109533f, 0.986605f,8.91914e-05f, 0.987225f,7.19933e-05f, 0.987826f,5.75904e-05f,
+0.988571f,4.83001e-05f, 0.989296f,4.03175e-05f, 0.989947f,3.27996e-05f, 0.990554f,2.62039e-05f, 0.99113f,2.0599e-05f,
+0.991682f,1.59252e-05f, 0.992213f,1.20818e-05f, 0.992725f,8.96054e-06f, 0.993218f,6.46011e-06f, 0.993848f,5.38951e-06f,
+0.99462f,4.91976e-06f, 0.995203f,3.59909e-06f, 0.995511f,2.61735e-06f,
+
+0.405768f,0.398816f, 0.363206f,0.36366f, 0.338613f,0.342147f, 0.324788f,0.328392f, 0.31805f,0.319383f,
+0.316286f,0.313112f, 0.318208f,0.308616f, 0.322962f,0.30519f, 0.32996f,0.302372f, 0.338724f,0.299649f,
+0.34894f,0.296951f, 0.360296f,0.293945f, 0.372683f,0.290971f, 0.385799f,0.287469f, 0.399445f,0.283361f,
+0.413557f,0.278906f, 0.428073f,0.274227f, 0.442846f,0.26918f, 0.457733f,0.263677f, 0.472683f,0.257836f,
+0.487728f,0.251879f, 0.502725f,0.245646f, 0.517614f,0.239171f, 0.532452f,0.232649f, 0.547055f,0.225871f,
+0.561425f,0.218949f, 0.57566f,0.212087f, 0.589614f,0.205127f, 0.603254f,0.198096f, 0.616623f,0.191096f,
+0.629707f,0.184141f, 0.642583f,0.177342f, 0.655151f,0.170601f, 0.667436f,0.163966f, 0.679428f,0.157443f,
+0.691003f,0.15094f, 0.702144f,0.144473f, 0.712991f,0.138179f, 0.723549f,0.132059f, 0.733724f,0.126047f,
+0.743647f,0.120244f, 0.753322f,0.114643f, 0.762715f,0.109219f, 0.771795f,0.103948f, 0.780527f,0.0988112f,
+0.788997f,0.093861f, 0.79717f,0.0890719f, 0.804987f,0.0844121f, 0.812531f,0.0799247f, 0.819779f,0.075596f,
+0.826799f,0.0714508f, 0.833633f,0.0675022f, 0.840249f,0.0637242f, 0.846605f,0.0600914f, 0.852651f,0.0565824f,
+0.858417f,0.0532076f, 0.863922f,0.0499716f, 0.869183f,0.0468754f, 0.874261f,0.0439364f, 0.87919f,0.0411561f,
+0.883924f,0.0385109f, 0.888643f,0.0360445f, 0.893111f,0.0336799f, 0.897426f,0.0314413f, 0.90166f,0.0293431f,
+0.905724f,0.0273528f, 0.909559f,0.0254504f, 0.913188f,0.0236395f, 0.916718f,0.0219423f, 0.920048f,0.0203284f,
+0.923203f,0.0188006f, 0.926198f,0.0173587f, 0.929046f,0.0160009f, 0.931757f,0.0147251f, 0.934338f,0.0135283f,
+0.936796f,0.0124078f, 0.93914f,0.0113603f, 0.941533f,0.0104084f, 0.943831f,0.0095208f, 0.945984f,0.00868662f,
+0.948017f,0.00790709f, 0.949942f,0.00718139f, 0.951779f,0.00650869f, 0.953638f,0.00589995f, 0.955376f,0.00533165f,
+0.957015f,0.00480479f, 0.958677f,0.00432994f, 0.960245f,0.00389021f, 0.961756f,0.00348664f, 0.963243f,0.00311909f,
+0.96464f,0.00278104f, 0.965962f,0.0024716f, 0.967217f,0.00218946f, 0.968412f,0.00193312f, 0.969553f,0.001701f,
+0.970644f,0.0014915f, 0.97175f,0.00130739f, 0.972881f,0.00114629f, 0.973928f,0.000998964f, 0.974914f,0.000866089f,
+0.975853f,0.000747233f, 0.97675f,0.000641568f, 0.977612f,0.000548127f, 0.97844f,0.000465904f, 0.979239f,0.000393908f,
+0.98001f,0.000331178f, 0.980816f,0.000279187f, 0.9817f,0.000237696f, 0.982501f,0.00019962f, 0.983249f,0.000165993f,
+0.98396f,0.000136848f, 0.984734f,0.000114409f, 0.985567f,9.70958e-05f, 0.986308f,8.05702e-05f, 0.986997f,6.58927e-05f,
+0.987651f,5.32489e-05f, 0.988279f,4.25492e-05f, 0.988881f,3.36101e-05f, 0.989464f,2.62211e-05f, 0.990219f,2.22484e-05f,
+0.990943f,1.85666e-05f, 0.991585f,1.48043e-05f, 0.992176f,1.14158e-05f, 0.992732f,8.52156e-06f, 0.993253f,6.13787e-06f,
+0.993738f,4.25774e-06f, 0.994392f,3.74181e-06f, 0.994513f,2.40559e-06f,
+
+0.419091f,0.386381f, 0.377552f,0.353932f, 0.352818f,0.333441f, 0.338394f,0.31997f, 0.330856f,0.310822f,
+0.328208f,0.3043f, 0.329204f,0.299481f, 0.333002f,0.295647f, 0.339057f,0.292582f, 0.346875f,0.289592f,
+0.356161f,0.286716f, 0.366646f,0.283757f, 0.378066f,0.280441f, 0.390389f,0.277218f, 0.403289f,0.273424f,
+0.416621f,0.269099f, 0.43035f,0.264497f, 0.44443f,0.259733f, 0.458717f,0.254652f, 0.473089f,0.249189f,
+0.487504f,0.24345f, 0.501939f,0.23753f, 0.516377f,0.231494f, 0.530693f,0.225239f, 0.54492f,0.218913f,
+0.558986f,0.21247f, 0.572802f,0.205868f, 0.586438f,0.19927f, 0.59988f,0.192696f, 0.612999f,0.186031f,
+0.625839f,0.179382f, 0.638427f,0.172808f, 0.650726f,0.166291f, 0.662829f,0.159945f, 0.674597f,0.153639f,
+0.686082f,0.147445f, 0.69734f,0.141417f, 0.708204f,0.135427f, 0.718646f,0.129479f, 0.728786f,0.123683f,
+0.738669f,0.118071f, 0.748199f,0.112573f, 0.757398f,0.107214f, 0.766449f,0.102105f, 0.775226f,0.0971589f,
+0.78374f,0.0923777f, 0.791923f,0.0877226f, 0.799811f,0.0832139f, 0.807468f,0.0788841f, 0.814823f,0.0746908f,
+0.821875f,0.0706349f, 0.828658f,0.0667289f, 0.835191f,0.0629788f, 0.841512f,0.0593938f, 0.847674f,0.0559882f,
+0.853617f,0.0527287f, 0.859347f,0.0496109f, 0.864796f,0.0466066f, 0.869987f,0.0437226f, 0.874938f,0.0409627f,
+0.879665f,0.0383275f, 0.884215f,0.0358275f, 0.888629f,0.0334669f, 0.89288f,0.0312305f, 0.896996f,0.0291196f,
+0.900986f,0.0271275f, 0.90482f,0.0252397f, 0.908646f,0.0234878f, 0.91235f,0.0218373f, 0.915887f,0.0202723f,
+0.919211f,0.0187799f, 0.922401f,0.0173749f, 0.925458f,0.0160522f, 0.928344f,0.0148005f, 0.931079f,0.0136207f,
+0.933675f,0.0125119f, 0.936145f,0.0114724f, 0.938496f,0.0104999f, 0.940736f,0.00959187f, 0.942872f,0.00874566f,
+0.944908f,0.00795851f, 0.947032f,0.00725211f, 0.949051f,0.00659359f, 0.950945f,0.00597756f, 0.952732f,0.00540476f,
+0.954428f,0.00487435f, 0.956067f,0.00438773f, 0.957717f,0.00394896f, 0.959261f,0.00354156f, 0.960721f,0.00316612f,
+0.962187f,0.00282909f, 0.963608f,0.00252194f, 0.964941f,0.0022394f, 0.966201f,0.00198129f, 0.967402f,0.00174667f,
+0.968547f,0.00153429f, 0.96972f,0.00134616f, 0.970858f,0.0011774f, 0.971939f,0.00102539f, 0.972967f,0.000889159f,
+0.974037f,0.00077262f, 0.975104f,0.000670563f, 0.976094f,0.000577763f, 0.977027f,0.00049475f, 0.977915f,0.00042122f,
+0.978767f,0.000356573f, 0.979584f,0.000300097f, 0.980373f,0.000251054f, 0.981135f,0.000208714f, 0.981873f,0.000172379f,
+0.982716f,0.000145204f, 0.983552f,0.000122141f, 0.984317f,0.000101117f, 0.985038f,8.2735e-05f, 0.985724f,6.69989e-05f,
+0.986606f,5.79827e-05f, 0.987377f,4.83712e-05f, 0.988079f,3.94119e-05f, 0.988738f,3.15476e-05f, 0.989367f,2.48416e-05f,
+0.989967f,1.9229e-05f, 0.990542f,1.46021e-05f, 0.99123f,1.19043e-05f, 0.992f,1.01277e-05f, 0.992635f,7.85139e-06f,
+0.993175f,5.75376e-06f, 0.993563f,4.05184e-06f, 0.993921f,3.19728e-06f,
+
+0.432102f,0.37425f, 0.391606f,0.344278f, 0.36682f,0.32481f, 0.351887f,0.311665f, 0.343628f,0.302429f,
+0.340166f,0.295744f, 0.340293f,0.29064f, 0.343201f,0.286512f, 0.348344f,0.283127f, 0.355285f,0.280037f,
+0.363677f,0.276979f, 0.373289f,0.273922f, 0.383874f,0.270634f, 0.395273f,0.267135f, 0.407448f,0.263686f,
+0.420092f,0.259707f, 0.433083f,0.255245f, 0.446409f,0.250554f, 0.460042f,0.245754f, 0.473847f,0.240691f,
+0.487711f,0.235306f, 0.501597f,0.229687f, 0.515467f,0.223885f, 0.529342f,0.218029f, 0.543108f,0.212008f,
+0.556759f,0.205902f, 0.570268f,0.199734f, 0.583569f,0.193471f, 0.596627f,0.187134f, 0.609539f,0.180885f,
+0.622198f,0.174626f, 0.634543f,0.168327f, 0.646618f,0.162075f, 0.658456f,0.155927f, 0.670012f,0.149852f,
+0.681381f,0.143949f, 0.692415f,0.138093f, 0.703172f,0.132354f, 0.713684f,0.12676f, 0.723877f,0.121257f,
+0.733679f,0.115812f, 0.743155f,0.110487f, 0.752406f,0.105351f, 0.761357f,0.10035f, 0.769966f,0.0954625f,
+0.778343f,0.0907573f, 0.786544f,0.0862549f, 0.794515f,0.0819173f, 0.802203f,0.0777139f, 0.809585f,0.0736333f,
+0.816729f,0.0697089f, 0.823645f,0.0659392f, 0.830271f,0.0622919f, 0.83664f,0.0587824f, 0.842747f,0.0554038f,
+0.848641f,0.0521733f, 0.854335f,0.0490883f, 0.859901f,0.0461687f, 0.865268f,0.0433801f, 0.870418f,0.0407103f,
+0.875343f,0.0381545f, 0.880027f,0.0357053f, 0.884492f,0.0333657f, 0.888753f,0.0311365f, 0.892836f,0.0290213f,
+0.896798f,0.0270294f, 0.900645f,0.0251546f, 0.904344f,0.0233829f, 0.90789f,0.021707f, 0.911324f,0.0201304f,
+0.91459f,0.0186372f, 0.917912f,0.0172684f, 0.921204f,0.0159944f, 0.924303f,0.0147818f, 0.927212f,0.0136299f,
+0.930048f,0.0125572f, 0.932721f,0.0115431f, 0.935245f,0.0105877f, 0.937638f,0.00969123f, 0.939911f,0.00885247f,
+0.942073f,0.00806976f, 0.944134f,0.00734102f, 0.946099f,0.00666401f, 0.947974f,0.00603637f, 0.949764f,0.00545569f,
+0.95168f,0.00494305f, 0.953477f,0.00446414f, 0.955163f,0.00401842f, 0.956757f,0.00360626f, 0.958271f,0.00322688f,
+0.959766f,0.00288421f, 0.961249f,0.00257493f, 0.96264f,0.00228966f, 0.963956f,0.00202858f, 0.965273f,0.00179556f,
+0.96658f,0.00158693f, 0.967804f,0.00139592f, 0.968963f,0.00122258f, 0.970066f,0.00106625f, 0.971123f,0.000925956f,
+0.972136f,0.000800626f, 0.97311f,0.000689143f, 0.974047f,0.000590399f, 0.974952f,0.000503318f, 0.976077f,0.000436145f,
+0.97712f,0.000374881f, 0.978083f,0.000319394f, 0.978991f,0.000270097f, 0.979852f,0.000226826f, 0.980677f,0.000189194f,
+0.981469f,0.00015672f, 0.982233f,0.000128902f, 0.982969f,0.00010524f, 0.983735f,8.65298e-05f, 0.984616f,7.3511e-05f,
+0.985398f,6.07865e-05f, 0.986125f,4.94156e-05f, 0.986813f,3.96164e-05f, 0.987708f,3.47504e-05f, 0.988482f,2.89371e-05f,
+0.98918f,2.32726e-05f, 0.989827f,1.82287e-05f, 0.990429f,1.39237e-05f, 0.990987f,1.03591e-05f, 0.991484f,7.49709e-06f,
+0.992205f,6.75315e-06f, 0.992297f,4.76431e-06f, 0.992858f,3.20967e-06f,
+
+0.444801f,0.362428f, 0.40536f,0.334718f, 0.380599f,0.316246f, 0.365241f,0.303457f, 0.35634f,0.294233f,
+0.352129f,0.287429f, 0.351447f,0.282093f, 0.353527f,0.277794f, 0.357801f,0.274071f, 0.3639f,0.270871f,
+0.371434f,0.267622f, 0.380201f,0.264463f, 0.389994f,0.261253f, 0.400581f,0.257727f, 0.411909f,0.25417f,
+0.423855f,0.250479f, 0.436203f,0.246366f, 0.448835f,0.241833f, 0.461748f,0.237106f, 0.474927f,0.232306f,
+0.488254f,0.2273f, 0.501627f,0.222034f, 0.514981f,0.21653f, 0.528305f,0.210875f, 0.541649f,0.205229f,
+0.554866f,0.199424f, 0.567959f,0.193541f, 0.580946f,0.187664f, 0.593717f,0.181689f, 0.606287f,0.175694f,
+0.618634f,0.169695f, 0.630825f,0.163793f, 0.642738f,0.157879f, 0.654344f,0.151963f, 0.6657f,0.146125f,
+0.676825f,0.140398f, 0.687679f,0.134758f, 0.698354f,0.129289f, 0.708703f,0.123875f, 0.718787f,0.118579f,
+0.728639f,0.11343f, 0.738183f,0.108375f, 0.747349f,0.103382f, 0.75621f,0.0985049f, 0.764871f,0.0938148f,
+0.773274f,0.0892696f, 0.781341f,0.0848269f, 0.789133f,0.080524f, 0.796763f,0.0764156f, 0.804214f,0.0724815f,
+0.811457f,0.0687015f, 0.818389f,0.0650234f, 0.825063f,0.061475f, 0.831531f,0.0580739f, 0.837789f,0.054813f,
+0.843768f,0.0516615f, 0.84953f,0.0486425f, 0.855039f,0.045738f, 0.860367f,0.0429711f, 0.865499f,0.0403297f,
+0.870539f,0.0378419f, 0.875398f,0.0354704f, 0.880021f,0.0331946f, 0.884489f,0.0310347f, 0.888735f,0.0289682f,
+0.892777f,0.0269977f, 0.89663f,0.0251239f, 0.900307f,0.0233459f, 0.903896f,0.0216808f, 0.90736f,0.0201121f,
+0.9107f,0.0186355f, 0.913936f,0.0172496f, 0.916998f,0.0159355f, 0.919951f,0.0147023f, 0.922851f,0.0135562f,
+0.92572f,0.0124947f, 0.928581f,0.0115143f, 0.931262f,0.0105828f, 0.933887f,0.00971685f, 0.936411f,0.00890759f,
+0.93878f,0.00814425f, 0.941017f,0.0074282f, 0.943137f,0.00675925f, 0.945151f,0.00613633f, 0.947069f,0.00555789f,
+0.948897f,0.00502215f, 0.950643f,0.00452716f, 0.95231f,0.00407091f, 0.953949f,0.00365596f, 0.955673f,0.00328913f,
+0.957292f,0.00294843f, 0.958814f,0.00263315f, 0.960253f,0.00234344f, 0.961624f,0.00207854f, 0.963027f,0.00184479f,
+0.964375f,0.00163207f, 0.965643f,0.00143741f, 0.966848f,0.00126067f, 0.968059f,0.00110472f, 0.969275f,0.000967179f,
+0.970414f,0.00084194f, 0.971493f,0.000729137f, 0.972524f,0.000628294f, 0.973511f,0.000538684f, 0.974459f,0.000459486f,
+0.975373f,0.000389849f, 0.976254f,0.000328927f, 0.977182f,0.000278776f, 0.978149f,0.000237289f, 0.979041f,0.000199574f,
+0.979881f,0.000166274f, 0.980762f,0.000138602f, 0.981639f,0.000115157f, 0.982467f,9.47938e-05f, 0.983252f,7.7331e-05f,
+0.984003f,6.25141e-05f, 0.984767f,5.09121e-05f, 0.985669f,4.37061e-05f, 0.986455f,3.60388e-05f, 0.987175f,2.90121e-05f,
+0.987941f,2.41102e-05f, 0.9888f,2.09536e-05f, 0.989504f,1.69419e-05f, 0.990094f,1.3118e-05f, 0.990508f,9.74804e-06f,
+0.990586f,6.70273e-06f, 0.991237f,4.81562e-06f, 0.991933f,3.79052e-06f,
+
+0.457187f,0.350913f, 0.418805f,0.325273f, 0.394139f,0.307765f, 0.378432f,0.29536f, 0.36896f,0.2862f,
+0.364065f,0.279334f, 0.362637f,0.273848f, 0.363932f,0.269358f, 0.367399f,0.265418f, 0.372674f,0.262011f,
+0.379425f,0.258758f, 0.387379f,0.255472f, 0.396367f,0.252185f, 0.406221f,0.248811f, 0.416731f,0.245109f,
+0.427925f,0.241504f, 0.439605f,0.237645f, 0.45163f,0.233446f, 0.463889f,0.228892f, 0.476382f,0.22417f,
+0.489106f,0.219401f, 0.501965f,0.214488f, 0.514852f,0.209356f, 0.527691f,0.20399f, 0.540516f,0.198544f,
+0.553296f,0.193038f, 0.566011f,0.187492f, 0.578575f,0.18185f, 0.591039f,0.176228f, 0.603327f,0.170567f,
+0.615379f,0.164847f, 0.627235f,0.159148f, 0.638919f,0.153527f, 0.650408f,0.147975f, 0.661602f,0.142417f,
+0.672522f,0.136901f, 0.683194f,0.131471f, 0.693644f,0.126156f, 0.703837f,0.12094f, 0.713857f,0.115889f,
+0.72358f,0.110911f, 0.733021f,0.106031f, 0.742263f,0.101308f, 0.751221f,0.096687f, 0.75984f,0.0921407f,
+0.768122f,0.0876828f, 0.776178f,0.0833808f, 0.784022f,0.0792376f, 0.791623f,0.075227f, 0.798928f,0.0713272f,
+0.806017f,0.0675783f, 0.812936f,0.0639938f, 0.819719f,0.0605801f, 0.82629f,0.0572976f, 0.832551f,0.0541034f,
+0.838605f,0.0510405f, 0.844459f,0.0481064f, 0.850133f,0.0453033f, 0.855541f,0.0425976f, 0.860766f,0.040016f,
+0.865751f,0.0375357f, 0.870576f,0.0351785f, 0.875205f,0.0329282f, 0.879784f,0.0308217f, 0.884196f,0.0288175f,
+0.888396f,0.0268993f, 0.892414f,0.0250728f, 0.896281f,0.0233415f, 0.899957f,0.0216932f, 0.903458f,0.0201287f,
+0.906798f,0.0186474f, 0.910048f,0.0172611f, 0.913171f,0.0159559f, 0.916212f,0.014736f, 0.919172f,0.013597f,
+0.921979f,0.0125203f, 0.924642f,0.0115053f, 0.927192f,0.0105548f, 0.929801f,0.00969005f, 0.932366f,0.00888924f,
+0.934844f,0.0081416f, 0.93722f,0.00744194f, 0.939538f,0.00679503f, 0.941725f,0.00618764f, 0.943844f,0.00562373f,
+0.945863f,0.00509871f, 0.947774f,0.0046102f, 0.949589f,0.00415739f, 0.951317f,0.00373905f, 0.952965f,0.00335373f,
+0.95454f,0.00299982f, 0.956048f,0.00267566f, 0.957585f,0.00238773f, 0.95916f,0.0021319f, 0.960639f,0.00189537f,
+0.96203f,0.00167791f, 0.963352f,0.00147947f, 0.964632f,0.00130096f, 0.965958f,0.00114586f, 0.967199f,0.00100344f,
+0.968371f,0.000874294f, 0.969487f,0.000758131f, 0.970635f,0.00065798f, 0.971776f,0.000570049f, 0.972845f,0.000490528f,
+0.97386f,0.000419523f, 0.97483f,0.000356679f, 0.97576f,0.000301452f, 0.976657f,0.000253226f, 0.977519f,0.000211369f,
+0.97839f,0.000176405f, 0.979364f,0.000149857f, 0.980249f,0.000125191f, 0.981079f,0.000103318f, 0.981866f,8.43585e-05f,
+0.982617f,6.8165e-05f, 0.983335f,5.44938e-05f, 0.984024f,4.30717e-05f, 0.984828f,3.48858e-05f, 0.985702f,2.97053e-05f,
+0.986564f,2.54344e-05f, 0.987277f,2.07332e-05f, 0.987862f,1.65251e-05f, 0.988469f,1.48678e-05f, 0.989057f,1.1734e-05f,
+0.989773f,8.68213e-06f, 0.990342f,6.00878e-06f, 0.990852f,4.19136e-06f,
+
+0.469251f,0.339703f, 0.43193f,0.315956f, 0.40742f,0.299379f, 0.391435f,0.287371f, 0.381462f,0.27833f,
+0.375942f,0.271425f, 0.373823f,0.265849f, 0.374384f,0.261197f, 0.377104f,0.25716f, 0.381589f,0.253499f,
+0.38758f,0.250212f, 0.394759f,0.246821f, 0.402991f,0.24352f, 0.412092f,0.240147f, 0.421908f,0.236601f,
+0.432299f,0.232826f, 0.4433f,0.229161f, 0.45469f,0.225206f, 0.466378f,0.220978f, 0.478257f,0.216441f,
+0.490331f,0.211762f, 0.502599f,0.207043f, 0.514997f,0.202246f, 0.527407f,0.197258f, 0.539767f,0.19208f,
+0.5521f,0.186835f, 0.56435f,0.181499f, 0.576569f,0.176193f, 0.588637f,0.170805f, 0.600546f,0.165374f,
+0.612374f,0.160023f, 0.623973f,0.154618f, 0.635347f,0.149202f, 0.646536f,0.143843f, 0.657563f,0.138582f,
+0.668384f,0.133387f, 0.678902f,0.128195f, 0.689176f,0.123078f, 0.699203f,0.118046f, 0.709017f,0.113133f,
+0.71859f,0.108324f, 0.727996f,0.103672f, 0.737142f,0.0991143f, 0.745978f,0.0946282f, 0.754661f,0.0903145f,
+0.763053f,0.0860885f, 0.771171f,0.0819638f, 0.778955f,0.0779158f, 0.786484f,0.0739921f, 0.793839f,0.0702321f,
+0.800959f,0.0665974f, 0.807779f,0.0630596f, 0.814361f,0.0596464f, 0.820817f,0.0564005f, 0.827121f,0.0533016f,
+0.833289f,0.0503506f, 0.839245f,0.0475119f, 0.844916f,0.0447578f, 0.850417f,0.0421293f, 0.855728f,0.0396139f,
+0.860887f,0.0372198f, 0.865801f,0.0349138f, 0.870547f,0.0327181f, 0.875076f,0.0306138f, 0.879456f,0.0286174f,
+0.883635f,0.02671f, 0.887811f,0.0249383f, 0.891834f,0.0232555f, 0.895667f,0.0216496f, 0.899304f,0.0201175f,
+0.902816f,0.0186714f, 0.906179f,0.0173029f, 0.909379f,0.0160061f, 0.912429f,0.0147809f, 0.915384f,0.0136345f,
+0.918236f,0.0125601f, 0.92101f,0.0115584f, 0.923718f,0.0106264f, 0.926311f,0.00975179f, 0.928765f,0.00892862f,
+0.931099f,0.00815704f, 0.933392f,0.00744587f, 0.935677f,0.00679348f, 0.938003f,0.00620134f, 0.94018f,0.0056428f,
+0.942322f,0.00512898f, 0.944426f,0.00465658f, 0.946394f,0.00421321f, 0.948251f,0.00380011f, 0.950011f,0.00341725f,
+0.951685f,0.00306392f, 0.953362f,0.00274365f, 0.954953f,0.00244905f, 0.95647f,0.00217913f, 0.957917f,0.0019327f,
+0.959347f,0.00171182f, 0.960787f,0.00151566f, 0.962255f,0.00134275f, 0.963624f,0.00118296f, 0.964913f,0.00103712f,
+0.966139f,0.000905076f, 0.967415f,0.000791887f, 0.968637f,0.000689851f, 0.969787f,0.000597243f, 0.970882f,0.000514149f,
+0.971926f,0.000440192f, 0.973051f,0.000379214f, 0.974121f,0.000324646f, 0.975128f,0.000275744f, 0.976084f,0.000232526f,
+0.976997f,0.000194707f, 0.977874f,0.000161882f, 0.978716f,0.0001336f, 0.979574f,0.000110631f, 0.980525f,9.36131e-05f,
+0.98138f,7.75301e-05f, 0.98217f,6.32317e-05f, 0.982907f,5.08804e-05f, 0.983589f,4.04046e-05f, 0.984206f,3.16456e-05f,
+0.984728f,2.44107e-05f, 0.985114f,1.90605e-05f, 0.985681f,1.63063e-05f, 0.986587f,1.35528e-05f, 0.987513f,1.15777e-05f,
+0.988456f,1.00404e-05f, 0.988902f,6.96987e-06f, 0.98957f,4.45112e-06f,
+
+0.480999f,0.328799f, 0.444733f,0.306785f, 0.420433f,0.291096f, 0.404235f,0.279497f, 0.393827f,0.270635f,
+0.387738f,0.263703f, 0.384983f,0.258083f, 0.384858f,0.253308f, 0.386873f,0.249189f, 0.390625f,0.245373f,
+0.395867f,0.241942f, 0.402341f,0.23861f, 0.409824f,0.235203f, 0.418192f,0.231797f, 0.427319f,0.228359f,
+0.43704f,0.224707f, 0.447263f,0.220884f, 0.458036f,0.217192f, 0.469119f,0.213194f, 0.480461f,0.208977f,
+0.491957f,0.20449f, 0.503613f,0.199881f, 0.515433f,0.195242f, 0.527371f,0.190561f, 0.539318f,0.185735f,
+0.551208f,0.180745f, 0.563062f,0.175698f, 0.574821f,0.170567f, 0.586533f,0.165464f, 0.598137f,0.160339f,
+0.609582f,0.155179f, 0.620902f,0.150055f, 0.632062f,0.14495f, 0.643002f,0.139833f, 0.653718f,0.134732f,
+0.664274f,0.129723f, 0.674683f,0.124827f, 0.68486f,0.119982f, 0.694748f,0.11516f, 0.704413f,0.11043f,
+0.713831f,0.105781f, 0.723049f,0.101255f, 0.732037f,0.0968322f, 0.740865f,0.0925604f, 0.74948f,0.0884027f,
+0.757756f,0.0842912f, 0.76591f,0.0803557f, 0.773804f,0.0765152f, 0.781428f,0.072767f, 0.788766f,0.0691075f,
+0.795831f,0.065548f, 0.80271f,0.0621309f, 0.809409f,0.0588512f, 0.815849f,0.0556719f, 0.822022f,0.0525898f,
+0.828006f,0.0496367f, 0.833849f,0.0468249f, 0.83956f,0.0441491f, 0.845128f,0.0416004f, 0.85052f,0.0391572f,
+0.855677f,0.0368002f, 0.860688f,0.0345582f, 0.865527f,0.0324178f, 0.870232f,0.0303854f, 0.874716f,0.0284343f,
+0.879042f,0.0265782f, 0.883173f,0.0248046f, 0.887167f,0.023125f, 0.890967f,0.021522f, 0.894774f,0.0200372f,
+0.898458f,0.0186341f, 0.901975f,0.0172993f, 0.90531f,0.0160281f, 0.908481f,0.0148224f, 0.911568f,0.0136931f,
+0.914512f,0.0126269f, 0.917317f,0.0116214f, 0.920017f,0.0106803f, 0.92265f,0.00980484f, 0.925179f,0.00898607f,
+0.927672f,0.00822985f, 0.930086f,0.00752599f, 0.932367f,0.00686443f, 0.934533f,0.00624568f, 0.936634f,0.00567353f,
+0.938688f,0.00514719f, 0.940743f,0.00466804f, 0.942828f,0.00423397f, 0.944792f,0.0038274f, 0.946737f,0.00345751f,
+0.948634f,0.00311709f, 0.950432f,0.0028009f, 0.952129f,0.00250776f, 0.953738f,0.00223757f, 0.95527f,0.00198971f,
+0.956731f,0.00176328f, 0.95813f,0.0015572f, 0.959478f,0.00137067f, 0.960847f,0.00120493f, 0.962274f,0.00106231f,
+0.96365f,0.000933395f, 0.965023f,0.000819327f, 0.966304f,0.000714706f, 0.967513f,0.000619965f, 0.968738f,0.000538313f,
+0.969953f,0.000466837f, 0.971089f,0.000401735f, 0.972163f,0.000343384f, 0.973185f,0.000291634f, 0.974218f,0.000247803f,
+0.975289f,0.00021142f, 0.976282f,0.000178462f, 0.977214f,0.000149275f, 0.978094f,0.000123794f, 0.978926f,0.000101786f,
+0.979709f,8.29528e-05f, 0.980561f,6.92783e-05f, 0.981383f,5.79321e-05f, 0.982055f,4.7259e-05f, 0.982519f,3.77966e-05f,
+0.982973f,2.96604e-05f, 0.983689f,2.2879e-05f, 0.984341f,1.7286e-05f, 0.984987f,1.34287e-05f, 0.98564f,1.11233e-05f,
+0.986265f,8.13028e-06f, 0.987488f,7.42215e-06f, 0.988177f,4.75539e-06f,
+
+0.492429f,0.318197f, 0.457209f,0.297772f, 0.433166f,0.28293f, 0.416814f,0.271744f, 0.40603f,0.263096f,
+0.39943f,0.25618f, 0.396089f,0.250538f, 0.39533f,0.245702f, 0.396675f,0.241471f, 0.39975f,0.237607f,
+0.404273f,0.233993f, 0.410059f,0.230677f, 0.416846f,0.227247f, 0.424522f,0.223851f, 0.43295f,0.220403f,
+0.442029f,0.216901f, 0.451602f,0.213172f, 0.461625f,0.209338f, 0.47214f,0.205633f, 0.482902f,0.20163f,
+0.493893f,0.197456f, 0.505004f,0.193042f, 0.51625f,0.188528f, 0.527626f,0.183984f, 0.539112f,0.17943f,
+0.550605f,0.174767f, 0.562055f,0.16999f, 0.573426f,0.165119f, 0.584742f,0.160234f, 0.595957f,0.155319f,
+0.607108f,0.150447f, 0.61811f,0.145551f, 0.628943f,0.140646f, 0.639682f,0.13583f, 0.650189f,0.130987f,
+0.660508f,0.126183f, 0.670593f,0.121402f, 0.680549f,0.116743f, 0.690359f,0.112197f, 0.699939f,0.107705f,
+0.709234f,0.103245f, 0.718328f,0.098886f, 0.727171f,0.0946036f, 0.735831f,0.0904454f, 0.74428f,0.0863946f,
+0.752567f,0.0824817f, 0.760683f,0.0786963f, 0.76847f,0.0749556f, 0.776095f,0.0713542f, 0.783542f,0.0678786f,
+0.790718f,0.0644843f, 0.797621f,0.0611733f, 0.804267f,0.0579564f, 0.810718f,0.0548618f, 0.817008f,0.0518999f,
+0.8231f,0.0490495f, 0.828929f,0.0462848f, 0.834535f,0.0436214f, 0.839995f,0.041084f, 0.845318f,0.0386687f,
+0.850531f,0.0363781f, 0.855607f,0.0341979f, 0.860459f,0.0320965f, 0.865124f,0.0300839f, 0.869645f,0.028171f,
+0.874026f,0.0263531f, 0.878303f,0.024635f, 0.882423f,0.0229969f, 0.886388f,0.0214398f, 0.890177f,0.0199558f,
+0.893837f,0.0185531f, 0.897322f,0.0172172f, 0.900793f,0.0159789f, 0.904187f,0.0148181f, 0.907436f,0.0137173f,
+0.910512f,0.0126705f, 0.913436f,0.0116797f, 0.916221f,0.010745f, 0.918953f,0.00987599f, 0.921551f,0.00905807f,
+0.924038f,0.00829196f, 0.926486f,0.00758492f, 0.928808f,0.00692127f, 0.931114f,0.00631248f, 0.93338f,0.00575177f,
+0.935518f,0.0052253f, 0.937546f,0.00473391f, 0.939478f,0.0042774f, 0.941417f,0.00386417f, 0.943251f,0.00347956f,
+0.945175f,0.00313936f, 0.946998f,0.00282271f, 0.948857f,0.00253908f, 0.950632f,0.00227698f, 0.952299f,0.00203326f,
+0.953958f,0.00181319f, 0.955531f,0.0016106f, 0.95702f,0.00142488f, 0.958437f,0.00125557f, 0.959789f,0.00110199f,
+0.961085f,0.000963289f, 0.962325f,0.000838553f, 0.963622f,0.000732202f, 0.964864f,0.000636336f, 0.966151f,0.000554133f,
+0.967454f,0.000481877f, 0.968666f,0.000416011f, 0.969874f,0.000359283f, 0.971082f,0.000310454f, 0.972198f,0.000265687f,
+0.973242f,0.000225526f, 0.974225f,0.000189988f, 0.975165f,0.000159191f, 0.976192f,0.000135501f, 0.977104f,0.00011366f,
+0.977912f,9.42178e-05f, 0.97859f,7.72471e-05f, 0.979059f,6.26181e-05f, 0.97972f,5.06471e-05f, 0.980703f,4.29161e-05f,
+0.981539f,3.49108e-05f, 0.98224f,2.75714e-05f, 0.982748f,2.10756e-05f, 0.983431f,1.57197e-05f, 0.984156f,1.14248e-05f,
+0.985088f,9.47717e-06f, 0.985813f,7.0254e-06f, 0.98677f,5.30481e-06f,
+
+0.503538f,0.307893f, 0.469354f,0.288925f, 0.445607f,0.27489f, 0.429157f,0.264121f, 0.418051f,0.255697f,
+0.410994f,0.24883f, 0.407116f,0.243204f, 0.405767f,0.238322f, 0.406484f,0.234004f, 0.408921f,0.230115f,
+0.412779f,0.226412f, 0.417877f,0.222977f, 0.424024f,0.219636f, 0.431016f,0.216174f, 0.438795f,0.21279f,
+0.447218f,0.20933f, 0.456193f,0.205782f, 0.465583f,0.202015f, 0.475383f,0.198205f, 0.48562f,0.194508f,
+0.49605f,0.190523f, 0.506688f,0.186419f, 0.517415f,0.182095f, 0.528262f,0.177702f, 0.539197f,0.173256f,
+0.550247f,0.168846f, 0.561296f,0.164348f, 0.572321f,0.159787f, 0.583244f,0.155118f, 0.594118f,0.150455f,
+0.604877f,0.145755f, 0.61556f,0.141091f, 0.626127f,0.136443f, 0.636546f,0.131805f, 0.646829f,0.127212f,
+0.656961f,0.122665f, 0.666875f,0.118125f, 0.676587f,0.113627f, 0.686078f,0.109171f, 0.695448f,0.104844f,
+0.704686f,0.100633f, 0.713711f,0.0964901f, 0.722459f,0.0923833f, 0.73101f,0.0883761f, 0.739317f,0.0844434f,
+0.747462f,0.080638f, 0.755404f,0.0769355f, 0.763189f,0.073361f, 0.77083f,0.069918f, 0.778184f,0.0665323f,
+0.785307f,0.0632392f, 0.792334f,0.0600997f, 0.799108f,0.0570375f, 0.805616f,0.0540506f, 0.811872f,0.051148f,
+0.817931f,0.0483529f, 0.823838f,0.04568f, 0.829589f,0.0431231f, 0.83512f,0.0406542f, 0.840406f,0.0382662f,
+0.845509f,0.0359782f, 0.850503f,0.0338103f, 0.855361f,0.0317474f, 0.860151f,0.0298034f, 0.864777f,0.0279453f,
+0.869176f,0.0261541f, 0.873428f,0.0244493f, 0.877543f,0.0228304f, 0.881546f,0.021299f, 0.885465f,0.0198575f,
+0.889216f,0.0184832f, 0.89282f,0.0171788f, 0.896269f,0.01594f, 0.899604f,0.014772f, 0.902777f,0.0136625f,
+0.905951f,0.0126366f, 0.909103f,0.0116849f, 0.912126f,0.0107853f, 0.914988f,0.00993096f, 0.917704f,0.00912374f,
+0.920291f,0.0083639f, 0.922764f,0.00765151f, 0.925196f,0.00699296f, 0.927511f,0.006376f, 0.929803f,0.00581013f,
+0.93198f,0.00528045f, 0.934106f,0.00479255f, 0.936243f,0.00434988f, 0.938263f,0.0039354f, 0.940176f,0.00354928f,
+0.941997f,0.00319145f, 0.943811f,0.00286788f, 0.945552f,0.00256985f, 0.947284f,0.00230094f, 0.949037f,0.00206022f,
+0.950719f,0.00183924f, 0.952409f,0.00164133f, 0.954042f,0.00145991f, 0.955575f,0.00129235f, 0.957036f,0.00113937f,
+0.958509f,0.0010036f, 0.9599f,0.000879724f, 0.961218f,0.0007675f, 0.962474f,0.000666444f, 0.963674f,0.000575934f,
+0.964923f,0.00049971f, 0.966119f,0.000431492f, 0.96729f,0.000371623f, 0.968468f,0.000320227f, 0.969555f,0.000273516f,
+0.970652f,0.000234436f, 0.971767f,0.000201488f, 0.972803f,0.000171712f, 0.973707f,0.000144832f, 0.974452f,0.000120998f,
+0.974994f,0.000100514f, 0.976076f,8.51685e-05f, 0.977037f,7.07574e-05f, 0.977888f,5.78364e-05f, 0.978603f,4.65055e-05f,
+0.979263f,3.67495e-05f, 0.980367f,3.11889e-05f, 0.981322f,2.50409e-05f, 0.982171f,1.93196e-05f, 0.98291f,1.43463e-05f,
+0.983465f,1.01207e-05f, 0.984131f,7.62357e-06f, 0.98523f,5.8521e-06f,
+
+0.514328f,0.297885f, 0.481164f,0.280253f, 0.457749f,0.26698f, 0.44125f,0.256641f, 0.429875f,0.24844f,
+0.422411f,0.241663f, 0.418039f,0.236042f, 0.416147f,0.231162f, 0.416282f,0.226806f, 0.418112f,0.222873f,
+0.421353f,0.219151f, 0.425798f,0.2156f, 0.431316f,0.212294f, 0.437691f,0.208897f, 0.444814f,0.205467f,
+0.452603f,0.202039f, 0.460965f,0.198581f, 0.469796f,0.195015f, 0.478985f,0.191261f, 0.488546f,0.187501f,
+0.498486f,0.183823f, 0.508588f,0.179898f, 0.518862f,0.175862f, 0.529208f,0.171644f, 0.53967f,0.167393f,
+0.550165f,0.163046f, 0.560784f,0.158779f, 0.57142f,0.154473f, 0.582018f,0.150105f, 0.592508f,0.145637f,
+0.602949f,0.141184f, 0.613288f,0.136715f, 0.623526f,0.13226f, 0.633678f,0.127854f, 0.643691f,0.123465f,
+0.653534f,0.119086f, 0.663297f,0.114813f, 0.672841f,0.110539f, 0.682199f,0.106311f, 0.691353f,0.102129f,
+0.700276f,0.0979881f, 0.709091f,0.093982f, 0.717753f,0.0900744f, 0.726261f,0.0862678f, 0.734503f,0.0825029f,
+0.742543f,0.0788275f, 0.75036f,0.0752323f, 0.758013f,0.0717522f, 0.765481f,0.0683755f, 0.77281f,0.0651255f,
+0.779994f,0.0619929f, 0.786953f,0.0589394f, 0.793637f,0.0559472f, 0.800239f,0.0531012f, 0.806647f,0.050347f,
+0.812817f,0.047669f, 0.818724f,0.045059f, 0.824406f,0.0425344f, 0.829958f,0.0401269f, 0.835378f,0.0378313f,
+0.840634f,0.0356313f, 0.845662f,0.0335051f, 0.850468f,0.0314556f, 0.855133f,0.0295045f, 0.859707f,0.0276608f,
+0.86415f,0.0259084f, 0.86857f,0.0242691f, 0.872798f,0.0226954f, 0.876819f,0.0211826f, 0.880686f,0.0197428f,
+0.884446f,0.018382f, 0.888092f,0.0170951f, 0.891711f,0.0158956f, 0.895177f,0.0147556f, 0.898503f,0.0136744f,
+0.90169f,0.0126507f, 0.904768f,0.0116872f, 0.907697f,0.0107741f, 0.910584f,0.00992686f, 0.913465f,0.00914536f,
+0.91625f,0.00841195f, 0.918884f,0.00771685f, 0.921384f,0.00706169f, 0.923765f,0.00644674f, 0.926043f,0.00587197f,
+0.928263f,0.005339f, 0.930453f,0.00484924f, 0.932616f,0.00440105f, 0.934676f,0.00398324f, 0.936662f,0.00359723f,
+0.93869f,0.00325145f, 0.940613f,0.00292911f, 0.942432f,0.00262935f, 0.944162f,0.00235227f, 0.94587f,0.00210198f,
+0.94753f,0.00187395f, 0.949119f,0.00166497f, 0.950787f,0.0014831f, 0.952398f,0.00131725f, 0.953996f,0.001169f,
+0.955489f,0.00103151f, 0.956971f,0.000908524f, 0.958383f,0.000796595f, 0.959714f,0.000694822f, 0.961015f,0.000604362f,
+0.962298f,0.000524549f, 0.963502f,0.00045265f, 0.964631f,0.000388385f, 0.96581f,0.000335606f, 0.966889f,0.000287819f,
+0.967875f,0.000245341f, 0.968848f,0.000210419f, 0.969604f,0.000178435f, 0.970535f,0.00015314f, 0.971611f,0.00012987f,
+0.972571f,0.000108594f, 0.973403f,8.96383e-05f, 0.974209f,7.36463e-05f, 0.975352f,6.1535e-05f, 0.976499f,5.15239e-05f,
+0.977533f,4.2053e-05f, 0.978473f,3.35706e-05f, 0.979363f,2.66888e-05f, 0.980334f,2.21519e-05f, 0.980948f,1.6799e-05f,
+0.981793f,1.20854e-05f, 0.982434f,7.94845e-06f, 0.983525f,6.35392e-06f,
+
+0.524801f,0.288169f, 0.492641f,0.271762f, 0.469587f,0.259211f, 0.453086f,0.249302f, 0.441487f,0.241329f,
+0.433666f,0.234671f, 0.428846f,0.22908f, 0.42645f,0.224216f, 0.426044f,0.219854f, 0.427298f,0.215862f,
+0.42996f,0.212152f, 0.433801f,0.208558f, 0.438683f,0.205143f, 0.444479f,0.201871f, 0.45099f,0.198445f,
+0.458177f,0.195071f, 0.465926f,0.191637f, 0.474184f,0.188195f, 0.482837f,0.184626f, 0.491809f,0.180919f,
+0.501114f,0.177218f, 0.51075f,0.173582f, 0.520525f,0.169738f, 0.530447f,0.165803f, 0.540404f,0.16168f,
+0.550487f,0.157577f, 0.560571f,0.153365f, 0.570752f,0.14922f, 0.580985f,0.145103f, 0.59116f,0.140915f,
+0.601267f,0.136686f, 0.611272f,0.132419f, 0.621218f,0.128186f, 0.631045f,0.12395f, 0.640762f,0.119744f,
+0.650382f,0.115591f, 0.659859f,0.111469f, 0.669176f,0.10738f, 0.67842f,0.103404f, 0.687411f,0.0994102f,
+0.696242f,0.0954875f, 0.704871f,0.0916155f, 0.713286f,0.0877973f, 0.721589f,0.0841051f, 0.729696f,0.0804842f,
+0.737663f,0.0769689f, 0.745437f,0.07353f, 0.753012f,0.0701746f, 0.760372f,0.0668961f, 0.767551f,0.0637151f,
+0.774594f,0.0606512f, 0.781496f,0.0576999f, 0.788238f,0.0548497f, 0.79484f,0.052106f, 0.801158f,0.0494099f,
+0.807325f,0.0468191f, 0.813401f,0.0443504f, 0.819257f,0.041953f, 0.824867f,0.03962f, 0.830239f,0.0373559f,
+0.835425f,0.0351796f, 0.840535f,0.0331201f, 0.845512f,0.0311569f, 0.850313f,0.0292712f, 0.854895f,0.0274521f,
+0.859285f,0.0257064f, 0.863578f,0.0240559f, 0.867776f,0.0224964f, 0.871843f,0.0210141f, 0.875925f,0.019638f,
+0.879805f,0.0183139f, 0.883496f,0.0170445f, 0.887059f,0.0158421f, 0.890474f,0.0146997f, 0.893789f,0.0136228f,
+0.897134f,0.0126301f, 0.900361f,0.0116922f, 0.903446f,0.0108027f, 0.906408f,0.00996346f, 0.909265f,0.00917464f,
+0.911983f,0.00842875f, 0.914662f,0.00773865f, 0.917326f,0.00710244f, 0.919938f,0.00651156f, 0.922403f,0.00595229f,
+0.924743f,0.00542619f, 0.92697f,0.00493357f, 0.929094f,0.00447407f, 0.931125f,0.00404687f, 0.933078f,0.00365186f,
+0.935089f,0.00329876f, 0.937006f,0.00297076f, 0.938828f,0.00266682f, 0.940726f,0.00239896f, 0.942527f,0.00215012f,
+0.944241f,0.00191979f, 0.945896f,0.00170847f, 0.947519f,0.00151808f, 0.949108f,0.00134623f, 0.950607f,0.0011884f,
+0.95214f,0.0010504f, 0.953688f,0.00092881f, 0.955221f,0.000820905f, 0.956634f,0.00072057f, 0.95795f,0.000628671f,
+0.959204f,0.000546314f, 0.960433f,0.000473932f, 0.961549f,0.000408575f, 0.962544f,0.000350076f, 0.963481f,0.000300274f,
+0.964268f,0.000256736f, 0.965487f,0.000221032f, 0.966575f,0.000188036f, 0.967552f,0.000158887f, 0.968599f,0.000135275f,
+0.969828f,0.000115035f, 0.971061f,9.80843e-05f, 0.972182f,8.1946e-05f, 0.973212f,6.73143e-05f, 0.974155f,5.43994e-05f,
+0.975019f,4.33743e-05f, 0.975955f,3.56746e-05f, 0.976714f,2.84534e-05f, 0.977713f,2.21661e-05f, 0.978828f,1.79467e-05f,
+0.98003f,1.38767e-05f, 0.981045f,9.80539e-06f, 0.981658f,6.82874e-06f,
+
+0.534955f,0.278739f, 0.503782f,0.263458f, 0.481115f,0.251589f, 0.464649f,0.242098f, 0.452873f,0.234361f,
+0.44474f,0.227854f, 0.439513f,0.2223f, 0.436656f,0.217482f, 0.435743f,0.213108f, 0.436461f,0.209092f,
+0.438571f,0.205385f, 0.441851f,0.201806f, 0.446144f,0.19834f, 0.45135f,0.195062f, 0.457306f,0.191751f,
+0.463889f,0.188345f, 0.471078f,0.185014f, 0.478753f,0.181614f, 0.486865f,0.178182f, 0.495318f,0.174637f,
+0.504059f,0.170994f, 0.513095f,0.167363f, 0.522424f,0.163787f, 0.531872f,0.160038f, 0.541451f,0.156221f,
+0.551042f,0.152226f, 0.560732f,0.148245f, 0.570425f,0.144186f, 0.580189f,0.140179f, 0.590007f,0.136219f,
+0.599788f,0.132227f, 0.609512f,0.128215f, 0.619109f,0.124143f, 0.628664f,0.120126f, 0.638097f,0.116104f,
+0.647431f,0.112119f, 0.656664f,0.108186f, 0.665761f,0.104284f, 0.674708f,0.100419f, 0.683554f,0.0966403f,
+0.69228f,0.0929365f, 0.700753f,0.0892266f, 0.709091f,0.0856039f, 0.717225f,0.0820308f, 0.725166f,0.0785224f,
+0.732998f,0.075133f, 0.740639f,0.0718142f, 0.74809f,0.0685709f, 0.755351f,0.0654047f, 0.762483f,0.0623475f,
+0.769409f,0.0593618f, 0.776167f,0.0564703f, 0.782809f,0.0536937f, 0.789302f,0.0510158f, 0.79564f,0.0484308f,
+0.801895f,0.0459651f, 0.8079f,0.0435506f, 0.813698f,0.0412091f, 0.819413f,0.0389824f, 0.824977f,0.0368405f,
+0.830324f,0.0347628f, 0.835439f,0.0327453f, 0.840348f,0.0307981f, 0.845109f,0.0289377f, 0.849804f,0.0271814f,
+0.854387f,0.0255111f, 0.858774f,0.023903f, 0.862964f,0.0223567f, 0.866992f,0.0208795f, 0.870952f,0.019491f,
+0.874821f,0.0181804f, 0.878568f,0.0169374f, 0.88234f,0.0157866f, 0.885915f,0.0146798f, 0.889314f,0.0136216f,
+0.892612f,0.0126244f, 0.895761f,0.0116769f, 0.898776f,0.0107802f, 0.90182f,0.00995614f, 0.904842f,0.00919139f,
+0.907721f,0.00846578f, 0.910491f,0.00778366f, 0.913157f,0.00714302f, 0.91569f,0.00653861f, 0.918193f,0.00598149f,
+0.920661f,0.00546746f, 0.92312f,0.0049957f, 0.925439f,0.00454968f, 0.927637f,0.00413091f, 0.929727f,0.00373977f,
+0.931717f,0.00337598f, 0.933619f,0.00303888f, 0.935437f,0.00272753f, 0.937268f,0.00244833f, 0.939082f,0.0021947f,
+0.940796f,0.00195985f, 0.942585f,0.00175475f, 0.944283f,0.00156513f, 0.945877f,0.00138949f, 0.947378f,0.00122814f,
+0.948848f,0.00108388f, 0.950277f,0.000954532f, 0.951605f,0.000836204f, 0.952925f,0.0007327f, 0.954261f,0.000643643f,
+0.955556f,0.000565625f, 0.956662f,0.000492942f, 0.957595f,0.000427228f, 0.958686f,0.000367778f, 0.959807f,0.000314482f,
+0.960912f,0.000269266f, 0.962051f,0.0002288f, 0.963248f,0.000192957f, 0.964568f,0.000165319f, 0.965863f,0.000141261f,
+0.967044f,0.000118977f, 0.968203f,0.000100206f, 0.969346f,8.46172e-05f, 0.970503f,7.24539e-05f, 0.971429f,6.00299e-05f,
+0.972308f,4.84452e-05f, 0.973426f,3.84375e-05f, 0.974492f,2.98544e-05f, 0.975734f,2.41845e-05f, 0.976822f,1.84631e-05f,
+0.977959f,1.43477e-05f, 0.97929f,1.14888e-05f, 0.97968f,7.40037e-06f,
+
+0.544796f,0.269593f, 0.514589f,0.255346f, 0.492329f,0.244121f, 0.475937f,0.23504f, 0.464023f,0.227538f,
+0.455621f,0.221203f, 0.450027f,0.215697f, 0.446744f,0.210916f, 0.445363f,0.206569f, 0.445585f,0.202573f,
+0.447168f,0.198837f, 0.44992f,0.195294f, 0.453663f,0.191822f, 0.458289f,0.188477f, 0.463712f,0.185278f,
+0.469758f,0.181963f, 0.476366f,0.178617f, 0.483496f,0.175298f, 0.491065f,0.171952f, 0.499009f,0.168556f,
+0.507246f,0.165051f, 0.515742f,0.161483f, 0.524503f,0.157934f, 0.533523f,0.154433f, 0.542648f,0.150794f,
+0.551888f,0.147099f, 0.561131f,0.143251f, 0.570453f,0.139414f, 0.579775f,0.13552f, 0.589114f,0.131629f,
+0.598504f,0.1278f, 0.607913f,0.124011f, 0.617258f,0.120199f, 0.626493f,0.116347f, 0.635638f,0.112507f,
+0.644719f,0.108716f, 0.653678f,0.10494f, 0.662526f,0.101203f, 0.671273f,0.0975253f, 0.679893f,0.0938957f,
+0.688329f,0.0902851f, 0.696727f,0.0868035f, 0.704956f,0.0833637f, 0.712949f,0.0799351f, 0.720826f,0.0766028f,
+0.728493f,0.0733145f, 0.735987f,0.0700987f, 0.743378f,0.0669964f, 0.750585f,0.0639628f, 0.757601f,0.0609983f,
+0.76443f,0.0581072f, 0.771091f,0.0553031f, 0.777608f,0.0525906f, 0.783936f,0.0499549f, 0.790151f,0.047426f,
+0.796271f,0.045004f, 0.802268f,0.0426787f, 0.808161f,0.0404524f, 0.813885f,0.0382991f, 0.819374f,0.0361986f,
+0.824754f,0.034193f, 0.830015f,0.0322745f, 0.835126f,0.0304305f, 0.840013f,0.0286394f, 0.844687f,0.0269068f,
+0.849202f,0.0252473f, 0.853605f,0.023671f, 0.857905f,0.0221754f, 0.862122f,0.0207601f, 0.866147f,0.0193979f,
+0.869992f,0.018092f, 0.873696f,0.0168499f, 0.877365f,0.0156893f, 0.880945f,0.0145953f, 0.884431f,0.0135632f,
+0.887907f,0.0126035f, 0.891212f,0.0116848f, 0.894359f,0.0108093f, 0.897421f,0.00998748f, 0.900335f,0.00920716f,
+0.903125f,0.00847073f, 0.905878f,0.00778792f, 0.908668f,0.00716391f, 0.911367f,0.00657742f, 0.913974f,0.0060284f,
+0.91647f,0.00551263f, 0.918839f,0.00502706f, 0.921187f,0.00458182f, 0.923496f,0.00417176f, 0.925796f,0.00379682f,
+0.927976f,0.00344442f, 0.930038f,0.00311417f, 0.931992f,0.00280647f, 0.933849f,0.00252114f, 0.935617f,0.00225764f,
+0.937299f,0.00201519f, 0.93899f,0.00179911f, 0.940606f,0.00160116f, 0.942184f,0.00142221f, 0.943831f,0.00126781f,
+0.945364f,0.00112498f, 0.946764f,0.000992896f, 0.948034f,0.00087192f, 0.949228f,0.000765113f, 0.950271f,0.000669205f,
+0.951277f,0.000581768f, 0.952537f,0.000506132f, 0.953789f,0.00044205f, 0.955284f,0.000386209f, 0.956683f,0.000334084f,
+0.957986f,0.000286458f, 0.959206f,0.000243568f, 0.960344f,0.00020536f, 0.9614f,0.000171622f, 0.96248f,0.000143759f,
+0.963514f,0.000120253f, 0.964647f,0.000101241f, 0.965773f,8.49886e-05f, 0.967103f,7.05996e-05f, 0.968534f,5.98804e-05f,
+0.970035f,5.16363e-05f, 0.971373f,4.26455e-05f, 0.972592f,3.40698e-05f, 0.973711f,2.63836e-05f, 0.974848f,2.05288e-05f,
+0.975975f,1.58836e-05f, 0.976941f,1.22009e-05f, 0.977583f,8.07381e-06f,
+
+0.554321f,0.260723f, 0.525061f,0.247428f, 0.503226f,0.236811f, 0.486939f,0.228128f, 0.474926f,0.220863f,
+0.466291f,0.214694f, 0.460372f,0.209274f, 0.456698f,0.204534f, 0.454888f,0.200242f, 0.454642f,0.19626f,
+0.455731f,0.192514f, 0.45798f,0.188999f, 0.461213f,0.185568f, 0.465302f,0.182206f, 0.470174f,0.178988f,
+0.475712f,0.175793f, 0.48179f,0.172497f, 0.488386f,0.169232f, 0.495421f,0.165943f, 0.502857f,0.162661f,
+0.510616f,0.159319f, 0.518623f,0.15587f, 0.526868f,0.152387f, 0.535349f,0.148928f, 0.544064f,0.14552f,
+0.552867f,0.141992f, 0.561772f,0.138425f, 0.570683f,0.134736f, 0.579645f,0.131043f, 0.58861f,0.127315f,
+0.597556f,0.123561f, 0.606546f,0.119877f, 0.615556f,0.116247f, 0.624519f,0.112616f, 0.633408f,0.108982f,
+0.642181f,0.105332f, 0.650901f,0.101744f, 0.659504f,0.0981714f, 0.668017f,0.0946516f, 0.676405f,0.0911682f,
+0.684677f,0.0877375f, 0.692835f,0.0843697f, 0.700795f,0.081016f, 0.708758f,0.0778138f, 0.716522f,0.0746337f,
+0.724063f,0.0714757f, 0.731509f,0.0684206f, 0.738742f,0.065405f, 0.745816f,0.0624651f, 0.752797f,0.0596337f,
+0.759599f,0.0568679f, 0.766226f,0.0541718f, 0.772659f,0.0515407f, 0.77895f,0.0489979f, 0.785044f,0.0465216f,
+0.79098f,0.0441262f, 0.796802f,0.0418273f, 0.802538f,0.0396316f, 0.808183f,0.0375345f, 0.813681f,0.0355126f,
+0.819135f,0.0335957f, 0.824366f,0.0317245f, 0.829443f,0.0299241f, 0.834445f,0.028215f, 0.839291f,0.0265697f,
+0.843977f,0.0249867f, 0.848454f,0.0234538f, 0.852748f,0.0219785f, 0.856915f,0.0205729f, 0.860995f,0.0192445f,
+0.864983f,0.0179866f, 0.868825f,0.0167849f, 0.87253f,0.0156389f, 0.876068f,0.0145432f, 0.879496f,0.0135071f,
+0.882917f,0.0125459f, 0.886223f,0.0116356f, 0.889481f,0.0107854f, 0.892687f,0.00998959f, 0.895753f,0.00923247f,
+0.898685f,0.00851501f, 0.901525f,0.00784113f, 0.904226f,0.00720301f, 0.906813f,0.0066027f, 0.909352f,0.00604644f,
+0.91193f,0.00554048f, 0.914396f,0.00506428f, 0.916834f,0.00462544f, 0.91917f,0.00421418f, 0.921383f,0.00382775f,
+0.923585f,0.00347604f, 0.925745f,0.00315303f, 0.927865f,0.0028569f, 0.929893f,0.00258116f, 0.931793f,0.00232321f,
+0.933579f,0.00208347f, 0.935256f,0.00186184f, 0.936829f,0.00165788f, 0.938308f,0.00147206f, 0.939744f,0.00130663f,
+0.941031f,0.00115451f, 0.942202f,0.00101824f, 0.943399f,0.000903513f, 0.944841f,0.000797033f, 0.946216f,0.000698723f,
+0.947682f,0.000609027f, 0.949162f,0.000531498f, 0.950557f,0.000461029f, 0.951856f,0.000397044f, 0.953172f,0.000342849f,
+0.95462f,0.000298339f, 0.956075f,0.000258623f, 0.957396f,0.000221537f, 0.958591f,0.000187727f, 0.959663f,0.000157391f,
+0.960914f,0.000130691f, 0.962111f,0.00010735f, 0.963336f,8.82994e-05f, 0.964717f,7.44528e-05f, 0.965976f,6.11631e-05f,
+0.967213f,4.97536e-05f, 0.96866f,4.2383e-05f, 0.970119f,3.6058e-05f, 0.971364f,2.89475e-05f, 0.972422f,2.21625e-05f,
+0.9733f,1.63749e-05f, 0.974248f,1.25605e-05f, 0.975294f,8.70447e-06f,
+
+0.563536f,0.252126f, 0.535201f,0.239707f, 0.513804f,0.229663f, 0.497652f,0.221364f, 0.485574f,0.214339f,
+0.476743f,0.208341f, 0.470536f,0.203024f, 0.466506f,0.198337f, 0.464297f,0.194103f, 0.463616f,0.190141f,
+0.464247f,0.186423f, 0.466013f,0.182907f, 0.468763f,0.179528f, 0.472352f,0.176187f, 0.476699f,0.172947f,
+0.481738f,0.169835f, 0.487327f,0.166644f, 0.493394f,0.16339f, 0.499933f,0.160197f, 0.506849f,0.156958f,
+0.514128f,0.15374f, 0.521688f,0.150467f, 0.529461f,0.147095f, 0.537447f,0.143703f, 0.545645f,0.140339f,
+0.55406f,0.137035f, 0.562542f,0.13362f, 0.571119f,0.130182f, 0.579712f,0.126664f, 0.588316f,0.123106f,
+0.596945f,0.119551f, 0.605531f,0.115959f, 0.614144f,0.112425f, 0.62277f,0.108944f, 0.631362f,0.105486f,
+0.639912f,0.102057f, 0.648317f,0.0985876f, 0.656648f,0.0951605f, 0.664941f,0.0918091f, 0.673091f,0.0884666f,
+0.681161f,0.0851888f, 0.689121f,0.0819629f, 0.696945f,0.0787799f, 0.704656f,0.0756595f, 0.712185f,0.0725695f,
+0.71972f,0.0696219f, 0.727046f,0.0666919f, 0.734168f,0.0637955f, 0.741206f,0.0609994f, 0.748034f,0.058243f,
+0.754716f,0.0555618f, 0.761312f,0.0529843f, 0.767739f,0.0504699f, 0.774002f,0.0480239f, 0.78007f,0.045635f,
+0.786012f,0.0433328f, 0.79178f,0.0410977f, 0.797368f,0.0389305f, 0.802786f,0.0368331f, 0.808131f,0.0348352f,
+0.813462f,0.03295f, 0.818651f,0.0311326f, 0.823792f,0.0294112f, 0.828775f,0.0277485f, 0.833569f,0.0261378f,
+0.838263f,0.024603f, 0.842852f,0.0231386f, 0.847329f,0.0217381f, 0.851635f,0.0203884f, 0.85575f,0.0190858f,
+0.859725f,0.0178418f, 0.863592f,0.0166617f, 0.867378f,0.0155472f, 0.87107f,0.014493f, 0.874595f,0.0134824f,
+0.87798f,0.01252f, 0.881245f,0.0116073f, 0.884436f,0.0107509f, 0.88763f,0.00995957f, 0.89069f,0.00920763f,
+0.893741f,0.00851256f, 0.896695f,0.00785691f, 0.899539f,0.00723759f, 0.902275f,0.00665443f, 0.904904f,0.00610596f,
+0.907401f,0.00558802f, 0.909793f,0.00510262f, 0.912146f,0.00465547f, 0.914487f,0.00424605f, 0.916766f,0.0038664f,
+0.918992f,0.00351645f, 0.921091f,0.00318783f, 0.923114f,0.00288352f, 0.925135f,0.00260946f, 0.927088f,0.002358f,
+0.92895f,0.00212621f, 0.930706f,0.00191258f, 0.93229f,0.00171304f, 0.933689f,0.00152802f, 0.934867f,0.00135747f,
+0.936195f,0.00120105f, 0.937756f,0.00106091f, 0.939355f,0.000935175f, 0.940856f,0.000820058f, 0.942347f,0.000718096f,
+0.944054f,0.000633273f, 0.945673f,0.000555139f, 0.947187f,0.000483144f, 0.948627f,0.000418612f, 0.950056f,0.000362821f,
+0.951357f,0.000311711f, 0.952593f,0.000266526f, 0.954115f,0.000229479f, 0.955689f,0.000198485f, 0.9572f,0.000170112f,
+0.958608f,0.000143756f, 0.959932f,0.000119907f, 0.961182f,9.87236e-05f, 0.962363f,8.01882e-05f, 0.963531f,6.49443e-05f,
+0.964775f,5.33459e-05f, 0.966016f,4.34223e-05f, 0.967108f,3.42665e-05f, 0.968564f,2.98369e-05f, 0.969773f,2.44932e-05f,
+0.970623f,1.8393e-05f, 0.971356f,1.26209e-05f, 0.972792f,9.24928e-06f,
+
+0.572442f,0.243795f, 0.54501f,0.232183f, 0.524062f,0.22268f, 0.508071f,0.214752f, 0.49596f,0.207972f,
+0.486966f,0.202141f, 0.480506f,0.196951f, 0.476151f,0.192308f, 0.473574f,0.188129f, 0.472493f,0.184224f,
+0.472695f,0.180542f, 0.474006f,0.177026f, 0.476296f,0.173692f, 0.47942f,0.170413f, 0.483277f,0.167182f,
+0.487801f,0.164037f, 0.492936f,0.160998f, 0.49853f,0.157838f, 0.504555f,0.154649f, 0.511003f,0.151522f,
+0.517778f,0.148344f, 0.524881f,0.145197f, 0.532232f,0.142f, 0.539766f,0.138716f, 0.547491f,0.135423f,
+0.555405f,0.132159f, 0.563522f,0.128964f, 0.571688f,0.125665f, 0.579944f,0.122361f, 0.588229f,0.119011f,
+0.596482f,0.115584f, 0.604782f,0.112201f, 0.613043f,0.108788f, 0.621286f,0.105396f, 0.629539f,0.102061f,
+0.637794f,0.0987845f, 0.64598f,0.0955177f, 0.654092f,0.0922697f, 0.662065f,0.0890074f, 0.669995f,0.0858201f,
+0.677833f,0.082676f, 0.685568f,0.0795773f, 0.69319f,0.0765234f, 0.700728f,0.0735375f, 0.70814f,0.0706024f,
+0.715418f,0.0677165f, 0.722557f,0.064886f, 0.729671f,0.0621728f, 0.736587f,0.0594832f, 0.743316f,0.0568341f,
+0.749968f,0.054282f, 0.756421f,0.0517701f, 0.762734f,0.0493307f, 0.768973f,0.0469904f, 0.775058f,0.0447132f,
+0.780981f,0.042498f, 0.786724f,0.0403402f, 0.792317f,0.0382516f, 0.797788f,0.0362419f, 0.803079f,0.0342904f,
+0.808206f,0.0324043f, 0.813209f,0.0305949f, 0.81813f,0.0288721f, 0.822983f,0.0272335f, 0.827795f,0.0256796f,
+0.832578f,0.0242125f, 0.837158f,0.0227853f, 0.841609f,0.0214181f, 0.845984f,0.0201209f, 0.850227f,0.0188775f,
+0.854313f,0.017682f, 0.858246f,0.0165346f, 0.862015f,0.0154329f, 0.865669f,0.0143867f, 0.869256f,0.0134017f,
+0.872786f,0.0124757f, 0.876192f,0.011595f, 0.879439f,0.0107527f, 0.882537f,0.00995054f, 0.88552f,0.00919187f,
+0.888501f,0.00849117f, 0.891475f,0.0078439f, 0.894337f,0.00723278f, 0.897154f,0.00666442f, 0.899859f,0.0061281f,
+0.902478f,0.00562525f, 0.905009f,0.00515544f, 0.907413f,0.00471253f, 0.909682f,0.00429544f, 0.911846f,0.00390635f,
+0.913975f,0.00355092f, 0.916043f,0.00322396f, 0.918033f,0.00292272f, 0.919954f,0.00264692f, 0.921694f,0.00238794f,
+0.923268f,0.00214804f, 0.924776f,0.00193466f, 0.926344f,0.0017413f, 0.928293f,0.00156158f, 0.930289f,0.00139809f,
+0.932198f,0.00124575f, 0.934008f,0.0011049f, 0.935727f,0.000975527f, 0.93736f,0.000857392f, 0.938998f,0.000753967f,
+0.940548f,0.000659728f, 0.941995f,0.000573947f, 0.943464f,0.000501138f, 0.944961f,0.000437279f, 0.946617f,0.000380432f,
+0.948177f,0.000328171f, 0.949753f,0.000283403f, 0.95126f,0.000242954f, 0.952683f,0.000206195f, 0.954147f,0.000175684f,
+0.955671f,0.000150769f, 0.957194f,0.000129027f, 0.958603f,0.000108578f, 0.959902f,8.98023e-05f, 0.961099f,7.30171e-05f,
+0.962196f,5.83113e-05f, 0.963297f,4.69529e-05f, 0.964301f,3.7309e-05f, 0.965119f,2.8916e-05f, 0.966121f,2.31532e-05f,
+0.96747f,1.89214e-05f, 0.968706f,1.37687e-05f, 0.970204f,1.00046e-05f,
+
+0.581039f,0.235725f, 0.554488f,0.224858f, 0.533999f,0.215863f, 0.51819f,0.208292f, 0.506077f,0.201759f,
+0.49695f,0.19609f, 0.49027f,0.191039f, 0.485622f,0.186457f, 0.482704f,0.182327f, 0.481253f,0.17849f,
+0.481055f,0.174849f, 0.481942f,0.171361f, 0.483788f,0.168043f, 0.486471f,0.164828f, 0.489871f,0.161633f,
+0.493922f,0.158512f, 0.498574f,0.155492f, 0.503735f,0.152478f, 0.509304f,0.149377f, 0.515261f,0.146272f,
+0.521589f,0.143204f, 0.528211f,0.140107f, 0.535123f,0.137031f, 0.542254f,0.133915f, 0.549546f,0.130727f,
+0.557011f,0.12754f, 0.56464f,0.124377f, 0.572466f,0.121299f, 0.580328f,0.118126f, 0.588261f,0.114947f,
+0.596244f,0.111758f, 0.604167f,0.108476f, 0.612151f,0.10526f, 0.620092f,0.102018f, 0.627988f,0.0987741f,
+0.635887f,0.0955869f, 0.643797f,0.0924694f, 0.651652f,0.0893729f, 0.659456f,0.0863155f, 0.667124f,0.0832424f,
+0.674706f,0.0802093f, 0.682243f,0.0772502f, 0.689662f,0.0743211f, 0.697003f,0.0714563f, 0.704211f,0.0686272f,
+0.711336f,0.0658679f, 0.718339f,0.0631615f, 0.725193f,0.0604966f, 0.731951f,0.0579076f, 0.738678f,0.055421f,
+0.745191f,0.052952f, 0.751549f,0.0505351f, 0.757841f,0.0482122f, 0.763947f,0.0459313f, 0.769912f,0.0437156f,
+0.775823f,0.0415985f, 0.781583f,0.0395393f, 0.787187f,0.0375377f, 0.792631f,0.0355936f, 0.797907f,0.0337064f,
+0.803088f,0.0318986f, 0.808106f,0.0301478f, 0.812966f,0.0284562f, 0.817682f,0.0268276f, 0.822325f,0.0252803f,
+0.826879f,0.0238061f, 0.831306f,0.0223907f, 0.835746f,0.0210665f, 0.840116f,0.019806f, 0.844367f,0.018598f,
+0.848507f,0.0174449f, 0.852569f,0.0163507f, 0.856492f,0.0153017f, 0.860245f,0.014291f, 0.863862f,0.013325f,
+0.867353f,0.0124053f, 0.870734f,0.0115337f, 0.874053f,0.0107155f, 0.877297f,0.00994608f, 0.880393f,0.00921159f,
+0.883339f,0.00851165f, 0.886144f,0.00784732f, 0.888815f,0.00721893f, 0.891567f,0.00665028f, 0.894283f,0.0061224f,
+0.896928f,0.0056307f, 0.899476f,0.00516989f, 0.901904f,0.00473618f, 0.90422f,0.00433017f, 0.906456f,0.00395455f,
+0.90852f,0.00359977f, 0.910408f,0.00326656f, 0.912138f,0.00295746f, 0.913785f,0.00267771f, 0.915443f,0.00241928f,
+0.917638f,0.00218359f, 0.919807f,0.00196826f, 0.921871f,0.00176717f, 0.923877f,0.00158332f, 0.925884f,0.0014185f,
+0.927871f,0.00126999f, 0.929794f,0.00113308f, 0.931676f,0.00100936f, 0.933425f,0.000894143f, 0.935044f,0.00078785f,
+0.936656f,0.00069059f, 0.938357f,0.000603872f, 0.940045f,0.000527198f, 0.941647f,0.000457168f, 0.943242f,0.000396049f,
+0.944869f,0.000343726f, 0.946438f,0.000296537f, 0.94799f,0.000254857f, 0.949531f,0.000218733f, 0.951036f,0.000186991f,
+0.952434f,0.00015781f, 0.953804f,0.000132732f, 0.955282f,0.000113439f, 0.956676f,9.57453e-05f, 0.95798f,7.97814e-05f,
+0.959101f,6.48257e-05f, 0.960008f,5.12766e-05f, 0.960742f,3.94441e-05f, 0.962034f,3.14101e-05f, 0.963066f,2.35558e-05f,
+0.964224f,1.7791e-05f, 0.966064f,1.45826e-05f, 0.967373f,1.06387e-05f,
+
+0.589333f,0.227912f, 0.56364f,0.21773f, 0.543615f,0.209215f, 0.528008f,0.201984f, 0.515919f,0.195694f,
+0.506688f,0.190186f, 0.499816f,0.18527f, 0.494909f,0.18077f, 0.49168f,0.176703f, 0.489884f,0.172929f,
+0.489312f,0.169335f, 0.489809f,0.165911f, 0.491232f,0.162594f, 0.493493f,0.159434f, 0.496467f,0.156309f,
+0.500072f,0.153217f, 0.504254f,0.150192f, 0.508979f,0.147278f, 0.514125f,0.144298f, 0.519632f,0.141251f,
+0.525503f,0.138243f, 0.531689f,0.13524f, 0.538146f,0.13223f, 0.544858f,0.129234f, 0.551764f,0.126206f,
+0.558812f,0.123119f, 0.566018f,0.120043f, 0.573364f,0.116984f, 0.580903f,0.114024f, 0.588468f,0.11098f,
+0.596085f,0.107923f, 0.603772f,0.104892f, 0.611399f,0.101778f, 0.619056f,0.098703f, 0.626684f,0.0956236f,
+0.634269f,0.0925464f, 0.641835f,0.089509f, 0.649383f,0.0865196f, 0.656932f,0.0835985f, 0.664417f,0.0807039f,
+0.671815f,0.0778305f, 0.679064f,0.0749467f, 0.686283f,0.072145f, 0.693424f,0.0693965f, 0.700458f,0.0666874f,
+0.707411f,0.0640412f, 0.714245f,0.0614382f, 0.720986f,0.0588984f, 0.727621f,0.0564177f, 0.734094f,0.0539701f,
+0.7405f,0.0516087f, 0.746841f,0.0493285f, 0.752979f,0.0470706f, 0.758946f,0.0448561f, 0.764881f,0.042742f,
+0.770648f,0.0406731f, 0.776274f,0.0386621f, 0.781879f,0.0367525f, 0.787335f,0.034895f, 0.792639f,0.0330906f,
+0.797803f,0.0313437f, 0.8028f,0.0296473f, 0.807687f,0.0280191f, 0.812447f,0.0264515f, 0.817057f,0.0249381f,
+0.821531f,0.0234833f, 0.82588f,0.0220884f, 0.83021f,0.0207774f, 0.834374f,0.0195106f, 0.838441f,0.018304f,
+0.842571f,0.0171858f, 0.846558f,0.0161107f, 0.85044f,0.0150859f, 0.854261f,0.0141158f, 0.858025f,0.0131992f,
+0.861623f,0.0123164f, 0.865055f,0.0114677f, 0.868374f,0.0106618f, 0.871583f,0.00989847f, 0.87471f,0.00918051f,
+0.877762f,0.00850675f, 0.880712f,0.00787108f, 0.8835f,0.00726436f, 0.886133f,0.006688f, 0.888618f,0.00614262f,
+0.890977f,0.00563078f, 0.893376f,0.00516964f, 0.895642f,0.00473688f, 0.897909f,0.0043423f, 0.900082f,0.00397077f,
+0.902068f,0.00362199f, 0.904022f,0.00329788f, 0.906298f,0.00299886f, 0.908624f,0.00271825f, 0.910839f,0.00245552f,
+0.913015f,0.0022155f, 0.915162f,0.00199709f, 0.917227f,0.00179496f, 0.919294f,0.00161375f, 0.921258f,0.00144544f,
+0.923138f,0.00129066f, 0.924978f,0.00115223f, 0.92695f,0.00102852f, 0.928938f,0.000915061f, 0.930821f,0.000809282f,
+0.932739f,0.000715996f, 0.934574f,0.00063005f, 0.936315f,0.000550976f, 0.93797f,0.000478858f, 0.93965f,0.000417003f,
+0.941232f,0.000360214f, 0.942761f,0.000309769f, 0.944299f,0.000266581f, 0.945825f,0.000229102f, 0.94723f,0.000194462f,
+0.948688f,0.000165156f, 0.950162f,0.000140566f, 0.951481f,0.000117575f, 0.952843f,9.78547e-05f, 0.95431f,8.31638e-05f,
+0.955573f,6.90894e-05f, 0.956904f,5.67472e-05f, 0.958206f,4.51397e-05f, 0.959275f,3.46781e-05f, 0.960577f,2.69635e-05f,
+0.961884f,1.99997e-05f, 0.96314f,1.49186e-05f, 0.964392f,1.13703e-05f,
+
+0.597325f,0.220347f, 0.572468f,0.210799f, 0.552911f,0.202736f, 0.537524f,0.195828f, 0.525482f,0.189779f,
+0.516175f,0.184434f, 0.509138f,0.179652f, 0.504001f,0.175257f, 0.500486f,0.171235f, 0.498371f,0.167528f,
+0.497453f,0.164f, 0.49758f,0.160628f, 0.498615f,0.157354f, 0.500465f,0.154212f, 0.503035f,0.151161f,
+0.506224f,0.148126f, 0.509975f,0.145137f, 0.51424f,0.142215f, 0.518989f,0.139383f, 0.524092f,0.136456f,
+0.529517f,0.133484f, 0.53528f,0.13057f, 0.541306f,0.127631f, 0.547589f,0.124714f, 0.554093f,0.121802f,
+0.560769f,0.118865f, 0.567573f,0.115883f, 0.574524f,0.112923f, 0.581588f,0.109967f, 0.588843f,0.107124f,
+0.596119f,0.104211f, 0.603445f,0.101294f, 0.610822f,0.0983947f, 0.618167f,0.0954491f, 0.625496f,0.0925026f,
+0.632835f,0.0895929f, 0.640121f,0.0866785f, 0.647366f,0.0837859f, 0.654585f,0.0809375f, 0.661814f,0.078166f,
+0.668985f,0.0754238f, 0.676124f,0.072738f, 0.683112f,0.070038f, 0.689986f,0.0673622f, 0.696837f,0.064771f,
+0.703595f,0.0622239f, 0.710271f,0.0597327f, 0.716851f,0.0572931f, 0.723324f,0.0549038f, 0.729704f,0.0525743f,
+0.735988f,0.0503046f, 0.742098f,0.0480628f, 0.748175f,0.0459149f, 0.754165f,0.0438333f, 0.759971f,0.0417799f,
+0.765611f,0.0397684f, 0.771183f,0.0378378f, 0.776647f,0.0359686f, 0.781955f,0.0341475f, 0.787252f,0.0324235f,
+0.792402f,0.0307477f, 0.797405f,0.0291209f, 0.802288f,0.0275517f, 0.807011f,0.0260296f, 0.81162f,0.0245678f,
+0.816086f,0.023157f, 0.820446f,0.0218053f, 0.824689f,0.020509f, 0.828788f,0.0192623f, 0.832856f,0.0180893f,
+0.836821f,0.01697f, 0.840632f,0.0158924f, 0.844361f,0.014871f, 0.848146f,0.0139256f, 0.851826f,0.0130248f,
+0.855396f,0.0121668f, 0.858869f,0.0113521f, 0.862236f,0.0105783f, 0.865452f,0.00983611f, 0.868528f,0.0091279f,
+0.871531f,0.0084633f, 0.874413f,0.0078353f, 0.877194f,0.00724574f, 0.879903f,0.00669611f, 0.882547f,0.00617398f,
+0.885009f,0.0056773f, 0.887286f,0.005207f, 0.889364f,0.00476342f, 0.891482f,0.00435372f, 0.89377f,0.00398411f,
+0.896331f,0.00364011f, 0.898831f,0.00332051f, 0.901283f,0.00302409f, 0.903637f,0.00274645f, 0.905929f,0.00249044f,
+0.908161f,0.00225395f, 0.910259f,0.00203197f, 0.912229f,0.00182488f, 0.914186f,0.00163999f, 0.916243f,0.00146912f,
+0.918309f,0.00131412f, 0.920352f,0.0011737f, 0.922288f,0.00104279f, 0.924274f,0.000927221f, 0.926247f,0.00082385f,
+0.928248f,0.000732217f, 0.930163f,0.000646688f, 0.931985f,0.000567759f, 0.933785f,0.00049737f, 0.935506f,0.000433086f,
+0.937176f,0.000375254f, 0.938833f,0.000325145f, 0.940399f,0.000279713f, 0.941959f,0.000239025f, 0.943552f,0.000204572f,
+0.945134f,0.00017496f, 0.946595f,0.000147751f, 0.947961f,0.000123811f, 0.949343f,0.000104531f, 0.950624f,8.67038e-05f,
+0.95212f,7.21018e-05f, 0.953631f,6.0295e-05f, 0.954936f,4.91102e-05f, 0.95651f,3.92454e-05f, 0.957899f,3.00341e-05f,
+0.959273f,2.3055e-05f, 0.960299f,1.66701e-05f, 0.961229f,1.21345e-05f,
+
+0.605018f,0.213026f, 0.580974f,0.204064f, 0.561887f,0.196424f, 0.546734f,0.189826f, 0.534761f,0.184011f,
+0.525402f,0.178829f, 0.518227f,0.174186f, 0.512888f,0.169905f, 0.509113f,0.165938f, 0.506701f,0.162286f,
+0.505464f,0.158834f, 0.505244f,0.155512f, 0.505922f,0.152315f, 0.507382f,0.149186f, 0.50956f,0.146184f,
+0.512358f,0.143221f, 0.5157f,0.140276f, 0.519547f,0.137392f, 0.52386f,0.134579f, 0.528588f,0.131808f,
+0.533624f,0.128949f, 0.538953f,0.126065f, 0.544589f,0.123239f, 0.550449f,0.120381f, 0.556543f,0.11755f,
+0.562834f,0.114725f, 0.56928f,0.111885f, 0.575838f,0.109008f, 0.582535f,0.106164f, 0.589324f,0.103317f,
+0.596297f,0.100587f, 0.603299f,0.0978127f, 0.610334f,0.0950253f, 0.617411f,0.0922563f, 0.624477f,0.08947f,
+0.631487f,0.086649f, 0.638549f,0.0839046f, 0.645545f,0.0811466f, 0.652497f,0.0784086f, 0.65942f,0.075712f,
+0.666301f,0.0730543f, 0.673192f,0.0704745f, 0.680018f,0.0679268f, 0.686788f,0.0654227f, 0.693393f,0.0629046f,
+0.699931f,0.0604436f, 0.706411f,0.0580452f, 0.712803f,0.0556937f, 0.719128f,0.0534046f, 0.725354f,0.0511641f,
+0.731482f,0.0489753f, 0.737523f,0.0468462f, 0.74347f,0.0447744f, 0.749241f,0.0427283f, 0.754997f,0.0407768f,
+0.760652f,0.0388805f, 0.766146f,0.0370186f, 0.771482f,0.0351983f, 0.776736f,0.0334473f, 0.781869f,0.0317498f,
+0.786877f,0.0301052f, 0.791887f,0.0285534f, 0.79676f,0.0270475f, 0.801501f,0.0255894f, 0.806113f,0.0241816f,
+0.810585f,0.0228207f, 0.814937f,0.0215123f, 0.819159f,0.0202533f, 0.823247f,0.0190423f, 0.827224f,0.0178837f,
+0.831083f,0.0167756f, 0.834839f,0.0157198f, 0.838565f,0.0147289f, 0.842126f,0.0137734f, 0.845582f,0.0128653f,
+0.848949f,0.0120059f, 0.85232f,0.011207f, 0.855633f,0.0104559f, 0.858806f,0.00973829f, 0.861955f,0.00906346f,
+0.865006f,0.00841846f, 0.867872f,0.00779955f, 0.870564f,0.00721014f, 0.873161f,0.00665991f, 0.875652f,0.00614706f,
+0.878214f,0.00567076f, 0.880734f,0.00522433f, 0.883384f,0.00479869f, 0.88603f,0.00439508f, 0.888553f,0.00401415f,
+0.890957f,0.00365604f, 0.893396f,0.00333348f, 0.89581f,0.00303785f, 0.898189f,0.00276717f, 0.900431f,0.00251182f,
+0.902571f,0.00227444f, 0.904923f,0.00205678f, 0.907236f,0.00185619f, 0.909494f,0.00167097f, 0.911655f,0.00149832f,
+0.913748f,0.00133965f, 0.915868f,0.00119872f, 0.917883f,0.00106741f, 0.919909f,0.000950637f, 0.921866f,0.000843304f,
+0.923719f,0.000743944f, 0.925612f,0.000657461f, 0.927543f,0.000582327f, 0.929477f,0.000513366f, 0.931307f,0.000448908f,
+0.933076f,0.000390599f, 0.934796f,0.000338344f, 0.93641f,0.000290559f, 0.938059f,0.000250009f, 0.939682f,0.000214458f,
+0.941185f,0.000182347f, 0.942637f,0.00015516f, 0.944037f,0.000131611f, 0.945574f,0.000110141f, 0.947038f,9.16486e-05f,
+0.948406f,7.57186e-05f, 0.949864f,6.18775e-05f, 0.95162f,5.18319e-05f, 0.953241f,4.20587e-05f, 0.954792f,3.3539e-05f,
+0.956044f,2.54324e-05f, 0.956903f,1.87798e-05f, 0.957859f,1.28946e-05f,
+
+0.612415f,0.205943f, 0.589161f,0.197523f, 0.570544f,0.190281f, 0.555639f,0.183978f, 0.543755f,0.178393f,
+0.534367f,0.173374f, 0.527077f,0.168863f, 0.521559f,0.164699f, 0.517552f,0.1608f, 0.514868f,0.15721f,
+0.513331f,0.153826f, 0.512788f,0.150563f, 0.513126f,0.147426f, 0.51423f,0.144351f, 0.516033f,0.141387f,
+0.518455f,0.138489f, 0.521417f,0.135613f, 0.524866f,0.132769f, 0.528766f,0.129979f, 0.533091f,0.127272f,
+0.537765f,0.124552f, 0.542717f,0.121772f, 0.547936f,0.118984f, 0.553431f,0.116248f, 0.559122f,0.11348f,
+0.565018f,0.110734f, 0.571091f,0.108f, 0.577309f,0.105262f, 0.583618f,0.102486f, 0.59006f,0.0997533f,
+0.596584f,0.0970212f, 0.60327f,0.0943944f, 0.610009f,0.0917599f, 0.61676f,0.0891013f, 0.623542f,0.0864562f,
+0.630339f,0.0838256f, 0.637066f,0.0811513f, 0.643828f,0.0785397f, 0.65055f,0.0759371f, 0.657221f,0.0733497f,
+0.66385f,0.0707927f, 0.670441f,0.0682777f, 0.677008f,0.0658181f, 0.683549f,0.0634138f, 0.690058f,0.0610651f,
+0.69645f,0.0587264f, 0.702697f,0.0563942f, 0.708919f,0.0541401f, 0.715047f,0.0519284f, 0.721072f,0.0497576f,
+0.727056f,0.0476582f, 0.732943f,0.045606f, 0.738743f,0.0436081f, 0.744464f,0.0416696f, 0.750083f,0.0397806f,
+0.755538f,0.0379208f, 0.760975f,0.0361478f, 0.766309f,0.0344249f, 0.7715f,0.0327401f, 0.776543f,0.0310968f,
+0.781489f,0.0295115f, 0.786328f,0.0279802f, 0.791028f,0.0264942f, 0.795729f,0.0250935f, 0.800335f,0.0237454f,
+0.804805f,0.0224398f, 0.809145f,0.0211789f, 0.813363f,0.0199655f, 0.817445f,0.018796f, 0.821423f,0.0176775f,
+0.825249f,0.016599f, 0.828927f,0.0155619f, 0.832524f,0.0145788f, 0.835971f,0.0136357f, 0.839389f,0.0127547f,
+0.842748f,0.0119143f, 0.846006f,0.0111108f, 0.849163f,0.0103505f, 0.852231f,0.00963414f, 0.855272f,0.00896892f,
+0.858207f,0.00834181f, 0.861014f,0.00774955f, 0.863822f,0.00719111f, 0.86655f,0.00665505f, 0.86913f,0.00614248f,
+0.871984f,0.00565971f, 0.874774f,0.00520863f, 0.877554f,0.00478936f, 0.880314f,0.00440261f, 0.882956f,0.00403644f,
+0.885476f,0.00369013f, 0.887881f,0.00336453f, 0.890153f,0.00305872f, 0.892581f,0.00277604f, 0.895068f,0.0025231f,
+0.897556f,0.00229243f, 0.900001f,0.00207945f, 0.902321f,0.00187802f, 0.904591f,0.00169253f, 0.906819f,0.00152289f,
+0.908962f,0.00136513f, 0.911074f,0.00122116f, 0.913098f,0.00108801f, 0.915226f,0.000970359f, 0.917292f,0.000862401f,
+0.919319f,0.000764816f, 0.921304f,0.000676373f, 0.923216f,0.000595253f, 0.925097f,0.00052291f, 0.927009f,0.000460083f,
+0.928948f,0.000405397f, 0.930742f,0.000353645f, 0.932404f,0.000305625f, 0.934016f,0.000263451f, 0.935487f,0.000225023f,
+0.936904f,0.000191934f, 0.938478f,0.000162294f, 0.94002f,0.000136778f, 0.94152f,0.000115104f, 0.942999f,9.6511e-05f,
+0.944594f,7.94029e-05f, 0.946211f,6.54416e-05f, 0.947713f,5.26781e-05f, 0.94933f,4.3257e-05f, 0.950909f,3.54124e-05f,
+0.952073f,2.748e-05f, 0.952965f,1.96146e-05f, 0.95429f,1.36753e-05f,
+
+0.619519f,0.199091f, 0.597033f,0.191172f, 0.578886f,0.184306f, 0.564239f,0.178284f, 0.55246f,0.172922f,
+0.543065f,0.168069f, 0.535681f,0.163683f, 0.530007f,0.15963f, 0.525794f,0.155821f, 0.522859f,0.152281f,
+0.521044f,0.148964f, 0.520202f,0.145773f, 0.520218f,0.142692f, 0.520994f,0.139701f, 0.522438f,0.136756f,
+0.524503f,0.133923f, 0.527101f,0.131112f, 0.530174f,0.128318f, 0.53369f,0.125577f, 0.537611f,0.122887f,
+0.541916f,0.120274f, 0.546514f,0.117616f, 0.551363f,0.114917f, 0.556464f,0.112233f, 0.561806f,0.109586f,
+0.567323f,0.106913f, 0.573028f,0.104268f, 0.578881f,0.101623f, 0.584861f,0.0989788f, 0.590916f,0.0962983f,
+0.597106f,0.0936761f, 0.603374f,0.0910651f, 0.609776f,0.0885371f, 0.616253f,0.0860352f, 0.622729f,0.0835039f,
+0.629222f,0.0809807f, 0.635761f,0.0785013f, 0.642224f,0.0759772f, 0.648666f,0.073473f, 0.655134f,0.0710305f,
+0.661532f,0.0685864f, 0.667886f,0.0661718f, 0.674203f,0.0637972f, 0.680474f,0.0614632f, 0.686723f,0.0591872f,
+0.692931f,0.0569589f, 0.699109f,0.0547882f, 0.705146f,0.0526191f, 0.711063f,0.0504734f, 0.716965f,0.0484074f,
+0.722755f,0.0463741f, 0.728451f,0.0443857f, 0.734064f,0.0424492f, 0.739624f,0.0405747f, 0.745105f,0.0387555f,
+0.750519f,0.0369953f, 0.755821f,0.0352779f, 0.760972f,0.0335925f, 0.766106f,0.031988f, 0.771118f,0.0304239f,
+0.776f,0.0289f, 0.780756f,0.0274199f, 0.785401f,0.0259898f, 0.789943f,0.0246111f, 0.794341f,0.0232725f,
+0.798732f,0.0220117f, 0.803032f,0.0208019f, 0.807203f,0.0196331f, 0.811249f,0.0185067f, 0.815182f,0.0174263f,
+0.818964f,0.0163843f, 0.822685f,0.0153905f, 0.826326f,0.0144345f, 0.82981f,0.0135143f, 0.833181f,0.0126389f,
+0.836433f,0.0118054f, 0.839611f,0.0110224f, 0.842682f,0.0102825f, 0.845572f,0.00957432f, 0.848425f,0.00890469f,
+0.851336f,0.00827025f, 0.854173f,0.00767967f, 0.857197f,0.00713115f, 0.860344f,0.00661087f, 0.863437f,0.0061229f,
+0.866461f,0.00566297f, 0.869329f,0.00522219f, 0.872068f,0.00480438f, 0.874705f,0.00441221f, 0.877257f,0.0040464f,
+0.88003f,0.00371153f, 0.882747f,0.00339866f, 0.885334f,0.00310122f, 0.887803f,0.00282021f, 0.89016f,0.00255611f,
+0.892428f,0.00230957f, 0.894733f,0.00208863f, 0.897099f,0.00189134f, 0.899559f,0.00171314f, 0.901911f,0.00154516f,
+0.904163f,0.00138777f, 0.906403f,0.00124536f, 0.908566f,0.00111362f, 0.910624f,0.000990644f, 0.912634f,0.000878565f,
+0.914673f,0.000779508f, 0.916712f,0.000691551f, 0.918678f,0.000611173f, 0.920566f,0.000537717f, 0.922401f,0.000471501f,
+0.924178f,0.000412334f, 0.92589f,0.000359588f, 0.927646f,0.000315465f, 0.929309f,0.000274385f, 0.931056f,0.000235955f,
+0.932716f,0.000201514f, 0.934281f,0.00017092f, 0.935776f,0.000144937f, 0.937436f,0.00012119f, 0.939069f,0.000100987f,
+0.940655f,8.33742e-05f, 0.942288f,6.90709e-05f, 0.943776f,5.62264e-05f, 0.945098f,4.49364e-05f, 0.946091f,3.48071e-05f,
+0.947441f,2.78992e-05f, 0.949056f,2.07419e-05f, 0.950519f,1.44766e-05f,
+
+0.626334f,0.192465f, 0.604594f,0.185011f, 0.586914f,0.178497f, 0.572533f,0.172743f, 0.560876f,0.167595f,
+0.551492f,0.16291f, 0.544036f,0.158646f, 0.538227f,0.154707f, 0.533832f,0.150999f, 0.530668f,0.147512f,
+0.528593f,0.144252f, 0.527473f,0.141138f, 0.527186f,0.13811f, 0.527649f,0.135187f, 0.528764f,0.132301f,
+0.530484f,0.129512f, 0.53274f,0.126778f, 0.535463f,0.124053f, 0.538606f,0.121344f, 0.542155f,0.118705f,
+0.546073f,0.116122f, 0.550326f,0.113584f, 0.554832f,0.110997f, 0.559562f,0.108378f, 0.564534f,0.1058f,
+0.569716f,0.103245f, 0.575056f,0.10067f, 0.580567f,0.0981284f, 0.586205f,0.0955792f, 0.591961f,0.093042f,
+0.597755f,0.0904479f, 0.603678f,0.0879199f, 0.609701f,0.0854344f, 0.615813f,0.082994f, 0.622037f,0.0806251f,
+0.628242f,0.0782165f, 0.634462f,0.0758189f, 0.64073f,0.0734696f, 0.646951f,0.0711028f, 0.653097f,0.0687144f,
+0.659286f,0.0664024f, 0.665427f,0.0641027f, 0.671519f,0.0618279f, 0.677562f,0.059584f, 0.683562f,0.0573804f,
+0.689523f,0.0552236f, 0.695456f,0.0531215f, 0.701347f,0.0510678f, 0.707186f,0.0490594f, 0.712881f,0.0470561f,
+0.718494f,0.045096f, 0.724075f,0.0432028f, 0.729544f,0.0413421f, 0.734925f,0.039528f, 0.740186f,0.0377483f,
+0.745392f,0.03603f, 0.750549f,0.0343739f, 0.755658f,0.0327797f, 0.760646f,0.0312229f, 0.765494f,0.0296996f,
+0.770327f,0.0282518f, 0.77501f,0.0268341f, 0.779568f,0.0254562f, 0.784021f,0.0241255f, 0.78836f,0.022841f,
+0.792574f,0.0215993f, 0.796639f,0.0203952f, 0.800684f,0.0192616f, 0.804776f,0.0181852f, 0.808728f,0.0171415f,
+0.812551f,0.0161364f, 0.816264f,0.0151741f, 0.819881f,0.0142529f, 0.823391f,0.013373f, 0.826746f,0.0125281f,
+0.829929f,0.0117172f, 0.832938f,0.0109419f, 0.836063f,0.0102042f, 0.839095f,0.00950857f, 0.842043f,0.00885824f,
+0.845235f,0.00823767f, 0.848406f,0.00764941f, 0.851487f,0.00709306f, 0.854497f,0.0065701f, 0.857498f,0.0060862f,
+0.860428f,0.00563153f, 0.86328f,0.00520475f, 0.866252f,0.00480382f, 0.869152f,0.00442287f, 0.871961f,0.0040624f,
+0.874701f,0.0037252f, 0.87736f,0.00340941f, 0.879951f,0.00311468f, 0.882684f,0.00284946f, 0.885295f,0.00259722f,
+0.887788f,0.00235843f, 0.890173f,0.00213376f, 0.892456f,0.0019235f, 0.894708f,0.00173172f, 0.896972f,0.00155906f,
+0.899306f,0.00140697f, 0.901574f,0.00126571f, 0.903753f,0.00113335f, 0.905873f,0.00101202f, 0.908008f,0.000903457f,
+0.910025f,0.000801838f, 0.911929f,0.00070751f, 0.913799f,0.000623316f, 0.915682f,0.000549857f, 0.917543f,0.000484652f,
+0.919291f,0.000425326f, 0.920959f,0.000370493f, 0.922816f,0.000322778f, 0.924602f,0.000280046f, 0.926409f,0.000244006f,
+0.928082f,0.000210756f, 0.929868f,0.000179907f, 0.931584f,0.000151839f, 0.933281f,0.000127748f, 0.934945f,0.000107199f,
+0.936438f,8.81669e-05f, 0.937877f,7.23684e-05f, 0.939127f,5.83319e-05f, 0.940201f,4.62816e-05f, 0.941505f,3.64043e-05f,
+0.942947f,2.72922e-05f, 0.944959f,2.15902e-05f, 0.946532f,1.52834e-05f,
+
+0.632863f,0.186058f, 0.611846f,0.179035f, 0.594629f,0.172853f, 0.580523f,0.167354f, 0.569f,0.162412f,
+0.559646f,0.15789f, 0.552136f,0.153748f, 0.546212f,0.149924f, 0.541655f,0.146319f, 0.538284f,0.142893f,
+0.535971f,0.139692f, 0.534589f,0.136646f, 0.534022f,0.133683f, 0.534186f,0.130819f, 0.535f,0.128021f,
+0.536385f,0.125252f, 0.538312f,0.122584f, 0.540704f,0.119938f, 0.543512f,0.117304f, 0.546697f,0.114695f,
+0.550244f,0.112144f, 0.554132f,0.109659f, 0.55831f,0.107194f, 0.562712f,0.104687f, 0.567313f,0.102151f,
+0.572147f,0.0996782f, 0.577164f,0.0972175f, 0.582321f,0.0947402f, 0.587638f,0.0923011f, 0.593063f,0.089854f,
+0.598596f,0.0874211f, 0.604154f,0.0849349f, 0.60981f,0.0824942f, 0.615573f,0.0801152f, 0.621393f,0.0777593f,
+0.627355f,0.075507f, 0.633304f,0.0732264f, 0.639273f,0.0709635f, 0.645241f,0.0687143f, 0.651228f,0.0664986f,
+0.657127f,0.0642527f, 0.663024f,0.0620508f, 0.668907f,0.0598873f, 0.674731f,0.0577388f, 0.680518f,0.055627f,
+0.686256f,0.0535502f, 0.691953f,0.0515174f, 0.697602f,0.0495268f, 0.703217f,0.0475884f, 0.708792f,0.0456996f,
+0.714288f,0.0438427f, 0.719657f,0.0420021f, 0.724967f,0.0402161f, 0.730223f,0.0384831f, 0.735376f,0.0367857f,
+0.740444f,0.0351343f, 0.745381f,0.0335126f, 0.750223f,0.0319366f, 0.755042f,0.0304299f, 0.759811f,0.0289823f,
+0.764471f,0.0275731f, 0.768999f,0.026199f, 0.773508f,0.0248953f, 0.777851f,0.0236166f, 0.782068f,0.0223728f,
+0.786284f,0.0211757f, 0.790436f,0.0200286f, 0.794473f,0.0189181f, 0.798378f,0.0178451f, 0.802221f,0.0168274f,
+0.806055f,0.0158734f, 0.809724f,0.0149484f, 0.813236f,0.0140565f, 0.816586f,0.0131991f, 0.819939f,0.012381f,
+0.823299f,0.0115998f, 0.826521f,0.0108541f, 0.829616f,0.0101406f, 0.832974f,0.00945495f, 0.836256f,0.00880649f,
+0.839416f,0.0081878f, 0.842569f,0.00761357f, 0.845617f,0.00706824f, 0.848566f,0.00655257f, 0.851562f,0.00606584f,
+0.854573f,0.00560751f, 0.857543f,0.00517944f, 0.86052f,0.00478436f, 0.863465f,0.00441067f, 0.866415f,0.00406311f,
+0.869299f,0.00373565f, 0.872085f,0.00342524f, 0.874789f,0.00313365f, 0.877459f,0.00286313f, 0.880059f,0.00261035f,
+0.882666f,0.00238f, 0.885232f,0.00216639f, 0.887688f,0.00196436f, 0.890028f,0.00177392f, 0.892261f,0.00159551f,
+0.894416f,0.0014306f, 0.89658f,0.00128307f, 0.898789f,0.00115273f, 0.900995f,0.00103543f, 0.903065f,0.000924332f,
+0.905003f,0.000820261f, 0.906964f,0.000729159f, 0.908778f,0.000643863f, 0.910478f,0.000565441f, 0.912171f,0.000494192f,
+0.914061f,0.000432979f, 0.915952f,0.000379422f, 0.917764f,0.000331163f, 0.919446f,0.000286763f, 0.921333f,0.000248472f,
+0.923224f,0.000214391f, 0.925168f,0.000185921f, 0.926945f,0.000158564f, 0.928641f,0.000133993f, 0.93017f,0.000111488f,
+0.93168f,9.3114e-05f, 0.933024f,7.62423e-05f, 0.934243f,6.17604e-05f, 0.935575f,4.86103e-05f, 0.937207f,3.76547e-05f,
+0.938881f,2.89618e-05f, 0.940367f,2.15602e-05f, 0.942338f,1.61178e-05f,
+
+0.639108f,0.179865f, 0.618793f,0.173241f, 0.602035f,0.167371f, 0.588209f,0.162116f, 0.576833f,0.157372f,
+0.567523f,0.153012f, 0.559978f,0.148988f, 0.553958f,0.145277f, 0.549256f,0.14177f, 0.545701f,0.13842f,
+0.543167f,0.135269f, 0.541541f,0.132285f, 0.540715f,0.129403f, 0.540595f,0.126588f, 0.541118f,0.12386f,
+0.542202f,0.121158f, 0.543807f,0.11853f, 0.545884f,0.115962f, 0.548368f,0.113401f, 0.551221f,0.11085f,
+0.554423f,0.108345f, 0.557946f,0.105884f, 0.561782f,0.103495f, 0.565865f,0.101099f, 0.570152f,0.0986758f,
+0.574619f,0.0962332f, 0.579304f,0.0938576f, 0.584151f,0.091491f, 0.589122f,0.0891122f, 0.594243f,0.0867745f,
+0.599457f,0.0844292f, 0.604773f,0.0821057f, 0.6101f,0.0797278f, 0.615504f,0.077386f, 0.620997f,0.0750966f,
+0.626557f,0.0728465f, 0.632231f,0.0706815f, 0.637934f,0.0685308f, 0.64363f,0.0663787f, 0.64932f,0.0642391f,
+0.655053f,0.062153f, 0.660718f,0.0600496f, 0.666325f,0.0579512f, 0.671961f,0.0559203f, 0.677525f,0.053896f,
+0.683045f,0.0519036f, 0.688527f,0.0499503f, 0.693957f,0.0480323f, 0.699351f,0.0461622f, 0.704688f,0.04433f,
+0.709994f,0.0425509f, 0.715235f,0.0408112f, 0.720395f,0.0391028f, 0.72543f,0.0374149f, 0.730437f,0.0357918f,
+0.735361f,0.0342089f, 0.740191f,0.0326653f, 0.744929f,0.0311636f, 0.74953f,0.0296898f, 0.754015f,0.0282545f,
+0.758442f,0.0268773f, 0.762908f,0.0255726f, 0.767368f,0.0243021f, 0.771708f,0.0230663f, 0.776051f,0.0218995f,
+0.780238f,0.0207567f, 0.784279f,0.0196444f, 0.788186f,0.018568f, 0.792021f,0.0175419f, 0.795706f,0.0165496f,
+0.79923f,0.0155903f, 0.802637f,0.0146764f, 0.806323f,0.0138287f, 0.809867f,0.0130101f, 0.813231f,0.0122179f,
+0.816565f,0.0114584f, 0.820146f,0.0107346f, 0.823621f,0.0100419f, 0.827001f,0.00938246f, 0.830262f,0.00875175f,
+0.833394f,0.00814779f, 0.83651f,0.0075781f, 0.839666f,0.00703396f, 0.842781f,0.00652453f, 0.845948f,0.00604818f,
+0.849026f,0.00559545f, 0.852069f,0.00517212f, 0.855032f,0.00477192f, 0.85796f,0.00439869f, 0.860894f,0.00405462f,
+0.863761f,0.00373047f, 0.866607f,0.00342954f, 0.86937f,0.00314525f, 0.872063f,0.00287825f, 0.874699f,0.00262869f,
+0.877261f,0.00239546f, 0.879751f,0.00217792f, 0.882243f,0.00197959f, 0.884719f,0.00179787f, 0.887094f,0.00162675f,
+0.88937f,0.00146628f, 0.891525f,0.00131571f, 0.893573f,0.00117574f, 0.895609f,0.00105081f, 0.897621f,0.000938777f,
+0.899674f,0.000841178f, 0.901564f,0.000749085f, 0.903453f,0.000662512f, 0.905426f,0.000585666f, 0.907309f,0.000515173f,
+0.909042f,0.000449586f, 0.910647f,0.000390109f, 0.912408f,0.000337441f, 0.914311f,0.000293552f, 0.916165f,0.000253985f,
+0.917867f,0.000216968f, 0.919633f,0.000186155f, 0.921405f,0.000159933f, 0.923115f,0.000137118f, 0.924721f,0.000115038f,
+0.926206f,9.53087e-05f, 0.927513f,7.81161e-05f, 0.929488f,6.42125e-05f, 0.931381f,5.16643e-05f, 0.933099f,4.02686e-05f,
+0.934679f,3.08132e-05f, 0.936185f,2.26835e-05f, 0.937943f,1.69992e-05f,
+
+0.645074f,0.173879f, 0.625439f,0.167627f, 0.609135f,0.162049f, 0.595593f,0.157026f, 0.584374f,0.152471f,
+0.575123f,0.148269f, 0.567559f,0.144365f, 0.56146f,0.14076f, 0.556631f,0.13735f, 0.552912f,0.134094f,
+0.550175f,0.130995f, 0.548322f,0.128069f, 0.547253f,0.12526f, 0.54687f,0.122504f, 0.547116f,0.119837f,
+0.54792f,0.117221f, 0.549215f,0.114622f, 0.550984f,0.112111f, 0.553168f,0.109639f, 0.555709f,0.107162f,
+0.558579f,0.104696f, 0.561771f,0.102291f, 0.565254f,0.0999261f, 0.569019f,0.0976244f, 0.572997f,0.0953058f,
+0.577151f,0.0929576f, 0.581475f,0.0906073f, 0.586002f,0.088327f, 0.590675f,0.086055f, 0.595459f,0.083774f,
+0.600381f,0.0815365f, 0.605387f,0.079295f, 0.610484f,0.0770752f, 0.615594f,0.074814f, 0.620757f,0.0725745f,
+0.625979f,0.0703714f, 0.631273f,0.0682168f, 0.636655f,0.0661308f, 0.642117f,0.064104f, 0.647551f,0.0620631f,
+0.652988f,0.0600433f, 0.658439f,0.0580597f, 0.663861f,0.0560874f, 0.669204f,0.0541061f, 0.674562f,0.0521819f,
+0.679893f,0.0502905f, 0.68515f,0.0484124f, 0.690359f,0.0465678f, 0.695525f,0.0447623f, 0.700642f,0.0429959f,
+0.705724f,0.0412775f, 0.710741f,0.0395955f, 0.715733f,0.0379688f, 0.720631f,0.0363688f, 0.725429f,0.0347971f,
+0.73013f,0.0332581f, 0.734804f,0.0317819f, 0.739423f,0.0303434f, 0.743957f,0.0289477f, 0.748503f,0.0275906f,
+0.752932f,0.0262611f, 0.757249f,0.0249674f, 0.761479f,0.0237189f, 0.765723f,0.0225416f, 0.769857f,0.021398f,
+0.773865f,0.0202889f, 0.777847f,0.0192404f, 0.781647f,0.0182127f, 0.785277f,0.0172132f, 0.788859f,0.0162521f,
+0.792517f,0.0153289f, 0.796066f,0.0144451f, 0.799436f,0.0135887f, 0.802867f,0.0127722f, 0.806626f,0.0120157f,
+0.81031f,0.0112931f, 0.813837f,0.0105908f, 0.817269f,0.00992095f, 0.820586f,0.00928031f, 0.824026f,0.00867083f,
+0.827494f,0.00809152f, 0.830867f,0.00753783f, 0.834124f,0.00700677f, 0.837307f,0.00650394f, 0.840419f,0.00602759f,
+0.843494f,0.00558136f, 0.846535f,0.0051641f, 0.849471f,0.0047664f, 0.852384f,0.00439569f, 0.855252f,0.00404879f,
+0.858077f,0.00372521f, 0.860875f,0.00342478f, 0.863632f,0.00314447f, 0.866345f,0.00288314f, 0.869008f,0.00263909f,
+0.871583f,0.00240895f, 0.874085f,0.00219366f, 0.876543f,0.00199451f, 0.878949f,0.00181031f, 0.881264f,0.00163826f,
+0.883597f,0.00148416f, 0.885812f,0.00133849f, 0.887925f,0.00120266f, 0.889922f,0.00107634f, 0.891764f,0.000958422f,
+0.893794f,0.000853284f, 0.895829f,0.000758456f, 0.897938f,0.00067717f, 0.899929f,0.000601312f, 0.901744f,0.000529682f,
+0.903719f,0.000465373f, 0.90568f,0.000407374f, 0.907537f,0.000353427f, 0.90931f,0.000304832f, 0.911002f,0.000261454f,
+0.912738f,0.000225406f, 0.914481f,0.000192943f, 0.916067f,0.000162655f, 0.917607f,0.000137247f, 0.919231f,0.000116995f,
+0.921083f,9.86674e-05f, 0.923045f,8.12248e-05f, 0.924932f,6.58348e-05f, 0.926924f,5.41166e-05f, 0.928695f,4.32291e-05f,
+0.930363f,3.31676e-05f, 0.932007f,2.50906e-05f, 0.93331f,1.78574e-05f,
+
+0.650764f,0.168095f, 0.631788f,0.162187f, 0.615931f,0.156885f, 0.602677f,0.152084f, 0.591623f,0.147709f,
+0.582444f,0.14366f, 0.574876f,0.13988f, 0.568713f,0.136374f, 0.563776f,0.133066f, 0.559909f,0.1299f,
+0.556991f,0.126863f, 0.554925f,0.123984f, 0.553625f,0.121237f, 0.553f,0.118558f, 0.55298f,0.115938f,
+0.553514f,0.113392f, 0.554533f,0.110869f, 0.555998f,0.10839f, 0.557886f,0.105986f, 0.560136f,0.103597f,
+0.562704f,0.101205f, 0.565567f,0.0988291f, 0.56873f,0.096523f, 0.572157f,0.0942579f, 0.575833f,0.0920354f,
+0.579696f,0.0897967f, 0.583715f,0.0875323f, 0.587888f,0.0852725f, 0.592248f,0.0830813f, 0.596738f,0.0808985f,
+0.60133f,0.0787135f, 0.606052f,0.076574f, 0.610852f,0.0744364f, 0.615729f,0.0723158f, 0.620623f,0.0701702f,
+0.625548f,0.068031f, 0.630528f,0.0659304f, 0.635551f,0.0638637f, 0.64065f,0.0618604f, 0.645836f,0.0599265f,
+0.651019f,0.0579999f, 0.656204f,0.0560945f, 0.661381f,0.0542114f, 0.666558f,0.0523612f, 0.671663f,0.0505051f,
+0.676728f,0.048673f, 0.681798f,0.0468949f, 0.6868f,0.0451321f, 0.691743f,0.0433967f, 0.696627f,0.0416928f,
+0.701456f,0.0400246f, 0.706258f,0.0384072f, 0.711f,0.0368269f, 0.715731f,0.0352929f, 0.720432f,0.0338104f,
+0.72501f,0.0323449f, 0.729543f,0.0309097f, 0.734086f,0.0295208f, 0.738596f,0.0281862f, 0.743013f,0.0268853f,
+0.747354f,0.0256258f, 0.751581f,0.0243971f, 0.755672f,0.0231954f, 0.759642f,0.0220276f, 0.763504f,0.0209005f,
+0.767328f,0.0198322f, 0.771032f,0.0188f, 0.774767f,0.0178054f, 0.778615f,0.0168681f, 0.782279f,0.0159494f,
+0.785761f,0.0150549f, 0.789311f,0.0141943f, 0.793036f,0.0133688f, 0.796663f,0.0125757f, 0.800172f,0.0118111f,
+0.803598f,0.0110829f, 0.807227f,0.0104109f, 0.810973f,0.00977359f, 0.814605f,0.00915715f, 0.818158f,0.00856736f,
+0.821622f,0.00800298f, 0.825037f,0.00746871f, 0.828378f,0.00696046f, 0.831631f,0.00647545f, 0.834779f,0.00601137f,
+0.837831f,0.00556964f, 0.840818f,0.00515295f, 0.843739f,0.00476029f, 0.846615f,0.00439293f, 0.849463f,0.00404862f,
+0.852213f,0.003722f, 0.854966f,0.00342083f, 0.857683f,0.0031407f, 0.860376f,0.00288157f, 0.863022f,0.00264018f,
+0.865598f,0.00241387f, 0.868155f,0.00220553f, 0.870592f,0.00200765f, 0.872961f,0.00182353f, 0.875276f,0.00165394f,
+0.877501f,0.00149641f, 0.87964f,0.00135052f, 0.881776f,0.00122054f, 0.884053f,0.0010979f, 0.886199f,0.000982134f,
+0.888252f,0.000874989f, 0.89023f,0.000776908f, 0.89214f,0.000688947f, 0.89425f,0.000610301f, 0.896424f,0.000542185f,
+0.898542f,0.000479967f, 0.900505f,0.000420933f, 0.902393f,0.000367763f, 0.904303f,0.000320052f, 0.906097f,0.000275653f,
+0.907795f,0.000236163f, 0.90935f,0.000200582f, 0.911022f,0.00017132f, 0.912601f,0.00014482f, 0.9145f,0.000121052f,
+0.916389f,0.000100694f, 0.918401f,8.47148e-05f, 0.92021f,6.91647e-05f, 0.921789f,5.48261e-05f, 0.923708f,4.43101e-05f,
+0.925522f,3.5242e-05f, 0.927277f,2.66956e-05f, 0.928464f,1.87498e-05f,
+
+0.656181f,0.162506f, 0.637843f,0.15692f, 0.622427f,0.151876f, 0.609464f,0.147286f, 0.598583f,0.143082f,
+0.589486f,0.139183f, 0.581929f,0.13553f, 0.575716f,0.132118f, 0.570685f,0.128907f, 0.566687f,0.125831f,
+0.563602f,0.122859f, 0.561342f,0.120035f, 0.559826f,0.117342f, 0.558975f,0.114742f, 0.558708f,0.112179f,
+0.558982f,0.109692f, 0.559741f,0.107249f, 0.560923f,0.104814f, 0.562518f,0.102455f, 0.564484f,0.100143f,
+0.566768f,0.0978322f, 0.569334f,0.0955212f, 0.572173f,0.0932413f, 0.575287f,0.0910292f, 0.578644f,0.0888602f,
+0.582217f,0.0867176f, 0.585956f,0.0845592f, 0.589832f,0.0823795f, 0.593852f,0.0802139f, 0.598045f,0.0781136f,
+0.602355f,0.0760249f, 0.60675f,0.0739309f, 0.611264f,0.0718821f, 0.615853f,0.0698426f, 0.620503f,0.0678158f,
+0.625181f,0.0657806f, 0.629873f,0.0637424f, 0.634614f,0.0617434f, 0.63939f,0.059777f, 0.644208f,0.0578535f,
+0.649098f,0.0559947f, 0.654027f,0.0541763f, 0.658944f,0.0523722f, 0.663846f,0.0505869f, 0.668767f,0.0488464f,
+0.673628f,0.0471089f, 0.678418f,0.0453771f, 0.683216f,0.0437012f, 0.68797f,0.0420543f, 0.692665f,0.0404261f,
+0.69733f,0.0388312f, 0.701935f,0.0372689f, 0.706478f,0.0357423f, 0.710974f,0.0342603f, 0.715514f,0.0328158f,
+0.720043f,0.0314199f, 0.72452f,0.0300651f, 0.728878f,0.0287282f, 0.73314f,0.0274211f, 0.737344f,0.02616f,
+0.741506f,0.0249493f, 0.745572f,0.0237735f, 0.749547f,0.0226365f, 0.753383f,0.0215262f, 0.757062f,0.0204422f,
+0.760799f,0.0193906f, 0.764519f,0.0183759f, 0.768184f,0.0174122f, 0.771721f,0.0164814f, 0.775352f,0.0155889f,
+0.779266f,0.0147494f, 0.783047f,0.01393f, 0.786726f,0.0131339f, 0.790344f,0.0123671f, 0.794068f,0.0116351f,
+0.797756f,0.0109302f, 0.801341f,0.0102487f, 0.804851f,0.00959708f, 0.808438f,0.00899755f, 0.812049f,0.0084371f,
+0.815562f,0.00789667f, 0.818983f,0.0073781f, 0.822337f,0.00688432f, 0.825629f,0.00641561f, 0.828855f,0.00597076f,
+0.832005f,0.00554776f, 0.835056f,0.00514389f, 0.837994f,0.00475728f, 0.840889f,0.0043954f, 0.843697f,0.00405287f,
+0.846464f,0.00373333f, 0.849159f,0.00343256f, 0.851749f,0.00314732f, 0.854274f,0.0028809f, 0.856845f,0.00263821f,
+0.859421f,0.00241543f, 0.861948f,0.002209f, 0.864379f,0.00201475f, 0.866774f,0.00183637f, 0.869056f,0.00166873f,
+0.871233f,0.00150969f, 0.873621f,0.00136671f, 0.875925f,0.00123384f, 0.878107f,0.00110907f, 0.880329f,0.000999486f,
+0.882447f,0.000897054f, 0.884648f,0.000800039f, 0.886722f,0.000709079f, 0.888693f,0.000625135f, 0.890681f,0.000551588f,
+0.892758f,0.000486945f, 0.894873f,0.000430343f, 0.896945f,0.000379398f, 0.898834f,0.000330873f, 0.90072f,0.000287524f,
+0.902527f,0.000248202f, 0.904144f,0.000211732f, 0.906017f,0.000180035f, 0.907951f,0.000152f, 0.909867f,0.000127877f,
+0.911691f,0.000106203f, 0.913433f,8.75918e-05f, 0.915257f,7.28398e-05f, 0.91708f,5.89734e-05f, 0.918551f,4.5801e-05f,
+0.920251f,3.5899e-05f, 0.921833f,2.7612e-05f, 0.9234f,1.96639e-05f,
+
+0.661329f,0.157107f, 0.64361f,0.15182f, 0.628627f,0.14702f, 0.615954f,0.142629f, 0.605253f,0.13859f,
+0.596249f,0.134835f, 0.588715f,0.131307f, 0.582466f,0.127986f, 0.577355f,0.12487f, 0.57324f,0.121882f,
+0.570008f,0.11899f, 0.56757f,0.116223f, 0.565852f,0.113579f, 0.564782f,0.111037f, 0.564287f,0.108546f,
+0.564312f,0.106104f, 0.564818f,0.10373f, 0.565748f,0.101381f, 0.567057f,0.0990455f, 0.568744f,0.0967947f,
+0.570755f,0.0945686f, 0.573048f,0.0923419f, 0.57559f,0.0901101f, 0.578384f,0.0879187f, 0.581431f,0.0857974f,
+0.584706f,0.0837261f, 0.588164f,0.0816608f, 0.591771f,0.0795848f, 0.5955f,0.0774918f, 0.599359f,0.075416f,
+0.603379f,0.0734039f, 0.607506f,0.0714076f, 0.611707f,0.0694071f, 0.616017f,0.0674499f, 0.620398f,0.06551f,
+0.62483f,0.0635802f, 0.629285f,0.061646f, 0.633738f,0.0597039f, 0.638233f,0.057799f, 0.64276f,0.0559288f,
+0.647306f,0.0540902f, 0.651914f,0.0523125f, 0.656559f,0.0505789f, 0.661213f,0.0488748f, 0.665833f,0.0471826f,
+0.67047f,0.0455355f, 0.675087f,0.0439075f, 0.679665f,0.0422888f, 0.684208f,0.0407014f, 0.688746f,0.0391629f,
+0.69322f,0.0376465f, 0.697628f,0.0361538f, 0.702095f,0.0346923f, 0.706504f,0.0332646f, 0.710858f,0.0318728f,
+0.715167f,0.0305233f, 0.719395f,0.0292037f, 0.723584f,0.0279315f, 0.727696f,0.0266917f, 0.731689f,0.0254744f,
+0.735561f,0.0242841f, 0.739361f,0.0231398f, 0.743082f,0.0220392f, 0.74692f,0.0209762f, 0.750758f,0.0199517f,
+0.75445f,0.0189493f, 0.758f,0.0179735f, 0.761573f,0.017029f, 0.765385f,0.0161185f, 0.76923f,0.0152548f,
+0.773007f,0.0144208f, 0.776729f,0.0136222f, 0.780718f,0.0128763f, 0.784579f,0.0121462f, 0.78835f,0.01144f,
+0.792029f,0.0107584f, 0.795671f,0.0101108f, 0.799225f,0.00948804f, 0.802649f,0.00888314f, 0.805977f,0.00830252f,
+0.809351f,0.00776592f, 0.812777f,0.00726951f, 0.816116f,0.00679258f, 0.819372f,0.00633583f, 0.822588f,0.00590375f,
+0.825737f,0.00549331f, 0.828853f,0.00510616f, 0.831899f,0.00473782f, 0.834862f,0.00438774f, 0.837695f,0.00405131f,
+0.840489f,0.0037375f, 0.843187f,0.00343989f, 0.845843f,0.00316335f, 0.848412f,0.00290253f, 0.850883f,0.00265652f,
+0.85326f,0.00242587f, 0.85559f,0.00221329f, 0.857867f,0.00201764f, 0.860258f,0.00184147f, 0.862698f,0.00167478f,
+0.865103f,0.00152178f, 0.867451f,0.00138023f, 0.869649f,0.00124575f, 0.871804f,0.00112232f, 0.874157f,0.00101091f,
+0.876393f,0.000906078f, 0.878642f,0.000813169f, 0.880906f,0.000726869f, 0.88308f,0.000646056f, 0.885113f,0.000570158f,
+0.887013f,0.000499869f, 0.888953f,0.00043802f, 0.890949f,0.000384442f, 0.89295f,0.00033791f, 0.894881f,0.000296313f,
+0.896869f,0.000257199f, 0.898981f,0.000221562f, 0.901017f,0.000189368f, 0.902947f,0.000160331f, 0.904755f,0.000134247f,
+0.906546f,0.000112566f, 0.908273f,9.24915e-05f, 0.910058f,7.57894e-05f, 0.91174f,6.17926e-05f, 0.913484f,4.95777e-05f,
+0.914773f,3.73602e-05f, 0.916172f,2.80012e-05f, 0.918104f,2.05791e-05f,
+
+0.666212f,0.151892f, 0.649091f,0.146884f, 0.634533f,0.142314f, 0.622151f,0.138113f, 0.611635f,0.134232f,
+0.602732f,0.130615f, 0.595233f,0.127208f, 0.588961f,0.123979f, 0.583782f,0.120951f, 0.579565f,0.118052f,
+0.576202f,0.11525f, 0.573599f,0.112533f, 0.571693f,0.10994f, 0.570417f,0.107447f, 0.56971f,0.105036f,
+0.569505f,0.102652f, 0.569766f,0.10033f, 0.570449f,0.0980511f, 0.571501f,0.095778f, 0.572908f,0.0935592f,
+0.574649f,0.0913967f, 0.576678f,0.0892535f, 0.578958f,0.0871105f, 0.581459f,0.0849617f, 0.584193f,0.0828611f,
+0.587158f,0.0808238f, 0.590337f,0.0788434f, 0.593669f,0.076855f, 0.597137f,0.0748622f, 0.600712f,0.0728552f,
+0.604405f,0.0708682f, 0.608244f,0.0689403f, 0.612185f,0.0670347f, 0.616191f,0.0651268f, 0.62029f,0.0632578f,
+0.624461f,0.0614128f, 0.628677f,0.0595804f, 0.632912f,0.0577472f, 0.637132f,0.0559012f, 0.641387f,0.0540922f,
+0.645659f,0.0523104f, 0.649956f,0.0505676f, 0.654275f,0.0488653f, 0.658629f,0.0472088f, 0.663046f,0.0455973f,
+0.667461f,0.0440152f, 0.671845f,0.0424524f, 0.67622f,0.0409258f, 0.680523f,0.0394058f, 0.68477f,0.0378987f,
+0.689144f,0.0364504f, 0.693496f,0.0350386f, 0.697778f,0.0336463f, 0.701997f,0.0322819f, 0.706134f,0.0309411f,
+0.710217f,0.0296376f, 0.714229f,0.0283676f, 0.718186f,0.0271367f, 0.722068f,0.0259399f, 0.72589f,0.0247862f,
+0.729566f,0.0236507f, 0.733332f,0.0225442f, 0.737089f,0.0214675f, 0.74078f,0.0204352f, 0.744382f,0.0194403f,
+0.74797f,0.0184814f, 0.751981f,0.0175634f, 0.755891f,0.0166637f, 0.759691f,0.0157888f, 0.763458f,0.0149433f,
+0.767336f,0.014129f, 0.771189f,0.0133534f, 0.774969f,0.0126049f, 0.778714f,0.0118908f, 0.782496f,0.011223f,
+0.786178f,0.0105737f, 0.789758f,0.00994432f, 0.793243f,0.00933664f, 0.796702f,0.00876109f, 0.800119f,0.00821176f,
+0.803423f,0.00767907f, 0.806608f,0.00716463f, 0.809835f,0.00668998f, 0.813084f,0.00624861f, 0.816296f,0.00583105f,
+0.819419f,0.00543015f, 0.822499f,0.00505168f, 0.825525f,0.00469409f, 0.828484f,0.0043555f, 0.831363f,0.00403387f,
+0.834188f,0.00373098f, 0.836878f,0.00343981f, 0.839503f,0.00316734f, 0.842028f,0.00290992f, 0.844489f,0.00267053f,
+0.846841f,0.00244518f, 0.84922f,0.00223306f, 0.851614f,0.00203419f, 0.853945f,0.00184991f, 0.856237f,0.00168083f,
+0.858546f,0.00152945f, 0.860784f,0.00138591f, 0.863163f,0.00125452f, 0.865483f,0.00113294f, 0.867857f,0.00102017f,
+0.870151f,0.000915673f, 0.872431f,0.000821359f, 0.874633f,0.000734f, 0.876905f,0.000656918f, 0.879123f,0.000584915f,
+0.881178f,0.000516611f, 0.883122f,0.000453618f, 0.884915f,0.000395861f, 0.886792f,0.00034422f, 0.888941f,0.000300511f,
+0.891143f,0.000262375f, 0.893297f,0.000227813f, 0.895383f,0.000196505f, 0.897294f,0.000167205f, 0.899124f,0.000140951f,
+0.901029f,0.000118024f, 0.9028f,9.77619e-05f, 0.904407f,7.99285e-05f, 0.906005f,6.42262e-05f, 0.907548f,5.11325e-05f,
+0.909094f,3.98896e-05f, 0.910834f,2.9372e-05f, 0.91258f,2.14998e-05f,
+
+0.670833f,0.146856f, 0.654292f,0.142108f, 0.640151f,0.137754f, 0.628058f,0.133733f, 0.617731f,0.130003f,
+0.608938f,0.12652f, 0.601482f,0.123228f, 0.5952f,0.120098f, 0.589965f,0.117151f, 0.585659f,0.114339f,
+0.582176f,0.111621f, 0.579424f,0.10896f, 0.577346f,0.106422f, 0.575878f,0.103982f, 0.574965f,0.101629f,
+0.574544f,0.0993113f, 0.574571f,0.0970367f, 0.575017f,0.0948221f, 0.575835f,0.0926348f, 0.576978f,0.0904514f,
+0.578449f,0.0883307f, 0.580217f,0.0862581f, 0.582238f,0.0841914f, 0.584484f,0.082129f, 0.586929f,0.0800648f,
+0.589588f,0.0780515f, 0.592459f,0.0760996f, 0.595527f,0.0742023f, 0.598724f,0.0722909f, 0.602046f,0.0703811f,
+0.605462f,0.0684597f, 0.608986f,0.0665615f, 0.612633f,0.0647115f, 0.616383f,0.0628938f, 0.620188f,0.0610757f,
+0.624075f,0.0592926f, 0.628029f,0.0575383f, 0.632026f,0.0557998f, 0.636037f,0.0540647f, 0.64002f,0.052312f,
+0.644031f,0.0505942f, 0.648073f,0.0489061f, 0.652164f,0.0472601f, 0.65627f,0.0456507f, 0.660387f,0.0440791f,
+0.66451f,0.042542f, 0.66865f,0.041049f, 0.672754f,0.0395717f, 0.677001f,0.0381451f, 0.681185f,0.0367266f,
+0.685302f,0.0353209f, 0.68938f,0.0339429f, 0.693443f,0.0326095f, 0.697462f,0.0313073f, 0.701407f,0.030029f,
+0.705286f,0.0287811f, 0.709067f,0.0275552f, 0.712788f,0.0263691f, 0.716414f,0.0252142f, 0.720118f,0.0240932f,
+0.723886f,0.0230079f, 0.727586f,0.0219601f, 0.731127f,0.0209252f, 0.734603f,0.0199205f, 0.738503f,0.0189451f,
+0.742406f,0.0180162f, 0.746243f,0.0171182f, 0.750122f,0.0162571f, 0.754129f,0.0154316f, 0.758038f,0.0146243f,
+0.761867f,0.0138412f, 0.765622f,0.0130843f, 0.769323f,0.0123573f, 0.773015f,0.0116644f, 0.776639f,0.0109968f,
+0.780226f,0.0103605f, 0.783863f,0.00976776f, 0.787394f,0.00919086f, 0.790833f,0.00863289f, 0.794195f,0.00809663f,
+0.797497f,0.0075853f, 0.80075f,0.00709919f, 0.803896f,0.00662942f, 0.806921f,0.00617575f, 0.809943f,0.00575344f,
+0.812996f,0.00536282f, 0.816032f,0.00499645f, 0.818957f,0.0046438f, 0.821815f,0.00430947f, 0.824673f,0.00399936f,
+0.827439f,0.00370439f, 0.83012f,0.00342529f, 0.832717f,0.00316219f, 0.835156f,0.00290938f, 0.837681f,0.00267226f,
+0.840197f,0.00244943f, 0.842675f,0.0022429f, 0.84507f,0.00204952f, 0.847336f,0.00186656f, 0.849585f,0.00169573f,
+0.851929f,0.00153759f, 0.854323f,0.00139213f, 0.856783f,0.00126335f, 0.85912f,0.00114087f, 0.861408f,0.00102827f,
+0.86373f,0.000925491f, 0.866009f,0.000829555f, 0.868227f,0.000741726f, 0.870395f,0.000661975f, 0.872487f,0.000588565f,
+0.874616f,0.000525452f, 0.876772f,0.000465754f, 0.878893f,0.000409019f, 0.880977f,0.000355895f, 0.883031f,0.000308806f,
+0.885039f,0.000267216f, 0.88703f,0.000231091f, 0.889049f,0.000200366f, 0.891114f,0.000172009f, 0.893077f,0.000146122f,
+0.894893f,0.000122458f, 0.896562f,0.000101837f, 0.898232f,8.31734e-05f, 0.89984f,6.71621e-05f, 0.901365f,5.26174e-05f,
+0.9034f,4.1413e-05f, 0.905227f,3.12844e-05f, 0.906823f,2.24193e-05f,
+
+0.675196f,0.141992f, 0.659214f,0.137487f, 0.645482f,0.133338f, 0.633678f,0.129486f, 0.623544f,0.125901f,
+0.614865f,0.122547f, 0.607462f,0.119366f, 0.601182f,0.116339f, 0.595903f,0.113471f, 0.591516f,0.110737f,
+0.587926f,0.108098f, 0.585044f,0.105523f, 0.582805f,0.10303f, 0.581157f,0.100638f, 0.580046f,0.0983267f,
+0.579425f,0.0960848f, 0.579236f,0.0938668f, 0.57945f,0.091701f, 0.580032f,0.0895744f, 0.58094f,0.0874619f,
+0.58215f,0.0853771f, 0.583658f,0.0833545f, 0.585428f,0.0813624f, 0.58742f,0.0793739f, 0.589613f,0.0773875f,
+0.591988f,0.0754092f, 0.59456f,0.0734823f, 0.597326f,0.0716149f, 0.600268f,0.0697936f, 0.603323f,0.0679589f,
+0.606491f,0.0661309f, 0.609741f,0.0642938f, 0.613088f,0.0624808f, 0.616546f,0.0607126f, 0.620089f,0.0589727f,
+0.62369f,0.0572423f, 0.627357f,0.0555418f, 0.631091f,0.0538762f, 0.634857f,0.0522244f, 0.638673f,0.050589f,
+0.642481f,0.0489439f, 0.646285f,0.0473135f, 0.650113f,0.0457224f, 0.653937f,0.0441567f, 0.65778f,0.0426334f,
+0.661628f,0.0411473f, 0.665582f,0.0396872f, 0.669588f,0.0382782f, 0.673589f,0.0369005f, 0.677563f,0.0355491f,
+0.681518f,0.0342293f, 0.685392f,0.0329162f, 0.689196f,0.0316217f, 0.692974f,0.0303697f, 0.696683f,0.0291438f,
+0.700318f,0.0279454f, 0.703865f,0.0267735f, 0.707413f,0.0256264f, 0.711064f,0.0245029f, 0.714676f,0.0234239f,
+0.718214f,0.0223729f, 0.721739f,0.0213569f, 0.72556f,0.0203796f, 0.729471f,0.0194305f, 0.733259f,0.0184943f,
+0.737045f,0.0175816f, 0.740935f,0.0167007f, 0.74485f,0.0158642f, 0.748706f,0.0150526f, 0.752555f,0.0142785f,
+0.756393f,0.0135388f, 0.760119f,0.0128131f, 0.763796f,0.0121145f, 0.767396f,0.0114393f, 0.770949f,0.0107923f,
+0.774453f,0.0101728f, 0.777894f,0.0095775f, 0.781309f,0.00901222f, 0.784749f,0.00848343f, 0.788113f,0.00797317f,
+0.791368f,0.0074779f, 0.794545f,0.00700256f, 0.797684f,0.00655187f, 0.800764f,0.00612303f, 0.803725f,0.00570841f,
+0.806557f,0.00530799f, 0.809392f,0.00493676f, 0.812191f,0.00458851f, 0.815025f,0.00426852f, 0.817743f,0.003961f,
+0.820356f,0.00366831f, 0.822924f,0.00339578f, 0.825642f,0.00314028f, 0.828324f,0.0028985f, 0.830943f,0.00267179f,
+0.833417f,0.00245387f, 0.83579f,0.00224899f, 0.838188f,0.00205703f, 0.840746f,0.00187855f, 0.843237f,0.00171184f,
+0.845611f,0.00155343f, 0.847916f,0.00140636f, 0.850231f,0.00127098f, 0.852567f,0.00114716f, 0.854937f,0.00103695f,
+0.857211f,0.00093347f, 0.859396f,0.000837541f, 0.861523f,0.000749839f, 0.863551f,0.000668713f, 0.865711f,0.000595611f,
+0.867863f,0.000528888f, 0.870081f,0.000467096f, 0.872404f,0.000414727f, 0.87461f,0.000365135f, 0.87666f,0.000318221f,
+0.878534f,0.000274377f, 0.880432f,0.000235521f, 0.882437f,0.000202696f, 0.884366f,0.000173628f, 0.886277f,0.000148572f,
+0.888033f,0.000125772f, 0.889836f,0.000104048f, 0.891648f,8.55461e-05f, 0.893516f,6.92963e-05f, 0.895548f,5.53581e-05f,
+0.897419f,4.28275e-05f, 0.899342f,3.3061e-05f, 0.900848f,2.33637e-05f,
+
+0.679306f,0.137296f, 0.663864f,0.133018f, 0.650531f,0.12906f, 0.639014f,0.125371f, 0.629074f,0.121926f,
+0.620517f,0.118693f, 0.613174f,0.115622f, 0.606905f,0.112695f, 0.601592f,0.109902f, 0.597138f,0.107245f,
+0.59345f,0.104681f, 0.59045f,0.102191f, 0.588064f,0.0997496f, 0.586248f,0.0974022f, 0.584954f,0.0951404f,
+0.584137f,0.0929547f, 0.583743f,0.0908f, 0.583738f,0.0886815f, 0.584097f,0.0866153f, 0.58478f,0.084578f,
+0.585748f,0.0825413f, 0.586999f,0.0805539f, 0.588513f,0.0786129f, 0.590262f,0.0767f, 0.592211f,0.074791f,
+0.594334f,0.0728798f, 0.596624f,0.0709834f, 0.599096f,0.0691401f, 0.601746f,0.0673546f, 0.604551f,0.0656074f,
+0.607457f,0.0638512f, 0.610461f,0.0621003f, 0.613539f,0.0603457f, 0.616701f,0.0586142f, 0.619962f,0.0569263f,
+0.623298f,0.0552653f, 0.62668f,0.0536147f, 0.63015f,0.051998f, 0.633714f,0.050428f, 0.6373f,0.0488682f,
+0.640909f,0.0473279f, 0.644494f,0.0457787f, 0.648066f,0.044238f, 0.651646f,0.0427296f, 0.655298f,0.0412519f,
+0.659036f,0.0398198f, 0.662782f,0.038423f, 0.666515f,0.0370533f, 0.670208f,0.0357012f, 0.673925f,0.0343989f,
+0.677617f,0.033125f, 0.681296f,0.0318898f, 0.684874f,0.0306565f, 0.688386f,0.0294458f, 0.691823f,0.0282609f,
+0.69523f,0.0271163f, 0.698843f,0.0259942f, 0.702374f,0.0248956f, 0.7059f,0.0238299f, 0.709343f,0.0227839f,
+0.712874f,0.0217647f, 0.7167f,0.0207843f, 0.720466f,0.0198283f, 0.724283f,0.0189068f, 0.728266f,0.0180244f,
+0.732196f,0.0171649f, 0.736037f,0.0163207f, 0.739793f,0.0154963f, 0.74352f,0.0147044f, 0.747256f,0.0139529f,
+0.750935f,0.0132261f, 0.754583f,0.0125294f, 0.758215f,0.0118641f, 0.761744f,0.0112133f, 0.76521f,0.0105857f,
+0.768629f,0.00998339f, 0.772007f,0.0094077f, 0.775329f,0.00885601f, 0.778593f,0.00832734f, 0.781821f,0.00782487f,
+0.785081f,0.00735694f, 0.788246f,0.0069038f, 0.791321f,0.00646671f, 0.79431f,0.00604752f, 0.797231f,0.00564844f,
+0.800089f,0.00526922f, 0.802844f,0.00490526f, 0.805457f,0.00455379f, 0.808035f,0.00422693f, 0.810518f,0.00391756f,
+0.813266f,0.00363578f, 0.815948f,0.0033665f, 0.818565f,0.00311273f, 0.821121f,0.002875f, 0.823626f,0.00265224f,
+0.826243f,0.0024414f, 0.828973f,0.00224691f, 0.831574f,0.00205975f, 0.834094f,0.00188357f, 0.836602f,0.00171914f,
+0.839105f,0.00156624f, 0.841542f,0.00142358f, 0.843846f,0.0012876f, 0.846081f,0.00116173f, 0.848252f,0.00104617f,
+0.850367f,0.000940648f, 0.852463f,0.000845748f, 0.854655f,0.000758276f, 0.856772f,0.000677145f, 0.859034f,0.000602689f,
+0.861232f,0.000534374f, 0.863431f,0.00047348f, 0.86555f,0.000417732f, 0.86761f,0.000367512f, 0.869735f,0.000323456f,
+0.871828f,0.000281914f, 0.873722f,0.000242469f, 0.875504f,0.000206833f, 0.877252f,0.000175675f, 0.87909f,0.000149065f,
+0.881033f,0.000125931f, 0.883156f,0.000106479f, 0.8852f,8.78767e-05f, 0.887233f,7.12753e-05f, 0.889213f,5.68846e-05f,
+0.891085f,4.45103e-05f, 0.892822f,3.34649e-05f, 0.894639f,2.43043e-05f,
+
+0.683165f,0.132762f, 0.668247f,0.128696f, 0.655303f,0.124919f, 0.644069f,0.121385f, 0.634326f,0.118072f,
+0.625895f,0.114955f, 0.61862f,0.111991f, 0.61237f,0.109161f, 0.607032f,0.106442f, 0.602521f,0.103861f,
+0.598747f,0.101372f, 0.595637f,0.0989564f, 0.593119f,0.0965798f, 0.59115f,0.0942869f, 0.589683f,0.0920708f,
+0.588675f,0.089922f, 0.588091f,0.0878361f, 0.587879f,0.0857717f, 0.58802f,0.0837541f, 0.588478f,0.0817679f,
+0.589229f,0.0798108f, 0.590235f,0.0778599f, 0.591498f,0.0759583f, 0.593001f,0.0741029f, 0.594709f,0.0722645f,
+0.596596f,0.0704319f, 0.598638f,0.0685981f, 0.600828f,0.0667794f, 0.603186f,0.065015f, 0.605712f,0.0633132f,
+0.608367f,0.0616344f, 0.611117f,0.0599556f, 0.613945f,0.0582778f, 0.616843f,0.0566039f, 0.61981f,0.0549501f,
+0.622892f,0.0533469f, 0.626067f,0.0517718f, 0.629288f,0.0502134f, 0.632565f,0.0486796f, 0.635913f,0.0471913f,
+0.639281f,0.0457179f, 0.642675f,0.0442692f, 0.646052f,0.0428125f, 0.649524f,0.0413632f, 0.653f,0.0399435f,
+0.656467f,0.0385477f, 0.659931f,0.0371835f, 0.663411f,0.0358632f, 0.666884f,0.0345763f, 0.670298f,0.0333006f,
+0.673696f,0.0320616f, 0.677058f,0.0308515f, 0.680418f,0.0296885f, 0.683706f,0.0285455f, 0.687082f,0.0274027f,
+0.690498f,0.0262886f, 0.693976f,0.0252158f, 0.697388f,0.0241709f, 0.700729f,0.0231499f, 0.704509f,0.0221524f,
+0.708254f,0.0211826f, 0.71196f,0.0202306f, 0.715849f,0.0193118f, 0.719723f,0.0184264f, 0.72353f,0.01756f,
+0.727321f,0.0167272f, 0.731109f,0.0159301f, 0.734828f,0.0151512f, 0.738451f,0.0143863f, 0.741994f,0.0136409f,
+0.745489f,0.012923f, 0.749013f,0.0122456f, 0.752507f,0.0115956f, 0.755971f,0.0109732f, 0.759391f,0.0103748f,
+0.762735f,0.00979446f, 0.766007f,0.00923431f, 0.769206f,0.00869467f, 0.772359f,0.00817939f, 0.775478f,0.00768881f,
+0.778546f,0.00722027f, 0.781565f,0.00677451f, 0.784622f,0.00636159f, 0.787578f,0.00596229f, 0.790411f,0.00557498f,
+0.793179f,0.005207f, 0.795864f,0.00485687f, 0.798439f,0.00452226f, 0.801127f,0.00420084f, 0.803728f,0.00389331f,
+0.806301f,0.00360781f, 0.808796f,0.00333798f, 0.811379f,0.00308931f, 0.81399f,0.00285259f, 0.816664f,0.00263051f,
+0.819337f,0.002425f, 0.822004f,0.00223247f, 0.82465f,0.00204976f, 0.8273f,0.00188192f, 0.829837f,0.00172109f,
+0.832306f,0.00157047f, 0.834709f,0.00143019f, 0.837043f,0.00129981f, 0.839281f,0.00117794f, 0.841383f,0.00106171f,
+0.84354f,0.000954008f, 0.845642f,0.000856056f, 0.847905f,0.000767075f, 0.850156f,0.000686338f, 0.852359f,0.000612356f,
+0.85446f,0.000543588f, 0.856459f,0.000480128f, 0.858471f,0.000422843f, 0.860564f,0.000371307f, 0.862604f,0.000324589f,
+0.864716f,0.000284751f, 0.866775f,0.000247998f, 0.868671f,0.000213323f, 0.870567f,0.000181145f, 0.872485f,0.000152483f,
+0.874451f,0.000128189f, 0.876422f,0.000107055f, 0.878596f,8.9306e-05f, 0.880713f,7.32871e-05f, 0.882563f,5.84954e-05f,
+0.884359f,4.55767e-05f, 0.886101f,3.43259e-05f, 0.888205f,2.52473e-05f,
+
+0.686778f,0.128386f, 0.672365f,0.124517f, 0.659802f,0.12091f, 0.648848f,0.117524f, 0.639302f,0.114338f,
+0.631001f,0.111332f, 0.623799f,0.108471f, 0.617575f,0.105733f, 0.612224f,0.103093f, 0.607665f,0.100587f,
+0.603814f,0.0981678f, 0.600603f,0.0958188f, 0.597967f,0.0935216f, 0.595854f,0.0912765f, 0.594225f,0.0891043f,
+0.593041f,0.0870008f, 0.592268f,0.0849618f, 0.591863f,0.0829588f, 0.591794f,0.0809861f, 0.592044f,0.0790632f,
+0.592574f,0.0771586f, 0.593356f,0.0752671f, 0.59438f,0.0734072f, 0.595633f,0.0715884f, 0.597104f,0.069812f,
+0.598751f,0.0680441f, 0.600562f,0.066288f, 0.60251f,0.064531f, 0.604591f,0.0627912f, 0.60682f,0.0611007f,
+0.609211f,0.059477f, 0.611708f,0.0578679f, 0.614286f,0.0562597f, 0.616931f,0.0546541f, 0.619695f,0.0530693f,
+0.622534f,0.0515086f, 0.625465f,0.0499952f, 0.628442f,0.0484983f, 0.631467f,0.0470254f, 0.634519f,0.0455699f,
+0.637616f,0.0441493f, 0.640832f,0.0427565f, 0.644135f,0.0413959f, 0.647411f,0.0400317f, 0.650648f,0.0386659f,
+0.653879f,0.037326f, 0.657089f,0.0360079f, 0.660271f,0.0347127f, 0.663457f,0.0334594f, 0.666636f,0.0322443f,
+0.669764f,0.0310498f, 0.672822f,0.0298721f, 0.675933f,0.0287329f, 0.679241f,0.0276199f, 0.682662f,0.0265606f,
+0.685997f,0.0255068f, 0.689222f,0.0244622f, 0.692673f,0.0234503f, 0.696364f,0.0224767f, 0.699998f,0.021524f,
+0.703835f,0.0205953f, 0.707642f,0.0196883f, 0.711407f,0.0188048f, 0.715106f,0.017938f, 0.71881f,0.0171086f,
+0.722487f,0.0163069f, 0.726099f,0.015524f, 0.729704f,0.0147744f, 0.733291f,0.0140538f, 0.73681f,0.0133507f,
+0.74024f,0.0126626f, 0.743589f,0.0119929f, 0.746879f,0.0113462f, 0.750175f,0.0107341f, 0.753463f,0.0101522f,
+0.756711f,0.00959475f, 0.75989f,0.00905615f, 0.762996f,0.00853528f, 0.766046f,0.00803596f, 0.769024f,0.00755535f,
+0.771959f,0.00709798f, 0.774824f,0.0066601f, 0.777625f,0.00624243f, 0.780385f,0.0058476f, 0.783162f,0.00548201f,
+0.785852f,0.00513139f, 0.788636f,0.00479051f, 0.791362f,0.00446643f, 0.794034f,0.00416022f, 0.796698f,0.0038677f,
+0.799237f,0.00358504f, 0.801796f,0.00331517f, 0.804457f,0.00306623f, 0.807094f,0.00283197f, 0.809785f,0.00261411f,
+0.812429f,0.00240902f, 0.814994f,0.00221463f, 0.817568f,0.00203605f, 0.820105f,0.00186973f, 0.822539f,0.00171105f,
+0.825f,0.00156742f, 0.827319f,0.00142942f, 0.829572f,0.00129997f, 0.831909f,0.00118058f, 0.834177f,0.00107007f,
+0.836499f,0.000966251f, 0.838737f,0.000867217f, 0.840925f,0.000775681f, 0.843098f,0.00069335f, 0.845234f,0.000619055f,
+0.847323f,0.000550716f, 0.849484f,0.000488468f, 0.851607f,0.000430719f, 0.85369f,0.000377786f, 0.855728f,0.000330669f,
+0.857657f,0.000287906f, 0.859558f,0.000249225f, 0.861822f,0.00021743f, 0.863879f,0.000186427f, 0.86588f,0.000157342f,
+0.867803f,0.000131935f, 0.869843f,0.000109922f, 0.871791f,9.05761e-05f, 0.873661f,7.39049e-05f, 0.875621f,5.96043e-05f,
+0.877665f,4.69366e-05f, 0.879494f,3.55916e-05f, 0.88154f,2.61799e-05f,
+
+0.690148f,0.124161f, 0.676223f,0.120478f, 0.664031f,0.117032f, 0.653353f,0.113784f, 0.644006f,0.11072f,
+0.635836f,0.10782f, 0.628713f,0.105059f, 0.622523f,0.10241f, 0.617167f,0.0998553f, 0.612567f,0.0974125f,
+0.608649f,0.0950631f, 0.605346f,0.0927803f, 0.602601f,0.0905551f, 0.600355f,0.0883611f, 0.598578f,0.0862439f,
+0.59723f,0.0841885f, 0.596274f,0.0821866f, 0.595683f,0.0802376f, 0.595419f,0.0783186f, 0.595459f,0.0764366f,
+0.59578f,0.0745916f, 0.596352f,0.0727671f, 0.597147f,0.0709504f, 0.598165f,0.0691735f, 0.599387f,0.0674311f,
+0.600804f,0.065728f, 0.60238f,0.0640358f, 0.604096f,0.0623474f, 0.605936f,0.0606667f, 0.607896f,0.059005f,
+0.609987f,0.0573866f, 0.612227f,0.0558348f, 0.614593f,0.0543052f, 0.617067f,0.0527863f, 0.619602f,0.0512712f,
+0.622189f,0.0497635f, 0.624835f,0.0482802f, 0.627554f,0.0468388f, 0.630309f,0.0454136f, 0.633108f,0.0440144f,
+0.636078f,0.0426425f, 0.639083f,0.0412986f, 0.64212f,0.0399829f, 0.645174f,0.0386925f, 0.648215f,0.0374109f,
+0.651206f,0.0361258f, 0.654169f,0.0348585f, 0.657105f,0.0336146f, 0.660002f,0.032394f, 0.66287f,0.0312048f,
+0.665708f,0.030049f, 0.668815f,0.0289351f, 0.672017f,0.0278352f, 0.675184f,0.0267645f, 0.678303f,0.0257199f,
+0.681411f,0.0247146f, 0.685014f,0.0237391f, 0.688514f,0.0227625f, 0.69214f,0.0218083f, 0.695867f,0.0208909f,
+0.699587f,0.0200038f, 0.703265f,0.0191357f, 0.706905f,0.0182894f, 0.710516f,0.017467f, 0.714074f,0.0166637f,
+0.717571f,0.0158781f, 0.721068f,0.0151265f, 0.724545f,0.0144023f, 0.727961f,0.0136967f, 0.731378f,0.013024f,
+0.734755f,0.0123736f, 0.738066f,0.0117402f, 0.741295f,0.0111226f, 0.744443f,0.0105221f, 0.747528f,0.00994293f,
+0.750583f,0.00939036f, 0.753656f,0.00887084f, 0.756688f,0.00837387f, 0.759644f,0.00789396f, 0.762498f,0.00742769f,
+0.765298f,0.00698298f, 0.768015f,0.00655561f, 0.770657f,0.00614776f, 0.773218f,0.00575865f, 0.775906f,0.00538572f,
+0.778589f,0.00503541f, 0.781343f,0.00470965f, 0.784091f,0.00440047f, 0.786721f,0.00410073f, 0.789403f,0.0038165f,
+0.792148f,0.00354792f, 0.794935f,0.003293f, 0.797602f,0.00304622f, 0.800178f,0.00281086f, 0.802758f,0.00259419f,
+0.805274f,0.00238994f, 0.807772f,0.00220032f, 0.810214f,0.00202226f, 0.812586f,0.00185486f, 0.814897f,0.00169914f,
+0.817251f,0.0015565f, 0.819601f,0.00142023f, 0.821959f,0.0012955f, 0.824353f,0.00117805f, 0.826775f,0.0010683f,
+0.829148f,0.000966931f, 0.831467f,0.000873214f, 0.833738f,0.000785556f, 0.835878f,0.000701932f, 0.838105f,0.000625157f,
+0.840367f,0.000556575f, 0.842615f,0.000495332f, 0.844741f,0.000438026f, 0.8468f,0.000386225f, 0.848755f,0.000337786f,
+0.850852f,0.000294606f, 0.852942f,0.000255932f, 0.855021f,0.000220148f, 0.85716f,0.000189976f, 0.85928f,0.000163244f,
+0.861334f,0.000137233f, 0.863225f,0.000113933f, 0.865049f,9.37863e-05f, 0.866937f,7.63048e-05f, 0.868901f,6.14431e-05f,
+0.870595f,4.79409e-05f, 0.872846f,3.71881e-05f, 0.874652f,2.71133e-05f,
+
+0.69328f,0.120082f, 0.679825f,0.116574f, 0.667995f,0.113279f, 0.657588f,0.110164f, 0.648439f,0.107216f,
+0.640404f,0.104419f, 0.633365f,0.101753f, 0.627214f,0.0991889f, 0.62186f,0.0967182f, 0.617227f,0.0943357f,
+0.61325f,0.092055f, 0.609866f,0.0898401f, 0.607019f,0.0876806f, 0.604653f,0.0855506f, 0.602736f,0.0834817f,
+0.601232f,0.0814693f, 0.600108f,0.0795126f, 0.599339f,0.0776122f, 0.598885f,0.0757405f, 0.598725f,0.0739018f,
+0.598843f,0.0721107f, 0.599204f,0.0703345f, 0.59979f,0.0685804f, 0.600578f,0.0668422f, 0.60157f,0.0651449f,
+0.602743f,0.0634788f, 0.604089f,0.061845f, 0.605577f,0.060224f, 0.607184f,0.0586041f, 0.608904f,0.0569963f,
+0.610742f,0.0554144f, 0.612752f,0.0538866f, 0.614908f,0.0524247f, 0.617145f,0.0509729f, 0.619444f,0.0495248f,
+0.621792f,0.0480818f, 0.624169f,0.0466383f, 0.626605f,0.0452273f, 0.629154f,0.0438575f, 0.631835f,0.0425107f,
+0.634552f,0.0411883f, 0.637299f,0.0398904f, 0.640064f,0.0386148f, 0.642852f,0.0373687f, 0.645652f,0.0361488f,
+0.648434f,0.0349423f, 0.651152f,0.0337302f, 0.653828f,0.0325332f, 0.656499f,0.0313682f, 0.659192f,0.0302223f,
+0.662204f,0.0291059f, 0.66519f,0.028018f, 0.668167f,0.0269677f, 0.671095f,0.02594f, 0.674211f,0.024931f,
+0.677585f,0.023949f, 0.681018f,0.0229948f, 0.684659f,0.0220799f, 0.688256f,0.021176f, 0.691784f,0.0202787f,
+0.695293f,0.0194079f, 0.69884f,0.0185784f, 0.702357f,0.0177709f, 0.705839f,0.0169835f, 0.709274f,0.0162146f,
+0.712674f,0.0154678f, 0.716008f,0.0147361f, 0.719308f,0.0140282f, 0.722595f,0.0133492f, 0.725843f,0.0126922f,
+0.729059f,0.0120588f, 0.732271f,0.0114552f, 0.735426f,0.0108694f, 0.738516f,0.0103005f, 0.741524f,0.00974688f,
+0.744456f,0.00921037f, 0.747316f,0.00869268f, 0.750127f,0.00819771f, 0.752931f,0.0077316f, 0.755714f,0.0072898f,
+0.758406f,0.00686311f, 0.760967f,0.00644761f, 0.763673f,0.00605263f, 0.766368f,0.00567331f, 0.769078f,0.00531213f,
+0.771733f,0.00496877f, 0.774293f,0.00463954f, 0.776942f,0.00433173f, 0.779763f,0.00404292f, 0.782583f,0.00376963f,
+0.785322f,0.00350603f, 0.788027f,0.00325755f, 0.790673f,0.00302207f, 0.793231f,0.00279677f, 0.795682f,0.00258036f,
+0.798023f,0.00237364f, 0.800398f,0.00218586f, 0.802747f,0.00200979f, 0.805078f,0.00184441f, 0.807465f,0.00169012f,
+0.809811f,0.0015468f, 0.812184f,0.00141395f, 0.814666f,0.00129004f, 0.817111f,0.0011746f, 0.819515f,0.00106787f,
+0.82184f,0.000967784f, 0.824142f,0.000874349f, 0.826578f,0.000789032f, 0.82897f,0.000710131f, 0.831231f,0.000635154f,
+0.833357f,0.00056428f, 0.835441f,0.000500702f, 0.837564f,0.000443936f, 0.839696f,0.000392784f, 0.841864f,0.000345274f,
+0.844024f,0.000301633f, 0.846125f,0.000261464f, 0.848188f,0.000226287f, 0.85021f,0.000194433f, 0.852227f,0.000165439f,
+0.854322f,0.000141442f, 0.856358f,0.000118553f, 0.858219f,9.74642e-05f, 0.860114f,7.94238e-05f, 0.86185f,6.36169e-05f,
+0.863859f,5.01844e-05f, 0.865737f,3.80942e-05f, 0.867546f,2.80486e-05f,
+
+0.696178f,0.116146f, 0.683177f,0.112801f, 0.671698f,0.109649f, 0.661559f,0.106661f, 0.652606f,0.103823f,
+0.644708f,0.101125f, 0.637756f,0.0985493f, 0.631649f,0.0960692f, 0.626305f,0.0936786f, 0.621646f,0.0913569f,
+0.617619f,0.0891428f, 0.61416f,0.0869908f, 0.611218f,0.0848937f, 0.608744f,0.0828357f, 0.606695f,0.0808087f,
+0.605046f,0.0788451f, 0.603764f,0.0769349f, 0.602819f,0.0750711f, 0.602191f,0.0732568f, 0.601842f,0.071464f,
+0.601755f,0.0697035f, 0.601918f,0.0679891f, 0.602298f,0.0662892f, 0.60287f,0.0645952f, 0.603634f,0.0629369f,
+0.604578f,0.0613132f, 0.605685f,0.0597196f, 0.606942f,0.0581515f, 0.608336f,0.0566033f, 0.609848f,0.0550608f,
+0.611512f,0.0535465f, 0.613276f,0.0520552f, 0.615146f,0.0506007f, 0.617137f,0.0492046f, 0.619196f,0.0478176f,
+0.621308f,0.0464387f, 0.623458f,0.0450652f, 0.625722f,0.0436989f, 0.628083f,0.0423559f, 0.630511f,0.0410566f,
+0.632968f,0.0397772f, 0.635451f,0.0385214f, 0.637958f,0.0372922f, 0.64047f,0.0360836f, 0.642992f,0.0349024f,
+0.645528f,0.033749f, 0.648074f,0.0326229f, 0.650542f,0.0314896f, 0.65322f,0.0303673f, 0.656037f,0.0292736f,
+0.658814f,0.0281979f, 0.661551f,0.0271459f, 0.664258f,0.0261257f, 0.667384f,0.0251245f, 0.670589f,0.0241589f,
+0.673997f,0.0232126f, 0.67743f,0.0222902f, 0.680843f,0.0213882f, 0.684296f,0.0205279f, 0.687727f,0.0196869f,
+0.691095f,0.0188518f, 0.694425f,0.0180344f, 0.697745f,0.0172447f, 0.701081f,0.0164893f, 0.704402f,0.0157575f,
+0.707686f,0.015045f, 0.710922f,0.0143498f, 0.714116f,0.0136741f, 0.717237f,0.013012f, 0.720335f,0.0123759f,
+0.723398f,0.0117627f, 0.726411f,0.0111683f, 0.729394f,0.0105976f, 0.732386f,0.0100569f, 0.735305f,0.00953102f,
+0.738154f,0.00902101f, 0.740917f,0.00852591f, 0.743602f,0.00804773f, 0.746201f,0.00758591f, 0.748736f,0.00714509f,
+0.751408f,0.00672888f, 0.754208f,0.0063339f, 0.756975f,0.00595534f, 0.759633f,0.00558747f, 0.762235f,0.0052374f,
+0.764871f,0.00490163f, 0.767654f,0.00458118f, 0.770419f,0.0042789f, 0.773108f,0.00398901f, 0.775804f,0.00371923f,
+0.778474f,0.00346519f, 0.781105f,0.00322466f, 0.78367f,0.00299294f, 0.7862f,0.00277606f, 0.788674f,0.00257094f,
+0.791035f,0.00237408f, 0.793326f,0.00218435f, 0.795655f,0.00200485f, 0.798011f,0.00184218f, 0.800326f,0.00168891f,
+0.802724f,0.00154434f, 0.805088f,0.00141017f, 0.807411f,0.00128561f, 0.809778f,0.00117178f, 0.812091f,0.00106437f,
+0.814503f,0.00096497f, 0.816916f,0.000874093f, 0.819258f,0.000789136f, 0.821552f,0.000710895f, 0.823795f,0.000639039f,
+0.826033f,0.00057216f, 0.828094f,0.000508173f, 0.830161f,0.000447957f, 0.832354f,0.000395503f, 0.834644f,0.000349545f,
+0.8368f,0.000306486f, 0.838868f,0.000267537