GSoC 2022: Many Lights Sampling in Cycles X (Feedback Thread)

I am very interested in this project! As I happened to be doing a procedural city generation via blender geometry node, and I was scattering spot light as street lamp over a pretty large region (large enough to easily go beyond the 128 lights limit of EEVEE, so I had to use Cycles).

One thing I find very interesting is: since all of these spot light are of equal strength and spot size, I could scatter emissive body to emulate them. It seems, no matter how large my emissive body surface is, it always render much faster than spot lights of the same coverage.

I wonder if there are optimization to be done with ā€œmany lights of equal strength / angleā€, the paper you implements didnā€™t discuss this so perhaps this wasnā€™t a part of your scope, but interesting to consider the possible gains.

1 Like

In the Many Lights Sampling Task ( āš“ T77889 Cycles: Many Lights Sampling ) and in previous discussions, the question has been asked. ā€œShould the splitting threshold be fixed or user controllable?ā€

One thing I thought I would bring up related to this is that in a scene where all lights are point lights, and nearby lights share similar colours, it seems having a splitting threshold of 0 is beneficial. So setting the splitting threshold to a constant like 0.85 will be detrimental for these scenes.

This was just something I wanted to bring up in favour of keeping the splitting threshold user controllable, or at the very least set the splitting threshold to a constant and allow the user to turn off splitting.

Here are some images to showcase what I mean:

Scene 1

This scene consists of three white point lights. Since the scene consists of point lights and nearby lights share similar colours (white), turning off splitting is beneficial for this scene.

1 sample per pixel, splitting disabled:

1 sample per pixel, splitting threshold = 0.85:

Scene 2

This scene consists of three point lights (one red, one green, one blue). Since nearby lights have wildly different colours, it benefits from splitting.

Note: I say this scene benefits from splitting specifically due to the advantage splitting has when it comes to mixing colours.

16 samples per pixel, splitting disabled:

16 sample per pixel, splitting threshold = 0.85:

2 Likes

Hi, sorry for the delayed responses. Iā€™ll try to respond to all 3 of your comments:

If this was working before the bit-trail commit, I think itā€™s just a bug thatā€™s been introduced (simple debugging should be enough).

This is actually pretty interesting - I have seen that presentation but I mustā€™ve missed that part where they mentioned it. Iā€™d imagine that this is feasible to implement, but I agree that we should discuss this with Brecht too. We could also implement certain heuristics to automatically detect which lights may be better excluded.

I think this one is still hard to say. Maybe the easiest solution is to also add a heuristic to calculate the splitting threshold based on certain criteria (e.g. different colors, etc). It might also be better to see how the splitting works in production-ready scenes rather than toy examples.

In any case, thank you very much for all of these reports. Iā€™ll add them to the backlog so that I, or other contributors, can pick it up in the future.

1 Like

I did some simple debugging, but couldnā€™t really figure out how to fix it.

In light_tree_pdf() in intern/cycles/kernel/light/light_tree.h the final PDF calculation:

(line 628) pdf *= light_leaf_pdf * light_tree_pdf * target_weight / total_weight

ends up being 1.0f *= 0.0f * 1.0f * 0.0f / 0.0f (this is NaN, or infinity depending on what you think) when it should probably be closer to 1.0f.

This occurs because a bunch of values donā€™t get set correctly due to certain criteria not being met for the case of the mesh light to actually run the code that sets the value.

Most notably, on line 556, the if (kemitter->prim_id == prim) criteria is not met, which results in certain values not being set.

1 Like

Hi, thank you for your interest in the project! Sorry Iā€™m not completely up to date on all of Blenderā€™s new updates - could you elaborate on what you mean by emissive bodies?

By the way, the way Cycles currently samples spotlights isnā€™t the best (slightly outside the scope of this project), but the implementation does take position/angle into consideration. For example, in your case, if there are many lights scattered around, the sampling method will be more likely to choose the lights that are nearby. I imagine that the algorithm will perform better than the default implementation in this case (for spotlights at least).

Feel free to share your scene with me and I can experiment with it for you.

I have a few ideas that Iā€™ll try to check out. Thanks for investigating!

1 Like

Iā€™m actually unable to reproduce this error (using the scene you uploaded, I tried playing around with the roughness but it seems to match up so far). I havenā€™t made any changes besides merging with master, so I may be misunderstanding something.

I can confirm your findings. Updating to the latest revision of the Many Lights Sampling branch resolved the issue.


I should note, the issue I described in Blender chat is still present in the latest revision from my testing.

For reference, the issue is that the area light in the ā€œLadderā€ scene is too dark in the reflection of some surfaces when Many Lights Sampling is On and there is the area light and another light in the scene.

