]> OCCT Git - occt.git/commitdiff
0032042: Visualization, TKOpenGl - pre-multiply headlight flag into light source...
authorkgv <kgv@opencascade.com>
Thu, 7 Jan 2021 21:48:29 +0000 (00:48 +0300)
committerbugmaster <bugmaster@opencascade.com>
Tue, 12 Jan 2021 13:41:38 +0000 (16:41 +0300)
OpenGl_ShaderManager::pushLightSourceState() now pre-multiplies headlight transformation.
Built-in shading GLSL programs have been updated to remove special handling if headlight flag;
also removed redundant pre-normalization of light source direction
(already normalized implicitly by Graphic3d_CLight interface).

Graphic3d_CLight::SetHeadlight() now raises exception in case of ambient light type.
OpenGl_ShaderManager::SetLastView() - removed unused property.

src/Graphic3d/Graphic3d_CLight.cxx
src/Graphic3d/Graphic3d_CLight.hxx
src/OpenGl/OpenGl_ShaderManager.cxx
src/OpenGl/OpenGl_ShaderManager.hxx
src/OpenGl/OpenGl_View.cxx
src/Shaders/Declarations.glsl
src/Shaders/Shaders_Declarations_glsl.pxx
src/ViewerTest/ViewerTest_ViewerCommands.cxx

index f46c67587c34cd299e930b57b7d0a76135ffad7e..b46de002b6a029762927457bee48a77dcefe0eb9 100644 (file)
@@ -114,6 +114,10 @@ void Graphic3d_CLight::SetEnabled (Standard_Boolean theIsOn)
 // =======================================================================
 void Graphic3d_CLight::SetHeadlight (Standard_Boolean theValue)
 {
+  if (myType == Graphic3d_TOLS_AMBIENT)
+  {
+    throw Standard_ProgramError ("Graphic3d_CLight::SetHeadlight() is not applicable to ambient light");
+  }
   updateRevisionIf (myIsHeadlight != theValue);
   myIsHeadlight = theValue;
 }
index a52f0dad2c083d8b7fc2f949dc7d74af61ee9160..b2218ff877e54ee60b7042c61bfc0979ff77b059 100644 (file)
@@ -202,6 +202,9 @@ public:
   //! Returns direction of directional/spot light and range for positional/spot light in alpha channel.
   const Graphic3d_Vec4& PackedDirectionRange() const { return myDirection; }
 
+  //! Returns direction of directional/spot light.
+  Graphic3d_Vec3 PackedDirection() const { return myDirection.xyz(); }
+
   //! @return modification counter
   Standard_Size Revision() const { return myRevision; }
   
index 274b298fbd0aacc3036c2b18df3c84dff73e0611..857b5c692e48edb130429198d4dca68ea20006f3 100644 (file)
@@ -110,12 +110,7 @@ const char THE_FUNC_pointLight[] =
   EOL"                 in vec3 thePoint,"
   EOL"                 in bool theIsFront)"
   EOL"{"
-  EOL"  vec3 aLight = occLight_Position (theId);"
-  EOL"  if (!occLight_IsHeadlight (theId))"
-  EOL"  {"
-  EOL"    aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 1.0));"
-  EOL"  }"
-  EOL"  aLight -= thePoint;"
+  EOL"  vec3 aLight = vec3 (occWorldViewMatrix * vec4 (occLight_Position (theId), 1.0)) - thePoint;"
   EOL
   EOL"  float aDist = length (aLight);"
   EOL"  float aRange = occLight_Range (theId);"
@@ -147,12 +142,7 @@ const char THE_FUNC_PBR_pointLight[] =
   EOL"                 in vec3 thePoint,"
   EOL"                 in bool theIsFront)"
   EOL"{"
