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

Sorry for the relatively bad report on this issue.

In Cycles, a light’s “power” can be changed to a negative value. And I decided to test this with Many Light Sampling and noticed two issues:

  1. In a scene with two lights, one with a positive power, one with a negative power, and Many Lights Sampling enabled, Blender can crash. I say “can crash” because sometimes it crashes quickly, sometimes the light needs to be moved around and the power needs to be changed, or light need to be duplicated, or other things. I’m not sure if this is a issue with Many Lights Sampling or something else.
    I was concerned this issue might be a compiler related issue. But I can reproduce it on Windows, Linux, and MacOS. So it’s either a issue with Cycles and/or Many Lights Sampling.
Demonstration of issue 1

Note: In the video below, the crash was “quick”. Most of the time it’s not this quick.


  1. If we have two lights, one with a positive power and a white colour, another with a negative power and a saturated colour (E.G. Red), and Many Lights Sampling is enabled with a low splitting threshold, then the scene will not render “properly”.
Demonstration of issue 2

1 Like

I just pushed a commit that should (tentatively) fix this issue. I say tentatively because I have a general idea of what should have caused this issue, and I could no longer replicate this issue after the change, but I’m not 100% certain that this fixed it completely.

From my understanding, the issue was that the negative energy was being used in the importance calculation, and thus the negative importance was messing things up. Thus, my solution was to take the absolute value of the energy in the importance calculation.

5 Likes

Edit: This issue was introduced with this commit rBa7cd05d15028


I found a bug.

The reflection of emmissive trianges in rough glossy surfaces isn’t working properly when Many Lights Sampling is On. It easiest to see at low roughnesses.

Here is a .blend file I used for testing:

Renders

This is a simple scene. I have a ground plane, fully metalic and a little bit rough. And an emissive plane. As you can see when Many Lights Sampling is On, the reflection of the plane renders incorrectly. Increasing the roughness hides the issue, and decreasing the roughness to 0 resolves the issue.

Many Lights Sampling Off:

Many Lights Sampling On:

2 Likes

This will propbably need to be discussed with Brecht or someone else on the Cycles team before considering.

In a presentation done by Sony Image Works on Many Lights Sampling (http://aconty.com/pdf/importance-sampling-lights-slides.pdf), they noted to get around issues with powerful and occluded lights being over sampled, they say:

“…we have a way to single out a particular light and exclude it from the heuristics and do traditional light loop”
Found on the last page of the PDF.

This could potentially be used with Many Lights Sampling in Cycles to work around problomatic lights (like textured lights) when using a low splitting threshold?

Although, I understand exposing certain options to the user just to work around an issue with the algorythm used is less than ideal.

2 Likes

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).