Page MenuHome

GSoC 2018 project: Implementing a Hair Shader for Cycles
Open, NormalPublic

Description

Hi all,

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

Synopsis

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.

Benefits

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.

Deliverables

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

Project Details

Shader Implementation

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:

General primitives

Cycles’ mathematical primitives are contained in intern/cycles/util.

Shader closure

Cycles’ BSDF closures are defined in intern/cycles/kernel/closure/. These define the primitives that will be used later by the chosen shader backend.

Shader implementation

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.

Verification

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.

Optimization

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.

Documentation

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.

Project Schedule

Weeks are measured from Mon-Sun to align with GSoC’s Coding Period start date.

WeekTimeframePlans
Apr 23 – May 13Get 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.
1May 14 – May 20Review of Pharr’s code. Implement a dummy Cycles node. Verify exposure of shader’s parameters and test setters/getters.
2May 21 – May 27Port Pharr’s shader primitives and statistical tests. Verify they work as expected.
3May 28 – Jun 3Port Pharr’s shading function.
4Jun 4 – Jun 10Test shader functionality. If working, release test build.
5Jun 11 – Jun 17Evaluate received feedback. Start bug fixes.
6Jun 18 – Jun 24Port Pharr’s furnace test. Verify it works as expected.
7Jun 25 – Jul 1Testing and bug fixes.
Jul 2*Uni’s winter break starts here!*
8Jul 2 – Jul 8Repurpose existing regression tests and obtain reference renders.
9Jul 9 – Jul 15General testing and bug fixes.
10Jul 16 – Jul 22User documentation revision.
11Jul 23 – Jul 29Developer documentation revision.
12Jul 30 – Aug 5Reserved week (just in case anything happens)
Aug 6*Finish line!* 👍

These are my university’s holiday dates as well (link in Spanish).

WeekTimeframeHoliday
May 1Workers’ Day
2May 25Anniversary of the May Revolution
5Jun 17Anniversary of the death of Martín Miguel de Güemes
6Jun 20Flag’s Day
9Jul 9Independence Day

School conflicts

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.

 References

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.

Details

