diff --git a/Rendering/Volume/Testing/Cxx/CMakeLists.txt b/Rendering/Volume/Testing/Cxx/CMakeLists.txt
index 3c88141d519263fafc229593a17ee385ca6af32d..7f73a557fb74fd8bbba4fd4789a9bea9c12eeba3 100644
--- a/Rendering/Volume/Testing/Cxx/CMakeLists.txt
+++ b/Rendering/Volume/Testing/Cxx/CMakeLists.txt
@@ -60,9 +60,12 @@ set (VolumeOpenGL2CxxTests
   TestGPURayCastClipping.cxx
   TestGPURayCastClippingPolyData.cxx
   TestGPURayCastClippingUserTransform.cxx
+  TestGPURayCastDependentComponentsLightParameters.cxx
   TestGPURayCastFourComponentsDependentGradient.cxx
   TestGPURayCastGradientOpacity.cxx
   TestGPURayCastGradientOpacityLight.cxx
+  TestGPURayCastIndependentComponentsLightParameters.cxx
+  TestGPURayCastLargeColorTransferFunction.cxx
   TestGPURayCastPositionalLights.cxx
   TestGPURayCastReleaseResources.cxx
   TestGPURayCastRenderDepthToImage.cxx
@@ -79,10 +82,9 @@ set (VolumeOpenGL2CxxTests
   TestGPURayCastVolumePolyData.cxx
   TestGPURayCastVolumeRotation.cxx
   TestGPURayCastVolumeScale.cxx
-  TestProjectedTetrahedraTransform.cxx
   TestProjectedTetrahedraOffscreen.cxx
+  TestProjectedTetrahedraTransform.cxx
   TestRemoveVolumeNonCurrentContext.cxx
-  TestGPURayCastLargeColorTransferFunction.cxx
   )
 
 # everyone gets these tests
diff --git a/Rendering/Volume/Testing/Cxx/TestGPURayCastDependentComponentsLightParameters.cxx b/Rendering/Volume/Testing/Cxx/TestGPURayCastDependentComponentsLightParameters.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..bf4cdd53e657ec67902e562da9139cc80fed034a
--- /dev/null
+++ b/Rendering/Volume/Testing/Cxx/TestGPURayCastDependentComponentsLightParameters.cxx
@@ -0,0 +1,120 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    TestGPURayCastDependentComponentsLightParameters.cxx
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+// This test volume renders the vase dataset with 4 dependent components the
+// composite method with shading and light parameters.
+
+#include "vtkGPUVolumeRayCastMapper.h"
+#include "vtkTestUtilities.h"
+#include "vtkXMLImageDataReader.h"
+#include "vtkImageShiftScale.h"
+#include "vtkColorTransferFunction.h"
+#include "vtkPiecewiseFunction.h"
+#include "vtkTransform.h"
+#include "vtkRenderer.h"
+#include "vtkRenderWindow.h"
+#include "vtkRenderWindowInteractor.h"
+#include "vtkVolumeProperty.h"
+#include "vtkCamera.h"
+#include "vtkRegressionTestImage.h"
+
+int TestGPURayCastDependentComponentsLightParameters(int argc,
+                                                     char *argv[])
+{
+  cout << "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)" << endl;
+  char *cfname=
+    vtkTestUtilities::ExpandDataFileName(argc, argv, "Data/vase_4comp.vti");
+
+  vtkXMLImageDataReader *reader=vtkXMLImageDataReader::New();
+  reader->SetFileName(cfname);
+  delete [] cfname;
+
+  vtkRenderer *ren1=vtkRenderer::New();
+  vtkRenderWindow *renWin=vtkRenderWindow::New();
+  renWin->AddRenderer(ren1);
+  renWin->SetSize(301,300);
+  vtkRenderWindowInteractor *iren=vtkRenderWindowInteractor::New();
+  iren->SetRenderWindow(renWin);
+
+  renWin->Render();
+
+  vtkGPUVolumeRayCastMapper *volumeMapper;
+  vtkVolumeProperty *volumeProperty;
+  vtkVolume *volume;
+
+  volumeMapper=vtkGPUVolumeRayCastMapper::New();
+  volumeMapper->SetBlendModeToComposite();
+  volumeMapper->SetInputConnection(
+    reader->GetOutputPort());
+
+  vtkPiecewiseFunction *opacity=vtkPiecewiseFunction::New();
+  opacity->AddPoint(0,0);
+  opacity->AddPoint(255,1);
+
+  volumeProperty=vtkVolumeProperty::New();
+  volumeProperty->IndependentComponentsOff();
+  volumeProperty->ShadeOn();
+  volumeProperty->SetScalarOpacity(opacity);
+  volumeProperty->SetAmbient(0.1);
+  volumeProperty->SetDiffuse(0.9);
+  volumeProperty->SetSpecular(0.4);
+  volumeProperty->SetSpecularPower(10.0);
+
+  volume=vtkVolume::New();
+  volume->SetMapper(volumeMapper);
+  volume->SetProperty(volumeProperty);
+  ren1->AddViewProp(volume);
+
+  int valid=volumeMapper->IsRenderSupported(renWin,volumeProperty);
+
+  int retVal;
+  if(valid)
+    {
+    iren->Initialize();
+    ren1->SetBackground(0.1,0.4,0.2);
+    ren1->ResetCamera();
+    renWin->Render();
+    retVal = vtkTesting::Test(argc, argv, renWin, 75);
+    if (retVal == vtkRegressionTester::DO_INTERACTOR)
+      {
+      iren->Start();
+      }
+    }
+  else
+    {
+    retVal=vtkTesting::PASSED;
+    cout << "Required extensions not supported." << endl;
+    }
+
+  iren->Delete();
+  renWin->Delete();
+  ren1->Delete();
+  volumeMapper->Delete();
+  volumeProperty->Delete();
+  volume->Delete();
+
+  opacity->Delete();
+
+  reader->Delete();
+
+  if ((retVal == vtkTesting::PASSED) || (retVal == vtkTesting::DO_INTERACTOR))
+    {
+    return 0;
+    }
+  else
+    {
+    return 1;
+    }
+}
diff --git a/Rendering/Volume/Testing/Cxx/TestGPURayCastIndependentComponentsLightParameters.cxx b/Rendering/Volume/Testing/Cxx/TestGPURayCastIndependentComponentsLightParameters.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..2db6b008e1152d767d09cca9ef8032a91a95a774
--- /dev/null
+++ b/Rendering/Volume/Testing/Cxx/TestGPURayCastIndependentComponentsLightParameters.cxx
@@ -0,0 +1,209 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    TestGPURayCastIndependentComponentsLightParameters.cxx
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+// Description
+// This test creates a vtkImageData with three components.
+// The data is volume rendered considering the three components as independent
+// with shading and complex light parameters.
+
+#include "vtkCamera.h"
+#include "vtkColorTransferFunction.h"
+#include "vtkGPUVolumeRayCastMapper.h"
+#include "vtkImageData.h"
+#include "vtkInteractorStyleTrackballCamera.h"
+#include "vtkNew.h"
+#include "vtkPiecewiseFunction.h"
+#include "vtkRegressionTestImage.h"
+#include "vtkRenderWindow.h"
+#include "vtkRenderWindowInteractor.h"
+#include "vtkRenderer.h"
+#include "vtkSphere.h"
+#include "vtkVolume.h"
+#include "vtkVolumeProperty.h"
+
+int TestGPURayCastIndependentComponentsLightParameters(int argc, char *argv[])
+{
+  cout << "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)" << endl;
+
+  int dims[3] = {100, 100, 100};
+
+  // Create a vtkImageData with two components
+  vtkNew<vtkImageData> image;
+  image->SetDimensions(dims[0], dims[1], dims[2]);
+  image->AllocateScalars(VTK_DOUBLE, 3);
+
+  // Fill the first half rectangular parallelopiped along X with the
+  // first component values and the second half with second component values
+  double * ptr = static_cast<double *> (image->GetScalarPointer(0, 0, 0));
+
+  double center1[3], center2[3], center3[3];
+  center1[0] = dims[0]/3; center2[0] = center1[0]*2; center3[0] = dims[0]/2;
+  center1[1] = center2[1] = dims[1]/2; center3[1] = dims[1]/3;
+  center1[2] = center2[2] = center3[2] = dims[2]/2;
+
+  double radius;
+  radius = center1[0];
+
+  vtkNew<vtkSphere> sphere1;
+  sphere1->SetCenter(center1);
+  sphere1->SetRadius(radius);
+  vtkNew<vtkSphere> sphere2;
+  sphere2->SetCenter(center2);
+  sphere2->SetRadius(radius);
+  vtkNew<vtkSphere> sphere3;
+  sphere3->SetCenter(center3);
+  sphere3->SetRadius(radius);
+
+  for (int z = 0; z < dims[2]; ++z)
+    {
+    for (int y = 0; y < dims[1]; ++y)
+      {
+      for (int x = 0; x < dims[0]; ++x)
+        {
+        // Set first component
+        if (sphere1->EvaluateFunction(x, y, z) > 0)
+          {
+          // point outside sphere 1
+          *ptr++ = 0.0;
+          }
+        else
+          {
+          *ptr++ = 0.33;
+          }
+        // Set second component
+        if (sphere2->EvaluateFunction(x, y, z) > 0)
+          {
+          // point outside sphere 2
+          *ptr++ = 0.0;
+          }
+        else
+          {
+          *ptr++ = 0.33;
+          }
+        // Set third component
+        if (sphere3->EvaluateFunction(x, y, z) > 0)
+          {
+          // point outside sphere 2
+          *ptr++ = 0.0;
+          }
+        else
+          {
+          *ptr++ = 0.33;
+          }
+        }
+      }
+    }
+
+  vtkNew<vtkRenderWindow> renWin;
+  renWin->SetSize(301, 300); // Intentional NPOT size
+  renWin->SetMultiSamples(0);
+
+  vtkNew<vtkRenderer> ren;
+  renWin->AddRenderer(ren.GetPointer());
+
+  vtkNew<vtkRenderWindowInteractor> iren;
+  vtkNew<vtkInteractorStyleTrackballCamera> style;
+  iren->SetInteractorStyle(style.GetPointer());
+  iren->SetRenderWindow(renWin.GetPointer());
+
+  renWin->Render();
+
+  // Volume render the dataset
+  vtkNew<vtkGPUVolumeRayCastMapper> mapper;
+  mapper->AutoAdjustSampleDistancesOff();
+  mapper->SetSampleDistance(0.9);
+  mapper->SetInputData(image.GetPointer());
+
+  // Color transfer function
+  vtkNew<vtkColorTransferFunction> ctf1;
+  ctf1->AddRGBPoint(0.0, 0.0, 0.0, 0.0);
+  ctf1->AddRGBPoint(1.0, 0.0, 1.0, 0.0);
+
+  vtkNew<vtkColorTransferFunction> ctf2;
+  ctf2->AddRGBPoint(0.0, 0.0, 0.0, 0.0);
+  ctf2->AddRGBPoint(1.0, 0.0, 1.0, 0.0);
+
+  vtkNew<vtkColorTransferFunction> ctf3;
+  ctf3->AddRGBPoint(0.0, 0.0, 0.0, 0.0);
+  ctf3->AddRGBPoint(1.0, 0.0, 1.0, 0.0);
+
+  // Opacity functions
+  vtkNew<vtkPiecewiseFunction> pf1;
+  pf1->AddPoint(0.0, 0.0);
+  pf1->AddPoint(1.0, 0.2);
+
+  vtkNew<vtkPiecewiseFunction> pf2;
+  pf2->AddPoint(0.0, 0.0);
+  pf2->AddPoint(1.0, 0.2);
+
+  vtkNew<vtkPiecewiseFunction> pf3;
+  pf3->AddPoint(0.0, 0.0);
+  pf3->AddPoint(1.0, 0.2);
+
+  // Volume property with independent components ON
+  vtkNew<vtkVolumeProperty> property;
+  property->IndependentComponentsOn();
+
+  // Set color and opacity functions
+  property->SetColor(0, ctf1.GetPointer());
+  property->SetColor(1, ctf2.GetPointer());
+  property->SetColor(2, ctf3.GetPointer());
+  property->SetScalarOpacity(0, pf1.GetPointer());
+  property->SetScalarOpacity(1, pf2.GetPointer());
+  property->SetScalarOpacity(2, pf3.GetPointer());
+
+  // Define light parameters
+  property->ShadeOn();
+
+  property->SetAmbient(0, 0.2);
+  property->SetDiffuse(0, 0.9);
+  property->SetSpecular(0, 0.4);
+  property->SetSpecularPower(0, 10.0);
+  property->SetAmbient(1, 0.5);
+  property->SetDiffuse(1, 0.3);
+  property->SetSpecular(1, 0.1);
+  property->SetSpecularPower(1, 1.0);
+  property->SetAmbient(2, 0.7);
+  property->SetDiffuse(2, 0.9);
+  property->SetSpecular(2, 0.4);
+  property->SetSpecularPower(2, 10.0);
+
+  vtkNew<vtkVolume> volume;
+  volume->SetMapper(mapper.GetPointer());
+  volume->SetProperty(property.GetPointer());
+  ren->AddVolume(volume.GetPointer());
+
+  ren->ResetCamera();
+
+  iren->Initialize();
+  renWin->Render();
+
+  ren->GetActiveCamera()->Zoom(1.5);
+
+  int retVal = vtkTesting::Test(argc, argv, renWin.GetPointer(), 15);
+  if (retVal == vtkRegressionTester::DO_INTERACTOR)
+    {
+    iren->Start();
+    }
+
+  if ((retVal == vtkTesting::PASSED) || (retVal == vtkTesting::DO_INTERACTOR))
+    {
+    return EXIT_SUCCESS;
+    }
+  else
+    {
+    return EXIT_FAILURE;
+    }
+}
diff --git a/Rendering/Volume/Testing/Data/Baseline/TestGPURayCastDependentComponentsLightParameters.png.md5 b/Rendering/Volume/Testing/Data/Baseline/TestGPURayCastDependentComponentsLightParameters.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..97eb0a544f8eb344d3eb70e8516216812ee0bbe3
--- /dev/null
+++ b/Rendering/Volume/Testing/Data/Baseline/TestGPURayCastDependentComponentsLightParameters.png.md5
@@ -0,0 +1 @@
+fe619da74c050bd7dfa273a6de98655b
diff --git a/Rendering/Volume/Testing/Data/Baseline/TestGPURayCastIndependentComponentsLightParameters.png.md5 b/Rendering/Volume/Testing/Data/Baseline/TestGPURayCastIndependentComponentsLightParameters.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..abaf38bad994cc082ab99d347fe511126bf29d1f
--- /dev/null
+++ b/Rendering/Volume/Testing/Data/Baseline/TestGPURayCastIndependentComponentsLightParameters.png.md5
@@ -0,0 +1 @@
+64475ab80f03db3b202edac5c492a421
diff --git a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx
index 798b925c164caf72b82c7dbdf0470b9dfed239ce..d9d4684c1d1014fd048daa92d5c4309ac24901a2 100644
--- a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx
+++ b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx
@@ -3012,23 +3012,23 @@ void vtkOpenGLGPUVolumeRayCastMapper::BuildShader(vtkRenderer* ren,
   if (this->Impl->CurrentSelectionPass != (vtkHardwareSelector::MIN_KNOWN_PASS - 1))
     {
     switch(this->Impl->CurrentSelectionPass)
-    {
-    case vtkHardwareSelector::ID_LOW24:
-      fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Picking::Exit",
-        vtkvolume::PickingIdLow24PassExit(ren, this, vol), true);
-      break;
-    case vtkHardwareSelector::ID_MID24:
-      fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Picking::Exit",
-        vtkvolume::PickingIdMid24PassExit(ren, this, vol), true);
-      break;
-    default: // ACTOR_PASS, PROCESS_PASS
-      fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Picking::Dec",
-        vtkvolume::PickingActorPassDeclaration(ren, this, vol), true);
+      {
+      case vtkHardwareSelector::ID_LOW24:
+        fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Picking::Exit",
+          vtkvolume::PickingIdLow24PassExit(ren, this, vol), true);
+        break;
+      case vtkHardwareSelector::ID_MID24:
+        fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Picking::Exit",
+          vtkvolume::PickingIdMid24PassExit(ren, this, vol), true);
+        break;
+      default: // ACTOR_PASS, PROCESS_PASS
+        fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Picking::Dec",
+          vtkvolume::PickingActorPassDeclaration(ren, this, vol), true);
 
