LuxCore icon indicating copy to clipboard operation
LuxCore copied to clipboard

Soft shadows of a small light source are not displayed correctly

Open DEBIHOOD opened this issue 4 years ago • 4 comments

If the point light source is small enough radius(in this example, radius is 0.026 m), it causes problems, at some point shadow goes from a soft state to an infinitely sharp. image image

Example scene softshadowsbug.zip


Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

DEBIHOOD avatar Sep 09 '20 12:09 DEBIHOOD

You may just literally observing the bits in floating point 32 but I'm going to check.

Dade916 avatar Sep 09 '20 12:09 Dade916

I believe this condition is responsible:

https://github.com/LuxCoreRender/LuxCore/blob/9131aa91478bedb11582f1c835477ac7a6c91dbe/src/slg/lights/spherelight.cpp#L119

It fits with a calculation on the distance and light radius where I observe this change. I'm currently trying to compile what I believe would fix this...

CodeFHD avatar Sep 09 '20 12:09 CodeFHD

Ok now after looking closer, the condition as such is actually not calculated wrong. I was misinterpreting at first due to an approximation in it.

If I just remove the condition in the line after, the image in my test scene improves a lot. Only when I use very small light radius some error starts to appear (radius = 0.0175 compared to radius = 0.45).

Maybe it is worth to remove the fallback condition, if it causes more unexpected results than to have it? Unless you know specific scenes that don't work well that way?

CodeFHD avatar Sep 09 '20 13:09 CodeFHD

I may have found a solution. What I did was to still do the cone sampling and subsequent shadow ray tracing, but replace the pdfw's and return value with the computations for a point light.

Comparison image: Top row: current code (shows sudden switch to point light) Middle row: current code without condition (shows banding in wide top view) Bottom row: new code

compare

I will submit a pull request so you can have a look if you agree.

P.S.: I was wrong about the condition being an approximation, it is correct. I only wonder about a little optimization: if you really need the Max() evaluation, as there already is a check for centerDistanceSquared - radiusSquared < DEFAULT_EPSILON_STATIC just before?

CodeFHD avatar Sep 14 '20 11:09 CodeFHD