Shadows and shadows with PBR materials have problems. This attempts to address
them.

1. The PBR illumination model didn't account for *non*-positional lights. It
   would always compute the direction to the light from fragment to light
   *position*. But non-positional lights don't have a position to speak of.
   Instead, it should simply be the negative of the light direction; that is the
   definition of the direction to the light source for directional lights.
2. The fragment shader has text search-and-replace games in two locations:
   vtkOpenGLPolyDataMapper and vtkShadowMapPass. The former introduces the
   lighting calculations to define "radiance", the latter updates the "radiance"
   definition to account for shadows. This update depends on the shadow map
   pass knowing what strings the data mapper uses. In this case, the strings
   that vtkShadowMapPass was expecting didn't cover all of the strings produced
   by vtkOpenGLPolyDataMapper. The latter has been updated.
3. VTK Uses exponential shadow maps (ESM). That algorithm has a particular tuning
   constant. Ideally, the constant would be infinity (so that the approximation
   of a step function is perfect). Finite numerical precision makes that
   impossible. However, it should be as large a number as possible before
   numerical precision issues kick in. The authors of ESM recommend 80; VTK
   used 11 (leading to bizarre shadow behaviors where shadows were being
   strongly attenuated based on increased distance from the light).
4. vtkShadowMapBakerPass does one rendering pass for each light to create a
   shadow map. Indirectly, this causes the light transform for each light to
   change, based on the camera associated with the light currently being
   rendered. For a light defined in the camera space, this would corrupt its
   transform matrix. When it comes time to render the shadow for that light,
   we'd have the wrong transform and we'd produce the wrong camera pose. Now,
   the shadow map baker caches the initial light transforms and resets the
   light's transform before creating its corresponding camera.

These changes should be upstreamed to VTK.

