Commit c1024e32 authored by François Bertel's avatar François Bertel
Browse files

BUG:Make some volume mappers aware of light source components.

parent 519be1b0
......@@ -13,7 +13,7 @@ IF (VTK_USE_RENDERING AND VTK_USE_DISPLAY)
PreIntegrationNonIncremental.cxx
ProjectedTetrahedraZoomIn.cxx
TestFinalColorWindowLevel.cxx
# TestFixedPointRayCastLightComponents.cxx
TestFixedPointRayCastLightComponents.cxx
TestGPURayCastAdditive.cxx
TestGPURayCastCompositeMaskBlend.cxx
TestGPURayCastCompositeMask.cxx
......@@ -34,6 +34,7 @@ IF (VTK_USE_RENDERING AND VTK_USE_DISPLAY)
TestProjectedTetrahedra.cxx
TestSmartVolumeMapper.cxx
TestSmartVolumeMapperWindowLevel.cxx
TestTM3DLightComponents.cxx
volProt.cxx
ZsweepConcavities.cxx
)
......
/*=========================================================================
Program: Visualization Toolkit
Module: TestGPURayCastMIPToComposite.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 covers vtkFixedPointVolumeRayCastMapper with a light where
// diffuse and specular components are different.
// This test volume renders a synthetic dataset with unsigned char values,
// with the composite method. The diffuse light component is gray, the
// light specular component is blue.
#include "vtkSphere.h"
#include "vtkSampleFunction.h"
#include "vtkTestUtilities.h"
#include "vtkColorTransferFunction.h"
#include "vtkPiecewiseFunction.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkVolumeProperty.h"
#include "vtkCamera.h"
#include "vtkRegressionTestImage.h"
#include "vtkImageShiftScale.h"
#include "vtkImageData.h"
#include "vtkPointData.h"
#include "vtkDataArray.h"
#include "vtkLight.h"
#include "vtkLightCollection.h"
#include <cassert>
#include "vtkFixedPointVolumeRayCastMapper.h"
int TestFixedPointRayCastLightComponents(int argc,
char *argv[])
{
cout << "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)" << endl;
// Create a spherical implicit function.
vtkSphere *shape=vtkSphere::New();
shape->SetRadius(0.1);
shape->SetCenter(0.0,0.0,0.0);
vtkSampleFunction *source=vtkSampleFunction::New();
source->SetImplicitFunction(shape);
shape->Delete();
source->SetOutputScalarTypeToDouble();
source->SetSampleDimensions(127,127,127); // intentional NPOT dimensions.
source->SetModelBounds(-100.0,100.0,-100.0,100.0,-100.0,100.0);
source->SetCapping(false);
source->SetComputeNormals(false);
source->SetScalarArrayName("values");
source->Update();
vtkDataArray *a=source->GetOutput()->GetPointData()->GetScalars("values");
double range[2];
a->GetRange(range);
vtkImageShiftScale *t=vtkImageShiftScale::New();
t->SetInputConnection(source->GetOutputPort());
source->Delete();
t->SetShift(-range[0]);
double magnitude=range[1]-range[0];
if(magnitude==0.0)
{
magnitude=1.0;
}
t->SetScale(255.0/magnitude);
t->SetOutputScalarTypeToUnsignedChar();
t->Update();
vtkRenderWindow *renWin=vtkRenderWindow::New();
vtkRenderer *ren1=vtkRenderer::New();
ren1->SetBackground(0.1,0.4,0.2);
renWin->AddRenderer(ren1);
ren1->Delete();
renWin->SetSize(301,300); // intentional odd and NPOT width/height
vtkRenderWindowInteractor *iren=vtkRenderWindowInteractor::New();
iren->SetRenderWindow(renWin);
renWin->Delete();
vtkLightCollection *lights=ren1->GetLights();
assert("check: lights_empty" && lights->GetNumberOfItems()==0);
vtkLight *light=vtkLight::New();
light->SetAmbientColor(0.0,0.0,0.0);
light->SetDiffuseColor(0.5,0.5,0.5);
light->SetSpecularColor(0.0,0.0,1.0);
light->SetIntensity(1.0);
// positional light is not supported by vtkFixedPointVolumeRayCastMapper
light->SetLightTypeToHeadlight();
lights->AddItem(light);
light->Delete();
vtkVolumeProperty *volumeProperty;
vtkVolume *volume;
vtkFixedPointVolumeRayCastMapper *volumeMapper=vtkFixedPointVolumeRayCastMapper::New();
volumeMapper->SetSampleDistance(1.0);
volumeMapper->SetInputConnection(
t->GetOutputPort());
volumeProperty=vtkVolumeProperty::New();
volumeMapper->SetBlendModeToComposite();
volumeProperty->ShadeOn();
volumeProperty->SetSpecularPower(128.0);
volumeProperty->SetInterpolationType(VTK_LINEAR_INTERPOLATION);
vtkPiecewiseFunction *compositeOpacity = vtkPiecewiseFunction::New();
compositeOpacity->AddPoint(0.0,1.0); // 1.0
compositeOpacity->AddPoint(80.0,1.0); // 1.0
compositeOpacity->AddPoint(80.1,0.0); // 0.0
compositeOpacity->AddPoint(255.0,0.0); // 0.0
volumeProperty->SetScalarOpacity(compositeOpacity);
vtkColorTransferFunction *color=vtkColorTransferFunction::New();
color->AddRGBPoint(0.0 ,1.0,1.0,1.0); // blue
color->AddRGBPoint(40.0 ,1.0,1.0,1.0); // red
color->AddRGBPoint(255.0,1.0,1.0,1.0); // white
volumeProperty->SetColor(color);
color->Delete();
volume=vtkVolume::New();
volume->SetMapper(volumeMapper);
volume->SetProperty(volumeProperty);
ren1->AddViewProp(volume);
int retVal;
ren1->ResetCamera();
renWin->Render();
retVal = vtkTesting::Test(argc, argv, renWin, 75);
if (retVal == vtkRegressionTester::DO_INTERACTOR)
{
iren->Start();
}
volumeMapper->Delete();
volumeProperty->Delete();
volume->Delete();
iren->Delete();
t->Delete();
compositeOpacity->Delete();
return !((retVal == vtkTesting::PASSED) || (retVal == vtkTesting::DO_INTERACTOR));
}
/*=========================================================================
Program: Visualization Toolkit
Module: TestGPURayCastMIPToComposite.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 covers vtkVolumeTextureMapper3D with a light where diffuse and
// specular components are different.
// This test volume renders a synthetic dataset with unsigned char values,
// with the composite method. The diffuse light component is gray, the
// light specular component is blue.
#include "vtkSphere.h"
#include "vtkSampleFunction.h"
#include "vtkTestUtilities.h"
#include "vtkColorTransferFunction.h"
#include "vtkPiecewiseFunction.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkVolumeProperty.h"
#include "vtkCamera.h"
#include "vtkRegressionTestImage.h"
#include "vtkImageShiftScale.h"
#include "vtkImageData.h"
#include "vtkPointData.h"
#include "vtkDataArray.h"
#include "vtkLight.h"
#include "vtkLightCollection.h"
#include <cassert>
#include "vtkVolumeTextureMapper3D.h"
int TestTM3DLightComponents(int argc,
char *argv[])
{
cout << "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)" << endl;
// Create a spherical implicit function.
vtkSphere *shape=vtkSphere::New();
shape->SetRadius(0.1);
shape->SetCenter(0.0,0.0,0.0);
vtkSampleFunction *source=vtkSampleFunction::New();
source->SetImplicitFunction(shape);
shape->Delete();
source->SetOutputScalarTypeToDouble();
source->SetSampleDimensions(127,127,127); // intentional NPOT dimensions.
source->SetModelBounds(-100.0,100.0,-100.0,100.0,-100.0,100.0);
source->SetCapping(false);
source->SetComputeNormals(false);
source->SetScalarArrayName("values");
source->Update();
vtkDataArray *a=source->GetOutput()->GetPointData()->GetScalars("values");
double range[2];
a->GetRange(range);
vtkImageShiftScale *t=vtkImageShiftScale::New();
t->SetInputConnection(source->GetOutputPort());
source->Delete();
t->SetShift(-range[0]);
double magnitude=range[1]-range[0];
if(magnitude==0.0)
{
magnitude=1.0;
}
t->SetScale(255.0/magnitude);
t->SetOutputScalarTypeToUnsignedChar();
t->Update();
vtkRenderWindow *renWin=vtkRenderWindow::New();
vtkRenderer *ren1=vtkRenderer::New();
ren1->SetBackground(0.1,0.4,0.2);
renWin->AddRenderer(ren1);
ren1->Delete();
renWin->SetSize(301,300); // intentional odd and NPOT width/height
vtkRenderWindowInteractor *iren=vtkRenderWindowInteractor::New();
iren->SetRenderWindow(renWin);
renWin->Delete();
vtkLightCollection *lights=ren1->GetLights();
assert("check: lights_empty" && lights->GetNumberOfItems()==0);
vtkLight *light=vtkLight::New();
light->SetAmbientColor(0.0,0.0,0.0);
light->SetDiffuseColor(0.5,0.5,0.5);
light->SetSpecularColor(0.0,0.0,1.0);
light->SetIntensity(1.0);
// positional light is not supported by vtkFixedPointVolumeRayCastMapper
light->SetLightTypeToHeadlight();
lights->AddItem(light);
light->Delete();
vtkVolumeProperty *volumeProperty;
vtkVolume *volume;
vtkVolumeTextureMapper3D *volumeMapper=vtkVolumeTextureMapper3D::New();
volumeMapper->SetSampleDistance(1.0);
volumeMapper->SetInputConnection(
t->GetOutputPort());
volumeProperty=vtkVolumeProperty::New();
volumeMapper->SetBlendModeToComposite();
volumeProperty->ShadeOn();
volumeProperty->SetSpecularPower(128.0);
volumeProperty->SetInterpolationType(VTK_LINEAR_INTERPOLATION);
vtkPiecewiseFunction *compositeOpacity = vtkPiecewiseFunction::New();
compositeOpacity->AddPoint(0.0,1.0); // 1.0
compositeOpacity->AddPoint(80.0,1.0); // 1.0
compositeOpacity->AddPoint(80.1,0.0); // 0.0
compositeOpacity->AddPoint(255.0,0.0); // 0.0
volumeProperty->SetScalarOpacity(compositeOpacity);
vtkColorTransferFunction *color=vtkColorTransferFunction::New();
color->AddRGBPoint(0.0 ,1.0,1.0,1.0); // blue
color->AddRGBPoint(40.0 ,1.0,1.0,1.0); // red
color->AddRGBPoint(255.0,1.0,1.0,1.0); // white
volumeProperty->SetColor(color);
color->Delete();
volume=vtkVolume::New();
volume->SetMapper(volumeMapper);
volume->SetProperty(volumeProperty);
ren1->AddViewProp(volume);
int retVal;
ren1->ResetCamera();
renWin->Render();
retVal = vtkTesting::Test(argc, argv, renWin, 75);
if (retVal == vtkRegressionTester::DO_INTERACTOR)
{
iren->Start();
}
volumeMapper->Delete();
volumeProperty->Delete();
volume->Delete();
iren->Delete();
t->Delete();
compositeOpacity->Delete();
return !((retVal == vtkTesting::PASSED) || (retVal == vtkTesting::DO_INTERACTOR));
}
......@@ -191,11 +191,15 @@ float *vtkEncodedGradientShader::GetBlueSpecularShadingTable( vtkVolume *vol )
return this->ShadingTable[index][5];
}
void vtkEncodedGradientShader::UpdateShadingTable( vtkRenderer *ren,
vtkVolume *vol,
vtkEncodedGradientEstimator *gradest)
void vtkEncodedGradientShader::UpdateShadingTable(
vtkRenderer *ren,
vtkVolume *vol,
vtkEncodedGradientEstimator *gradest)
{
double lightDirection[3], material[4], lightColor[3];
double lightDirection[3], material[4];
double lightAmbientColor[3];
double lightDiffuseColor[3];
double lightSpecularColor[3];
double lightPosition[3], lightFocalPoint[3];
double lightIntensity, viewDirection[3];
double cameraPosition[3], cameraFocalPoint[3], mag;
......@@ -320,7 +324,9 @@ void vtkEncodedGradientShader::UpdateShadingTable( vtkRenderer *ren,
}
// Get the light color, position, focal point, and intensity
light->GetColor( lightColor );
light->GetAmbientColor(lightAmbientColor);
light->GetDiffuseColor(lightDiffuseColor);
light->GetSpecularColor(lightSpecularColor);
light->GetTransformedPosition( lightPosition );
light->GetTransformedFocalPoint( lightFocalPoint );
lightIntensity = light->GetIntensity( );
......@@ -346,10 +352,11 @@ void vtkEncodedGradientShader::UpdateShadingTable( vtkRenderer *ren,
lightDirection[2] = out[2] / out[3] - zero[2];
// Build / Add to the shading table
this->BuildShadingTable( index, lightDirection, lightColor,
lightIntensity, viewDirection,
material, ren->GetTwoSidedLighting(),
gradest, update_flag );
this->BuildShadingTable(index, lightDirection, lightAmbientColor,
lightDiffuseColor,lightSpecularColor,
lightIntensity, viewDirection,
material, ren->GetTwoSidedLighting(),
gradest, update_flag );
update_flag = 1;
}//while there is a light in the list of lights
......@@ -378,7 +385,9 @@ void vtkEncodedGradientShader::UpdateShadingTable( vtkRenderer *ren,
// value indicates which index table is to be updated
void vtkEncodedGradientShader::BuildShadingTable( int index,
double lightDirection[3],
double lightColor[3],
double lightAmbientColor[3],
double lightDiffuseColor[3],
double lightSpecularColor[3],
double lightIntensity,
double viewDirection[3],
double material[4],
......@@ -387,8 +396,8 @@ void vtkEncodedGradientShader::BuildShadingTable( int index,
int updateFlag )
{
double lx, ly, lz;
float n_dot_l;
float n_dot_v;
double n_dot_l;
double n_dot_v;
int i;
float *nptr;
float *sdr_ptr;
......@@ -397,9 +406,9 @@ void vtkEncodedGradientShader::BuildShadingTable( int index,
float *ssr_ptr;
float *ssg_ptr;
float *ssb_ptr;
float Ka, Es, Kd_intensity, Ks_intensity;
double Ka, Es, Kd_intensity, Ks_intensity;
double half_x, half_y, half_z;
float mag, n_dot_h, specular_value;
double mag, n_dot_h, specular_value;
int norm_size;
// Move to local variables
......@@ -474,22 +483,25 @@ void vtkEncodedGradientShader::BuildShadingTable( int index,
}
// Now add in ambient
*(sdr_ptr) += Ka * lightColor[0];
*(sdg_ptr) += Ka * lightColor[1];
*(sdb_ptr) += Ka * lightColor[2];
*(sdr_ptr) += static_cast<float>(Ka * lightAmbientColor[0]);
*(sdg_ptr) += static_cast<float>(Ka * lightAmbientColor[1]);
*(sdb_ptr) += static_cast<float>(Ka * lightAmbientColor[2]);
// Add in diffuse
*(sdr_ptr) +=
(Kd_intensity * this->ZeroNormalDiffuseIntensity * lightColor[0]);
*(sdg_ptr) +=
(Kd_intensity * this->ZeroNormalDiffuseIntensity * lightColor[1]);
*(sdb_ptr) +=
(Kd_intensity * this->ZeroNormalDiffuseIntensity * lightColor[2]);
*(sdr_ptr) += static_cast<float>
(Kd_intensity * this->ZeroNormalDiffuseIntensity*lightDiffuseColor[0]);
*(sdg_ptr) += static_cast<float>
(Kd_intensity * this->ZeroNormalDiffuseIntensity*lightDiffuseColor[1]);
*(sdb_ptr) += static_cast<float>
(Kd_intensity * this->ZeroNormalDiffuseIntensity*lightDiffuseColor[2]);
// Add in specular
*(ssr_ptr) += this->ZeroNormalSpecularIntensity * lightColor[0];
*(ssg_ptr) += this->ZeroNormalSpecularIntensity * lightColor[1];
*(ssb_ptr) += this->ZeroNormalSpecularIntensity * lightColor[2];
*(ssr_ptr) += static_cast<float>(
this->ZeroNormalSpecularIntensity*lightSpecularColor[0]);
*(ssg_ptr) += static_cast<float>(
this->ZeroNormalSpecularIntensity*lightSpecularColor[1]);
*(ssb_ptr) += static_cast<float>(
this->ZeroNormalSpecularIntensity*lightSpecularColor[2]);
}
else
{
......@@ -521,35 +533,41 @@ void vtkEncodedGradientShader::BuildShadingTable( int index,
// If we are updating, then begin by adding in ambient
if ( updateFlag )
{
*(sdr_ptr) += Ka * lightColor[0];
*(sdg_ptr) += Ka * lightColor[1];
*(sdb_ptr) += Ka * lightColor[2];
*(sdr_ptr) += static_cast<float>(Ka * lightAmbientColor[0]);
*(sdg_ptr) += static_cast<float>(Ka * lightAmbientColor[1]);
*(sdb_ptr) += static_cast<float>(Ka * lightAmbientColor[2]);
}
// Otherwise begin by setting the value to the ambient contribution
else
{
*(sdr_ptr) = Ka * lightColor[0];
*(sdg_ptr) = Ka * lightColor[1];
*(sdb_ptr) = Ka * lightColor[2];
*(ssr_ptr) = 0.0;
*(ssg_ptr) = 0.0;
*(ssb_ptr) = 0.0;
*(sdr_ptr) = static_cast<float>(Ka * lightAmbientColor[0]);
*(sdg_ptr) = static_cast<float>(Ka * lightAmbientColor[1]);
*(sdb_ptr) = static_cast<float>(Ka * lightAmbientColor[2]);
*(ssr_ptr) = 0.0f;
*(ssg_ptr) = 0.0f;
*(ssb_ptr) = 0.0f;
}
// If there is some diffuse contribution, add it in
if ( n_dot_l > 0 )
{
*(sdr_ptr) += (Kd_intensity * n_dot_l * lightColor[0]);
*(sdg_ptr) += (Kd_intensity * n_dot_l * lightColor[1]);
*(sdb_ptr) += (Kd_intensity * n_dot_l * lightColor[2]);
*(sdr_ptr) += static_cast<float>(
Kd_intensity * n_dot_l * lightDiffuseColor[0]);
*(sdg_ptr) += static_cast<float>(
Kd_intensity * n_dot_l * lightDiffuseColor[1]);
*(sdb_ptr) += static_cast<float>(
Kd_intensity * n_dot_l * lightDiffuseColor[2]);
if ( n_dot_h > 0.001 )
{
specular_value = Ks_intensity * pow(static_cast<double>(n_dot_h),
static_cast<double>(Es) );
*(ssr_ptr) += specular_value * lightColor[0];
*(ssg_ptr) += specular_value * lightColor[1];
*(ssb_ptr) += specular_value * lightColor[2];
*(ssr_ptr) += static_cast<float>(
specular_value * lightSpecularColor[0]);
*(ssg_ptr) += static_cast<float>(
specular_value * lightSpecularColor[1]);
*(ssb_ptr) += static_cast<float>(
specular_value * lightSpecularColor[2]);
}
}
}
......
......@@ -51,9 +51,9 @@ public:
// Description:
// Set / Get the intensity diffuse / specular light used for the
// zero normals.
vtkSetClampMacro( ZeroNormalDiffuseIntensity, float, 0.0, 1.0);
vtkSetClampMacro( ZeroNormalDiffuseIntensity, float, 0.0f, 1.0f);
vtkGetMacro( ZeroNormalDiffuseIntensity, float );
vtkSetClampMacro( ZeroNormalSpecularIntensity, float, 0.0, 1.0);
vtkSetClampMacro( ZeroNormalSpecularIntensity, float, 0.0f, 1.0f);
vtkGetMacro( ZeroNormalSpecularIntensity, float );
// Description:
......@@ -96,7 +96,9 @@ protected:
// should be used. It is computed in the UpdateShadingTable method.
void BuildShadingTable( int index,
double lightDirection[3],
double lightColor[3],
double lightAmbientColor[3],
double lightDiffuseColor[3],
double lightSpecularColor[3],
double lightIntensity,
double viewDirection[3],
double material[4],
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment