Simple Ray Tracing in Rust 4: Exporting PNG Outputs
Now that we’re able to output the pixels of our ray traced image,
we can work on exporting it in a format that can be easily displayed,
such as a .png
file. Of course, building a .png
from scratch
would be quite an undertaking. Instead, we will output our
image as a .ppm
file, a much simpler format.
.ppm Formatting
Let’s take a look at an example .ppm
file.
P3 # This is an RGB image
3 2 # This image is 3 pixels wide and 2 pixels tall
255 # RGB values go from 0 to 255
255 255 255 # The top left pixel is white
255 255 255
0 0 255 # The top right pixel is blue
100 0 64
10 10 10
255 0 0 # The bottom right pixel is red
After 3 initial metadata lines, each line describes a pixel’s color. The pixels are ordered from left to right, top to bottom.
Our .ppm Writer
Recall that our main function currently looks like this:
Let’s add a simple helper method on scene that will write our output.
We’ll implement it as a method on Scene
, and move the
call to iterate_over_rays
from main
to here:
With this helper and a couple of new imports
from Rust’s standard library, we can put together a compact
and robust main
function. It creates an output file
and writes our rendering to it in a .ppm
format,
just as we want:
Incredibly, this is essentially all we need for our program.
With just this, we’re now able to crunch a .obj
input
into a .ppm
output that a good image viewer will
be able to display on your computer screen!
Exporting as PNG Files
There’s one more thing we can do here. For convenience,
we can convert our .ppm
output file into a much
more universally recognized format like .png
.
This can be easily accomplished with a tool
like ImageMagick; using the command line on Linux,
we can write convert path/to/x.ppm path/to/y.png
to create a new .png
file from x.ppm
.
For this program, we can use a Bash script to automate the typing away:
This little script will look through all generated
outputs, convert them into .png
files,
and delete the originals. Nice! Let’s put
it in ./scripts/export.sh
.
We can finally organize everything in a Makefile so that we can execute our program from the command line without having to memorize long, tedious sequences to type in.
Here, we make use of eog
as an image displayer.
make run
produces.ppm
outputs for given inputsmake all
produces.png
outputs for given inputs and displays themmake display
displays pre-rendered output filesmake clean
removes all files in the output folder
Conclusion
Well this was short and sweet. And… what’s this, we can actually see our renderings now! Awesome! And we even added some convenience scripts to smooth out our workflow. Now we have the meat of our program done. Time to optimize…