-      fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Picking::Exit",
-        vtkvolume::PickingActorPassExit(ren, this, vol), true);
-      break;
-    }
+        fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Picking::Exit",
+          vtkvolume::PickingActorPassExit(ren, this, vol), true);
+        break;
+      }
     }
 
   // Render to texture
@@ -3576,17 +3576,26 @@ void vtkOpenGLGPUVolumeRayCastMapper::DoGPURender(vtkRenderer* ren,
   //--------------------------------------------------------------------------
   this->Impl->SetLightingParameters(ren, prog, vol);
 
-  fvalue3[0] = fvalue3[1] = fvalue3[2] = volumeProperty->GetAmbient();
-  prog->SetUniform3f("in_ambient", fvalue3);
-
-  fvalue3[0] = fvalue3[1] = fvalue3[2] = volumeProperty->GetDiffuse();
-  prog->SetUniform3f("in_diffuse", fvalue3);
+  float ambient[4][3];
+  float diffuse[4][3];
+  float specular[4][3];
+  float specularPower[4];
 
-  fvalue3[0] = fvalue3[1] = fvalue3[2] = volumeProperty->GetSpecular();
-  prog->SetUniform3f("in_specular", fvalue3);
+  for (int i = 0; i < numberOfSamplers; ++i)
+    {
+    ambient[i][0] = ambient[i][1] = ambient[i][2] =
+      volumeProperty->GetAmbient(i);
+    diffuse[i][0] = diffuse[i][1] = diffuse[i][2] =
+      volumeProperty->GetDiffuse(i);
+    specular[i][0] = specular[i][1] = specular[i][2] =
+      volumeProperty->GetSpecular(i);
+    specularPower[i] = volumeProperty->GetSpecularPower(i);
+    }
 
-  fvalue3[0] = volumeProperty->GetSpecularPower();
-  prog->SetUniformf("in_shininess", fvalue3[0]);
+  prog->SetUniform3fv("in_ambient", numberOfSamplers, ambient);
+  prog->SetUniform3fv("in_diffuse", numberOfSamplers, diffuse);
+  prog->SetUniform3fv("in_specular", numberOfSamplers, specular);
+  prog->SetUniform1fv("in_shininess", numberOfSamplers, specularPower);
 
   double clippingRange[2];
   cam->GetClippingRange(clippingRange);
diff --git a/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h b/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h
index 4b3db072bee0741a3a1ee5fa4f2e8c9bf57f4da1..f493876e883e7b3bae1400feaa836d44dde1e5a8 100644
--- a/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h
+++ b/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h
@@ -180,10 +180,10 @@ namespace vtkvolume
       \nuniform vec3 in_textureExtentsMin;\
       \n\
       \n// Material and lighting\
-      \nuniform vec3 in_diffuse;\
-      \nuniform vec3 in_ambient;\
-      \nuniform vec3 in_specular;\
-      \nuniform float in_shininess;\
+      \nuniform vec3 in_diffuse[4];\
+      \nuniform vec3 in_ambient[4];\
+      \nuniform vec3 in_specular[4];\
+      \nuniform float in_shininess[4];\
       \n\
       \n// Others\
       \nuniform bool in_cellFlag;\
@@ -616,14 +616,16 @@ namespace vtkvolume
           \n     }\
           \n   if (nDotL > 0.0)\
           \n     {\
-          \n     diffuse = nDotL * in_diffuse * in_lightDiffuseColor[0]\
-          \n                 * color.rgb;\
+          \n     diffuse = nDotL * in_diffuse[component] *\
+          \n               in_lightDiffuseColor[0] * color.rgb;\
           \n     }\
