Shader composer error when specifying no GradientTF on a MultiVolume
When using a GPUVolumeRayCastMapper (OpenGLGPUVolumeRayCastMapper) with a MultiVolume, specifying a gradient opacity transfer function is supposed to be optional. However, not specifying one leads to a bug in the shader code composer : the glsl function computeColor
expects an argument for the gradientTF texture, but none is given. If it shouldn't be supported, maybe at least a cleaner warning message should be displayed. Supporting multivolume with no gradientTF is currently addressed by !8898 (closed).
Below some c++ code to reproduce the bug.
#include <vtk-9.1/vtkNew.h>
#include <vtk-9.1/vtkMultiVolume.h>
#include <vtk-9.1/vtkGPUVolumeRayCastMapper.h>
#include <vtk-9.1/vtkRenderer.h>
#include <vtk-9.1/vtkRenderWindow.h>
#include <vtk-9.1/vtkInteractorStyleTrackballCamera.h>
#include <vtk-9.1/vtkRenderWindowInteractor.h>
#include <vtk-9.1/vtkDataArray.h>
#include <vtk-9.1/vtkFloatArray.h>
#include <vtk-9.1/vtkVolumeProperty.h>
#include <vtk-9.1/vtkPiecewiseFunction.h>
#include <vtk-9.1/vtkColorTransferFunction.h>
#include <vtk-9.1/vtkPointData.h>
#include <vtk-9.1/vtkPolyDataMapper.h>
#include <vtk-9.1/vtkPolyData.h>
#include <vtk-9.1/vtkActor.h>
#include <vtk-9.1/vtkPoints.h>
#include <vtk-9.1/vtkCellArray.h>
#include <vtk-9.1/vtkVertex.h>
#include <vtk-9.1/vtkActor.h>
#include <vtk-9.1/vtkLight.h>
#include <vtk-9.1/vtkProperty.h>
#include <vtk-9.1/vtkUniformGrid.h>
int main(int argc, char *argv[])
{
//
double origin1[3] = {0, 0, 0};
double origin2[3] = {3, 0, 0};
double spacing[3] = {0.1, 0.1, 0.1};
int dimension[3] = {50, 50, 50};
//
int number_tuples = dimension[0] * dimension[1] * dimension[2];
vtkNew<vtkUniformGrid> grid1;
vtkNew<vtkUniformGrid> grid2;
grid1->SetDimensions(dimension);
grid1->SetSpacing(spacing);
grid1->SetOrigin(origin1);
grid2->SetDimensions(dimension);
grid2->SetSpacing(spacing);
grid2->SetOrigin(origin2);
vtkNew<vtkFloatArray> scalar1;
scalar1->SetNumberOfComponents(1);
scalar1->SetNumberOfTuples(number_tuples);
vtkNew<vtkFloatArray> scalar2;
scalar2->SetNumberOfComponents(1);
scalar2->SetNumberOfTuples(number_tuples);
for(int x = 0; x < number_tuples; x++)
{
scalar1->SetTuple1(x, 0);
scalar2->SetTuple1(x, 1);
}
grid1->GetPointData()->SetScalars(scalar1);
grid2->GetPointData()->SetScalars(scalar2);
// now the color function and all
vtkNew<vtkPiecewiseFunction> opacity;
opacity->AddPoint(0, 0.7);
opacity->AddPoint(1, 0.7);
vtkNew<vtkColorTransferFunction> color;
color->AddRGBPoint(0, 1, 0, 0);
color->AddRGBPoint(1, 0, 1, 0);
vtkNew<vtkPiecewiseFunction> gradient;
gradient->AddPoint(0, 0.4);
gradient->AddPoint(1, 0.4);
vtkNew<vtkVolume> vol1;
vol1->GetProperty()->SetColor(color);
vol1->GetProperty()->SetScalarOpacity(opacity);
// so here, we specify no gradient TF, as well as 10 lines below.
// you can try decommenting those two lines to see the bug appear/disappear.
//vol1->GetProperty()->SetGradientOpacity(gradient);
vol1->GetProperty()->SetInterpolationTypeToLinear();
vol1->GetProperty()->ShadeOn();
vtkNew<vtkVolume> vol2;
vol2->GetProperty()->SetColor(color);
vol2->GetProperty()->SetScalarOpacity(opacity);
//vol2->GetProperty()->SetGradientOpacity(gradient);
vol2->GetProperty()->SetInterpolationTypeToLinear();
vol2->GetProperty()->ShadeOn();
// now mapper and volumes and whatever
vtkNew<vtkMultiVolume> multivolume;
vtkNew<vtkGPUVolumeRayCastMapper> mapper;
mapper->SetUseJittering(true);
multivolume->SetMapper(mapper);
mapper->SetInputDataObject(0, grid1);
multivolume->SetVolume(vol1, 0);
mapper->SetInputDataObject(2, grid2);
multivolume->SetVolume(vol2, 2);
// now rendering pipeline
vtkNew<vtkRenderWindow> renWin;
renWin->SetSize(800, 800);
renWin->SetMultiSamples(0);
vtkNew<vtkRenderer> ren;
renWin->AddRenderer(ren);
ren->SetBackground(0.3, 0.3, 0.3);
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renWin);
vtkNew<vtkInteractorStyleTrackballCamera> style;
iren->SetInteractorStyle(style);
ren->AddVolume(multivolume);
renWin->Render();
iren->Start();
return 0;
}