6
$\begingroup$

Recently a user on here offered a tip to be careful when making shaders so I don't violate energy conservation. Blender stores colors in the value range of 0-1. If you go above 1, then more light is being reflected than is being received and you get physically inaccurate results.

From the documentation:

In order for materials to work well with global illumination, they should be, speaking in terms of physics, energy conserving. That means they cannot reflect more light than comes in. This property is not strictly enforced, but if colors are in the range 0.0 to 1.0, and BSDFs are only mixed together with the Mix Shader node, this will automatically be true.

So my question is, what scenarios would break energy conservation (other than what is mentioned in the documentation)? When do I need to be vigilant about this?

I've been making utility node groups for myself - an example is my Falloff Map node shown below:

Falloff Map

And this "texture adjustment" node group:

Texture Adjustment

I'm a little concerned that my node groups could be outputting values higher than 1. For instance in the falloff map node group, I have an exponential "power" math node that then feeds into an RGB Curves node. Wouldn't the power node have the potential to output values above 1?

Another example with my "Texture Adjust" node group: I have three MixRGB nodes set to screen chained together for an alternate way to lighten a texture than simply adjusting brightness.

Is it possible that I am violating energy conservation with either of these node groups?

I am also aware of the ability to clamp values, but I usually leave it unchecked. Should I be clamping values as I go about building node groups?

I've attached both node groups so you can download and test them yourself.

Texture adjust nodegroup:

Falloff Map nodegroup:

Thanks so much for any advice or help.

$\endgroup$
4
  • $\begingroup$ Hello :). This whole thread on devtalk is interesting: Principled BSDF violating energy conservation? $\endgroup$ – Jachym Michal Feb 23 at 21:24
  • $\begingroup$ And here's the 2012 paper from Brent Burley introducing the Principled BRDF shader. The Principled BRDF is leaning toward being more artist-friendly than strictly energy-conserving. $\endgroup$ – Jachym Michal Feb 23 at 21:27
  • $\begingroup$ Thank you, I'll read through those links! Appreciate it. :) $\endgroup$ – Jay Feb 23 at 21:42
  • $\begingroup$ @JachymMichal With respect to my node setups above, do you think I am violating energy conservation? I'm trying to understand what circumstances or nodes I need to be careful with. Or should I just clamp at the very end always? $\endgroup$ – Jay Feb 23 at 21:47
4
$\begingroup$

It depends on how you're going to use the value.

Generally, anything that goes into a shader should be within the 0 - 1 range.

enter image description here

But not necessarily Normal values or perhaps Subsurface (theoretically in either case your model would have to be huge for this to make sense) because these values deal with scale or distance.

The same could be said for the Emission values, which turn the surface of your mesh into a light source.

When creating a mask you might generate values far outside the 0 - 1 range, but this may not be a problem. For example, if you want to generate a displacement map for a mountain range you need to generate bumps several hundred meters high. If, however, this has anything to do with Base Color or any physical property of the material, you will want to do something to normalize the value.

So what can you do?

You can check the Clamp button, this takes any value above 1 and reports 1 instead.

enter image description here

Or, if you know the new minimum and maximum values you're dealing with (you did the math), you can use a Map Range node to compress that larger range back into the 0 - 1 range.

enter image description here

Regarding when to clamp:

It depends, again, on what you want. Consider the following example which is a gradient with a value from 0 to 10.

enter image description here

And then say we clamp the multiply.

enter image description here

We have almost all of this plane with a value of 1. Now if we wanted to move this gradient over some we might subtract something from this, let's say .6

enter image description here

Well we've moved it but now the majority of the plane has a value of .4, and to boot it appears the portion of the plane that actually had a gradient has shrunk significantly.

That's not actually true because what we've done is create a gradient of negative values on the left all of which are represented by black. A whole other can of worms!

enter image description here

So probably what we want to do here is not clamp the multiply, so the subtract operation has some higher values to deal with, and then do clamp the subtract so that we don't generate negative values.

enter image description here

Of course, all according to what you want. If you want the short gradient ending at .4 you should clamp both!

So what are some specific things to watch out for?

