canvas

loader / nrrd

What this shows

Load an NRRD scalar volume and show three orthogonal slices inside its bounding box, with index, threshold, and window sliders.

Side by side with the three.js r186 original: webgl_loader_nrrd.html

Differences from three.js

  • The volume is stent.nrrd (public domain) instead of I.nrrd, whose license is unknown; the slider ranges come from stent.nrrd, whose samples run from 0 to 1, so the threshold and window sliders with upstream's step of 1 only toggle between 0 and 1.
  • EASEL's NRRDLoader cannot decode gzip payloads, so the EASEL side inflates the same stent.nrrd bytes with DecompressionStream and parses the result as raw data; the bounding box, which needs only the header, draws on the first frame and the slices appear a moment later.
  • EASEL has no Volume.extractSlice or VolumeSlice, so the example repaints each slice itself from NRRDVolume.data into a DataTexture on a PlaneGeometry, using three.js's threshold and window formulas, and only when a slider changes.
  • EASEL textures are capped at 128x128 texels, so the 256-sample edges of the x and y slices are sampled nearest-neighbor at half resolution.
EASEL (Canvas2D)
This example needs a canvas-capable browser.

Loading scene…

three.js r186 (WebGL)
This example needs a canvas-capable browser.

Loading scene…

Loading scene…

Key API excerpt

import * as EASEL from "@xsyetopz/easel";


const volume = new EASEL.NRRDLoader().parse(rawNrrdBytes);
const texture = new EASEL.DataTexture(slicePixels, 128, 128);
texture.buildBrightnessLevels();
const slice = new EASEL.Mesh(
  new EASEL.PlaneGeometry(volume.xLength, volume.yLength),
  new EASEL.BasicMaterial({ map: texture, side: EASEL.Side.Double, transparent: true }),
);

scene.add(slice);

const trackball = new EASEL.TrackballControls(camera, canvas);
trackball.minDistance = 100;
trackball.maxDistance = 500;