Commits
rB5078b9d2d08a: Cycles: add Principled Hair BSDF.
rB8547643039a2: Give the Absorption coefficient its own socket
rB714c67ad5634: Indent typo in the node update
rB535e2e4ade24: Merge branch 'master' into soc-2018-hair-shader
rB9b632addd347: Merge branch 'master' into soc-2018-hair-shader
rBbd37b18a0d6d: Update signatures to use Lukas's new linear_rgb_to_gray
rB2d1eef87f6b6: Fix discrepancy between RNG in CPU and GPU
rBe267191393fe: Fix a precision issue in the coord frame with low roughness
rBdc2827fd907d: Cleanup: store and retrieve parameters consistently
rB60a59fbae6b0: Merge branch 'master' into soc-2018-hair-shader
rB4f4b7ea9d70b: Remove unused closure
rB5c07292bde39: UI: rename various nodes
rBf91635e64e50: Refactor Melanin into Tungsten's quantity and ratio parameters
rBb005c15f6734: Amend OSL shader w.r.t. Melanin changes
rB06fb2a06738c: Amend OSL shader again to account for parameter renaming
rBc36722f96287: Remap randomization to roughness/color ± the given percentage factor
rB45abb2eee803: Reorder sockets according to usefulness
rB20ed03722fad: Remove "Physical" parametrization [READ BELOW PLEASE]
rBc59ed14619e7: Remove two possible sources of NaNs
rB332b2d6206c1: Randomization is (currently) only available for melanin
rB9e59a1f7b5c0: Merge branch 'master' into soc-2018-hair-shader
rB257a7701e04d: Apologies, I didn't complete the defaults properly!
rBafa31086bcca: Revert "Take out two of Lukas's optimizations in the Bessel function"
rB6e8ab6d21395: Add hair dye to Melanin concentration mode
rBb891aa810947: Use Benedikt Bitterli's and PBRT's sane defaults
rB11633e89b6ea: Take out two of Lukas's optimizations in the Bessel function
rBcb983aabacf8: Cleanup: missing parentheses
rB6d8eb3bdbceb: Lift max value in Melanin sockets
rB7d324c74cd2b: Cleanup: formatting
rBf1bcaabb8ad1: Add random number socket
rB3c02585238db: Cleanup: get rid of compiler warnings
rB1eb55b6d12bd: Separate the randomized factors into new variables
rB03d57e126ba9: Remove unnecessary cast to float
rB08f3536d17ff: Fix double casting error in Linux
rBb7d540f245aa: Add color and roughness randomization
rBc33fbdb9cc68: Fix interpolation in melanin randomization
rB23d92659c7e9: Automagically get a RNG even if the user doesn't socket Random
rBfede34a58a8d: Merge branch 'master' into soc-2018-hair-shader
rB7780d306a416: Initialize the default color parameterization
rB66483e761fae: Add some help tooltips to the shader
rB574781ff1d9b: Make use of our customized OSL allocator
rB30369e55c145: Allow using the Color socket for all parametrizations except Direct coloring
rB31c3476fd31c: Add separate sockets for managing melanin coefficients
rB9973c2c26f35: Clarify one of the parameters
rB4774e906e198: Copy geometry data when allocating the OSL shader closure
rBdf1e50fa5d91: Enable blur on primary reflection roughness too
rBbf5a378c3c35: Fix Direct coloring calculation
rB07696962c4dc: Remove extra comment in Spanish
rB25677d773853: Add primary refraction roughness modifier
rBb3ebdf64459d: Access primary reflection roughness via cycles's stack
rBb7a92fa75e56: Protect against OSL alloc's null pointer dereference
rBc3048b5f53aa: Fix typo with Chiang's roughness modifier
rBdf0ead4dabd0: OSL: initialize geometry as part of the setup
rB82e63de2842c: Merge branch 'master' into soc-2018-hair-shader
rB8087cefd0302: Enable Filter Glossy for the hair shader
rB00d0f3c23527: Fix more of nirved's OpenCL errors
rB9d6333127623: Add nirved's OpenCL compatibility patch
rB718d730bb409: A first attempt towards a OSL shader
rB4a73f5ce584f: Use two variables to store azimuthal and longitudinal roughness
rB32408243bdb2: I knew I had a leftover printf somewhere...
rB2af62e27e2c8: Fix improper optimization in the trimmed logistic function
rB92030f83362f: Ringfence possible NaNs with degenerate hair geometry
rBadacd20abad3: Remove last remnants of debugging code
rB3b6c2e0b65fb: Add missing files registration
rB63ee7fabf6c7: Publish debug code for Lukas
rBc4174a44dc31: Actually classify Zootopia shader as BSDF + transmissive
rB14f881dbacff: Change comment wrt. node numbering
rB04d40de354eb: Rename possible hair parametrizations
rBe3b30fb7ec3e: Sync default shader values
rB09bb0bca0f1f: Adjusting license information
rB40bc1a5cddf2: GSoC 2018: port Lukas Stockner's hair patch
Type
Design

Event Timeline

L. E. Segovia (amyspark) triaged this task as Normal priority.
L. E. Segovia (amyspark) created this object with edit policy "Cycles (Project)".

Hey @L. E. Segovia (amyspark), and welcome!
Please rename your task to some more specific name, we have more than one GSoC project this year again. ;)

L. E. Segovia (amyspark) renamed this task from GSoC 2018 project: to GSoC 2018 project: Implementing a Hair Shader for Cycles.Apr 25 2018, 2:05 PM

@Bastien Montagne (mont29) /facepalm :)

I've edited the task name. Thanks for the heads up!

I don't have much to add to this really.

Some of work planned for at the end like "Repurpose existing regression tests and obtain reference renders." doesn't need a week. But it's also not really possible to do detailed plans that far ahead, maybe there will be more bugs to fix, or maybe some extra features can be added to the shader, so it doesn't really matter.

Hey all,

With rBadacd20abad3996ac5deb9e9a6b52fe244011853, I think I have a first "working" version of the hair shader. I managed to figure out why Lukas's patch as is wasn't recognised by the SVM, and now it compiles successfully in my work devices.

Obviously, it's still in a rough state:

  • CUDA in Windows doesn't seem to like curve_core_distance - I'll get the console log in the evening
  • There are crashes when integrating more than 1 sample - the returned indirect transmittance is NaN

So I'd like to ask:

  • Do you want to have test builds à la GraphicAll.org? If so, I'll ask Brecht or Lukas if I can get access to the Buildbot.
  • About bugs: how would you like to organize them? Subtasks, comments?

Thanks in advance!

Hi @L. E. Segovia (amyspark)

I believe for testing you may be want to post a link in BA thread that you have started, there you will have more traffic ( which is not always good, you don't have to answer everybody ;) ) In BA there is more artists/users who will want to play with it and give some feedbacks.

Yes Graphicall is the "traditional" place but googledrive and other place are good as well and you can ask users to build and share, here many users can build.

Good luck with your project I m following :)

