0032200: Visualization, TKOpenGl - unify Phong/PBR light space calculations
authorkgv <kgv@opencascade.com>
Fri, 5 Mar 2021 20:06:50 +0000 (23:06 +0300)
committerbugmaster <bugmaster@opencascade.com>
Wed, 17 Mar 2021 16:53:13 +0000 (19:53 +0300)
Graphic3d_ShaderManager - Phong shading now uses World space calculations.
OpenGl_ShaderManager::pushLightSourceState() - fixed unnormalized direction of headlight source.

src/Graphic3d/Graphic3d_ShaderManager.cxx
src/OpenGl/OpenGl_ShaderManager.cxx
src/Shaders/DirectionalLightShadow.glsl
src/Shaders/PhongDirectionalLight.glsl
src/Shaders/PhongPointLight.glsl
src/Shaders/PhongSpotLight.glsl
src/Shaders/Shaders_DirectionalLightShadow_glsl.pxx
src/Shaders/Shaders_PhongDirectionalLight_glsl.pxx
src/Shaders/Shaders_PhongPointLight_glsl.pxx
src/Shaders/Shaders_PhongSpotLight_glsl.pxx

index 5621aeb..aec6b76 100644 (file)
@@ -107,7 +107,7 @@ const char THE_FUNC_directionalLightFirst[] =
   EOL"                            in bool theIsFront,"
   EOL"                            in float theShadow)"
   EOL"{"
-  EOL"  vec3 aLight = vec3 (occWorldViewMatrix * vec4 (occLight_Position (0), 0.0));"
+  EOL"  vec3 aLight = occLight_Position (0);"
   EOL
   EOL"  vec3 aHalf = normalize (aLight + theView);"
   EOL
