Generic selectors
Exact matches only
Search in title
Search in content
Post Type Selectors

GPU volume rendering for faster CT visualization

For a long time I used VTK’s CPU mapper for volume rendering out of habit. It worked. Once we switched to the GPU mapper, the difference was obvious. If the workstation or server has a GPU, moving from vtkFixedPointVolumeRayCastMapper to vtkGPUVolumeRayCastMapper is a small change that pays off immediately. This page is that swap. It is not “what volume rendering is.”

If you meant what volume rendering is (MIP / DVR / transfer functions) → volume rendering of CT. If you meant a Python VTK slice viewer (axial / coronal / sagittal, no volume render) → DICOM viewer in Python.

# explicit GPU mapper — not the CPU ray cast, not the auto pick
mapper = vtk.vtkGPUVolumeRayCastMapper()
# was: vtk.vtkFixedPointVolumeRayCastMapper()
# skip: vtk.vtkSmartVolumeMapper()  # auto-select; we set GPU on purpose

What changed in our viewer

GPU volume-rendered full-body CT rotating in a PYCAD viewer

We pointed the viewer at vtkGPUVolumeRayCastMapper wherever a compatible GPU is available.

  • Rotation and zoom stay fluid on large studies.
  • Live cropping updates without the lag you learn to tolerate on the CPU.
  • Lighting and gradient-based shading no longer hitch the camera.

The GIF is a full-body CT in that viewer — navigation and crop without the old stutter.

Why the GPU mapper is faster

Ray casting on the GPU uses 3D textures and parallel sampling. Shading, gradient opacity, and transfer-function edits are cheap enough to do while the mouse is down. Volumes that felt heavy on vtkFixedPointVolumeRayCastMapper become usable in a clinical click-path.

vtkSmartVolumeMapper

vtkSmartVolumeMapper can pick a mapper from the machine. In practice we set vtkGPUVolumeRayCastMapper ourselves so workstations and headless servers behave the same, then fall back to CPU only when we have to.

Setup that actually mattered

  • Drivers and headless. On Linux servers use an offscreen OpenGL context (EGL) and the NVIDIA Container Toolkit if you are in Docker.
  • VRAM. A large CT can exhaust the card. Resample, crop, or tile before you upload the whole series as one 3D texture.
  • Scalars and transfer functions. Many CTs are 12–16 bit. Set vtkVolumeProperty and the transfer functions to that range or you get banding / a washed-out window.
  • Sampling distance. Smaller is prettier and more expensive. Tune per modality.
  • Shading on purpose. vtkVolumeProperty can do gradient opacity and shading. Turn them on when they add a diagnostic edge, not by default on every study.
  • Crop in the mapper. vtkGPUVolumeRayCastMapper has cropping planes natively. That is why a region-of-interest stay interactive.
  • CPU fallback. No GPU or a dead driver → switch back to vtkFixedPointVolumeRayCastMapper (or drop features) instead of crashing the viewer.

When we still use the CPU

  • No compatible GPU, or drivers that will not give a usable context.
  • Batch pipelines where nobody is dragging a camera.
  • Memory-constrained boxes where CPU behaviour is the predictable one.

We do not quote a speed-up percentage. On a modern GPU you feel it on rotate, window/level, and crop. That is the result.

This is the mapper work we ship in PYCAD viewers — not a listicle. Case studies.

We build custom medical imaging platforms — advanced DICOM viewers, AI segmentation, and the clinical systems around them.

Get in Touch

Copyright © 2026 PYCAD. All Rights Reserved.