I confirm that CUDA have problems under linux, too.

Is it really a principled shader ? There are 4 color parametrizations.
They seems to be a different way to manage hair transmission. But hair reflection does not seem to be involved.

It is hard to make tests because it is slow on CPU.

I think we can simplify the color parametrizations, and maybe even get rid of them. I don't think we need "Physical" and "Absorption". The color and melanin controls could be exposed at the same time, at least there should be a way to tint the hair even if melanin controls are used.

For reflection, the assumption is that this is always white (as it is in reality). From a single transmission color we can get the realistic primary and secondary specular highlight colors already. More artistic controls could be added later, I suggest to get the basics working well first.

Hey @Erick Tukuniata (erickblender) - BA thread is here: https://blenderartists.org/t/cycless-gsoc-2018-project-new-hair-shader-expectations/1103070 . I don't want to post till I have a stable (i.e. non crashing) build to show.

About builds - I'm happy to share windows and mac builds, but as the bandwidth compared with European standards is atrocious (3Mb), I think I'll need some serious help.

@Lukas Stockner (lukasstockner97) - you added the physical parameterization. I take it's to avoid having a zero absorption coefficient? What would be the benefits compared with directly setting sigma?

@ronan ducluzeau (zeauro) - It shouldn't be *that* slow unless there is a console debug log still being printed. Did you check this? Also, this shaders handles all modes in one pass (R, TT, TRT and 4+ bounces) so there would be no way to separate them unless we extend the original formulation.

I just added all parametrizations I could think of to make testing easier, there wasn't a lot of planning going into my implementation. For the actual implementation, I don't think the physical mode is needed.

Regarding builds: You can use the experimental buildbot to create builds. Alternatively, you can just poke me on IRC, I can also build for Win, Linux and OSX.

No log in console, here.

Maybe it s not a valid comparaison.
But here, addition of old hair shader nodes (R+T) and new shader with direct coloring method. a Sun as unique lamp. 256 samples + default settings

It is a lot noisier. In fact I don't manage to get rid of noise.

Hey @ronan ducluzeau (zeauro) ,

No log in console, here.

Maybe it s not a valid comparaison.
But here, addition of old hair shader nodes (R+T) and new shader with direct coloring method. a Sun as unique lamp. 256 samples + default settings

It is a lot noisier. In fact I don't manage to get rid of noise.

I think I found the source of the noise, it was one of the functions that was improperly optimized (rB2af62e27e2c894217b5d7daa880434447ea6ed35). Could you please checkout the branch again and test? If possible, please send me the scene so I can have a look at it.

For everyone who's testing my branch - please remember it's booby-trapped with assertions, since there are bugs with Blender's hair primitive and ray intersection. If you trigger any, please send the scenes!

I destroyed old_hair set-up when I tested new one. I only saved 3D scene, not the material.

So, here is a .blend file that does not give same render ; but where you can clearly see a problem with hair primitive render with new shader that does not occur with old one.

Edit:
I just made a new build of branch. Problem seems to be gone.

Hey all,

I'd like to summarize my progress with the project.

  • With rBdf0ead4dabd0c0f07ff046b59c7d850005d59e60 I added a (sort of) OSL connection to our shader. I know it receives the correct values, thanks to the printf line in the OSL shader file, but it doesn't render properly.
  • I moved the geometry setup back to bsdf_principled_hair_setup, which required a custom OSL closure to send the ShaderData too.
  • I also added @Brecht Van Lommel (brecht) 's suggestion about enabling Filter Glossy.
  • I fixed the OpenCL issues that nirved (IRC) found.

What's left now is:

  • Figure out the OSL closure function signature (not how to define it, but rather how the values are passed back to the Cycles renderer. I suspect some issue there is messing up with the geometry values)
  • Add Chiang's multiplier for simulating undercoat
  • Blender-Wiki documentation

Please, have a look at the shader and tell me if you find anything else.