diff --git Rendering/OpenGL2/vtkOpenGLPolyDataMapper.cxx Rendering/OpenGL2/vtkOpenGLPolyDataMapper.cxx
index 94f2a7f20f..5ec85bf6ec 100644
--- Rendering/OpenGL2/vtkOpenGLPolyDataMapper.cxx
+++ Rendering/OpenGL2/vtkOpenGLPolyDataMapper.cxx
@@ -1245,46 +1245,23 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight(
       {
         for (int i = 0; i < lastLightCount; ++i)
         {
-          toString << "  L = lightPositionVC" << i
-                   << " - vertexVC.xyz;\n"
-                      "  distanceVC = length(L);\n"
-                      "  L = normalize(L);\n"
-                      "  H = normalize(V + L);\n"
-                      "  NdL = clamp(dot(N, L), 1e-5, 1.0);\n"
-                      "  NdH = clamp(dot(N, H), 1e-5, 1.0);\n"
-                      "  HdL = clamp(dot(H, L), 1e-5, 1.0);\n"
-                      "  if (lightPositional"
-                   << i
-                   << " == 0)\n"
-                      "  {\n"
+          toString << "  if (lightPositional" << i << " == 0) {\n"
                       "    attenuation = 1.0;\n"
-                      "  }\n"
-                      "  else\n"
-                      "  {\n"
-                      "    attenuation = 1.0 / (lightAttenuation"
-                   << i
-                   << ".x\n"
-                      "      + lightAttenuation"
-                   << i
-                   << ".y * distanceVC\n"
-                      "      + lightAttenuation"
-                   << i
-                   << ".z * distanceVC * distanceVC);\n"
+                      "    L = -lightDirectionVC" << i << ";\n"
+                      "  } else {\n"
+                      "    L = lightPositionVC" << i << " - vertexVC.xyz;\n"
+                      "    distanceVC = length(L);\n"
+                      "    L = normalize(L);\n"
+                      "    attenuation = 1.0 / (lightAttenuation" << i << ".x\n"
+                      "      + lightAttenuation" << i << ".y * distanceVC\n"
+                      "      + lightAttenuation" << i << ".z * distanceVC * distanceVC);\n"
                       "    // cone angle is less than 90 for a spot light\n"
-                      "    if (lightConeAngle"
-                   << i
-                   << " < 90.0) {\n"
-                      "      float coneDot = dot(-L, lightDirectionVC"
-                   << i
-                   << ");\n"
+                      "    if (lightConeAngle" << i << " < 90.0) {\n"
+                      "      float coneDot = dot(-L, lightDirectionVC" << i << ");\n"
                       "      // if inside the cone\n"
-                      "      if (coneDot >= cos(radians(lightConeAngle"
-                   << i
-                   << ")))\n"
+                      "      if (coneDot >= cos(radians(lightConeAngle" << i << ")))\n"
                       "      {\n"
-                      "        attenuation = attenuation * pow(coneDot, lightExponent"
-                   << i
-                   << ");\n"
+                      "        attenuation = attenuation * pow(coneDot, lightExponent" << i << ");\n"
                       "      }\n"
                       "      else\n"
                       "      {\n"
@@ -1292,8 +1269,14 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight(
                       "      }\n"
                       "    }\n"
                       "  }\n"
-                      "  radiance = lightColor"
-                   << i << " * attenuation;\n";
+                      "  H = normalize(V + L);\n"
+                      "  NdL = clamp(dot(N, L), 1e-5, 1.0);\n"
+                      "  NdH = clamp(dot(N, H), 1e-5, 1.0);\n"
+                      "  HdL = clamp(dot(H, L), 1e-5, 1.0);\n"
+                      // Don't change this definition of radiance; vtkShadowMapPass
+                      // uses it to inject shadows.
+                      "  radiance = lightColor" << i << ";\n"
+                      "  radiance *= attenuation;\n";
 
           if (hasAnisotropy)
           {
diff --git Rendering/OpenGL2/vtkShadowMapBakerPass.cxx Rendering/OpenGL2/vtkShadowMapBakerPass.cxx
index e557044f37..5d218b7a9c 100644
--- Rendering/OpenGL2/vtkShadowMapBakerPass.cxx
+++ Rendering/OpenGL2/vtkShadowMapBakerPass.cxx
@@ -10,6 +10,7 @@
 #include "vtkLightCollection.h"
 #include "vtkLightsPass.h"
 #include "vtkMath.h"
+#include "vtkMatrix4x4.h"
 #include "vtkNew.h"
 #include "vtkObjectFactory.h"
 #include "vtkOpaquePass.h"
@@ -453,6 +454,25 @@ void vtkShadowMapBakerPass::Render(const vtkRenderState* s)
         first = false;
       }
 
+      // Rendering a map for each light requires creating a camera from that
+      // light's perspective and doing an opaque rendering pass. That opaque
+      // rendering pass, in turn, updates the light transforms relative to that
+      // particular light camera. When it comes time to create a camera for
+      // a subsequent light, we need to restore it to its original light
+      // transform. We cache them here so we can restore them later.
+      std::map<vtkLight*, vtkSmartPointer<vtkMatrix4x4>> cachedLightTransforms;
+      lights->InitTraversal();
+      l = lights->GetNextItem();
+      while (l != nullptr) {
+        if (l->GetTransformMatrix() == nullptr) {
+          cachedLightTransforms[l] = nullptr;
+        } else {
+          cachedLightTransforms[l] = vtkNew<vtkMatrix4x4>();
+          cachedLightTransforms[l]->DeepCopy(l->GetTransformMatrix());
+        }
+        l = lights->GetNextItem();
+      }
+
       lights->InitTraversal();
       l = lights->GetNextItem();
       this->CurrentLightIndex = 0;
@@ -464,6 +484,17 @@ void vtkShadowMapBakerPass::Render(const vtkRenderState* s)
       {
         if (l->GetSwitch() && this->LightCreatesShadow(l))
         {
+          {
+            // Restore the light's original matrix.
+            vtkMatrix4x4* cachedTransform = cachedLightTransforms.at(l);
+            if (cachedTransform != nullptr) {
+              l->GetTransformMatrix()->DeepCopy(cachedTransform);
+            } else {
+              // This may be redundant; it is unlikely if the light didn't
+              // originally have a transform that it would pick one up.
+              l->SetTransformMatrix(nullptr);
+            }
+          }
           vtkTextureObject* map = (*this->ShadowMaps)[this->CurrentLightIndex];
           if (map == nullptr)
           {
@@ -558,7 +589,7 @@ bool vtkShadowMapBakerPass::SetShaderParameters(vtkShaderProgram* program, vtkAb
   vtkCamera* lightCamera = (*this->LightCameras)[this->CurrentLightIndex];
   double* crange = lightCamera->GetClippingRange();
 
-  program->SetUniformf("depthC", 11.0);
+  program->SetUniformf("depthC", ExponentialConstant);
   program->SetUniformf("nearZ", crange[0]);
   program->SetUniformf("farZ", crange[1]);
 
diff --git Rendering/OpenGL2/vtkShadowMapBakerPass.h Rendering/OpenGL2/vtkShadowMapBakerPass.h
index db13f455d8..14528326c7 100644
--- Rendering/OpenGL2/vtkShadowMapBakerPass.h
+++ Rendering/OpenGL2/vtkShadowMapBakerPass.h
@@ -94,6 +94,21 @@ public:
   vtkGetMacro(Resolution, unsigned int);
   ///@}
 
+  ///@{
+  /**
+   * Set/Get the exponential constant for the Exponential Shadow Maps. The
+   * default value is the value recommended by the authors of the Exponential
+   * Shadow Map paper: 80. This represents the maximum practical value for
+   * 32-bit floating point precision in the shadow map. Values that are too
+   * small will lead to "light leaking" (where shadows get attenuated away from
+   * the light source). Larger values will cause shadows near the light to
+   * disappear.
+   */
+  vtkSetMacro(ExponentialConstant, float);
+  vtkGetMacro(ExponentialConstant, float);
+  ///@}
+  
+
   /**
    * INTERNAL USE ONLY.
    * Internally used by vtkShadowMapBakerPass and vtkShadowMapPass.
@@ -200,6 +215,7 @@ protected:
   vtkRenderPass* CompositeZPass;
 
   unsigned int Resolution;
+  float ExponentialConstant{80.0f};
 
   bool HasShadows;
 
diff --git Rendering/OpenGL2/vtkShadowMapPass.cxx Rendering/OpenGL2/vtkShadowMapPass.cxx
index 1381cf3afa..1f04f3bf23 100644
--- Rendering/OpenGL2/vtkShadowMapPass.cxx
+++ Rendering/OpenGL2/vtkShadowMapPass.cxx
@@ -264,7 +264,8 @@ bool vtkShadowMapPass::SetShaderParameters(vtkShaderProgram* program, vtkAbstrac
   float transform[16];
   std::ostringstream toString;
 
-  program->SetUniformf("depthC", 11.0);
+  // We have to use the same exponential constant that was used when baking.
+  program->SetUniformf("depthC", this->ShadowMapBakerPass->GetExponentialConstant());
   for (size_t i = 0; i < numLights; i++)
   {
     if (this->ShadowTextureUnits[i] >= 0)