-          \n    specular = pow(nDotH, in_shininess) * in_specular *\
+          \n    specular = pow(nDotH, in_shininess[component]) *\
+          \n                 in_specular[component] *\
           \n                 in_lightSpecularColor[0];\
           \n  // For the headlight, ignore the light's ambient color\
           \n  // for now as it is causing the old mapper tests to fail\
-          \n  finalColor.xyz = in_ambient * color.rgb + diffuse + specular;"
+          \n  finalColor.xyz = in_ambient[component] * color.rgb +\
+          \n                   diffuse + specular;"
           );
         }
       else if (lightingComplexity == 2)
@@ -669,13 +671,14 @@ namespace vtkvolume
           \n    }\
           \n  if (nDotH > 0.0)\
           \n    {\
-          \n    specular = in_lightSpecularColor[lightNum] * pow(nDotH, in_shininess);\
+          \n    specular = in_lightSpecularColor[lightNum] *\
+          \n               pow(nDotH, in_shininess[component]);\
           \n    }\
           \n  ambient += in_lightAmbientColor[lightNum];\
           \n  }\
-          \n  finalColor.xyz = in_ambient * ambient +\
-          \n                   in_diffuse * diffuse * color.rgb +\
-          \n                   in_specular * specular;"
+          \n  finalColor.xyz = in_ambient[component] * ambient +\
+          \n                   in_diffuse[component] * diffuse * color.rgb +\
+          \n                   in_specular[component] * specular;"
           );
         }
       else if (lightingComplexity == 3)
@@ -746,13 +749,14 @@ namespace vtkvolume
           \n    }\
           \n  if (nDotH > 0.0)\
           \n    {\
-          \n    float sf = attenuation * pow(nDotH, in_shininess);\
+          \n    float sf = attenuation * pow(nDotH, in_shininess[component]);\
           \n    specular += (sf * in_lightSpecularColor[lightNum]);\
           \n    }\
           \n    ambient += in_lightAmbientColor[lightNum];\
           \n  }\
-          \n  finalColor.xyz = in_ambient * ambient + in_diffuse *\
-          \n                   diffuse * color.rgb + in_specular * specular;\
+          \n  finalColor.xyz = in_ambient[component] * ambient +\
+          \n                   in_diffuse[component] * diffuse * color.rgb +\
+          \n                   in_specular[component] * specular;\
         ");
         }
       }