@@ -1025,10 +1025,8 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramUnlit (Sta
   if ((theBits & Graphic3d_ShaderFlags_ClipPlanesN) != 0)
   {
     aStageInOuts.Append (Graphic3d_ShaderObject::ShaderVariable ("vec4 PositionWorld", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
-    aStageInOuts.Append (Graphic3d_ShaderObject::ShaderVariable ("vec4 Position",      Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
     aSrcVertExtraMain +=
-      EOL"  PositionWorld = occModelWorldMatrix * occVertex;"
-      EOL"  Position      = occWorldViewMatrix * PositionWorld;";
+      EOL"  PositionWorld = occModelWorldMatrix * occVertex;";
 
     if ((theBits & Graphic3d_ShaderFlags_ClipPlanesN) == Graphic3d_ShaderFlags_ClipPlanesN)
     {
@@ -1430,10 +1428,8 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramGouraud (c
   if ((theBits & Graphic3d_ShaderFlags_ClipPlanesN) != 0)
   {
     aStageInOuts.Append (Graphic3d_ShaderObject::ShaderVariable ("vec4 PositionWorld", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
-    aStageInOuts.Append (Graphic3d_ShaderObject::ShaderVariable ("vec4 Position",      Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
     aSrcVertExtraMain +=
-      EOL"  PositionWorld = aPositionWorld;"
-      EOL"  Position      = aPosition;";
+      EOL"  PositionWorld = aPositionWorld;";
 
     if ((theBits & Graphic3d_ShaderFlags_ClipPlanesN) == Graphic3d_ShaderFlags_ClipPlanesN)
     {
@@ -1472,18 +1468,17 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramGouraud (c
   Standard_Integer aNbLights = 0;
   const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, theLights, !aSrcVertColor.IsEmpty(), false, toUseTexColor, 0);
   aSrcVert = TCollection_AsciiString()
-    + THE_FUNC_transformNormal_view
+    + THE_FUNC_transformNormal_world
     + EOL
     + aSrcVertColor
     + aLights
     + EOL"void main()"
       EOL"{"
       EOL"  vec4 aPositionWorld = occModelWorldMatrix * occVertex;"
-      EOL"  vec4 aPosition      = occWorldViewMatrix * aPositionWorld;"
       EOL"  vec3 aNormal        = transformNormal (occNormal);"
-      EOL"  vec3 aView          = vec3 (0.0, 0.0, 1.0);"
-      EOL"  FrontColor  = computeLighting (aNormal, aView, aPosition, true);"
-      EOL"  BackColor   = computeLighting (aNormal, aView, aPosition, false);"
+      EOL"  vec3 aView = (occWorldViewMatrixInverse * vec4(0.0, 0.0, 1.0, 0.0)).xyz;"
+      EOL"  FrontColor  = computeLighting (aNormal, aView, aPositionWorld, true);"
+      EOL"  BackColor   = computeLighting (aNormal, aView, aPositionWorld, false);"
     + aSrcVertExtraMain
     + THE_VERT_gl_Position
     + EOL"}";
@@ -1526,9 +1521,8 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramPhong (con
                                                                              const Standard_Boolean theIsPBR,
                                                                              const Standard_Integer theNbShadowMaps) const
 {
-  TCollection_AsciiString aPosition = theIsPBR ? "PositionWorld" : "Position";
   TCollection_AsciiString aPhongCompLight = TCollection_AsciiString() +
-    "computeLighting (normalize (Normal), normalize (View), " + aPosition + ", gl_FrontFacing)";
+    "computeLighting (normalize (Normal), normalize (View), PositionWorld, gl_FrontFacing)";
   const bool isFlatNormal = theIsFlatNormal && myHasFlatShading;
   const char* aDFdxSignReversion = myToReverseDFdxSign ? "-" : "";
   bool toUseTexColor = false;
@@ -1646,7 +1640,7 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramPhong (con
   if (isFlatNormal)
   {
     aSrcFragExtraMain += TCollection_AsciiString()
-      + EOL"  Normal = " + aDFdxSignReversion + "normalize (cross (dFdx (" + aPosition + ".xyz / " + aPosition + ".w), dFdy (" + aPosition + ".xyz / " + aPosition + ".w)));"
+      + EOL"  Normal = " + aDFdxSignReversion + "normalize (cross (dFdx (PositionWorld.xyz / PositionWorld.w), dFdy (PositionWorld.xyz / PositionWorld.w)));"
         EOL"  if (!gl_FrontFacing) { Normal = -Normal; }";
   }
   else
@@ -1674,15 +1668,9 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramPhong (con
         EOL"  }"
         EOL"#endif";
     }
-    if (!theIsPBR)
-    {
-      aSrcFragExtraMain +=
-        EOL"  Normal = normalize ((occWorldViewMatrixInverseTranspose * vec4 (Normal, 0.0)).xyz);";
-    }
   }
 
   aStageInOuts.Append (Graphic3d_ShaderObject::ShaderVariable ("vec4 PositionWorld", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
-  aStageInOuts.Append (Graphic3d_ShaderObject::ShaderVariable ("vec4 Position",      Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
   aStageInOuts.Append (Graphic3d_ShaderObject::ShaderVariable ("vec3 View",          Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
   if (theNbShadowMaps > 0)
   {
@@ -1703,16 +1691,16 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramPhong (con
     + EOL"void main()"
       EOL"{"
       EOL"  PositionWorld = occModelWorldMatrix * occVertex;"
-      EOL"  Position      = occWorldViewMatrix * PositionWorld;"
       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"    vec4 aPosition = occWorldViewMatrix * PositionWorld;"
+      EOL"    View = -aPosition.xyz;"
       EOL"  }"
-    + (theIsPBR ? EOL"  View = (occWorldViewMatrixInverse * vec4(View, 0.0)).xyz;" : "")
+      EOL"  View = (occWorldViewMatrixInverse * vec4(View, 0.0)).xyz;"
     + aSrcVertExtraMain
     + THE_VERT_gl_Position
     + EOL"}";
index d3c1067..93a1642 100644 (file)
@@ -488,6 +488,7 @@ void OpenGl_ShaderManager::pushLightSourceState (const Handle(OpenGl_ShaderProgr
         {
           const Graphic3d_Mat4& anOrientInv = myWorldViewState.WorldViewMatrixInverse();
           aLightParams.Position = anOrientInv * Graphic3d_Vec4 (-aLight.PackedDirection(), 0.0f);
+          aLightParams.Position.SetValues (aLightParams.Position.xyz().Normalized(), 0.0f);
         }
         else
         {
@@ -501,6 +502,7 @@ void OpenGl_ShaderManager::pushLightSourceState (const Handle(OpenGl_ShaderProgr
         {
           const Graphic3d_Mat4& anOrientInv = myWorldViewState.WorldViewMatrixInverse();
           aLightParams.Direction = anOrientInv * Graphic3d_Vec4 (aLight.PackedDirection(), 0.0f);
+          aLightParams.Direction.SetValues (aLightParams.Direction.xyz().Normalized(), 0.0f);
         }
         else
         {
index dd98071..d0447fd 100644 (file)
@@ -15,7 +15,7 @@ float occDirectionalLightShadow (in sampler2D theShadow,
                                  in vec3 theNormal)
 {
   vec4 aPosLightSpace = PosLightSpace[occLight_Index(theId)];
-  vec3 aLightDir = vec3 (occWorldViewMatrix * vec4 (occLight_Position (theId), 0.0));
+  vec3 aLightDir = occLight_Position (theId);
   vec3 aProjCoords = (aPosLightSpace.xyz / aPosLightSpace.w);
 #ifdef THE_ZERO_TO_ONE_DEPTH
   aProjCoords.xy = aProjCoords.xy * 0.5 + vec2 (0.5);
index f1a6c9b..38bde81 100644 (file)
@@ -11,7 +11,7 @@ void occDirectionalLight (in int  theId,
                           in bool theIsFront,
                           in float theShadow)
 {
-  vec3 aLight = vec3 (occWorldViewMatrix * vec4 (occLight_Position (theId), 0.0));
+  vec3 aLight = occLight_Position (theId);
   vec3 aHalf = normalize (aLight + theView);
 
   vec3  aFaceSideNormal = theIsFront ? theNormal : -theNormal;
index f9e50ed..1b49bfe 100644 (file)
@@ -3,7 +3,7 @@
 //! @param theId      light source index
 //! @param theNormal  surface normal
 //! @param theView    view direction
-//! @param thePoint   3D position (view space)
+//! @param thePoint   3D position (world space)
 //! @param theIsFront front/back face flag
 void occPointLight (in int  theId,
                     in vec3 theNormal,
@@ -11,7 +11,7 @@ void occPointLight (in int  theId,
                     in vec3 thePoint,
                     in bool theIsFront)
 {
-  vec3 aLight = vec3 (occWorldViewMatrix * vec4 (occLight_Position (theId), 1.0)) - thePoint;
+  vec3 aLight = occLight_Position (theId) - thePoint;
 
   float aDist = length (aLight);
   float aRange = occLight_Range (theId);
index d4bf917..aab56c1 100644 (file)
@@ -3,7 +3,7 @@
 //! @param theId      light source index
 //! @param theNormal  surface normal
 //! @param theView    view direction
-//! @param thePoint   3D position (view space)
+//! @param thePoint   3D position (world space)
 //! @param theIsFront front/back face flag
 void occSpotLight (in int  theId,
                    in vec3 theNormal,
@@ -11,7 +11,7 @@ void occSpotLight (in int  theId,
                    in vec3 thePoint,
                    in bool theIsFront)
 {
-  vec3 aLight = vec3 (occWorldViewMatrix * vec4 (occLight_Position (theId), 1.0)) - thePoint;
+  vec3 aLight = occLight_Position (theId) - thePoint;
 
   float aDist = length (aLight);
   float aRange = occLight_Range (theId);
@@ -19,8 +19,7 @@ void occSpotLight (in int  theId,
   if (anAtten <= 0.0) return;
   aLight /= aDist;
 
-  vec3 aSpotDir = vec3 (occWorldViewMatrix * vec4 (occLight_SpotDirection (theId), 0.0));
-  aSpotDir = normalize (aSpotDir);
+  vec3 aSpotDir = occLight_SpotDirection (theId);
   // light cone
   float aCosA = dot (aSpotDir, -aLight);
   if (aCosA >= 1.0 || aCosA < cos (occLight_SpotCutOff (theId)))
index 5b93571..d84223d 100644 (file)
@@ -18,7 +18,7 @@ static const char Shaders_DirectionalLightShadow_glsl[] =
   "                                 in vec3 theNormal)\n"
   "{\n"
   "  vec4 aPosLightSpace = PosLightSpace[occLight_Index(theId)];\n"
-  "  vec3 aLightDir = vec3 (occWorldViewMatrix * vec4 (occLight_Position (theId), 0.0));\n"
+  "  vec3 aLightDir = occLight_Position (theId);\n"
   "  vec3 aProjCoords = (aPosLightSpace.xyz / aPosLightSpace.w);\n"
   "#ifdef THE_ZERO_TO_ONE_DEPTH\n"
   "  aProjCoords.xy = aProjCoords.xy * 0.5 + vec2 (0.5);\n"
index df22227..feeed5b 100644 (file)
@@ -14,7 +14,7 @@ static const char Shaders_PhongDirectionalLight_glsl[] =
   "                          in bool theIsFront,\n"
   "                          in float theShadow)\n"
   "{\n"
-  "  vec3 aLight = vec3 (occWorldViewMatrix * vec4 (occLight_Position (theId), 0.0));\n"
+  "  vec3 aLight = occLight_Position (theId);\n"
   "  vec3 aHalf = normalize (aLight + theView);\n"
   "\n"
   "  vec3  aFaceSideNormal = theIsFront ? theNormal : -theNormal;\n"
index bccdfe6..9b48db3 100644 (file)
@@ -6,7 +6,7 @@ static const char Shaders_PhongPointLight_glsl[] =
   "//! @param theId      light source index\n"
   "//! @param theNormal  surface normal\n"
   "//! @param theView    view direction\n"
-  "//! @param thePoint   3D position (view space)\n"
+  "//! @param thePoint   3D position (world space)\n"
   "//! @param theIsFront front/back face flag\n"
   "void occPointLight (in int  theId,\n"
   "                    in vec3 theNormal,\n"
@@ -14,7 +14,7 @@ static const char Shaders_PhongPointLight_glsl[] =
   "                    in vec3 thePoint,\n"
   "                    in bool theIsFront)\n"
   "{\n"
-  "  vec3 aLight = vec3 (occWorldViewMatrix * vec4 (occLight_Position (theId), 1.0)) - thePoint;\n"
+  "  vec3 aLight = occLight_Position (theId) - thePoint;\n"
   "\n"
   "  float aDist = length (aLight);\n"
   "  float aRange = occLight_Range (theId);\n"
index d7f5e3e..0725975 100644 (file)
@@ -6,7 +6,7 @@ static const char Shaders_PhongSpotLight_glsl[] =
   "//! @param theId      light source index\n"
   "//! @param theNormal  surface normal\n"
   "//! @param theView    view direction\n"
-  "//! @param thePoint   3D position (view space)\n"
+  "//! @param thePoint   3D position (world space)\n"
   "//! @param theIsFront front/back face flag\n"
   "void occSpotLight (in int  theId,\n"
   "                   in vec3 theNormal,\n"
@@ -14,7 +14,7 @@ static const char Shaders_PhongSpotLight_glsl[] =
   "                   in vec3 thePoint,\n"
   "                   in bool theIsFront)\n"
   "{\n"
-  "  vec3 aLight = vec3 (occWorldViewMatrix * vec4 (occLight_Position (theId), 1.0)) - thePoint;\n"
+  "  vec3 aLight = occLight_Position (theId) - thePoint;\n"
   "\n"
   "  float aDist = length (aLight);\n"
   "  float aRange = occLight_Range (theId);\n"
@@ -22,8 +22,7 @@ static const char Shaders_PhongSpotLight_glsl[] =
   "  if (anAtten <= 0.0) return;\n"
   "  aLight /= aDist;\n"
   "\n"
-  "  vec3 aSpotDir = vec3 (occWorldViewMatrix * vec4 (occLight_SpotDirection (theId), 0.0));\n"
-  "  aSpotDir = normalize (aSpotDir);\n"
+  "  vec3 aSpotDir = occLight_SpotDirection (theId);\n"
   "  // light cone\n"
   "  float aCosA = dot (aSpotDir, -aLight);\n"
   "  if (aCosA >= 1.0 || aCosA < cos (occLight_SpotCutOff (theId)))\n"