This is the Phabricator task for my GSoC 2018 project. Please have a look at it, and comment if you have any feedback, expectations, etc.
I'll be making subtasks later for each part/feature/documentation item.
Thanks in advance!
Implementing a Hair Shader for Cycles
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 intern/cycles/util.
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 (intern/cycles/kernel/shaders/).
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 intern/cycles/kernel/closure/svm_closure.h.
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 source/blender/blenkernel/.
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 source/blender/nodes/shader/nodes;
- reserve a new shader ID at source/blender/blenkernel/BKE_node.h and register it at source/blender/nodes/NOD_static_types.h.
- declare the new registration function in blender/blenkernel/intern/NOD_shader.h and call it from registerShaderNodes() in node.c.
Blender employs two types of testing:
- unit tests, in src/test/render_graph_finalize_test.cpp
- regression tests, implemented as reproducible scenes (lib/tests/cycles/ctests/shader/hair_*.blend)
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. SafeASin and 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.
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.