Volume rendering with VTK: CPU-based OK, GPU-based not visible

Hi VTK experts.

I am experimenting with Volume Rendering in my VTK-based Java application, and I am facing some issues with the GPU-based volume mapper. On the other side, my code seems to work fine (but slow) with the CPU-based volume mapper

Foreword: I am still using VTK version 6.1, so if you believe the issues that I’ll describe here may be fixed just by upgrading to the latest VTK version, please let me know, and I will work in this direction.

As I anticipated above, I am working in Java. Here is how my pipeline looks like:

=====

  // Initialize opacity function
  opacityFunct = new vtkPiecewiseFunction();
  // ...(code)...
  
  // Initialize the gradient opacity function
  gradientOpacityFunct = new vtkPiecewiseFunction();
  // ...(code)...
  
  // Initialize the color transfer function
  colorTransfFunct = new vtkColorTransferFunction();
  // ...(code)...
  
  // Initialize the volume's properties
  vtkVolumeProperty volumeProperty = new vtkVolumeProperty();
  volumeProperty.ShadeOn();
  volumeProperty.SetInterpolationTypeToLinear();
  volumeProperty.SetScalarOpacity(opacityFunct);
  volumeProperty.SetGradientOpacity(gradientOpacityFunct);
  volumeProperty.SetColor(colorTransfFunct);
  volumeProperty.SetAmbient(0.4);
  volumeProperty.SetDiffuse(0.8);
  volumeProperty.SetSpecular(0.2);

  // Initialize the mapper
  volumeMapper = new vtkFixedPointVolumeRayCastMapper(); 
  // If I replace the line above with:
  // volumeMapper = new vtkOpenGLGPUVolumeRayCastMapper();
  // then I won't see any volume in my render scene. Why?

  volumeMapper.AutoAdjustSampleDistancesOn();
  volumeMapper.SetBlendModeToComposite();
  volumeMapper.SetSampleDistance(1.0);
  volumeMapper.SetInputConnection(getVTKImageReader().GetOutputPort());
  
  
  // Initialize the actual volume prop
  volume = new vtkVolume();
  volume.SetMapper(volumeMapper);
  volume.SetProperty(volumeProperty);
  
  vtkRenderer existingCanvasRenderer = GetRenderer();
  existingCanvasRenderer.AddViewProp(volume);

=====

In brief, if I use vtkFixedPointVolumeRayCastMapper as my volume mapper, then rendering works fine, and I can see the volume as show in this screenshot:

https://drive.google.com/open?id=1rembBgloqJalqeUTMZlpp7sPku4B3yeI

However, interaction with the volume is extremely slow.

On the other side, if I use vtkOpenGLGPUVolumeRayCastMapper (or also vtkSmartVolumeMapper), then I cannot see any volume in my rendering panel, and the scene looks like this:

https://drive.google.com/open?id=1w_rXP2Q03frRdafG5BtacTK9LJ52g8Ji

Can you see any obvious reason for that?
Can it be an issue of my graphics adapter (NVIDIA GeForce GTX 1060 6 GB) or of its driver?
Or, can it be an issue related to VTK 6.1?

Thank you in advance for your comments.
Regards,

Marco

Hi all.
I went ahead, and managed to build the latest VTK 8.2 and integrate it with my application.

The situation has improved, and vtkSmartVolumeMapper now seems to work “almost” correctly with GPU rendering.
However, I am still facing a blocking issue.

Basically, my volume can only be seen “from above”, as shown in this screenshot:

https://drive.google.com/open?id=1N3MXdRXcZX8RX2n--cT4u5QKi6qRb3mv

On the other side, if I try to view the volume “from the front”, I cannot see it, as the volume appears like being inside an opaque box, hence it cannot be seen:

https://drive.google.com/open?id=1sE2c1xda3qJLCCKPBE5rQ9RPtWXRweiy

Can you guess why and maybe provide some hints on how to correctly configure my mapper to see the whole volume?

Thanks in advance and best regards,

