Distributed Rendering with Rust and Mio

02 Jan 2016

In this post we’ll take a look at adding distributed rendering to tray_rust which will let us take advantage of multiple machines when rendering an image, like a compute cluster. To do this we’ll look at options for how to distribute the rendering job across multiple nodes and what sort of communication is needed synchronize their work. We’ll also look into how we can use mio to write an efficient master process that can manage multiple workers effectively.

After implementing a simple technique to distribute the job we’ll discuss the scalability of this approach and possible paths forward to improve it. I’ve also recently written a plugin for Blender so you can easily create your own scenes and will mention a bit on how to run the ray tracer on Google Compute Engine (or AWS EC2) if you want to try out the distributed rendering yourself.

Continue...

Rendering an Animation in Rust

16 Dec 2015

In this post we’ll look at adding a pretty awesome new feature to tray_rust, something I’ve never implemented before: animation! We’ll take a look at a simple way for sampling time in our scene, how we can associate time points with transformations of objects to make them move and how to compute smooth animation paths with B-Splines. Then we’ll wrap up with rendering a really cool animation by using 60 different machines spread across two clusters at my lab.

Continue...

Porting a Ray Tracer to Rust, part 3

15 May 2015

It’s been a little while since my last post on tray_rust as I’ve been a busy with classes, but I’ve had a bit of free time to implement some extremely cool features. In this post we’ll look at porting over the path tracing code and adding a bounding volume hierarchy, along with adding support for triangle meshes and measured material data from the MERL BRDF Database introduced by Matusik et al. in 2003 in A Data-Driven Reflectance Model. In the process of implementing the BVH we’ll get a taste of Rust’s generic programming facilities and use them to write a flexible BVH capable of storing any type that can report its bounds. In the spirit of fogleman’s gorgeous Go Gopher in Go we’ll wrap up by rendering the Rust logo in Rust using a model made by Nylithius on BlenderArtists.

If you’ve been following Rust’s development a bit you have probably noticed that the timing of this post is not a coincidence, since Rust 1.0.0 is being released today!

Continue...

Porting a Ray Tracer to Rust, part 2

30 Jan 2015

As mentioned in my previous post I spent the past month-ish working on improving both the rendering capabilities and performance of tray_rust. While it’s not yet capable of path tracing we can at least have light and shadow and shade our objects with diffuse or specularly reflective and/or transmissive materials. Along with this I’ve improved performance by parallelizing the rendering process using Rust’s multithreading capabilities. Although ray tracing is a trivially parallel task there are two pieces of state that must be shared and modified between threads: the pixel/block counter and the framebuffer. With Rust’s strong focus on safety I was worried that I would have to resort to unsafe blocks to share these small pieces of mutable state but I found that the std::sync module provided safe methods for everything I needed and performs quite well. While it’s difficult to compare against tray (my initial C++ version) as the design of tray_rust has diverged quite a bit I’ll put some performance numbers in the multithreading section.

During the past month Rust has also seen some pretty large changes and is currently in its 1.0 alpha release with the first beta fast approaching.

Continue...

Porting a Ray Tracer to Rust, part 1

30 Dec 2014

I’ve decided to port over my physically based ray tracer tray to Rust to finally try out the language with a decent sized project. In the series we’ll work through the implementation of a physically based ray tracer built on the techniques discussed in Physically Based Rendering. I won’t go into a lot of detail about rendering theory or the less exciting implementation details but will focus more on Rust specific concerns and implementation decisions along with comparisons vs. my C++ version. If you’re looking to learn more about ray tracing I highly recommend picking up Physically Based Rendering and working through it. Hopefully throughout the series folks more experienced with Rust can point out mistakes and improvements as well, since I have no experience with Rust prior to this series.

With the intro out of the way, let’s get started! Since it’s the beginning of the series this is my first time really working with Rust and our goal is pretty simple: render a white sphere and save the image.

Continue...

Postscript 1: Easy Cleanup

01 Aug 2014

In this quick postscript we’ll look into a simple way to clean up our various SDL resources with variadic templates and template specialization. This will let us clean up all our resources with a single simple call: cleanup(texA, texB, renderer, window) instead of calling all the corresponding SDL_Destroy/Free* functions, saving ourselves a lot of typing.

We’ll do this by creating a variadic function cleanup that will take the list of SDL resources to be free’d and then define specializations of it for each resource we’ll be passing, eg. for SDL_Window, SDL_Renderer, SDL_Texture and so on.

Continue...

Postscript 0: Properly Finding Resource Paths

16 Jun 2014

In this short postscript we’ll learn how to make use of SDL_GetBasePath to properly resolve the path to our resource directory where we’ll be storing all the assets needed for each lesson. This approach lets us avoid issues with relative paths since it doesn’t depend on where the program working directory is set when it’s run. This functionality was introduced in SDL 2.0.1 so if you haven’t updated to the latest SDL be sure to grab that before getting started.

Continue...

Lesson 0: CMake

06 Mar 2014

CMake is really useful for building the lessons since it lets us generate make files or project files for just about any platform and IDE. It also helps with resolving dependencies (such as SDL2), platform specific configurations and much much more. If you’re unfamiliar with CMake there’s a nice introduction available on their site to help you get started.

Continue...

Lesson 6: True Type Fonts with SDL_ttf

18 Dec 2013

In this lesson we’ll see how to perform basic True Type font rendering with the SDL_ttf extension library. Setting up the library is identical to what we did in Lesson 3 for SDL_image, but just replace “image” with “ttf” (Windows users should also copy the included freetype dll over). So download SDL_ttf, take a peek at the documentation, and let’s get started!

Continue...

Lesson 5: Clipping Sprite Sheets

27 Aug 2013

It’s common in sprite based games to use a larger image file containing many smaller images, such as the tiles for a tileset, instead of having a separate image file for each tile. This type of image is known as a sprite sheet and is very handy to work with since we don’t need to change which texture we’re drawing each time but rather just which subsection of the texture.

Continue...

Lesson 4: Handling Events

20 Aug 2013

In this lesson we’ll learn the basics of reading user input with SDL, in this simple example we’ll interpret any input as the user wanting to quit our application. To read events SDL provides the SDL_Event structure and functions to get events from the queue such as SDL_PollEvent. The code for this lesson is built off of the lesson 3 code, if you need that code to start from grab it on Github and let’s get started!

Continue...

Lesson 3: SDL Extension Libraries

18 Aug 2013

Up until now we’ve only been using BMP images as they’re the only type supported by the base SDL library, but being restricted to using BMP images isn’t that great. Fortunately there are a set of SDL extension libraries that add useful features to SDL, such as support for a wide variety of image types through SDL_image. The other available libraries are SDL_ttf which provides TTF rendering support, SDL_net which provides low level networking and SDL_mixer which provides multi-channel audio playback.

Continue...

Lesson 2: Don't Put Everything in Main

17 Aug 2013

In this lesson we’ll begin organizing our texture loading and rendering code from the previous lesson by moving them out of main and placing them into some useful functions. We’ll also write a simple generic SDL error logger and learn how images are positioned and scaled when rendering with SDL.

Continue...

Lesson 1: Hello World

17 Aug 2013

In this lesson we’ll learn how to open a window, create a rendering context and draw an image we’ve loaded to the screen. Grab the BMP we’ll be drawing below and save it somewhere in your project and let’s get started!

Continue...

Lesson 0: Visual Studio

15 Aug 2013

Now that we’ve got the libraries installed we’ll want to create a new project to include and link against SDL. At the end we’ll save this as a template project so in the future we can just load our template and get to work. First we need a new empty C++ project.

Continue...

Lesson 0: Setting Up SDL

15 Aug 2013

The first step is to get the SDL2 development libraries setup on your system, you can download them from the SDL2 downloads page.

Continue...

Lesson 0: MinGW

15 Aug 2013

To build the projects with mingw we’ll be using a lightweight makefile that will set the include and library paths along with linking our dependencies for us. The makefile assumes that you’ve placed the SDL mingw development libraries under C:/SDL2-2.0.0-mingw/ and that you’re using the 32bit version of mingw and the 32bit libraries. You should change this to match your compiler (32/64bit) and the location of your SDL folder. To use makefiles with mingw call mingw32-make.exe in the folder containing the makefile.

If you’re unfamiliar with Makefiles a basic introduction can be found here.

Continue...

Lesson 0: Mac Command Line

15 Aug 2013

To build the projects on OS X we’ll be using a simple makefile that will include the framework for us. The makefile assumes you’ve installed SDL following the instructions in the .dmg file on the SDL2 downloads page and now have it available as a framework.

If you’re unfamiliar with Makefiles a basic introduction can be found here.

Continue...

Lesson 0: Linux Command Line

15 Aug 2013

To build the projects on Linux we’ll be using a simple makefile that will setup the include and library dependencies for us. The makefile assumes that your SDL libraries are installed under /usr/local/lib and the headers are under /usr/local/include. These are the install locations if you built the project through cmake, some more detail on building from source can be found here. If you’ve installed it through your package manager or placed the libraries and headers elsewhere you may need to change these paths to match your installation. You can also check the output of sdl2-config with the --cflags and --libs switches to locate your install, assuming you haven’t moved it.

If you’re unfamiliar with Makefiles a basic introduction can be found here.

Continue...