Commit Graph

132 Commits

Author SHA1 Message Date
Weizhen Huang
2ddc936cbb Cleanup: simplify computation in Cycles area light sampling
`diff` in numerator and denominator cancels out, except for the signs,
which we know beforehand since `x1 > x0`, `y1 > y0`

Pull Request: https://projects.blender.org/blender/blender/pulls/122740
2024-06-04 23:37:48 +02:00
Lukas Stockner
fbc770d58b Cycles: Fallback to area PDF when spherical rectangles are too small
This fixes #69535 and #98930.

We use a equi-solid-angle sampling algorithm for rectangular area lights,
but it is not particularly robust for small area lights (either small
in general and/or small because it's being viewed from grazing angles).

The actual sampling part is fine since it just gets clamped into the
valid area anyways, and the difference isn't notable for small lights.

However, we also need to compute the solid angle to get the sampling PDF,
and that computation is quite sensitive to numerical issues for small
values.

Therefore, this commit adds a fallback path for small values, which instead
uses the classic equi-area sampling PDF term times the area-to-solid-angle
Jacobian term. This approximation assumes that all points on the light have
the same distance and angle to the sampling point, which is of course not
strictly the case, but it's close enough for small area lights and better
than failing altogether.

Pull Request: https://projects.blender.org/blender/blender/pulls/122323
2024-06-04 01:55:26 +02:00
Lukas Stockner
a5dc233aa2 Cycles: Tweak area light sampling to improve numerical robustness
Reformulates some terms in the equi-solid-angle rectangle sampling code to
handle small area lamps better, and allows for some rounding error in the
check whether the sampled position is inside the area light.

Pull Request: https://projects.blender.org/blender/blender/pulls/122323
2024-06-04 01:55:25 +02:00
Weizhen Huang
296ac0e9ef Cycles: improve light tree with large spot blend
In the original paper, the falloff inside `bcone.theta_e` is assumed to
be `pi/2`, which is too large for spot light and resulted in an
overestimation near the cone boundary.
To address this issue, attenuate the energy of a spot light using the
minimal possible angle formed by the light axis and the shading point
when traversing the light tree.

Ref: #122362

Pull Request: https://projects.blender.org/blender/blender/pulls/122667
2024-06-03 23:33:29 +02:00
Lukas Stockner
392b84f879 Fix #114515: Cycles: Numerical precision issues in triangle light sampling
The refactor in 97d9bbbc97 changed the way q is computed in the spherical triangle sampling code. While the new approach is more efficient and saves a few operations, it introduces numerical precision issues for skinny/small (spherical) triangles.

Therefore, this change moves the computation of q back to the method from the paper, while keeping the more efficient solid angle computation.

Pull Request: https://projects.blender.org/blender/blender/pulls/119224
2024-05-23 02:27:48 +02:00
Weizhen Huang
0c9ce4ba4f Refactor: handle MIS weight in lower-level functions
it is difficult to keep in mind when MIS weight is needed, better to
handle this logic in the lower-level functions.
This reduces code duplication in many places.
2024-04-17 18:49:00 +02:00
Weizhen Huang
418acfe8bb Cleanup: remove unused function parameters
This is not a complete list of all the unused parameters in kernel, but
those I touch often, so I am more confident that it's safe to delete them.
2024-04-17 18:49:00 +02:00
Weizhen Huang
68253b4937 Fix: Cycles volume light tree using wrong point to compute uncertainty angle
it is not clear from which point the `cos_theta_u` should be computed in
volume segment, so the original implementation was mixing the closest point
and the point where the minimal angle is formed.
Use the closest point on segment as a conservative measure.

Pull Request: https://projects.blender.org/blender/blender/pulls/119965
2024-03-27 15:06:05 +01:00
Weizhen Huang
72780c3769 Fix: Cycles light tree assertion failing on Intel Mac
in the test scene `all_light_types_in_volume.blend`, `theta - theta_o -
theta_u` is slightly above the threshold. Even if we do a strict check
with `acos` on the failing cases, it will go to the other branch and
deliver a result which is also 1.0f. Better to relax the threshold.
2024-03-27 13:46:57 +01:00
Weizhen Huang
fdc2962beb Fix #114634: correlated samples in volume when using equiangular sampling and light tree
The same random number was used when sampling from the volume segment
and from the direct scattering position, causing correlation issues with
light tree.

To solve this problem, we ensure the same light is picked for
volume segment/direct scattering, equiangular/distance sampling by
sampling the light tree only once in volume segment. From the direct
scattering position in volume, we sample a position on the picked light
as usual. If sampling from the light tree fails, we continue with
indirect scattering.
For unbiased MIS weight for forward sampling, we retrieve the `P`, `D`
and `t` used in volume segment for traversing the light tree.

The main changes are:
1. `light_tree_sample()` and `light_distribution_sample()` now only pick
lights. Sampling a position on light is done separately via
`light_sample()`.
2. `light_tree_sample()` is now only called only once from volume
segment. For direct lighting we call `light_sample()`.
3. `light_tree_pdf()` now has a template `<in_volume_segment>`.
4. A new field `emitter_id` is added to struct `LightSample`, which just
stores the picked emitter index.
5. Additional field `previous_dt = ray->tmax - ray->tmin` is added to
`state->ray`, because we need this quantity for computing the pdf.
6. Distant/Background lights are also picked by light tree in volume
segment now, because we have no way to pick them afterwards. The direct
sample event for these lights will be handled by
`VOLUME_SAMPLE_DISTANCE`.
7. Original paper suggests to use the maximal importance, this results
in very poor sampling probability for distant and point lights therefore
excessive noise. We have a minimal importance for surface to balance, we
could do the same for volume but I do not want to spend much time on
this now. Just doing `min_importance = 0.0f` seems to do the job
okayish. This way we still won't sample the light with zero
`max_importance`.

The current solution might perform worse with distance sampling, because
the light tree measure is biased towards equiangular sampling. However,
it is difficult to perform MIS between equiangular and distance sampling
if different lights are picked for each method. This is something we can
look into in the future if proved to be a serious regression.

Pull Request: https://projects.blender.org/blender/blender/pulls/119389
2024-03-25 18:50:52 +01:00
Alaska
43cef92f66 Fix #119692: Cycles render issue with light tree and light linking
When using light linking with the light tree, the root index of a
mesh light subtree can be 0. The current code assumed this wasn't
possible, and as such it caused rendering issues, specifically the
incorrect computation of the PDF of certain mesh lights during
forward path tracing.

So we adjust the code to allow mesh light subtree root node
indices of 0.

This was worked on by Alaska, Sergey, and Weizhen

Pull Request: https://projects.blender.org/blender/blender/pulls/119770
2024-03-25 14:47:18 +01:00
Weizhen Huang
082b68fcb9 Cycles: improve equiangular sampling in volume
By restricting the sample range along the ray to the valid segment.

Supports

**Mesh Light**
- [x] restrict the ray segment to the side with MIS

**Area Light**
- [x] when the spread is zero, find the intersection of the ray and the bounding box/cylinder of the rectangle/ellipse area light beam
- [x] when the spread is non-zero, find the intersection of the ray and the minimal enclosing cone of the area light beam
*note the result is also unbiased when we just consider the cone from the sampled point in volume segment. Far away from the light source it's less noisy than the current solution, but near the light source it's much noisier. We have to restrict the sample region on the area light to the part that lits the ray then, I haven't tried yet to see if it would be less noisy.*

**Point Light**
- [x] the complete ray segment should be valid.

**Spot Light**
- [x] intersect the ray with the spot light cone
- [x] support non-zero radius

Pull Request: https://projects.blender.org/blender/blender/pulls/119438
2024-03-25 13:02:02 +01:00
Weizhen Huang
a2bb547b9a Fix: Cycles spot light spread sampling not considering non-uniform scaling
For spherical spot light, when the shading point is close to the light
source, we switch to sampling the light spread instead of the visible
cone from the shading point. This has the benefit of less noise when the
spread is small.
However, the light spread sampling was not considering non-uniform
object scaling, where the actual spread might be different.
This patch switches sampling method only when the smallest enclosing
spread cone is smaller than the visible cone from the shading point.

An alternative method would be to compute the actual solid angle of the
scaled cone, and sample from the scaled cone. However, that involves
ray transformation and modifying the sampling pdf and angle. Since
non-uniform scaling is rather a niche case, it's probably not worth the
computation effort.

Pull Request: https://projects.blender.org/blender/blender/pulls/119661
2024-03-19 18:55:35 +01:00
Weizhen Huang
a6fba7b59d Cleanup: Cycles: remove unnecessary storage of the spot light axes 2024-03-19 18:55:34 +01:00
Weizhen Huang
8536575263 Fix: Cycles area light ignores some valid samples in volume segment 2024-03-19 14:48:43 +01:00
Weizhen Huang
161881322e Merge branch 'blender-v4.1-release' 2024-03-15 18:13:40 +01:00
Weizhen Huang
682f984dbe Fix: Cycles mesh light ignores some valid samples in volume segment
Ref: #118534
turns out `in_volume_segment` does need to be checked. If the ray origin
lies on the wrong side of the mesh light, part of the ray could still be
lit by the other side, so the sample should not be considered invalid.

Pull Request: https://projects.blender.org/blender/blender/pulls/119529
2024-03-15 18:11:40 +01:00
Weizhen Huang
5782555c47 Merge branch 'blender-v4.1-release' 2024-02-22 12:26:37 +01:00
Weizhen Huang
0007c7a6b2 Fix #115997: Emission sampling setting ignored when not using light tree
if emission sampling is not set, we do not use MIS weight when sampling
from the BSDF, but we were still drawing samples from the light,
resulting in double contribution.

Pull Request: https://projects.blender.org/blender/blender/pulls/118534
2024-02-22 12:24:12 +01:00
Lukas Stockner
06b42313a6 Cleanup: Cycles: Replace cos with cosf 2024-02-20 02:57:29 +01:00
Brecht Van Lommel
bd8a44e169 Lights: Option to use old point light falloff
Add new "Soft Falloff" option on point and spot light that uses
the old light behavior from Blender versions before 4.0. Blend
files saved with those older versions will use the option.

This option is enabled by default on new lights.

Fix #114241

Co-authored-by: Weizhen Huang <weizhen@blender.org>
Co-authored-by: Clément Foucault <foucault.clem@gmail.com>
Pull Request: https://projects.blender.org/blender/blender/pulls/117832
2024-02-07 19:07:11 +01:00
Alaska
a3183fb95f Fix #117771: Incorrect Cycles texture position on emissive triangles
Pull Request: https://projects.blender.org/blender/blender/pulls/117801
2024-02-05 13:56:18 +01:00
Brecht Van Lommel
d377ef2543 Clang Format: bump to version 17
Along with the 4.1 libraries upgrade, we are bumping the clang-format
version from 8-12 to 17. This affects quite a few files.

If not already the case, you may consider pointing your IDE to the
clang-format binary bundled with the Blender precompiled libraries.
2024-01-03 13:38:14 +01:00
Campbell Barton
d31c61edee Cleanup: spelling in comments 2023-10-27 12:13:48 +11:00
Campbell Barton
137f8dd7bc Cleanup: spelling in comments 2023-10-10 09:44:57 +11:00
Lukas Stockner
97dfbc9a63 Fix #110183: Cycles: Numerical issues with distant area light sampling
The solid angle computation for the sampling/PDF code was running into
cancellation issues for small solid angles.
Reformulating the terms using asin() instead avoids this.
2023-10-05 22:53:33 +02:00
Brecht Van Lommel
a455eca7a0 Fix #112931: Cycles mesh light sampling artifacts 2023-10-02 19:18:42 +02:00
Campbell Barton
2721b937fb Cleanup: use braces in headers 2023-09-24 14:52:38 +10:00
Weizhen Huang
1284e98ab8 Cycles: use low-distortion mapping when sampling cone and hemisphere
based on concentric disk mapping.
Concentric disk mapping was already present, but not used everywhere.
Now `sample_cos_hemisphere()`, `sample_uniform_hemisphere()`, and
`sample_uniform_cone()` use concentric disk mapping.
This changes the noise in many test images.

Pull Request: https://projects.blender.org/blender/blender/pulls/109774
2023-08-23 17:25:27 +02:00
Weizhen Huang
c076202e23 Fix illegal address error in Cycles Light Tree when no emitter is selected
ensure that `sample_reservoir()` chooses index -1 when the weights are invalid,
and returns `false` from `light_tree_sample()`.

Previous attempt: 206ab6437b

Pull Request: https://projects.blender.org/blender/blender/pulls/111428
2023-08-23 16:09:06 +02:00
Weizhen Huang
3cd14df7d8 Revert "Fix illegal address error in Cycles Light Tree when no emitter is selected"
This reverts commit 206ab6437b.

Seems that the illegal address error should be covered elsewhere, but it's not directly
clear where. Revert the commit for further investigation.
2023-08-23 12:42:57 +02:00
Alaska
206ab6437b Fix illegal address error in Cycles Light Tree when no emitter is selected
Discovered during an investigation into #111277
in rare situations (E.G. When normals are NaN), an emitter
won't be selected as part of `light_tree_cluster_select_emitter()`
and as a result of that, an `emitter_index` of `-1` is passed to
`kernel_data_fetch(light_tree_emitters, emitter_index)` resulting in
an "illegal address" error on some devices.

Pull Request: https://projects.blender.org/blender/blender/pulls/111292
2023-08-23 11:54:20 +02:00
Alaska
52ed6a216f Fix #110255: Cover up CPU/GPU differences with small suns in light tree
This pull request covers up a subtle difference between the CPU and GPU
when rendering with a light tree. Specifically a case where the user
has a sun light with a small angle.

The difference was caused by the dot() function being different between
CPU and GPU backends, with the GPU showing more meaningful
floating-point precision losses when working with small suns.

Pull Request: https://projects.blender.org/blender/blender/pulls/110307
2023-08-07 07:29:14 +02:00
Sergey Sharybin
8ea68765fc Fix CUDA error with light linking and emissive world volume
The issue was an out-of-bounds read access when checking whether
the world volume emission needs to be accumulated.

Solution is to check for this case. Done in the generic place, so
that the shade_volume kernel is more readable and no branching
added there, and there is no impact on scenes without the light
linking.

Assume that the world emissive volume belongs to the default light
linking group, as there is no way to link it explicitly to anything.

Pull Request: https://projects.blender.org/blender/blender/pulls/110733
2023-08-03 07:54:06 +02:00
Campbell Barton
3889baab4f Cleanup: spelling in comments 2023-07-15 15:54:55 +10:00
Weizhen Huang
ab12d2836b Cycles: add texture to sun light
Using area-preserving mapping from cone to disk. Has somewhat distortion
near 90°.
The texture rotates with the transformation of the light object, can
have negative and non-uniform scaling.

Pull Request: https://projects.blender.org/blender/blender/pulls/109842
2023-07-10 12:20:47 +02:00
Campbell Barton
6290451712 Cleanup: spelling in comments 2023-07-09 21:22:45 +10:00
Lukas Stockner
213204c229 Cycles: Change sun lamp to have uniform intensity at high angles
This fixes the issue described in https://projects.blender.org/blender/blender/issues/108957.

Instead of modeling distant lights like a disk light at infinity, it models them as cones. This way, the radiance is constant across the entire range of directions that it covers.

For smaller angles, the difference is very subtle, but for very large angles it becomes obvious (here's the file from #108957, the angle is 179°):
| Old | New |
| - | - |
| ![old_bigsun.png](/attachments/4ef8e7a7-1a29-4bdf-a74c-3cfa103bf1e7) | ![new_bigsun.png](/attachments/d53c7749-2672-40b6-9048-ccf2fffceeb7) |

One notable detail is the sampling method: Using `sample_uniform_cone` can increase noise, since the sampling method no longer preserves the stratification of the samples. This is visible in the "light tree multi distant" test scene.
Turns out we can do better, and after a bit of testing I found a way to adapt the concentric Shirley mapping to uniform cone sampling. I hope the comment explains the logic behind it reasonably well.

Here's the result, note that even the noise distribution is the same when using the new sampling:
| Method | Old | New, basic sampling | New, concentric sampling |
| - | - |- | - |
| Image | ![old.png](/attachments/b3258a70-f015-4065-a774-193974cce439) | ![new_basic.png](/attachments/a9008576-0af6-4152-a687-c800fd958bbd) | ![new_concentric.png](/attachments/769b6c43-34bc-434e-a4fd-ce69addd1ba5) |
| Render time (at higher spp)| 9.03sec | 8.79sec | 8.96sec |

I'm not sure if I got the `light->normalized` handling right, since I don't really know what the expectation from Hydra is here.

Co-authored-by: Weizhen Huang <weizhen@blender.org>
Pull Request: https://projects.blender.org/blender/blender/pulls/108996
2023-07-07 17:20:19 +02:00
Weizhen Huang
9fe87646d5 Cycles: replace spot light disk sampling with sphere sampling
The spotlight is now treated as a sphere instead of a view-aligned disk.
The implementation remains almost identical to that of a point light,
except for the spotlight attenuation and spot blend. There is no
attenuation inside the sphere. Ref #108505

Other changes include:
## Sampling
Instead of sampling the disk area, the new implementation samples either
the cone of the visible portion on the sphere or the spread cone, based
on which cone has a smaller solid angle. This reduces noise when the
spotlight has a large radius and a small spread angle.
| Before | After  |
|   --   |   --   |
|![spot_size_before.png](/attachments/04ea864a-6bf9-40fe-b11b-61c838ae70cf)|![spot_size_after.png](/attachments/7077eaf9-b7a8-41b1-a8b6-aabf1eadb4f4)
## Texture
Spot light can now project texture using UV coordinates.
<video src="/attachments/6db989d2-7a3c-4b41-9340-f5690d48c4fb"
title="spot_light_texture.mp4" controls></video>
## Normalization
Previously, the normalization factor for the spotlight was \(\pi r^2\),
the area of a disk. This factor has been adjusted to \(4\pi r^2\) to
account for the surface area of a sphere. This change also affects point
light since they share the same kernel type.
## Versioning
Some pipeline uses the `Normal` socket of the Texture Coordinate node for
projection, because `ls->Ng` was set to the incoming direction at the
current shading point. Now that `ls->Ng` corresponds to the normal
direction of a point on the sphere (except when the radius is zero),
we replace these nodes with a combination of the Geometry shader node
and the Vector Transform node, which gives the same result as before.
![versioning.png](/attachments/5bbfcacc-26c5-4f7f-8360-c42bcd851f68)
Example file see https://archive.blender.org/developer/T93676

Pull Request: https://projects.blender.org/blender/blender/pulls/109329
2023-07-07 17:15:18 +02:00
Weizhen Huang
482211b7e0 Fix wrong conversion from power to radiance of area lights
The correct conversion factor should be 1 / (pi * area), see #108505

Co-authored-by: Brecht Van Lommel <brecht@blender.org>
Pull Request: https://projects.blender.org/blender/blender/pulls/109153
2023-07-07 17:03:02 +02:00
Weizhen Huang
be06c4b383 Cleanup: minor computational simplification in Cycles area light 2023-06-26 11:47:50 +02:00
Weizhen Huang
fcbf66d51f Cleanup: pre-scale spot light axes to avoid unnecessary division
`spot.dir` is kept normalized because it is used in the light tree.
2023-06-23 15:45:45 +02:00
Weizhen Huang
37d3daaea6 Cycles: remove clamping of area lights at small spread angles
there is still artifacts at extremely small angles, but should be
unnoticeable due to improved accuracy.
2023-06-22 17:52:41 +02:00
Weizhen Huang
9aaf28954b Cleanup: avoid division in #spot_light_attenuation 2023-06-22 17:19:01 +02:00
Weizhen Huang
a4d792a3ad Cycles/EEVEE: change point light to double-sided sphere light
for energy preservation and better compatibility with other renderes. Ref: #108505

Point light now behaves the same as a spherical mesh light with the same overall energy (scaling from emission strength to power is \(4\pi^2R^2\)).
# Cycles
## Comparison
| Mesh Light | This patch | Previous behavior |
| -------- | -------- | -------- |
| ![mesh_1024](attachments/2900954c-57f8-49c2-b6f3-8fb559b820ac)     | ![sphere_1024](attachments/148241ca-9350-48b6-be04-3933e015424c)     | ![point_1024](attachments/d9b19d54-2b00-4986-ba8c-c4b28f687f09)  |

The behavior stays the same when `radius = 0`.

| This patch | Previous behavior |
| -------- | -------- |
| ![sphere_64](attachments/aa05d59a-146a-4f69-b257-5d09a7f41d4e)     | ![point_64](attachments/69a743be-bc15-454b-92d8-af02f4e8ab07)    |

No obvious performance change observed.

## Sampling
When shading point lies outside the sphere, sample the spanned solid angle uniformly.
When shading point lies inside the sphere, sample spherical direction uniformly when inside volume or the surface is transmissive, otherwise sample cosine-weighted upper hemisphere.
## Light Tree
When shading point lies outside the sphere, treat as a disk light spanning the same solid angle.
When shading point lies inside the sphere, it behaves like a background light, with estimated outgoing radiance
\[L_o=\int f_aL_i\cos\theta_i\mathrm{d}\omega_i=\int f_a\frac{E}{\pi r^2}\cos\theta_i\mathrm{d}\omega_i\approx f_a \frac{E}{r^2}\],
with \(f_a\) being the BSDF and \(E\) `measure.energy` in `light_tree.cpp`.
The importance calculation for `LIGHT_POINT` is
\[L_o=f_a E\cos\theta_i\frac{\cos\theta}{d^2}\].
Consider `min_importance = 0` because maximal incidence angle is \(\pi\), we could substitute \(d^2\) with \(\frac{r^2}{2}\) so the averaged outgoing radiance is \(f_a \frac{E}{r^2}\).
This only holds for non-transmissive surface, but should be fine to use in volume.
# EEVEE
When shading point lies outside the sphere, the sphere light is equivalent to a disk light spanning the same solid angle. The sine of the new half-angle is the tangent of the previous half-angle.
When shading point lies inside the sphere, integrating over the cosine-weighted hemisphere gives 1.0.
## Comparison with Cycles
The plane is diffuse, the blue sphere has specular component.
| Before | |After ||
|---|--|--|--|
|Cycles|EEVEE|Cycles|EEVEE|
|![](attachments/5824c494-0645-461a-b193-d74e02f353b8)|![](attachments/d2e85b53-3c2a-4a9f-a3b2-6e11c6083ce0)|![](attachments/a8dcdd8b-c13c-4fdc-808c-2563624549be)|![](attachments/8c3618ef-1ab4-4210-9535-c85e873f1e45)|

Pull Request: https://projects.blender.org/blender/blender/pulls/108506
2023-06-20 12:23:05 +02:00
Campbell Barton
c12994612b License headers: use SPDX-FileCopyrightText in intern/cycles 2023-06-14 16:53:23 +10:00
Sergey Sharybin
376467de3c Merge branch 'blender-v3.6-release' 2023-06-13 15:36:38 +02:00
Alaska
623cb023b9 Cycles: Fix light tree sampling of multiple large distant lights
This fixes an issue where the light tree sampling algorithm would
discard light samples from groups of distance lights with an angle
greater than 0 when it shouldn't.

Pull Request: https://projects.blender.org/blender/blender/pulls/108832
2023-06-13 15:36:05 +02:00
Weizhen Huang
97d9bbbc97 Cycles: more efficient and better-behaved sampling of spherical triangles
uses less inverse trigonometric functions and normalizations.
Also `q` is now guaranteed to be smaller than or equal to 1.

Pull Request: https://projects.blender.org/blender/blender/pulls/108380
2023-06-02 16:57:50 +02:00
Sergey Sharybin
50ba227740 Fix #108316: CUDA error rendering Attic scene
The light tree dependent on the first threshold to evaluate to 1
when picking up an emitter.

Pull Request: https://projects.blender.org/blender/blender/pulls/108323
2023-05-30 11:44:33 +02:00