Three.js-based volume ray tracer for visualizing recovered protoplanetary disk CO density volume.
Renders the disk in 3D space with orthographic projection, with highlighting for emission per frequency, with a non-physical Gaussian PSF simulation preview, very-non-physical spectral broadening slider, and simple observational parameter controls with inclination and position angle.
- Orthographic Volume Ray Marching: Proper orthographic projection with parallel rays for consistent magnification across all viewing angles
- External Data Loading: Supports CO density volumes exported from
radjax(RAW+JSON format) and frequency mapping data (NPY files) - Dual View System: Main 3D volume view + PSF blurred thumbnail (256×256) with Inferno colormap
- Debug Wireframe: Optional white wireframe outline to visualize volume boundaries
The viewer expects data in the ./data/ directory:
freqs.json: Array of frequency values in Hzcenter_index.npy: 3D array of center frequency indices per voxelsigma_channels.npy: 3D array of thermal broadening widths
co_volume_meanT_160x160x160.raw: Float32 volume dataco_volume_meanT_160x160x160.json: Metadata with shape and bounds
# Start local server
python3 -m http.server 5173
# Open in browser
open http://localhost:5173/- Plain: Grayscale volume rendering of just the disk CO density
- Frequency Slice: Doppler-shifted frequency slice 3D highlighting
- Density: Opacity scaling (1-10x)
- Step Size: Ray marching step size (0.25-2.0x)
- Log Window: Min/max values for logarithmic mapping
- Frequency Slider: Select observation frequency channel
- Disk Opacity: Background disk visibility (0.0-1.0)
- Turbulence: NON-PHYSICAL Minimum sigma broadening threshold (will be updated to physical model later)
- PSF Blur: Gaussian kernel size for point spread function
- Position Angle: Image-plane rotation angle (PSF view only)
- Frequency Weighting: GPU-computed per-fragment Gaussian/band integration
- Coordinate Transforms: Automatic observer frame ↔ disk frame rotation
- Absorption Model: Beer-Lambert law with pre-multiplied alpha compositing
- Load external volume and frequency data
- Build velocity and broadening textures
- Upload as 3D textures for GPU sampling
- Real-time shader-based frequency weighting
- Post-process PSF simulation with Inferno mapping
- WebGL2: Required for 3D texture sampling and float render targets
- Modern Browser: Chrome 57+, Firefox 51+, Safari 15+, Edge 79+
- Hardware: Dedicated GPU recommended for smooth performance
- Standard NumPy binary format with little-endian encoding
- Supported dtypes:
<f4,<f8,<i4,<i8,<u1 - Shape information parsed from header
{
"shape": [nz, ny, nx],
"bounds": {
"x": [xmin, xmax],
"y": [ymin, ymax],
"z": [zmin, zmax]
}
}// Get current camera state
const pose = window.getPose();
// Apply saved camera state
window.applyPose({
position: [x, y, z],
target: [tx, ty, tz],
quaternion: [qx, qy, qz, qw],
zoom: 1.0
});
// Access controls
window.ppd.camera // Three.js camera
window.ppd.controls // OrbitControls instance