I have created a simplified scene here:

Renders

Many Lights Sampling Off (Expected result):

Many Lights Sampling On:

Edit: Upon further testing I found another scene that doesnā€™t work right.

If you have a mesh light and a point light in the same scene, the point light doesnā€™t render correctly in reflections. These are probably all related.

1 Like

Thanks, Iā€™ll check these out. It seems like I canā€™t access the link you provided, but Iā€™ll try recreating the issues you described on my own.

Hereā€™s an updated link:

1 Like

Thanks. This should be resolved with the latest commit.

The issue was closely related to the lines that you mentioned. The general issue was that when we recalculate the PDF, we go from the primitiveā€™s index into a lookup table, to get an index to the leaf node. I was accidentally comparing a given nodeā€™s index to the index in the lookup table rather than the index to the leaf node, which was why we were getting weird results.

Although this issue should be fixed, Iā€™m now slightly concerned that we may sometimes end up sampling a really obscure light that will never be reached in the light tree. Iā€™m not completely sure if this will occur, but Iā€™ll try playing around with some toy scenes.

2 Likes

Edit: This issue is fixed by: https://developer.blender.org/D14664#432183


I just thought Iā€™d report, the exact same issue as before is still present when the splitting threshold is set to a small value, or 0.

1 Like

Hi Alaska, can you kindly share a windows build for trying out different test cases? Thanks!

Hereā€™s a Windows build for you. I donā€™t know if itā€™ll work for you, but hopefully it does.

1 Like

I should note. I didnā€™t build this version of Blender with GPU rendering support. But with some modifications to the code (I have left some comments on the patch: āš™ D14664 Cycles: Many Lights Sampling for Cycles X [WIP]) Blender can be compiled with GPU rendering support.

1 Like

Thx for your reply, by emissive bodies I meant objects with a bright emission color and strength well over 1, which also contribute ā€œlightsā€ in cycles.

I will get a test blend file back to you this week, knowing you are finishing up your work, I think it will serve as a good test case for next iteration. (or at least a good comparison of rendering performance when trying to emulate many lights scenario).

I just thought Iā€™d report a issue I found.

I constructed a scene like this:

  1. There is a gound plane.
  2. 0.1m above the ground plane is 2500 point lights spaced 1 meter away from each other with a power of 1 watt.
  3. The camera is placed above these looking down.

The issue I found was that lights closer to the center of this group of lights will render incorrectly with Many Lights Sampling.

Note: I used a splitting threshold of 0 to remove that as a factor as splitting seems to be causing itā€™s own issues

I tested with both the latest commit of the Many Lights Sampling Branch, and the latest commit with my own modifications (Which I have left in comments on āš™ D14664 Cycles: Many Lights Sampling for Cycles X [WIP]. And here is a patch file with all my modifications: āœŽ P3178 Alaska's modifications to Many Lights Sampling)

Render show casing the issue.

These renders were done at roughly 2000 samples per pixel.

Here is the .blend file for the scene.

2 Likes

I have managed to fix (or at the very least improve) on this issue.

Hereā€™s what I found to be the issue:

  1. Part of the PDF calculations relied on the bit trail for tree traversal, but didnā€™t make proper use of it. So I fixed that.
  2. The bit trail was incorrect. So I fixed that.

The changes I made can be found here: āš™ D15935 Fix bit trail construction and bit trail PDF calulations

1 Like

Great work Alaska!
Iā€™d like to ask if the GPU fix is in already with the latest build; if it is, can you kindly share a Windows build with all these latest fixes for testing? Thanks

Currently none of these changes are in the Many Lights Sampling branch. I am just maintaining them in my own personal build.

I have posted these changes as patches for Brecht to review and commit.

As for whether or not I can share a build with GPU rendering and the fixes Iā€™ve made? There is currently a bug I am investigating. If itā€™s a simple fix, then Iā€™ll fix it and share a new build with you. If itā€™s a complex issue, then Iā€™ll probably give up after maybe a few hours and create a new build for you and detail what the bug is.


Some notes about GPU rendering:
On Windows, I can only build Blender with CUDA, OptiX, and OneAPI support. I can not build with HIP.

Along with that, I have not personally tested OneAPI, so I do not know if it works.

Another issue is that with my current build environment, CUDA support will be limited to ā€œmodern GPUsā€ (I believe itā€™s Maxwell and later - So GTX 900 series and later).

Also, in my previous testing, CUDA easily experiences ā€œillegal addressā€ errors when using Many Lights Sampling in the viewport. To ā€œwork aroundā€ this, you need to close Blender and reopen it again.

1 Like