-  EOL"  vec3 aLight = occLight_Position (theId);"
-  EOL"  if (occLight_IsHeadlight (theId))"
-  EOL"  {"
-  EOL"    aLight = vec3 (occWorldViewMatrixInverse * vec4 (aLight, 1.0));"
-  EOL"  }"
-  EOL"  aLight -= thePoint;"
+  EOL"  vec3 aLight = occLight_Position (theId) - thePoint;"
   EOL
   EOL"  float aDist = length (aLight);"
   EOL"  float aRange = occLight_Range (theId);"
@@ -175,14 +165,7 @@ const char THE_FUNC_spotLight[] =
   EOL"                in vec3 thePoint,"
   EOL"                in bool theIsFront)"
   EOL"{"
-  EOL"  vec3 aLight   = occLight_Position      (theId);"
-  EOL"  vec3 aSpotDir = occLight_SpotDirection (theId);"
-  EOL"  if (!occLight_IsHeadlight (theId))"
-  EOL"  {"
-  EOL"    aLight   = vec3 (occWorldViewMatrix * vec4 (aLight,   1.0));"
-  EOL"    aSpotDir = vec3 (occWorldViewMatrix * vec4 (aSpotDir, 0.0));"
-  EOL"  }"
-  EOL"  aLight -= thePoint;"
+  EOL"  vec3 aLight = vec3 (occWorldViewMatrix * vec4 (occLight_Position (theId), 1.0)) - thePoint;"
   EOL
   EOL"  float aDist = length (aLight);"
   EOL"  float aRange = occLight_Range (theId);"
@@ -190,6 +173,7 @@ const char THE_FUNC_spotLight[] =
   EOL"  if (anAtten <= 0.0) return;"
   EOL"  aLight /= aDist;"
   EOL
+  EOL"  vec3 aSpotDir = vec3 (occWorldViewMatrix * vec4 (occLight_SpotDirection (theId), 0.0));"
   EOL"  aSpotDir = normalize (aSpotDir);"
   // light cone
   EOL"  float aCosA = dot (aSpotDir, -aLight);"
@@ -228,14 +212,7 @@ const char THE_FUNC_spotLight[] =
   EOL"                in vec3 thePoint,"
   EOL"                in bool theIsFront)"
   EOL"{"
-  EOL"  vec3 aLight   = occLight_Position      (theId);"
-  EOL"  vec3 aSpotDir = occLight_SpotDirection (theId);"
-  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"  vec3 aLight = occLight_Position (theId) - thePoint;"
   EOL
   EOL"  float aDist = length (aLight);"
   EOL"  float aRange = occLight_Range (theId);"
@@ -243,7 +220,7 @@ const char THE_FUNC_spotLight[] =
   EOL"  if (anAtten <= 0.0) return;"
   EOL"  aLight /= aDist;"
   EOL
-  EOL"  aSpotDir = normalize (aSpotDir);"
+  EOL"  vec3 aSpotDir = occLight_SpotDirection (theId);"
   // light cone
   EOL"  float aCosA = dot (aSpotDir, -aLight);"
   EOL"  float aRelativeAngle = 2.0 * acos(aCosA) / occLight_SpotCutOff(theId);"
@@ -274,11 +251,7 @@ const char THE_FUNC_directionalLight[] =
   EOL"                       in vec3 theView,"
   EOL"                       in bool theIsFront)"
   EOL"{"
-  EOL"  vec3 aLight = normalize (occLight_Position (theId));"
-  EOL"  if (!occLight_IsHeadlight (theId))"
-  EOL"  {"
-  EOL"    aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 0.0));"
-  EOL"  }"
+  EOL"  vec3 aLight = vec3 (occWorldViewMatrix * vec4 (occLight_Position (theId), 0.0));"
   EOL
   EOL"  vec3 aHalf = normalize (aLight + theView);"
   EOL
@@ -303,11 +276,7 @@ const char THE_FUNC_PBR_directionalLight[] =
   EOL"                       in vec3 theView,"
   EOL"                       in bool theIsFront)"
   EOL"{"
