npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

raytracer-node

v5.0.0

Published

An Node.js interface to a C++ Raytracing Engine

Downloads

15

Readme

Monte Carlo Raytracing Engine

A Dynamic Fully Fledged Raytracing Engine Built in C++

About Project

An engine built to render complex scenes with all the capabilities of real world private engines. Images are outputted in the PPM format and use a simple driver file system for creation.

The engine uses a Monte Carlo technique to render images. This process randomly fires rays on contact with Lambertian materials. This creates much more accurate lighting than traditional Ray Tracing. The downside is of course speed. The engine can handle simple Lambertian surfaces, metal surfaces with total reflection, and refractive surfaces such as glass. The engine also produces accurate shadows and highlights and has complex material control.

Current work on this project is to migrate all base files to GPU compatible Cuda code.

Example Images

Spheres

Shown below are the resulting images when running the engine with the driver "Spheres".

| Number of Samples | Resulting Image | | ----------------- | --------------- | | 10 Samples | 10 Samples | | 100 Samples | 100 Samples | | 1000 Samples | 1000 Samples | | 10000 Samples | 10000 Samples |

Mando

Shown below are the resulting images when running the engine with the driver "Mando".

| Number of Samples | Resulting Image | | ----------------- | --------------- | | 10 Samples | 10 Samples | | 100 Samples | 100 Samples |

Installation

Building the Executable

After downloading the repository, navigate to the directory where the repository is stored.

From the command line, enter the following commands.

mkdir build
cmake .. && make

At this time, we do not support Windows or MacOS.

Running the Engine

After You Have Built the Executable, Run The Program Using the Command

./raytracer [Driver File] [Ouput File] [Samples]

The output format for the image is the PPM model. You can open such images in most image viewers and applications such as Adobe Photoshop. The number of Samples directly coresponds to the amount of noise in the image. The higher the samples, the higher quality of an image.

Node Driver

In addition, you can build this project as a Node.js package. Simply install the package with the following command.

npm install raytracer-node

Here are a couple of example functions that utilize the library (written with ES6 syntax). Please note that node is single threaded, and as such, this library will appear to "crash" your thread. It will complete its task given time. If you wish to use a rendering engine with this program, I would recommend looking into experimental node features or using worker windows in something like electron to hide the slowdown.

function runRaytracer() {
    createImage(
        [
            "0 0.25 -30", 
            "0 0 1", 
            "0 1 0", 
            "-10", 
            "-10 10 -10 10", 
            "400 400", 
            "100"
        ],
		[
			"0 0 -10000000030 10000000000 0.3 0.3 0.8",
			"0 0 10000000020 10000000000 0.3 0.3 0.8",
			"0 -10000000020 0 10000000000 0.9 0.9 0.9",
			"0 10000000020 0 10000000000 0.9 0.9 0.9",
			"0 59.5 0 40 1.5 1.5 1.5 light",
			"-10000000020 0 0 10000000000 0.3 0.8 0.3",
			"10000000020 0 0 10000000000 0.8 0.3 0.3",
			"-7 -17.1 0 3 0.8 0.8 0.8 glass",
			"5 -17.1 5 3 0.8 0.8 0.8 mirror"
		])
}
import raytracer from 'raytracer-node';

var lastCall = 0;

function createImage(sceneData, sphereData) {
    const emitter = new EventEmitter()

	emitter.on('start', (file) => console.log(file));
	emitter.on('progress', (percent, time) =>
	{
        let splitTime = time.split(" ");
        splitTime[3] = parseFloat(splitTime[3]).toFixed(2);

        let fixedString = splitTime.join(" ");

        if (new Date() - lastCall < 500)
        {
            return false;
        }

        lastCall = new Date();
        console.log("Percent Complete", parseInt(percent.substring(0, 2)), "Time Remaining", fixedString);
    });
    emitter.on('finish', (time) => console.log(time));
    const imageString = raytracer(emitter.emit.bind(emitter), sceneData, sphereData);

    emitter.removeListener('start', () => {});
	emitter.removeListener('progress', () => {});
	emitter.removeListener('finish', () => {});

    return imageString;
}
function generateHTMLElement(imageString) {
    let imageDataLines = outputImageString.split("\n");
    let imageDataLinesBroken = [];

    imageDataLines.forEach((line) =>
    {
        imageDataLinesBroken.push(line.split(" "));
    });

    let width = imageDataLinesBroken[1][0];
    let height = imageDataLinesBroken[1][1];

    let c = document.createElement("canvas");
    let ctx = c.getContext("2d");

    c.width = width;
    c.height = height;

    let myImageData = ctx.createImageData(width, height);
    let counter = 0;

    let imageData = myImageData.data;

    for (let i = 2; i < imageDataLinesBroken.length; i++)
    {
        for (let j = 0; j < imageDataLinesBroken[i].length; j++)
        {
            imageData[counter] = parseInt(imageDataLinesBroken[i][j]);
            counter++;

            if ((j + 1) % 3 === 0)
            {
                imageData[counter] = 255;
                counter++;
            }
        }
    }

    ctx.putImageData(myImageData, 0, 0);
    return c.toDataURL("image/png");
}

Creating Driver Files

For your convenience, example driver files have been provided under the folder titled ExampleDriverFiles. These driver files are all fully featured to create interesting and dramatic images that showcase the features of the engine.

If you wish to create your own driver files, the following fields are required for each element:

eye X Y Z  
look X Y Z  
up X Y Z  
d Distance  
bounds Left Right Bottom Top  
res Width Height  
sphere X Y Z Radius AlbedoRed AlbedoGreen AlbedoBlue  
model RX RY RZ RTheta ScaleFactor TX TY TZ SmoothingTheta FilePath

For Spheres and for Model Material Files, optional fields exist. Appending light, mirror, or glass to the end of a sphere line or material description will activate the corresponding property for that section of the image. See reference driver files for examples. Make sure that the bounds and resolution share an aspect ratio. This is important to ensure no artifacts.

For a node install, you directly input the fields above into the function call. The first arguement to the library will be an emitter, followed by the scene data, and then the sphere data. You must also append the number of samples required to the scene data, as shown in the example above.

Where to Find OBJ Files

Finding obj files is inconsequential. Simply look up ".obj files" on the internet and choose one that fits your liking. Make sure that you create the proper material file using the format showcases in the example files. Files with Triangle counts of over 10K will result in images that take a significant time to render.