Marco Sambin

Hi all,

while trying to understand why my volume appears only partially (i.e., only when seen from the top of the chest) when I use vtkSmartVolumeMapper with GPU rendering active, i noticed another strange thing, which hopefully may tell something to you.
Basically, when I use vtkFixedPointVolumeRayCastMapper, my volume appears like this when seen from above:

https://drive.google.com/open?id=19THxUb9Eazg6AC8vnx6Sqsp6xQx_4dmI

As you can see, in this rendering the top of this chest corresponds with the “S = Superior” (which is the label assigned to the ZPlus face) orientation of the orientation widget on the top right.

On the other side, if I use vtkSmartVolumeMapper, my volume appears like this when seen from above:

https://drive.google.com/open?id=1N3MXdRXcZX8RX2n--cT4u5QKi6qRb3mv

As you can see, in this case the top of chest corresponds with the “I = Inferior” (which is the label assigned to the ZMinus face) orientation of the orientation widget on the top right.
Can you tell why there is this difference?

Please notice that the two renderings above are obtained by exactly the same code, except for the single line which instantiates the volume mapper (which is vtk FixedPointVolumeRayCastMapper in the first case and vtkSmartVolumeMapper in the second case).

I would really appreciate if some VTK expert could provide some hint allowing me to make some progress with GPU-based volume rendering, and understand why in this mode I obtain “strange” results, as explained in this message and in the previous one.

Thanks in advance.
Best regards,

Marco Sambin

Hi all.
I’ve tried setting several different combinations of parameters on my vtkSmartVolumeMapper and on my renderer, but I continue getting a “partially visible” volume on my vtkCanvas-derived panel:

I have not so much experience with volume rendering in VTK, so I am really running out of ideas about what I could try to fix this rendering issue.

The fact that my volume, when rendered through the vtkSmartVolumeMapper appears z-flipped w.r.t. when using vtkFixedPointVolumeRayCastMapper (see my previous message), confuses me further.

Just as an additional information, I’ve tried generating the volume in VolView 3.4 starting from the same dataset (which is a DICOM dataset), and the volume displays fine (through the GPU) in VolView.

I would really appreciate some suggestions about what to try to make some progress.
Thanks and best regards,

Marco Sambin

Hi all.
Any suggestion on this topic would be really appreciated.

Any idea about why I am obtaining these strange behaviors with vtkSmartVolumeMapper?

Thanks in advance for your input.
Best regards,

Marco Sambin

Maybe reset your camera clipping planes? See vtkRenderer::ResetCameraClippingRange.

Hi Cory,

thanks a lot for getting back to me.

Finally, after a lot of analysis, I think I understood what’s going on!!! :slight_smile:

This has nothing to do with the camera, and indeed my rendering worked fine if using the vtkFixedPointVolumeRayCastMapper.

It turned out that my reader (vtkImageReader2) was generating source image data with the following spatial features:

xSpacing = 0.68
ySpacing = 0.68
zSpacing = -1 (since the CT slices in my volume are stacking towards lower z values, i.e., from top to bottom of the human body)

It looks like this negative zSpacing (-1) is causing severe issues to vtkSmartVolumeMapper, while on the other side it works fine with vtkFixedPointVolumeRayCastMapper. Is this expected, or it is a bug of the vtkSmartVolumeMapper / GPU mode?

For now, I’ve fixed by passing an always-positive zSpacing, and simply reversing the order of the slices in case the original zSpacing was negative.

But I would be interested in understanding if this behavior of the vtkSmartVolumeMapper can be considered “normal”, since it is different from the behavior of vtkFixedPointVolumeRayCastMapper.

Thanks in advance for any feedback and best regards,

Marco Sambin

Ah, that’s interesting. My guess is that vtkFixedPointVolumeRayCastMapper just happens to work with negative spacing. I think it is safe to say that VTK does not guarantee support for negative spacing in most filters (thought it may happen to work in some), so flipping the z slices and changing the z spacing to 1 is the safest thing to do.