A Node.js raytracing renderer with RenderMan RIB format support, implemented in pure JavaScript.
Example render showing multi-colored spheres with reflections, realistic lighting, and antialiasing
- Pure JavaScript Implementation: No external dependencies, runs entirely in Node.js
- Multi-Threaded Rendering: Automatic CPU detection and parallel processing using worker threads
- RenderMan RIB Support: Parse and render RenderMan RIB format files
- Advanced Antialiasing: Stratified sampling with quality presets
- Core Raytracing: Full raytracing pipeline with reflection support
- Lighting Models: Phong/Blinn-Phong shading with multiple light sources
- Geometry Primitives: Spheres, planes, triangles, and NURBS surfaces
- Material System: Support for different surface materials (plastic, metal, matte)
- Gamma Correction: Proper color space handling
- PPM Image Output: Generates standard PPM image files
git clone https://github.com/anders94/render.js.git
cd render.jsNote: there are no dependancies so npm install is not necessary.
# Run the raytracer with example scene
npm start
# Run tests to verify everything works
npm test
# Render a high-quality example
npm run render:example
# Try the NURBS examples
node src/renderer.js --rib examples/nurbs_center.rib --aa medium
node src/renderer.js --rib examples/nurbs_complex.rib --width 800 --height 600 --aa highnode src/renderer.js# Basic sphere scene
node src/renderer.js --rib examples/simple.rib
# NURBS surface examples
node src/renderer.js --rib examples/nurbs_center.rib
node src/renderer.js --rib examples/nurbs_simple.rib# Using manual sample count
node src/renderer.js --width 800 --height 600 --samples 4 --output my_render.ppm
# Using quality presets (recommended)
node src/renderer.js --width 800 --height 600 --aa high --output my_render.ppm
# With custom gamma correction
node src/renderer.js --aa medium --gamma 1.8 --output linear.ppm
# Multi-threaded high quality rendering
node src/renderer.js --width 800 --height 600 --aa high --threads 8--rib <file>: Render from RIB file--width <number>: Image width (default: 400)--height <number>: Image height (default: 300)--samples <number>: Samples per pixel for anti-aliasing (default: 1)--aa <quality>: Antialiasing quality preset: none, low, medium, high, ultra--gamma <number>: Gamma correction value (default: 2.2)--no-stratified: Disable stratified sampling (use random sampling)--single-threaded: Disable multi-threading (use single thread)--threads <number>: Number of threads to use (default: auto-detect)--output <file>: Output filename (default: output.ppm)--help: Show help message
none: No antialiasing (1 sample per pixel) - fastestlow: Light antialiasing (4 samples per pixel) - good performancemedium: Good quality (9 samples per pixel) - balanced quality/speedhigh: High quality (16 samples per pixel) - better qualityultra: Maximum quality (25 samples per pixel) - best quality
The renderer supports a subset of RenderMan RIB commands:
WorldBegin/WorldEndAttributeBegin/AttributeEndTransformBegin/TransformEndTranslate x y zRotate angle x y zScale sx sy szColor [r g b]Surface "material"Sphere radius zmin zmax thetamaxPolygon(converted to triangles)NuPatch(NURBS surfaces with full B-spline evaluation)LightSource "type"
plastic: Standard plastic material with moderate reflectionmetal: Highly reflective metallic materialmatte: Non-reflective diffuse material
The renderer includes full support for Non-Uniform Rational B-Spline (NURBS) surfaces via the NuPatch command:
- Complete B-spline evaluation using Cox-de Boor recursion algorithm
- Arbitrary degree surfaces with custom knot vectors
- Tessellation-based ray intersection for reliable rendering
- Multi-threaded NURBS rendering with proper serialization
- Standard RenderMan syntax compatibility
Example NURBS syntax:
NuPatch 3 3 "0 0 0 1 1 1" 0 1 3 3 "0 0 0 1 1 1" 0 1 "P" [
-1.0 -1.0 -3.0 0.0 -1.0 -3.0 1.0 -1.0 -3.0
-1.0 0.0 -3.0 0.0 0.0 -3.0 1.0 0.0 -3.0
-1.0 1.0 -3.0 0.0 1.0 -3.0 1.0 1.0 -3.0
]
The raytracer includes a comprehensive testing framework that validates output using deterministic seeding:
# Run all tests
npm test
# Generate reference images for tests
npm run test:references
# Clean test output files
npm run test:clean
# Compare two images manually
npm run image:diff image1.ppm image2.ppm- Bit-for-bit comparison of rendered images with reference images
- Multi-threading validation ensures single and multi-threaded renders are identical
- Deterministic seeding for reproducible test results
- Automatic reference generation when references don't exist
- Comprehensive reporting with detailed failure analysis
The renderer is built with a modular architecture:
- math.js: Vector math, matrices, rays, and color utilities
- geometry.js: Geometric primitives and scene management
- rib-parser.js: RenderMan RIB file parser
- raytracer.js: Core raytracing engine and camera system
- multi-threaded-raytracer.js: Multi-threading implementation with worker threads
- random.js: Deterministic random number generator for reproducible results
- image-output.js: Image file generation (PPM format)
- renderer.js: Main application and command-line interface
##RenderMan RIB-Structure 1.1
version 3.03
Format 400 300 1
Projection "perspective" "fov" [45]
WorldBegin
LightSource "distantlight" 1 "from" [1 1 1] "to" [0 0 0]
AttributeBegin
Color [0.8 0.2 0.2]
Surface "plastic"
Sphere 0.5 -0.5 0.5 360
AttributeEnd
WorldEnd
- Rendering time increases significantly with resolution and sample count
- Multi-Threading:
- Multi-threaded rendering is enabled by default and automatically uses all available CPU cores
- Performance improvement scales with CPU core count (typically 2-8x faster)
- Use
--threads Nand--seedto seed the random number generation for debugging or comparison
- Antialiasing Options:
--aa none: Fastest, aliased edges--aa low: 4x slower than none, removes most aliasing--aa medium: 9x slower, good quality for most scenes--aa high: 16x slower, high quality for final renders--aa ultra: 25x slower, maximum quality
- Stratified vs Random Sampling:
- Stratified sampling (default) provides better quality and more even noise distribution
- Random sampling (
--no-stratified) may be faster but with more noise
- Use multi-threading for production renders (enabled by default)
- Start with
--aa mediumfor quality/speed balance - Use lower resolutions for testing and development
- Consider
--threads Nwhere N is slightly less than your CPU cores for better system responsiveness
PPM files can be viewed with most image viewers or converted to other formats:
# Convert to PNG using ImageMagick
convert output.ppm output.png
# View directly (on macOS)
open output.ppm