3
$\begingroup$

Here are three monkeys lit by the same sun lamp. They have only a Toon Diffuse shader set to color of 0.2 value, and size of 0.8, 0.5, and 0.2 respectively. But it can clearly be seen that their lit areas are displaying very different colors. When rendered, the difference shows up in the Diffuse Direct pass.

enter image description here

Does anyone know why this works this way, and what is going on mathematically? I want to make an adjustment to the color going into the shader based on the size to compensate for this and bring them all back to the same level of brightness in their lit area. Is it intended for the Toon shader to behave this way? Is this a bug?

$\endgroup$
  • 1
    $\begingroup$ Now you've had a really good answer, I feel more free to ask.. wouldn't EEVEE and Shader to RGB, manipulated, serve you better for NPR effects? $\endgroup$ – Robin Betts Sep 7 '19 at 18:13
  • 1
    $\begingroup$ @RobinBetts Some of them. It has a lot more control. But it isn't a proper toon shader since you are ramping the light. So changing light intensity changes the size of your shaded area, which a Cycles toon doesn't. There's strong points to both for different styles right now. Once Eevee gets a real toon shader (hopefully) then it'll be different. $\endgroup$ – Drudge Sep 8 '19 at 3:27
  • $\begingroup$ Ahhh.. I see. Maybe that also goes some way to explaining the way the Cycles shader is implemented.. but you (I) would have thought they could have written @lemon's normalization in.. at least as an option. $\endgroup$ – Robin Betts Sep 8 '19 at 6:02
4
+50
$\begingroup$

According to the code currently here, and the sample_uniform_cone currently here, without smoothing the resulting diffuse intensity depends on the size of the toon shader node.

So we can compensate this value to invert the calculation:

The size is multiplied by pi/2 (so this is relative to half cone angle).

Then take 1 minus the cosinus of the previous result.

Then divide pi/2 by the previous result.

Last, multiply the intensity value by it.

As this last step is multiplication factor in the shader code, we need to divide by it in the nodes. This is done by this node group:

enter image description here

The result is not exactly perfect (should be some rounding or an error by me). But we obtain this:

enter image description here

$\endgroup$
  • 1
    $\begingroup$ @RobinBetts weird? It is as it is in the code... for some reason the intensity relies on the diffuse surface. I don't know why though. $\endgroup$ – lemon Sep 7 '19 at 18:06
  • 1
    $\begingroup$ Oops, I meant them, not you. Great answer. $\endgroup$ – Robin Betts Sep 7 '19 at 18:09
  • 1
    $\begingroup$ @RobinBetts, will try to find a way to ask (maybe Brecht) and report here if I've an answer. $\endgroup$ – lemon Sep 7 '19 at 18:10
  • 1
    $\begingroup$ For information, suggested on blender-coders chat (by Jeroen Bakker): toon shader respects conservation of energy in Cycles and that may be why the colors are different depending on the size (@RobinBetts) $\endgroup$ – lemon Sep 9 '19 at 9:50
  • 1
    $\begingroup$ @lemon OK. Rooted in the fundamental conflict between the goals of PBR and NPR. On that basis, a purist would say there shouldn't be a toon shader in Cycles, I guess.. $\endgroup$ – Robin Betts Sep 9 '19 at 9:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.