L. E. Segovia (amyspark) added commits: rBc3048b5f53aa: Fix typo with Chiang's roughness modifier, rBb7a92fa75e56: Protect against OSL alloc's null pointer dereference, rBb3ebdf64459d: Access primary reflection roughness via cycles's stack, rB25677d773853: Add primary refraction roughness modifier, rB07696962c4dc: Remove extra comment in Spanish, rBbf5a378c3c35: Fix Direct coloring calculation, rBdf1e50fa5d91: Enable blur on primary reflection roughness too, rB4774e906e198: Copy geometry data when allocating the OSL shader closure, rB9973c2c26f35: Clarify one of the parameters, rB31c3476fd31c: Add separate sockets for managing melanin coefficients, rB30369e55c145: Allow using the Color socket for all parametrizations except Direct coloring, rB574781ff1d9b: Make use of our customized OSL allocator, rB66483e761fae: Add some help tooltips to the shader, rB7780d306a416: Initialize the default color parameterization, rBfede34a58a8d: Merge branch 'master' into soc-2018-hair-shader, rB23d92659c7e9: Automagically get a RNG even if the user doesn't socket Random, rBc33fbdb9cc68: Fix interpolation in melanin randomization, rBb7d540f245aa: Add color and roughness randomization, rB08f3536d17ff: Fix double casting error in Linux, rB03d57e126ba9: Remove unnecessary cast to float, rB1eb55b6d12bd: Separate the randomized factors into new variables, rB3c02585238db: Cleanup: get rid of compiler warnings, rBf1bcaabb8ad1: Add random number socket, rB7d324c74cd2b: Cleanup: formatting, rB6d8eb3bdbceb: Lift max value in Melanin sockets, rBcb983aabacf8: Cleanup: missing parentheses, rB11633e89b6ea: Take out two of Lukas's optimizations in the Bessel function, rBb891aa810947: Use Benedikt Bitterli's and PBRT's sane defaults, rB6e8ab6d21395: Add hair dye to Melanin concentration mode, rBafa31086bcca: Revert "Take out two of Lukas's optimizations in the Bessel function", rB257a7701e04d: Apologies, I didn't complete the defaults properly!, rB9e59a1f7b5c0: Merge branch 'master' into soc-2018-hair-shader, rB332b2d6206c1: Randomization is (currently) only available for melanin, rBc59ed14619e7: Remove two possible sources of NaNs, rB20ed03722fad: Remove "Physical" parametrization [READ BELOW PLEASE], rB45abb2eee803: Reorder sockets according to usefulness, rBc36722f96287: Remap randomization to roughness/color ± the given percentage factor, rB06fb2a06738c: Amend OSL shader again to account for parameter renaming, rBb005c15f6734: Amend OSL shader w.r.t. Melanin changes, rBf91635e64e50: Refactor Melanin into Tungsten's quantity and ratio parameters, rB5c07292bde39: UI: rename various nodes, rB4f4b7ea9d70b: Remove unused closure, rB60a59fbae6b0: Merge branch 'master' into soc-2018-hair-shader, rBdc2827fd907d: Cleanup: store and retrieve parameters consistently, rBe267191393fe: Fix a precision issue in the coord frame with low roughness, rB2d1eef87f6b6: Fix discrepancy between RNG in CPU and GPU, rBbd37b18a0d6d: Update signatures to use Lukas's new linear_rgb_to_gray, rB9b632addd347: Merge branch 'master' into soc-2018-hair-shader, rB535e2e4ade24: Merge branch 'master' into soc-2018-hair-shader, rB714c67ad5634: Indent typo in the node update, rB8547643039a2: Give the Absorption coefficient its own socket.Jun 17 2018, 6:04 PM
L. E. Segovia (amyspark) added commits: rBc3048b5f53aa: Fix typo with Chiang's roughness modifier, rBb7a92fa75e56: Protect against OSL alloc's null pointer dereference, rBb3ebdf64459d: Access primary reflection roughness via cycles's stack, rB25677d773853: Add primary refraction roughness modifier, rB07696962c4dc: Remove extra comment in Spanish, rBbf5a378c3c35: Fix Direct coloring calculation, rBdf1e50fa5d91: Enable blur on primary reflection roughness too, rB4774e906e198: Copy geometry data when allocating the OSL shader closure, rB9973c2c26f35: Clarify one of the parameters, rB31c3476fd31c: Add separate sockets for managing melanin coefficients, rB30369e55c145: Allow using the Color socket for all parametrizations except Direct coloring, rB574781ff1d9b: Make use of our customized OSL allocator, rB66483e761fae: Add some help tooltips to the shader, rB7780d306a416: Initialize the default color parameterization, rBfede34a58a8d: Merge branch 'master' into soc-2018-hair-shader, rB23d92659c7e9: Automagically get a RNG even if the user doesn't socket Random, rBc33fbdb9cc68: Fix interpolation in melanin randomization, rBb7d540f245aa: Add color and roughness randomization, rB08f3536d17ff: Fix double casting error in Linux, rB03d57e126ba9: Remove unnecessary cast to float, rB1eb55b6d12bd: Separate the randomized factors into new variables, rB3c02585238db: Cleanup: get rid of compiler warnings, rBf1bcaabb8ad1: Add random number socket, rB7d324c74cd2b: Cleanup: formatting, rB6d8eb3bdbceb: Lift max value in Melanin sockets, rBcb983aabacf8: Cleanup: missing parentheses, rB11633e89b6ea: Take out two of Lukas's optimizations in the Bessel function, rBb891aa810947: Use Benedikt Bitterli's and PBRT's sane defaults, rB6e8ab6d21395: Add hair dye to Melanin concentration mode, rBafa31086bcca: Revert "Take out two of Lukas's optimizations in the Bessel function", rB257a7701e04d: Apologies, I didn't complete the defaults properly!, rB9e59a1f7b5c0: Merge branch 'master' into soc-2018-hair-shader, rB332b2d6206c1: Randomization is (currently) only available for melanin, rBc59ed14619e7: Remove two possible sources of NaNs, rB20ed03722fad: Remove "Physical" parametrization [READ BELOW PLEASE], rB45abb2eee803: Reorder sockets according to usefulness, rBc36722f96287: Remap randomization to roughness/color ± the given percentage factor, rB06fb2a06738c: Amend OSL shader again to account for parameter renaming, rBb005c15f6734: Amend OSL shader w.r.t. Melanin changes, rBf91635e64e50: Refactor Melanin into Tungsten's quantity and ratio parameters, rB5c07292bde39: UI: rename various nodes, rB4f4b7ea9d70b: Remove unused closure, rB60a59fbae6b0: Merge branch 'master' into soc-2018-hair-shader, rBdc2827fd907d: Cleanup: store and retrieve parameters consistently, rBe267191393fe: Fix a precision issue in the coord frame with low roughness, rB2d1eef87f6b6: Fix discrepancy between RNG in CPU and GPU, rBbd37b18a0d6d: Update signatures to use Lukas's new linear_rgb_to_gray, rB9b632addd347: Merge branch 'master' into soc-2018-hair-shader, rB535e2e4ade24: Merge branch 'master' into soc-2018-hair-shader, rB714c67ad5634: Indent typo in the node update, rB8547643039a2: Give the Absorption coefficient its own socket.

