Volume Rendering of Voxel Based Data

Deborah Schmidt
Helmholtz Imaging | MDC Berlin
Sep 24, 2026
Slides available at https://ida-mdc.github.io/workshop-visualization/2026-workshop/voxels/

Voxels

  • A grid-based data structure: a value at every position in a discrete block
  • Transparency makes the shape - voxels outside a chosen intensity range are not drawn
  • Voxel size can differ per axis, and belongs in the metadata

Voxels

When the spacing is wrong

Same data in the middle and on the right. Only the metadata differs.

Ray casting

Ray casting sends one ray from the camera through each pixel and records what it meets.

Ray casting

What the shader does with the samples

  • Each is a shader, a small program run per pixel on the GPU - and more modes exist than these four

Transfer functions

Value in, color and opacity out

A transfer function turns a voxel’s value into a color and an opacity. The same lookup table is applied to every voxel in the volume. It includes:

  • A color ramp spanning the range the data occupies
  • An opacity curve, which decides what is visible and what is seen through

Transfer functions

Examples

Try it out

napari

uvx --from "napari[all]" napari

Drag frog-head.tif onto the window, then press

and pick a rendering mode in the layer controls

Try it out

Jupyter notebooks

uv venv .venv_volumetric --python 3.12 --seed
uv pip install --python .venv_volumetric -r visualization_software/requirements_volumetric.txt
uv run --python .venv_volumetric jupyter lab

Challenges

Separating foreground from background

  • A threshold works when there is a background
  • Some datasets have none - FIB-SEM is resin, stain and membrane, edge to edge
  • No transfer function fixes this - it requires a preprocessing step

Challenges

Denoising and segmentation, before rendering

  • nnInteractive for your own volumes: a point, a scribble or a box on one 2D slice gives a full 3D mask you can correct, in napari, MITK or 3D Slicer