0024323: TKOpenGl - spot light sources are not handled in Phong GLSL program
authorduv <duv@opencascade.com>
Wed, 12 Feb 2014 10:42:27 +0000 (14:42 +0400)
committerapn <apn@opencascade.com>
Thu, 13 Feb 2014 10:04:37 +0000 (14:04 +0400)
Limit number of lights (breaks compatibility with old hardware).

src/Shaders/PhongShading.fs
src/ViewerTest/ViewerTest_ViewerCommands.cxx

index af79124..0cb63e2 100755 (executable)
@@ -56,6 +56,57 @@ void pointLight (in int  theId,
   Specular += occLight_Specular (theId).rgb * aSpecl * anAtten;
 }
 
+//! Computes contribution of spotlight source
+void spotLight (in int  theId,
+                in vec3 theNormal,
+                in vec3 theView,
+                in vec3 thePoint)
+{
+  vec3 aLight   = occLight_Position      (theId).xyz;
+  vec3 aSpotDir = occLight_SpotDirection (theId).xyz;
+  if (occLight_IsHeadlight (theId) == 0)
+  {
+    aLight   = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aLight,   1.0));
+    aSpotDir = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aSpotDir, 0.0));
+  }
+  aLight -= thePoint;
+
+  float aDist = length (aLight);
+  aLight = aLight * (1.0 / aDist);
+
+  aSpotDir = normalize (aSpotDir);
+
+  // light cone
+  float aCosA = dot (aSpotDir, -aLight);
+  if (aCosA >= 1.0 || aCosA < cos (occLight_SpotCutOff (theId)))
+  {
+    return;
+  }
+
+  float anExponent = occLight_SpotExponent (theId);
+  float anAtten    = 1.0 / (occLight_ConstAttenuation  (theId)
+                          + occLight_LinearAttenuation (theId) * aDist);
+  if (anExponent > 0.0)
+  {
+    anAtten *= pow (aCosA, anExponent * 128.0);
+  }
+
+  vec3 aHalf = normalize (aLight + theView);
+
+  vec3  aFaceSideNormal = gl_FrontFacing ? theNormal : -theNormal;
+  float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));
+  float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));
+
+  float aSpecl = 0.0;
+  if (aNdotL > 0.0)
+  {
+    aSpecl = pow (aNdotH, gl_FrontFacing ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());
+  }
+
+  Diffuse  += occLight_Diffuse  (theId).rgb * aNdotL * anAtten;
+  Specular += occLight_Specular (theId).rgb * aSpecl * anAtten;
+}
+
 //! Computes contribution of directional light source
 void directionalLight (in int  theId,
                        in vec3 theNormal,
@@ -93,7 +144,7 @@ vec4 computeLighting (in vec3 theNormal,
   Diffuse  = vec3 (0.0);
   Specular = vec3 (0.0);
   vec3 aPoint = thePoint.xyz / thePoint.w;
-  for (int anIndex = 0; anIndex < THE_MAX_LIGHTS; ++anIndex)
+  for (int anIndex = 0; anIndex < occLightSourcesCount; ++anIndex)
   {
     int aType = occLight_Type (anIndex);
     if (aType == OccLightType_Direct)
@@ -106,7 +157,7 @@ vec4 computeLighting (in vec3 theNormal,
     }
     else if (aType == OccLightType_Spot)
     {
-      // Not implemented
+      spotLight (anIndex, theNormal, theView, aPoint);
     }
   }
 
index 405e23c..d4ced53 100644 (file)
@@ -6539,12 +6539,25 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     "vdefaults [absDefl=value] [devCoeff=value] [angDefl=value]",
     __FILE__, VDefaults, group);
   theCommands.Add("vlight",
-            "vlight [add|new {amb}ient|directional|{spot}light|positional]"
-    "\n\t\t:        [{def}aults] [clear]"
-    "\n\t\t:        [{del}ete|change lightId] [local|global]"
-    "\n\t\t:        [{pos}ition X Y Z] [color colorName] [{head}light 0|1]"
-    "\n\t\t:        [{constAtten}uation value] [{linearAtten}uation value]"
-    "\n\t\t:        [angle angleDeg] [{spotexp}onent value]",
+    "tool to manage light sources, without arguments shows list of lights."
+    "\n    Main commands: "
+    "\n      'clear' to clear lights"
+    "\n      '{def}aults' to load deafault lights"
+    "\n      'add' (or 'new') <type> to add any light source"
+    "\n          where <type> is one of {amb}ient|directional|{spot}light|positional"
+    "\n      'change' <lightId> to edit light source with specified lightId"
+    "\n\n      In addition to 'add' and 'change' commands you can use light parameters:"
+    "\n        {pos}ition X Y Z"
+    "\n        {dir}ection X Y Z (for directional light or for spotlight)"
+    "\n        color colorName"
+    "\n        {head}light 0|1"
+    "\n        {constAtten}uation value"
+    "\n        {linearAtten}uation value"
+    "\n        angle angleDeg"
+    "\n        {spotexp}onent value"
+    "\n        local|global"
+    "\n\n        example: vlight add positional head 1 pos 0 1 1 color red"
+    "\n        example: vlight change 0 direction 0 -1 0 linearAttenuation 0.2",
     __FILE__, VLight, group);
   theCommands.Add("vraytrace",
     "vraytrace 0|1",