Hey all,

I've not updated this task in more than a month, so I'm dropping by to let you know about the state of the shader.

Currently, I've implemented the following features:

  • Color parametrizations: Direct, Melanin and Absorption Coefficient. These also govern the visible sockets.
    • Direct: set your desired RGB color. It's the Plug&Play method by default.
    • Melanin: Use the Melanin parameter to set how much melanin concentration you'd like, and the Melanin Redness to distribute it between eumelanin (black pigment) and pheomelanin (orange-red pigment).
    • Absorption coefficient: pull the material's σ coefficient from Pharr's paper or other sources in the literature. (I left this one for debugging purposes, since it bypasses all parametrizations.)
  • Tint: available only for Melanin, allows you to add a dye color to the hair.
  • Roughness: renamed them to Roughness (this is the longitudinal roughness, formerly known as RoughnessU), Radial Roughness (azimuthal roughness, or RoughnessV), and Undercoat Roughness (this is the Primary Reflection Roughness from Chiang's paper).
  • IOR: no news here.
  • Offset: the latter has a default now, 2º.
  • Color and Roughness Randomization: if you set anything different than 0, the hair's parameters will vary in the range Color/Roughness ± Randomization% (Randomization is in the range [0, 1], 0 = disabled, 1 = 100%).
    • I didn't clamp the Randomization parameter, so you can force it to have a bigger span if you need that.
    • This uses Hair Info->Random as a RNG source, which is retrieved automagically. You can still socket a node if you want an exact value or a custom source.
    • Remember that using Hair Info->Random with few (or a single) parent hairs and Interpolated children will not result in a smooth or even visible effect, since the Random value isn't changed per-hair. Use many parents or Simple children.
    • Color Randomization is available for and only affects the Melanin concentration.
  • Filter Glossy support: as with other Cycles nodes, this clamps the (after randomization) Roughness values to the specified maximum.
  • OSL and SVM versions are available and are fully feature equivalent.

Hey all,

As the GSoC task comes to an end, I'd like to summarise the results of the project. I invite everyone to read the documentation at the Blender manual, watch the demo, and read my portfolio page.

Further development and bug fixes is in the branch soc-2018-hair-shader-fixes:

What's left for future work:

  • Find out the source of the noise in the TT mode of the Glossy Indirect light pass.