VTK.js 3D Visualization
Volume rendering, isosurfaces, and FEM mesh visualization
VTK.js (Visualization Toolkit for JavaScript) enables advanced 3D visualization capabilities including volume rendering, isosurface extraction, and finite element mesh visualization. All VTK functions are available under the vtk namespace.
Interactive Controls: Drag to rotate, scroll to zoom, and shift+drag to pan.
Getting Started
The simplest way to get started is with built-in primitives. VTK provides sphere, cone, cube, and cylinder shapes that you can customize with parameters.
# Create a simple sphere
vtk.sphere()Customizing Primitives
You can customize primitives with radius, center position, and resolution parameters. Higher resolution creates smoother surfaces but renders slower.
# Create a sphere with custom radius, center, and resolution
# Parameters: radius, [centerX, centerY, centerZ], resolution
vtk.sphere(2, [1, 0, 0], 64)# VTK provides several built-in geometric primitives
vtk.cone(2, 0.5) # Cone with height 2, radius 0.5
title("Cone")vtk.cube(1, 1.5, 2) # Box with dimensions 1x1.5x2
title("Cube")vtk.cylinder(2, 0.5, 32) # Cylinder with height 2, radius 0.5
title("Cylinder")Function Reference
Geometric Primitives
| Function | Description | Example |
|---|---|---|
vtk.sphere(r, center, res) | Create a sphere | vtk.sphere(1, [0, 0, 0], 32) |
vtk.cone(h, r) | Create a cone | vtk.cone(1, 0.5) |
vtk.cube(x, y, z) | Create a box | vtk.cube(1, 2, 1) |
vtk.cylinder(h, r, res) | Create a cylinder | vtk.cylinder(2, 0.5, 32) |
Data Visualization
| Function | Description | Example |
|---|---|---|
vtk.polydata(points, polys, scalars) | Surface mesh from points and polygons | vtk.polydata(pts, polys) |
vtk.volume(data, dims) | Volume rendering of 3D scalar field | vtk.volume(data, dims) |
vtk.isosurface(data, dims, isovalue) | Extract isosurface at constant value | vtk.isosurface(data, dims, 0.5) |
vtk.femgrid(nodes, elements, types, scalars) | FEM mesh visualization | vtk.femgrid(nodes, elems, types) |
Visualization Options
| Function | Description | Example |
|---|---|---|
vtk.colormap(name) | Set colormap (viridis, rainbow, coolwarm, jet, grayscale) | vtk.colormap("coolwarm") |
vtk.opacity(value) | Set opacity (0-1) | vtk.opacity(0.5) |
vtk.edges("on"/"off") | Toggle mesh edge visibility | vtk.edges("on") |
vtk.wireframe() | Wireframe rendering mode | vtk.wireframe() |
vtk.surface() | Surface rendering mode (default) | vtk.surface() |
vtk.points() | Points-only rendering mode | vtk.points() |
PolyData Meshes
PolyData is VTK's format for surface meshes. You define vertices (points) and connectivity (which points form polygons). The polygon array uses the format: [n, p1, p2, ..., pn] where n is the number of vertices in the polygon.
# Define 3 vertices (flat array: x1,y1,z1, x2,y2,z2, ...)
points = [0, 0, 0, 1, 0, 0, 0.5, 1, 0]
# Define a triangle (3 = number of vertices, then indices 0, 1, 2)
polys = [3, 0, 1, 2]
vtk.polydata(points, polys)
title("Triangle")Colored Meshes
Add scalar values to color the mesh based on data. Each point gets a scalar value that maps to the current colormap.
# Create a simple tetrahedron (4 points × 3 coords = 12 values)
points = [0, 0, 0, 1, 0, 0, 0.5, 1, 0, 0.5, 0.5, 0.8]
# Four triangular faces (each: 3, idx0, idx1, idx2)
polys = [3, 0, 1, 2, 3, 0, 1, 3, 3, 1, 2, 3, 3, 0, 2, 3]
# Assign scalar values to each point for coloring
scalars = [0, 0.33, 0.66, 1]
vtk.colormap("viridis")
vtk.polydata(points, polys, scalars)
title("Colored Tetrahedron")Volume Rendering
Volume rendering visualizes 3D scalar data as a translucent volume, revealing internal structures. Use meshgrid with three arguments to create 3D coordinate arrays.
Note: Volume rendering is GPU-intensive. Start with small dimensions (e.g., 20×20×20) and increase resolution as needed.
# Create a 3D Gaussian blob
n = 21
coords = linspace(-2, 2, n)
(X, Y, Z) = meshgrid(coords, coords, coords)
data = exp(-(X.^2 + Y.^2 + Z.^2))
# Render as volume
vtk.volume(data, [n, n, n])
title("3D Gaussian Volume")Isosurface Extraction
Isosurfaces are 3D contours at a constant scalar value — useful for visualizing boundaries in volumetric data. VTK uses the Marching Cubes algorithm to extract these surfaces.
# Create an implicit sphere function
n = 41
coords = linspace(-2, 2, n)
(X, Y, Z) = meshgrid(coords, coords, coords)
sphere_field = X.^2 + Y.^2 + Z.^2
# Extract isosurface at radius 1 (where x^2+y^2+z^2 = 1)
vtk.isosurface(sphere_field, [n, n, n], 1.0)
title("Sphere Isosurface (r=1)")Torus Example
Create complex shapes using implicit surface equations. A torus can be defined as:
where is the major radius (distance from center to tube center) and is the minor radius (tube radius).
# Torus parameters
R_major = 1.5 # Major radius (distance from center to tube center)
r_minor = 0.5 # Minor radius (tube radius)
# Use uniform grid
n = 51
coords = linspace(-2.5, 2.5, n)
(X, Y, Z) = meshgrid(coords, coords, coords)
# Torus implicit equation
torus_field = (sqrt(X.^2 + Y.^2) - R_major).^2 + Z.^2 - r_minor^2
# Isosurface at 0 gives the torus surface
vtk.colormap("rainbow")
vtk.isosurface(torus_field, [n, n, n], 0)
title("Torus (R=1.5, r=0.5)")FEM Mesh Visualization
Finite Element Method meshes consist of nodes (vertices) and elements (cells) of various types. Use vtk.femgrid to visualize tetrahedral, hexahedral, and other element types.
VTK Cell Type Reference
| Code | Name | Description |
|---|---|---|
| 1 | VERTEX | Single point |
| 3 | LINE | Line segment |
| 5 | TRIANGLE | Triangle (3 nodes) |
| 9 | QUAD | Quadrilateral (4 nodes) |
| 10 | TETRA | Tetrahedron (4 nodes) |
| 12 | HEXAHEDRON | Hexahedron/brick (8 nodes) |
| 13 | WEDGE | Wedge/prism (6 nodes) |
| 14 | PYRAMID | Pyramid (5 nodes) |
# Define 4 nodes of a tetrahedron (flat: x1,y1,z1, x2,y2,z2, ...)
nodes = [0, 0, 0, 1, 0, 0, 0.5, 1, 0, 0.5, 0.5, 1]
# Define one tetrahedron element
# Format: [numPoints, node0, node1, node2, node3]
elements = [4, 0, 1, 2, 3]
types = [10] # VTK_TETRA = 10
vtk.edges("on")
vtk.femgrid(nodes, elements, types)
title("Tetrahedral Element")Hexahedral Elements and Stress Visualization
Pass scalar values (stress, temperature, etc.) to color the mesh based on field data.
# Simple beam mesh (3 hex elements)
# 16 nodes × 3 coords = 48 values
beam_nodes = [
0, 0, 0, 1, 0, 0, 2, 0, 0, 3, 0, 0,
0, 1, 0, 1, 1, 0, 2, 1, 0, 3, 1, 0,
0, 0, 1, 1, 0, 1, 2, 0, 1, 3, 0, 1,
0, 1, 1, 1, 1, 1, 2, 1, 1, 3, 1, 1
]
# Three hexahedra forming a beam
# Each: [8, n0, n1, n2, n3, n4, n5, n6, n7]
beam_elements = [
8, 0, 1, 5, 4, 8, 9, 13, 12,
8, 1, 2, 6, 5, 9, 10, 14, 13,
8, 2, 3, 7, 6, 10, 11, 15, 14
]
beam_types = [12, 12, 12]
# Von Mises stress (higher at fixed end)
stress = [100, 90, 80, 70, 100, 90, 80, 70, 100, 90, 80, 70, 100, 90, 80, 70]
vtk.colormap("coolwarm")
vtk.edges("on")
vtk.femgrid(beam_nodes, beam_elements, beam_types, stress)
title("Beam with Stress Visualization")Visualization Options
Customize the appearance of your visualizations with colormaps, opacity, edge visibility, and rendering modes.
# Show edges for better mesh visibility
vtk.edges("on")
# Set partial transparency (0=invisible, 1=opaque)
vtk.opacity(0.8)
# Create a sphere
vtk.sphere(1, [0, 0, 0], 16)
title("Semi-transparent Sphere with Edges")# Wireframe mode shows only the mesh lines
vtk.wireframe()
vtk.sphere(1, [0, 0, 0], 16)
title("Wireframe Sphere")Advanced Examples
Heat Distribution
Visualize a 3D temperature field using volume rendering with a thermal colormap.
# Simulate heat distribution in a block
n = 11
coords = linspace(0, 1, n)
(X, Y, Z) = meshgrid(coords, coords, coords)
# Heat source at center, cooling at boundaries
T = exp(-10 * ((X - 0.5).^2 + (Y - 0.5).^2 + (Z - 0.5).^2))
vtk.colormap("coolwarm")
vtk.volume(T, [n, n, n])
title("Heat Distribution (Hot Center)")Molecular Surface
Create molecular visualizations by blending electron density fields from multiple atomic centers.
# Implicit surface for a simple diatomic molecule
nx = 61
ny = 41
nz = 41
(X, Y, Z) = meshgrid(linspace(-3, 3, nx), linspace(-2, 2, ny), linspace(-2, 2, nz))
# Two atomic centers (spherical electron density)
r1 = sqrt(X.^2 + Y.^2 + Z.^2)
r2 = sqrt((X - 1.5).^2 + Y.^2 + Z.^2)
# Blend the two electron densities
molecule_field = exp(-r1) + exp(-r2) - 0.3
vtk.colormap("viridis")
vtk.isosurface(molecule_field, [nx, ny, nz], 0)
title("Diatomic Molecule Surface")Summary
We've covered the main VTK.js visualization capabilities:
Key Concepts
- Primitives - Built-in shapes (sphere, cone, cube, cylinder) with customizable parameters
- PolyData - Custom surface meshes defined by points and polygon connectivity
- Volume Rendering - Visualize 3D scalar fields as translucent volumes
- Isosurfaces - Extract constant-value surfaces from volumetric data using Marching Cubes
- FEM Grids - Visualize finite element meshes with various cell types and scalar fields
- Options - Customize colormaps, opacity, edges, and rendering modes
Tips
- 3D Meshgrid: Use
(X, Y, Z) = meshgrid(x, y, z)to create 3D coordinate arrays - Performance: Start with coarse grids during development; volume rendering is GPU-intensive
- Colormaps: Call
vtk.colormap()before creating the visualization