-  EOL"  vec3 aLight = normalize (occLight_Position (theId));"
-  EOL"  if (occLight_IsHeadlight (theId))"
-  EOL"  {"
-  EOL"    aLight = vec3 (occWorldViewMatrixInverse * vec4 (aLight, 0.0));"
-  EOL"  }"
+  EOL"  vec3 aLight = occLight_Position (theId);"
   EOL
   EOL"  theNormal = theIsFront ? theNormal : -theNormal;"
   EOL"  DirectLighting += occPBRIllumination (theView, aLight, theNormal,"
@@ -323,11 +292,7 @@ const char THE_FUNC_directionalLightFirst[] =
   EOL"                            in vec3 theView,"
   EOL"                            in bool theIsFront)"
   EOL"{"
-  EOL"  vec3 aLight = normalize (occLight_Position(0));"
-  EOL"  if (!occLight_IsHeadlight (0))"
-  EOL"  {"
-  EOL"    aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 0.0));"
-  EOL"  }"
+  EOL"  vec3 aLight = vec3 (occWorldViewMatrix * vec4 (occLight_Position (0), 0.0));"
   EOL
   EOL"  vec3 aHalf = normalize (aLight + theView);"
   EOL
@@ -546,8 +511,7 @@ OpenGl_ShaderManager::OpenGl_ShaderManager (OpenGl_Context* theContext)
   myUnlitPrograms (new OpenGl_SetOfPrograms()),
   myContext  (theContext),
   mySRgbState (theContext->ToRenderSRGB()),
-  myHasLocalOrigin (Standard_False),
-  myLastView (NULL)
+  myHasLocalOrigin (Standard_False)
 {
   //
 }
@@ -910,33 +874,60 @@ void OpenGl_ShaderManager::pushLightSourceState (const Handle(OpenGl_ShaderProgr
     aLightType = aLight.Type();
     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.PackedDirectionRange();
-    }
-    else if (!aLight.IsHeadlight())
-    {
-      aLightParams.Position.x() = static_cast<float>(aLight.Position().X() - myLocalOrigin.X());
-      aLightParams.Position.y() = static_cast<float>(aLight.Position().Y() - myLocalOrigin.Y());
-      aLightParams.Position.z() = static_cast<float>(aLight.Position().Z() - myLocalOrigin.Z());
-    }
-    else
-    {
-      aLightParams.Position.x() = static_cast<float>(aLight.Position().X());
-      aLightParams.Position.y() = static_cast<float>(aLight.Position().Y());
-      aLightParams.Position.z() = static_cast<float>(aLight.Position().Z());
-    }
-    aLightParams.Position.w() = aLight.IsHeadlight() ? 1.0f : 0.0f;
-
-    if (aLight.Type() == Graphic3d_TOLS_SPOT)
-    {
-      aLightParams.Direction = aLight.PackedDirectionRange();
-    }
-    if (aLight.Type() == Graphic3d_TOLS_POSITIONAL)
+    aLightParams.Parameters = aLight.PackedParams();
+    switch (aLight.Type())
     {
-      aLightParams.Direction.w() = aLight.Range();
+      case Graphic3d_TOLS_AMBIENT:
+      {
+        break;
+      }
+      case Graphic3d_TOLS_DIRECTIONAL:
+      {
+        if (aLight.IsHeadlight())
+        {
+          const Graphic3d_Mat4& anOrientInv = myWorldViewState.WorldViewMatrixInverse();
+          aLightParams.Position = anOrientInv * Graphic3d_Vec4 (-aLight.PackedDirection(), 0.0f);
+        }
+        else
+        {
+          aLightParams.Position = Graphic3d_Vec4 (-aLight.PackedDirection(), 0.0f);
+        }
+        break;
+      }
+      case Graphic3d_TOLS_SPOT:
+      {
+        if (aLight.IsHeadlight())
+        {
+          const Graphic3d_Mat4& anOrientInv = myWorldViewState.WorldViewMatrixInverse();
+          aLightParams.Direction = anOrientInv * Graphic3d_Vec4 (aLight.PackedDirection(), 0.0f);
+        }
+        else
+        {
+          aLightParams.Direction = Graphic3d_Vec4 (aLight.PackedDirection(), 0.0f);
+        }
+      }
+      Standard_FALLTHROUGH
+      case Graphic3d_TOLS_POSITIONAL:
+      {
+        if (aLight.IsHeadlight())
+        {
+          aLightParams.Position.x() = static_cast<float>(aLight.Position().X());
+          aLightParams.Position.y() = static_cast<float>(aLight.Position().Y());
+          aLightParams.Position.z() = static_cast<float>(aLight.Position().Z());
+          const Graphic3d_Mat4& anOrientInv = myWorldViewState.WorldViewMatrixInverse();
+          aLightParams.Position = anOrientInv * Graphic3d_Vec4 (aLightParams.Position.xyz(), 1.0f);
+        }
+        else
+        {
+          aLightParams.Position.x() = static_cast<float>(aLight.Position().X() - myLocalOrigin.X());
+          aLightParams.Position.y() = static_cast<float>(aLight.Position().Y() - myLocalOrigin.Y());
+          aLightParams.Position.z() = static_cast<float>(aLight.Position().Z() - myLocalOrigin.Z());
+          aLightParams.Position.w() = 0.0f;
+        }
+        aLightParams.Direction.w() = aLight.Range();
+        break;
+      }
     }
-    aLightParams.Parameters = aLight.PackedParams();
     ++aLightsNb;
   }
 
