Cycles: Don't run full shader evaluation for constant emission lamps

Authored by Lukas Stockner (lukasstockner97) on Sep 3 2016, 10:46 PM.



Most of the time, Lamps in Cycles are just a constant emission closure, no texturing etc. Therefore, running a full shader evaluation is wasteful.
To avoid that, Cycles now detects these constant emission shaders and stores their value in the lamp data along with a flag in the shader.
Then, at runtime, if this flag is set, the lamp code just uses this value and only runs the full shader evaluation if it is neccessary.

In scenes with a lot of lamps and with "Sample all direct/indirect" enabled, this saves up to 20% of rendering time in my tests.

Diff Detail

rB Blender
Lukas Stockner (lukasstockner97) retitled this revision from to Cycles: Don't run full shader evaluation for constant emission lamps.Sep 3 2016, 10:46 PM

Nice work. It is not needed to increase the LIGHT_SIZE though, see

light_data[light_index*LIGHT_SIZE + 4] = make_float4(max_bounces, 0.0f, 0.0f, 0.0f);

There you have 3 empty floats which you can use.

The patch now uses the three empty fields in the light_data, thanks for pointing those out!

Also, I did some more benchmarking, and it turns out that this patch helps even more for OSL:

  • Test scene, Suzanne + 113 Point Lamps, direct light only, Branched+Sample All, with patch: SVM 1:37, OSL 1:38
  • Same scene, but forced to evaluate lamp shaders by using a 1x1 image as the lamp color: SVM 2:21, OSL 4:25
Brecht Van Lommel (brecht) accepted this revision.EditedSep 9 2016, 12:33 AM

Great optimization! 20% in such a scene is great.

For those last numbers, adding in a texture lookup doesn't really make it a fair comparison though? Certainly OSL texture lookups are a lot slower than we'd like, but this patch is not optimizing those out.


Can we use surf->link->parent->type != EmissionNode::node_type instead?

This revision is now accepted and ready to land.Sep 9 2016, 12:33 AM
This revision was automatically updated to reflect the committed changes.

True, the last test isn't exactly fair.
I re-checked with a master build - 1:58 SVM, 2:28 OSL. So, still a clear difference, but not as big as before.


Yes, definitely! I searched for a way to do that check without the name hack, but apparently I missed the static node_type.