diff --git a/Documentation/release/dev/fix-shadowmap-light.md b/Documentation/release/dev/fix-shadowmap-light.md
new file mode 100644
index 0000000000000000000000000000000000000000..e22d1d3d77878b465290c7f58cce2060e42fa43d
--- /dev/null
+++ b/Documentation/release/dev/fix-shadowmap-light.md
@@ -0,0 +1,9 @@
+## Fix light transforms when computing shadow maps
+
+The `vtkShadowMapBakerPass` computes shadow maps for each light by simulating a `vtkCamera` for each
+light and compositing the rendered images. However, an unintentional side-effect of this was that
+the original light's transforms were being affected by this. In other words, the lights would be
+corrupt after the shadow map computation. To circumvent this, we cache the light
+transforms prior to the shadow map computation and then reset them after.
+
+![](http://vtk.org/files/ExternalData/SHA512/9412ed54080c7a972d786a269538a3dbd56a5aa070f2b35ba448dfd3cca211e7e4b4d196e07c8ff2d56ff4bb7b0855e5584758c09457d3d6f3c760ee47a4dded)
diff --git a/Rendering/OpenGL2/Testing/Cxx/TestShadowMapBakerPass.cxx b/Rendering/OpenGL2/Testing/Cxx/TestShadowMapBakerPass.cxx
index 27c1f1a8b849287c0458ca049cdf697b5e6935ec..8c5dc323ab10c80f8780bab4c8cb2b4ebfe9af28 100644
--- a/Rendering/OpenGL2/Testing/Cxx/TestShadowMapBakerPass.cxx
+++ b/Rendering/OpenGL2/Testing/Cxx/TestShadowMapBakerPass.cxx
@@ -51,7 +51,6 @@ int TestShadowMapBakerPass(int argc, char* argv[])
   delete[] fileName;
 
   mapper->SetInputConnection(reader->GetOutputPort());
-  // mapper->SetInputConnection(norms->GetOutputPort());
   actor->SetMapper(mapper);
   actor->GetProperty()->SetAmbientColor(0.2, 0.2, 1.0);
   actor->GetProperty()->SetDiffuseColor(1.0, 0.65, 0.7);
diff --git a/Rendering/OpenGL2/Testing/Cxx/TestShadowMapPass.cxx b/Rendering/OpenGL2/Testing/Cxx/TestShadowMapPass.cxx
index 4c6d8d620fe475c553b43eb145d92babd26ee207..2b82e9a9c8d409d3c9f84c45306a0cf1274c454d 100644
--- a/Rendering/OpenGL2/Testing/Cxx/TestShadowMapPass.cxx
+++ b/Rendering/OpenGL2/Testing/Cxx/TestShadowMapPass.cxx
@@ -41,20 +41,29 @@ int TestShadowMapPass(int argc, char* argv[])
   vtkNew<vtkRenderWindowInteractor> iren;
   iren->SetRenderWindow(renderWindow);
 
+  // Add a couple of additional lights
   vtkNew<vtkLight> light1;
-  light1->SetFocalPoint(0, 0, 0);
+  light1->SetFocalPoint(1, 0, 1);
   light1->SetPosition(0, 1, 0.2);
   light1->SetColor(0.95, 0.97, 1.0);
   light1->SetIntensity(0.8);
   renderer->AddLight(light1);
 
   vtkNew<vtkLight> light2;
-  light2->SetFocalPoint(0, 0, 0);
-  light2->SetPosition(1.0, 1.0, 1.0);
+  light2->SetFocalPoint(0, 0, 1);
+  light2->SetPosition(0.2, 0.5, 0.5);
   light2->SetColor(1.0, 0.8, 0.7);
-  light2->SetIntensity(0.3);
+  light2->SetIntensity(0.5);
   renderer->AddLight(light2);
 
+  vtkNew<vtkLight> light3;
+  light3->SetFocalPoint(-0.1, -0.5, -0.5);
+  light3->SetPosition(0.2, 0.5, 0.5);
+  light3->SetColor(1.0, 0.8, 0.7);
+  light3->SetPositional(true);
+  light3->SetIntensity(0.3);
+  renderer->AddLight(light3);
+
   const char* fileName = vtkTestUtilities::ExpandDataFileName(argc, argv, "Data/dragon.ply");
   vtkNew<vtkPLYReader> reader;
   reader->SetFileName(fileName);
diff --git a/Rendering/OpenGL2/Testing/Data/Baseline/TestShadowMapBakerPass.png.sha512 b/Rendering/OpenGL2/Testing/Data/Baseline/TestShadowMapBakerPass.png.sha512
index 0767af628c04d84c37dd774f1bac3026c9bf22b7..bb16a9c29dff48e34f8f8051c310bece5cd06b9b 100644
--- a/Rendering/OpenGL2/Testing/Data/Baseline/TestShadowMapBakerPass.png.sha512
+++ b/Rendering/OpenGL2/Testing/Data/Baseline/TestShadowMapBakerPass.png.sha512
@@ -1 +1 @@
-8e1cdfe8edc9fbe88c027fca7521e8f6c2dadb16d9b3c99baef2b093bfb42fc3aa56e251f3d5b02ee66a67f5c86cf4e92a9b0901cfb4cbd9e58f04b7f5e1a333
+a33be4c89e9eb6a282ac4ed7b14d3cd9fa8b90f3e493937c1c022faddfa678a5efb466b48f0951a1f880325f0234cfbd99c0c1c64d4a410eb4e64c8888a9f29c
diff --git a/Rendering/OpenGL2/Testing/Data/Baseline/TestShadowMapPass.png.sha512 b/Rendering/OpenGL2/Testing/Data/Baseline/TestShadowMapPass.png.sha512
index 19128806d8104609b9d73cec0932b48e882f8e40..f83f09d5228a056f684cdfb26530e468a7ce70c4 100644
--- a/Rendering/OpenGL2/Testing/Data/Baseline/TestShadowMapPass.png.sha512
+++ b/Rendering/OpenGL2/Testing/Data/Baseline/TestShadowMapPass.png.sha512
@@ -1 +1 @@
-e9402f528869f5f3e6367b479e062aa1cfa63a781697f45fc89efd23cf6feb8a5e12a0b7ff1ebcd1b751515eca38945c710afc30ba225b847b3d7f851d270f06
+9412ed54080c7a972d786a269538a3dbd56a5aa070f2b35ba448dfd3cca211e7e4b4d196e07c8ff2d56ff4bb7b0855e5584758c09457d3d6f3c760ee47a4dded
diff --git a/Rendering/OpenGL2/vtkShadowMapBakerPass.cxx b/Rendering/OpenGL2/vtkShadowMapBakerPass.cxx
index 9ca97a4bd619c467fd427e86e8bc0c86f2b65eea..dfc4ec742e18ab2955e1d6a3b5a8a4229ad58676 100644
--- a/Rendering/OpenGL2/vtkShadowMapBakerPass.cxx
+++ b/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,29 @@ 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->GetSwitch() || !this->LightCreatesShadow(l) || 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 +488,19 @@ 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)
+          {
+            // Restore values without tweaking modified time.
+            vtkMatrix4x4::DeepCopy(*l->GetTransformMatrix()->Element, *cachedTransform->Element);
+          }
+          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)
           {