@@ -1426,10 +1417,10 @@ void OpenGl_ShaderManager::PushState (const Handle(OpenGl_ShaderProgram)& thePro
 {
   const Handle(OpenGl_ShaderProgram)& aProgram = !theProgram.IsNull() ? theProgram : myFfpProgram;
   PushClippingState    (aProgram);
+  PushLightSourceState (aProgram); // should be before PushWorldViewState()
   PushWorldViewState   (aProgram);
   PushModelWorldState  (aProgram);
   PushProjectionState  (aProgram);
-  PushLightSourceState (aProgram);
   PushMaterialState    (aProgram);
   PushOitState         (aProgram);
 
index 755be61a705c72a52a0f7c2c027d7f06db53652f..f6280fde0a1c415ee629cc331abdb1640174cdb2 100644 (file)
@@ -293,9 +293,11 @@ public:
   Standard_EXPORT void UpdateLightSourceState();
 
   //! Pushes current state of OCCT light sources to specified program (only on state change).
+  //! Note that light sources definition depends also on WorldViewState.
   void PushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const
   {
-    if (myLightSourceState.Index() != theProgram->ActiveState (OpenGl_LIGHT_SOURCES_STATE))
+    if (myLightSourceState.Index() != theProgram->ActiveState (OpenGl_LIGHT_SOURCES_STATE)
+     || myWorldViewState.Index()   != theProgram->ActiveState (OpenGl_WORLD_VIEW_STATE))
     {
       pushLightSourceState (theProgram);
     }
@@ -540,19 +542,6 @@ public:
   //! Sets shading model.
   Standard_EXPORT void SetShadingModel (const Graphic3d_TypeOfShadingModel theModel);
 
-  //! Sets last view manger used with.
-  //! Helps to handle matrix states in multi-view configurations.
-  void SetLastView (const OpenGl_View* theLastView)
-  {
-    myLastView = theLastView;
-  }
-
-  //! Returns true when provided view is the same as cached one.
-  bool IsSameView (const OpenGl_View* theView) const
-  {
-    return myLastView == theView;
-  }
-
 protected:
 
   //! Define clipping planes program bits.
@@ -849,10 +838,6 @@ protected:
   mutable NCollection_Array1<OpenGl_Vec4d>                 myClipPlaneArrayFfp;
   mutable NCollection_Array1<Standard_Integer>             myClipChainArray;
 
-private:
-
-  const OpenGl_View*                 myLastView;           //!< Pointer to the last view shader manager used with
-
 };
 
 DEFINE_STANDARD_HANDLE(OpenGl_ShaderManager, Standard_Transient)
index 5f8e602b5142ca2c9c6eebdc8136b3c18b4b9cbf..449d58fdeb72ba85c5750b97118f144242a7fbfe 100644 (file)
@@ -129,7 +129,6 @@ OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr,
   myWorkspace = new OpenGl_Workspace (this, NULL);
 
   Handle(Graphic3d_CLight) aLight = new Graphic3d_CLight (Graphic3d_TOLS_AMBIENT);
-  aLight->SetHeadlight (false);
   aLight->SetColor (Quantity_NOC_WHITE);
   myLights = new Graphic3d_LightSet();
   myNoShadingLight = new Graphic3d_LightSet();
@@ -2063,15 +2062,6 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection,
   {
     aContext->ShaderManager()->PushState (Handle(OpenGl_ShaderProgram)());
   }
-
-  // ==============================================================
-  //      Step 6: Keep shader manager informed about last View
-  // ==============================================================
-
-  if (!aManager.IsNull())
-  {
-    aManager->SetLastView (this);
-  }
 }
 
 // =======================================================================
index 081fa70e7f6dc2f27b5f1ff3bb84056f9698d85e..644fe7b2a90fbeb7084877c6a56c73bcb3f784ca 100644 (file)
@@ -147,10 +147,10 @@ uniform THE_PREC_ENUM int  occLightSourcesCount; //!< Total number of light sour
 //! Intensity of light source (>= 0), float.
 #define occLight_Intensity(theId)         occLightSources[theId * 4 + 0].a
 
-//! Is light a headlight, bool?
-#define occLight_IsHeadlight(theId)      (occLightSources[theId * 4 + 1].w > 0.5)
+//! Is light a headlight, bool? DEPRECATED method.
+#define occLight_IsHeadlight(theId) false
 
-//! Position of specified light source, vec3.
+//! Position of specified light source or direction of directional light source, vec3.
 #define occLight_Position(theId)          occLightSources[theId * 4 + 1].xyz
 
 //! Direction of specified spot light source, vec3.
index cffec840910cd9b2b0f8b2ba8f1eed9778a63b43..b64b83d0453f2263500e7d59a0a1b33f67242d36 100644 (file)
@@ -150,10 +150,10 @@ static const char Shaders_Declarations_glsl[] =
   "//! Intensity of light source (>= 0), float.\n"
   "#define occLight_Intensity(theId)         occLightSources[theId * 4 + 0].a\n"
   "\n"
-  "//! Is light a headlight, bool?\n"
-  "#define occLight_IsHeadlight(theId)      (occLightSources[theId * 4 + 1].w > 0.5)\n"
+  "//! Is light a headlight, bool? DEPRECATED method.\n"
+  "#define occLight_IsHeadlight(theId) false\n"
   "\n"
-  "//! Position of specified light source, vec3.\n"
+  "//! Position of specified light source or direction of directional light source, vec3.\n"
   "#define occLight_Position(theId)          occLightSources[theId * 4 + 1].xyz\n"
   "\n"
   "//! Direction of specified spot light source, vec3.\n"
index a8b8a84d05ec4554c19be4d36b309fb351fd06bb..fd09f894399271fb7d6c35c10390c57f1487e0f3 100644 (file)
@@ -11562,6 +11562,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
       case Graphic3d_TOSM_PBR:       theDI << "pbr";       break;
       case Graphic3d_TOSM_PBR_FACET: theDI << "pbr_facet"; break;
     }
+    theDI << "\n";
     {
       theDI << "perfCounters:";
       if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_FrameRate) != 0)