You are now armed with this knowledge, you can never unlearn it. With regard to color you should now be afraid of basically any unclamped Mix operation aside from good old fashioned Mix (and that's only if you know the colors going in are safe in the first place), physical properties outside 0 - 1, and then specifically the Add Shader. 👍

Any times where I shouldn't clamp?

When you're operating on the coordinate space itself, you are necessarily operating on values above 1 and in the negative range. These operations shouldn't be clamped unless there is some particular behavior you're going for.

It may seem like a lot to maintain, but now you know.

enter image description here

$\endgroup$
4
  • 1
    $\begingroup$ I would point out that emission can be any value you want, not limited to 0-1 $\endgroup$ – susu Feb 24 at 2:29
  • $\begingroup$ Can confirm that Subsurface Radius values can go over 1 without problems. It's simply a multiplier for SSS :) $\endgroup$ – Jachym Michal Feb 24 at 7:43
  • $\begingroup$ This is an incredible post. Thank you so very much for the breakdown. Wish I could give you more rep! $\endgroup$ – Jay Feb 24 at 22:46
  • $\begingroup$ What I've found is that doing these is a good way for me to organize and reinforce my own thoughts about things. Plus, you know... it's one way to leave a mark on the world. $\endgroup$ – Allen Simpson Feb 24 at 22:53
5
$\begingroup$

It is impossible to say whether the groups you show conserve energy, because whether or not they conserve energy depends on what values you send them, and they don't output shaders anyways.

If you want to conserve energy, and you don't want to clamp unless you have to, there are only various things to know:

  1. If you send a shader a color outside of the 0,1 range of color, you probably don't conserve energy.
  2. If you use emission, you don't conserve energy. (Emission creates energy from nothing.)
  3. If you use an add shader node, you probably don't conserve energy.
  4. If you use specular values outside of the 0,1 range in a principled shader, you probably don't conserve energy.
  5. If you use sheen or clearcoat in a principled shader, you probably don't conserve energy. (Not 100% sure about sheen, but 100% sure about clearcoat.)
  6. If you send a mix shader a fac outside the 0,1 range, you probably don't conserve energy.

That's a lot of "probably"s. Because there are corner cases. Is it safe to add shader a 1,0,0 diffuse to a 0,1,1 diffuse? Yes. Because the output cannot exceed 1,1,1. Is it safe to add 0.1 clearcoat to a 0.9 diffuse principled? Yes, because the output cannot exceed 1,1,1. Is it safe to mix shader a 0.5 diffuse shader at fac 2.0 from a 0.0 diffuse shader? Yes, because you cannot exceed 1,1,1.

I'm sure I could have missed some examples.

$\endgroup$
3
  • $\begingroup$ I want to start pushing back against emission not conserving energy. I think instead we should say if you are using emission you are turning the mesh into a light. It's like trying to use the concept of energy conservation when it comes to point or area lights. It's one of the things that can give your scene energy. You would only have to potentially justify it from an artistic perspective with a power source. $\endgroup$ – Allen Simpson Feb 24 at 0:52
  • $\begingroup$ But this is a great post, I don't want you to take this the wrong way. :) $\endgroup$ – Allen Simpson Feb 24 at 0:55
  • 1
    $\begingroup$ @Allen Simpson I don't disagree with you. Considering emission (or, for that matter, lighting) as failing to conserve energy is a technical consideration-- the reality is, pure, whole-scene energy "conservation" isn't actually a desirable characteristic! Emission doesn't conserve energy, but it's not like it would make any sense to have emission that did. Note that this does actually have some consequences and meaning, for rasterizers that aim for energy conservation (where emission is not light), for using emission to cheat things like volume scatter, and surfaces that reflect and emit. $\endgroup$ – Nathan Feb 24 at 5:12
0
$\begingroup$

You use clamp checkbox

It limits outputs to only numbers between 0 and one

There is also a clamp node that does the same thing, but you arent limited to only 0-1 with the node

$\endgroup$
1
  • $\begingroup$ Like I said in my post, I do know what clamping does, but I'm trying to figure out when I absolutely need to clamp, and when I don't. Also, with more complex node setups I think clamping could result in inaccurate values if you're not paying attention. Should I only clamp at the very end? $\endgroup$ – Jay Feb 23 at 21:44

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.