Implementing a Hair Shader for Cycles
Leonardo Emanuel Segovia
Realistic hair or fur is essential when creating a plausible virtual world. In feature animation, this is often used to define the signature look of characters; examples include Pixar’s Brave (Iben et al. 2013), and Walt Disney Animation Studios’ Tangled (Sadeghi et al. 2010; also Ward et al. 2010) and Zootopia (Chiang et al. 2016).
Currently, Cycles has a working hair shader (wiki page, sources), based on Marschner et al. (2003)’s model. Its several assumptions and simplifications make it inaccurate for light colored hair (d’Eon et al. 2011) as well as for most types of fur (Yan et al. 2015). Furthermore, d’Eon et al. (2011) and Khungurn and Marschner (2017) demonstrated it to not be energy conserving.
This project intends to upgrade Cycles’ hair shader to the aforementioned Zootopia shader by Chiang et al. (2016), by porting Pharr (2017)’s implementation. Lukas Stockner has made available a WIP patch, which may also serve as a basis for this work.
By having this functionality, the Blender community will be able to render physically accurate, production-level quality hair without resorting to proprietary engines such as RenderMan.
The delivered shader implementation should be expected to include:
- the node itself (in SVM as well as OSL)
- node-UI bindings
- energy conservation tests i.e. white furnace test
- formal verification tests i.e. correctness of the mathematical primitives
- Blender-Wiki documentation
- developer documentation
Cycles shader nodes are implemented using one of the following choices:
- simply using a custom Open Shading Language node;
- these are only usable with CPU renders
- direct C++ implementation via SVM and OSL (in the sections below).
- these are available for both CPU and GPU
Anatomy of a Shader
The layout of a Cycles node is as follows (guidance taken from here:
Cycles’ mathematical primitives are contained in
Cycles’ BSDF closures are defined in
intern/cycles/kernel/closure/. These define the primitives that will be used later by the chosen shader backend.
Cycles has two backends available for direct shader implementation.
The first is the Open Shading Language (OSL,
intern/cycles/kernel/osl). These kind of shaders are only usable in the CPU. To implement them, the shader’s closure must be registered first in
intern/cycles/kernel/osl/osl_closures.cpp, which makes the necessary functions available for use by the shader itself (
A similar workflow is followed by the Shader Virtual Machine (SVM,
intern/cycles/kernel/osl/). Shaders implemented using the SVM can be used in both CPU and GPU renders. In this case, the shader’s BSDF components must be registered in
intern/cycles/kernel/closure/bsdf.h, and then the closure is evaluated in the interpreter loop at
Blender UI registration
New Cycles shader nodes need to be made available to Blender’s UI. This is implemented in the files at
source/blender/nodes/shader/nodes, while the general registration calls are available at
The registration logic includes:
- implementing node sockets i.e. input and output parameters;
- registering the shader itself with the GPU kernel.
After implementing the shader, the workflow would be as follows:
- create and implement the registration logic in
- reserve a new shader ID at
source/blender/blenkernel/BKE_node.hand register it at
- declare the new registration function in
blender/blenkernel/intern/NOD_shader.hand call it from
Blender employs two types of testing:
- unit tests, in
- regression tests, implemented as reproducible scenes (
From a technical point of view, Pharr’s implementation already includes:
- a white furnace test to ensure energy conservation
- a statistical test to verify correctness of the custom primitives.
These should be easily ported to Cycles’ unit test framework. As an addition, I can also repurpose the existing hair tests to suit the new shader.
Pharr’s implementation comes out-of-the-box with several customized, high performance primitives e.g.
SafePow. They are all defined in terms of C++ standard functions, so there should be no need to change them.
Further optimization could be done with flame graphs and Perfview in Windows (the platform I’m most experienced with). For the GPU version, I could profile it with Nvidia Nsight Visual Studio Edition’s Heads-Up Display.
In addition to the above, I should also test the shader’s:
- compatibility with different types of lights (point, area, etc.)
- compatibility with importance sampling mechanisms
- sampling noise results.
I expect to have testing builds available, if possible via Blender’s experimental-buildbot to receive and act on early feedback.
We divide the shader documentation in two:
- developer documentation: I expect the implementation to be self-documented simultaneously with the coding. There is also very little documentation on Blender’s node architecture as well; I can produce blog posts providing further insight on this.
- Blender-Wiki documentation: apart from the obvious adjustments to the wiki page, I suggest to make the shader’s theoretical background more explicit. A link to the paper, as well as a bit of theoretical background (for those more technically inclined) would suffice.
Weeks are measured from Mon-Sun to align with GSoC’s Coding Period start date.
|Apr 23 – May 13||Get acquainted with Blender’s code layout and standards, especially how Cycles nodes are implemented and the available mathematical facilities. Ensure Blender compiles successfully on all work devices.|
|1||May 14 – May 20||Review of Pharr’s code. Implement a dummy Cycles node. Verify exposure of shader’s parameters and test setters/getters.|
|2||May 21 – May 27||Port Pharr’s shader primitives and statistical tests. Verify they work as expected.|
|3||May 28 – Jun 3||Port Pharr’s shading function.|
|4||Jun 4 – Jun 10||Test shader functionality. If working, release test build.|
|5||Jun 11 – Jun 17||Evaluate received feedback. Start bug fixes.|
|6||Jun 18 – Jun 24||Port Pharr’s furnace test. Verify it works as expected.|
|7||Jun 25 – Jul 1||Testing and bug fixes.|
|Jul 2||Uni’s winter break starts here!|
|8||Jul 2 – Jul 8||Repurpose existing regression tests and obtain reference renders.|
|9||Jul 9 – Jul 15||General testing and bug fixes.|
|10||Jul 16 – Jul 22||User documentation revision.|
|11||Jul 23 – Jul 29||Developer documentation revision.|
|12||Jul 30 – Aug 5||Reserved week (just in case anything happens)|
|Aug 6||Finish line! 👍|
These are my university’s holiday dates as well (link in Spanish).
|May 1||Workers’ Day|
|2||May 25||Anniversary of the May Revolution|
|5||Jun 17||Anniversary of the death of Martín Miguel de Güemes|
|6||Jun 20||Flag’s Day|
|9||Jul 9||Independence Day|
I have the following fixed commitments during the GSoC coding period. The timetable is given in GMT-3:
- French classes
- Tue & Thu 1800-2000
- Postgraduate course “Digital Image Processing”
- Thu 1230-1400
- Fri 0800-1000
Any new commitments will be reported and coordinated with my assigned mentor as soon as possible.
Hi all! My name is Leonardo, and I am a 25-years-old student of the MSc in Computer Science (Spanish: Magister en Ciencias de la Computación), at the Universidad Nacional del Sur in Bahía Blanca, Argentina. Previously, I got my BSc in Computer Science in December 2016 from the same university, with a thesis in collision detection and handling in the Unity engine (see Selzer et al. (2017)).
My coding experience has already involved working with large code bases: I have contributed several patches to the Krita painting suite and the Mitsuba renderer (C++, LaTeX), and Homebrew as well (Ruby). Thanks to these projects, I am familiar with all operating systems in which Blender runs (Linux, MacOS, Windows). I have also picked some knowledge of OpenGL and CUDA from university courses.
I would love to do this project for two reasons. The first one is that, as part of my MSc thesis (started Aug 2017), I planned to implement one of Disney or Pixar’s shaders in an open source rendering engine. I never expected to see this very same idea proposed for GSoC 😂 ! The second reason is that working with people from around the world, in a production-level rendering engine, would be an invaluable experience for me as well as for my university.
The following references include a DOI for your viewing pleasure.
Chiang, Matt Jen-Yuan, Benedikt Bitterli, Chuck Tappan, and Brent Burley. 2016. “A Practical and Controllable Hair and Fur Model for Production Path Tracing.” Computer Graphics Forum 35 (2): 275–83. https://doi.org/10.1111/cgf.12830.
d’Eon, Eugene, Guillaume Francois, Martin Hill, Joe Letteri, and Jean-Marie Aubry. 2011. “An Energy-Conserving Hair Reflectance Model.” Computer Graphics Forum 30 (4): 1181–7. https://doi.org/10.1111/j.1467-8659.2011.01976.x.
Iben, Hayley, Mark Meyer, Lena Petrovic, Olivier Soares, John Anderson, and Andrew Witkin. 2013. “Artistic Simulation of Curly Hair.” In Proceedings of the 12th Acm Siggraph/Eurographics Symposium on Computer Animation, 63–71. SCA ’13. New York, NY, USA: ACM. https://doi.org/10.1145/2485895.2485913.
Khungurn, Pramook, and Steve Marschner. 2017. “Azimuthal Scattering from Elliptical Hair Fibers.” ACM Trans. Graph. 36 (2). New York, NY, USA: ACM: 13:1–13:23. https://doi.org/10.1145/2998578.
Marschner, Stephen R., Henrik Wann Jensen, Mike Cammarano, Steve Worley, and Pat Hanrahan. 2003. “Light Scattering from Human Hair Fibers.” In ACM Siggraph 2003 Papers, 780–91. SIGGRAPH ’03. New York, NY, USA: ACM. https://doi.org/10.1145/1201775.882345.
Pharr, Matt. 2017. “The Implementation of a Hair Scattering Model.” In Physically Based Rendering: From Theory to Implementation, 3rd ed. Boston, MA, USA: Morgan Kaufmann. http://www.pbrt.org/hair.pdf.
Sadeghi, Iman, Heather Pritchett, Henrik Wann Jensen, and Rasmus Tamstorf. 2010. “An Artist Friendly Hair Shading System.” In ACM Siggraph 2010 Papers, 56:1–56:10. SIGGRAPH ’10. New York, NY, USA: ACM. https://doi.org/10.1145/1833349.1778793.
Selzer, Matías Nicolás, Elisabet Arriata, Leonardo Segovia, Nicolás Fernando Gazcón, and Martín Leonardo Larrea. 2017. “Modelos de interacción y aplicaciones en realidad virtual mediante dispositivos móviles.” In XIX Workshop de Investigadores en Ciencias de la Computación (WICC 2017, ITBA, Buenos Aires). Buenos Aires, Argentina. http://hdl.handle.net/10915/61869.
Ward, Kelly, Maryann Simmons, Andy Milne, Hidetaka Yosumi, and Xinmin Zhao. 2010. “Simulating Rapunzel’s Hair in Disney’s Tangled.” In ACM Siggraph 2010 Talks, 22:1–22:1. SIGGRAPH ’10. New York, NY, USA: ACM. https://doi.org/10.1145/1837026.1837055.
Yan, Ling-Qi, Chi-Wei Tseng, Henrik Wann Jensen, and Ravi Ramamoorthi. 2015. “Physically-Accurate Fur Reflectance: Modeling, Measurement and Rendering.” ACM Trans. Graph. 34 (6). New York, NY, USA: ACM: 185:1–185:13. https://doi.org/10.1145/2816795.2818080.