Skip to content

Instantly share code, notes, and snippets.

@Celeborn2BeAlive
Last active June 11, 2019 15:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Celeborn2BeAlive/370f3a4fd274688d2c9aa6dc3f33015d to your computer and use it in GitHub Desktop.
Save Celeborn2BeAlive/370f3a4fd274688d2c9aa6dc3f33015d to your computer and use it in GitHub Desktop.
Diving into Cycles source code

Diving into Cycles source code

This document describes my understanding of the Cycles renderer source code. Cycles is a unidirectional path tracer provided with Blender for production rendering. As a production renderer, its code favors performance and simplicity over generality. It can run on CPU or GPU, and the same kernel code can be compiled with a CPU compiler (gcc, msbuild) or a GPU compiler (cuda, OpenCL). To do that, the code tries to remain simple (mostly C code) but exploit macros to specialize some parts of the code.

In this document I focus on the CPU rendering. I compiled blender in "full" mode, meaning Cuda kernels are not compiled. One reason for that is Cuda kernel compilation seems quite expensive so if I want to change the code and quickly iterate, it might be hard. I may do another analysis for GPU part later but I doubt it would be very interesting since it is the same code.

Entry point

By running blender in render mode with cycles, I can break into the function CPUDevice::thread_render, which seems to be the function run by each thread in order to aquire tiles and render them with path tracing.

The actual call stack is:

  • CPUDevice::thread_run which take a DeviceTask instance as parameter. This task is typed either RENDER, FILM_CONVERT and SHADER. For now I'm only interested in the RENDER case, which call thread_render
  • CPUDevice::thread_render which is the rendering function

This call stack is triggered in TaskScheduler::thread_run, which seems to be a utility class for task scheduling.

The task has been added from the Session class, in the render() method. render() is called in Session::run_cpu(), which seems after that to wait for the rendering to finish and print progress.

Projects

In Visual Studio, the code is divided into multiple projects:

  • cycle_util : utility code, not related to rendering, contrains things such as util_xml.h, util_task.h, util_time.h, etc.
  • cycle_subd : subdivision code, wrap opensubdiv
  • cycle_render : library for the renderer, contains things on top of path tracing, represents a rendering session with the Session class. It seems to be the thing to interract with if we want to make a standalone app using cycles ?
  • bf_intern_cycles : bf stands for "blender foundation". It seems to be the library that interract with blender. The concept of session and synchronisation seems also present here. I see some files "blender_*.cpp"
  • cycles_graph : obviously a DAG, we seen a node class, XML representation. Maybe it is used to represent shading graphs in cycles.
  • cycles_bvh : bounding volume hierarchy for ray tracing. There is a bvh_embree.h file so I think some code has been taken directly from embree.
  • cycles_device : cycles seems to abstract the thing is is running on (cpu, gpu, etc) as a Device instance, which make sense. Implementations of such device seems to be in this project.
  • cycles_kernel : seems to be the big part, the actual path tracing code. Kernels seem to be simple functions that can be compiled on multiple devices and called from Device instance methods.
  • kernel/cycles_kernel_osl : optionally cycles can use OSL for shading graph evaluation, the code for the glue seems here
  • kernel/cycles_osl_shaders : well, OSL shaders.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment