Commit Graph

59 Commits

Author SHA1 Message Date
Campbell Barton
5b9740c913 Cleanup: use braces for sources in intern/
Omitted intern/itasc as some of these sources are from KDL:
https://www.orocos.org/kdl.html
2023-09-17 09:05:40 +10:00
Brecht Van Lommel
6fa4519b98 Cycles: remove unnecessary transform parameters from lights
The transform matrix already specifies everything, no need to duplicate
this which can lead to mistakes.

Ref #110689
2023-08-11 17:41:06 +02:00
Alaska
18575e411b Cleanup: Cycles device_update_lights
Rearrange and remove some unnecessary lines of code
to improve readability.

Pull Request: https://projects.blender.org/blender/blender/pulls/110377
2023-07-31 10:46:31 +02:00
Brecht Van Lommel
7f04df62e4 Fix Cycles division by zero in recent distant light texture coordinates 2023-07-12 18:14:11 +02: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
Brecht Van Lommel
05c97df2de USD: improve light units conversion
* Use pi factor to convert between radiant flux and intensity
* Mark lights as normalized on export
* Add spot light export support
* Add treatAsPoint support for import and export
* Empirically match normalized distant light
* Fix wrong unnormalized point/sphere/disk light unit in Cycles

Overall it should be much closer now for all light types. Point and distant
light units are inconsistent between renderers, so not possible to match
everything there.

Ref #109404

Pull Request: https://projects.blender.org/blender/blender/pulls/109795
2023-07-07 18:20:39 +02: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
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
5c25277f6c Fix #108374: Sun light linking issue on direct sampling
This is a continuation of a fix from the last week in #108311.
The issue was not fully fixed due to a mistake in the regression
test file.

There are two major things which left to be fixed since the
previous patch:

1. Root nodes can not be shared, even if the local and distant
lights belong to the same light set. If the root node is shared
then the flattening will use the same node index for specialized
trees, which is not a desired behavior.

2. The node type needs to be preserved when a new node is
created for a subset of emitters. This is because tree sampling
in kernel will handle distant and local lights differently for
nodes where there are multiple emitters.

Pull Request: https://projects.blender.org/blender/blender/pulls/108427
2023-05-30 17:39:50 +02:00
Sergey Sharybin
5e971e8d7f Fix hiding receiver disabling light/shadow linking
Turns out it is not enough to check for the receiver/blocker set,
as the object might be hidden. This should not change the light
behavior.

Pull Request: https://projects.blender.org/blender/blender/pulls/108307
2023-05-26 12:21:44 +02:00
Sergey Sharybin
ba3f26fac5 Cycles: light and shadow linking
With light linking, lights can be set to affect only specific objects in the
scene. Shadow linking additionally gives control over which objects acts a
shadow blockers for a light.

Usage:
https://wiki.blender.org/wiki/Reference/Release_Notes/4.0/Cycles

Implementation:
https://wiki.blender.org/wiki/Source/Render/Cycles/LightLinking

Ref #104972
Co-authored-by: Brecht Van Lommel <brecht@blender.org>
2023-05-24 14:11:47 +02:00
Brecht Van Lommel
0ffde36fe7 Refactor: flatten light tree in recursive function
This will make further changes for light linking easier, where we want to
build multiple trees specialized for each light linking set.

It's also easier to understand than the stack used previously.

Pull Request: https://projects.blender.org/blender/blender/pulls/107560
2023-05-05 16:32:59 +02:00
Campbell Barton
6859bb6e67 Cleanup: format (with BraceWrapping::AfterControlStatement "MultiLine") 2023-05-02 09:37:49 +10:00
Weizhen Huang
4d7a7ce67c Fix #107050: accessing nullptr after progress is canceled 2023-04-18 11:58:07 +02:00
Brecht Van Lommel
92919864a0 Fix #106293: Cycles importance sampling with multiple suns works poorly
Keep sun in importance map in this case, as we do not use special sun
importance sampling in this case.
2023-04-17 17:30:47 +02:00
Alaska
cff94a808e Fix #106706: fireflies with Nishita sky sun sampling at certain angles
Due to floating point differences between importance sampling and
texture evaluation, disagreeing on whether or not a ray lies within
the sun disc.

* Use the same input values for geographical_to_direction() in
  sky_radiance_nishita() and kernel_data.background.sun.
* The mathematical operations in pdf_uniform_cone() were adjusted to
  match sky_radiance_nishita().

Pull Request: https://projects.blender.org/blender/blender/pulls/106764
2023-04-17 17:29:27 +02:00
Weizhen Huang
bfd1836861 Cycles: add instancing support in light tree
Build a subtree for each unique mesh light.

Pull Request: #106683
2023-04-14 19:12:16 +02:00
Brecht Van Lommel
b288c4004e Cleanup: fix various Cycles compilar warnings
Mainly for the build configuration of the Hydra render delegate and
standalone repo.
2023-04-05 19:48:19 +02:00
Weizhen Huang
87cbdcbe7c Refactor: move part of light tree logic from #LightManager to #LightTree 2023-04-04 16:24:21 +02:00
Weizhen Huang
e58a05ca68 Refactor: renaming a few light-tree-related variables
primitives -> emitters, `index` -> `node_index`
2023-04-04 16:24:21 +02:00
Alex Fuller
4f0092c1ff Refactor: add native Cycles Normalize option on lights for Hydra
Make it a native Cycles light option instead of counter-acting the inverse
area calculation in Hydra.

Differential Revision: https://developer.blender.org/D16838
2023-04-03 17:23:46 +02:00
Weizhen Huang
f692010ae1 Cleanup: remove redundant call to #free() for light tree arrays 2023-04-03 11:48:09 +02:00
Weizhen Huang
1205111fe9 Refactor: move #object_usable_as_light() from #LightManager class to #Object
so that the function can also be used by other classes.
Also change `!bounds.valid()` to `!is_traceable()` so zero-sized objects
are skipped.
2023-04-03 11:16:00 +02:00
Campbell Barton
35f770a689 Cleanup: duplicate words in comments 2023-03-29 14:17:32 +11:00
Weizhen Huang
17c8e0d309 Refactor Light Tree to improve readability and efficiency
* Group bounding box, bounding cone and energy to a struct called `LightTreePrimitivesMeasure`
* Add utility functions to add primitives to nodes or buckets
* Precompute the split bucket cost to improve efficiency (about 1.4x expected)

Pull Request: https://projects.blender.org/blender/blender/pulls/105931
2023-03-21 11:06:41 +01:00
Weizhen Huang
23c5e06932 Cycles: build Light Tree in parallel
Push a task to `TaskPool` when more than `MIN_PRIMS_PER_THREAD` primitives are to be processed. The nodes are rearranged in a depth-first order when copied to the device.
Tested with the scene in #105550 on an Apple M1 Ultra (20 cores), about 11x speedup.

Pull Request: https://projects.blender.org/blender/blender/pulls/105862
2023-03-20 18:02:11 +01:00
Julian Eisel
c437a8aea8 Revert release branch only commit after merge
This is a revert of a revert, because the initial revert is only
supposed to be in the release branch.

This reverts commit 3eed00dc54.
2023-02-20 11:51:16 +01:00
Julian Eisel
3eed00dc54 Revert "GPencil: Include UV information in simplify->sample modifier."
This reverts commit 19222627c6.

Something went wrong here, seems like this commit merged the main branch
into the release branch, which should never be done.
2023-02-20 11:20:07 +01:00
YimingWu
19222627c6 GPencil: Include UV information in simplify->sample modifier.
Simplify modifier sample mode didn't transfer UV parameters, now fixed.

Pull Request #104942
2023-02-19 11:45:22 +01:00
Weizhen Huang
b454416927 Cycles: add non-uniform scaling to spot light size
Cycles ignores the size of spot lights, therefore the illuminated area doesn't match the gizmo. This patch resolves this discrepancy.
| Before (Cycles) | After (Cycles) | Eevee
|{F14200605}|{F14200595}|{F14200600}|
This is done by scaling the ray direction by the size of the cone. The implementation of `spot_light_attenuation()` in `spot.h` matches `spot_attenuation()` in `lights_lib.glsl`.
**Test file**:
{F14200728}

Differential Revision: https://developer.blender.org/D17129
2023-02-03 18:51:14 +01:00
Campbell Barton
844cca9984 Cleanup: spelling in comments 2023-01-20 15:19:32 +11:00
Jeffrey Liu
05bdef7ce6 Fix T103094: Cycles ignores small suns in Nishita sky
The background evaluation samples the sky discretely, so if the sun is
too small, it can be missed in the evaluation. To solve this, the sun is
ignored during the background evaluation and its contribution is
computed separately.
2023-01-19 18:31:54 -06:00
Weizhen Huang
e378bd70ed Cleanup: remove code duplication in cycles light sampling
There has been an attempt to reorganize this part, however, it seems that didn't compile on HIP, and is reverted in
rBc2dc65dfa4ae60fa5d2c3b0cfe86f99dcb5bf16f. This is another attempt of refactoring. as I have no idea why some things don't work on HIP, it's
best to check whether this compiles on other platforms.
The main changes are creating a new struct named `MeshLight` that is shared between `KernelLightDistribution` and `KernelLightTreeEmitter`,
and a bit of renaming, so that light sampling with or without light tree could call the same function.
Also, I noticed a patch D16714 referring to HIP compilation error. Not sure if it's related, but browsing
https://builder.blender.org/admin/#/builders/30/builds/7826/steps/7/logs/stdio, it didn't work on gfx1102, not gfx9*.

Differential Revision: https://developer.blender.org/D16722
2022-12-12 21:25:09 +01:00
Thomas Dinges
54aec4629e Cleanup: Remove unused code in Cycles
* preempt_attr was copied from CUDA, but not used in HIP.
* Remove shadowed variable before conditional in EnvironmentTextureNode code.

Differential Revision: https://developer.blender.org/D16741
2022-12-12 18:15:41 +01:00
Campbell Barton
cb45b0bb2a Cleanup: spelling in comments 2022-12-08 13:47:55 +11:00
Weizhen Huang
bf18032977 Cycles: support spread angle 0 for area lights
Ref: T87053
2022-12-07 20:05:20 +01:00
Weizhen Huang
f68634a379 Cleanup: store tan instead of cot in area lights to increase precision 2022-12-07 18:54:41 +01:00
Weizhen Huang
53ef52f165 Cycles: improve sampling of ellipse area light with spread
**Problem**:
Area lights in Cycles have spread angle, in which case some part of the area light might be invisible to a shading point. The current implementation samples the whole area light, resulting some samples invisible and thus simply discarded. A technique is applied on rectangular light to sample a subset of the area light that is potentially visible (rB3f24cfb9582e1c826406301d37808df7ca6aa64c), however, ellipse (including disk) area lights remained untreated. The purpose of this patch is to apply a techniques to ellipse area light.
**Related Task**:
T87053
**Results**:
These are renderings before and after the patch:
|16spp|Disk light|Ellipse light|Square light (for reference, no changes)
|Before|{F13996789}|{F13996788}|{F13996822}
|After|{F13996759}|{F13996787}|{F13996852}
**Explanation**:
The visible region on an area light is found by drawing a cone from the shading point to the plane where the area light lies, with the aperture of the cone being the light spread.
{F13990078,height=200}
Ideally, we would like to draw samples only from the intersection of the area light and the projection of the cone onto the plane (forming a circle). However, the shape of the intersection is often irregular and thus hard to sample from directly.
{F13990104,height=200}
Instead, the current implementation draws samples from the bounding rectangle of the intersection. In this case, we still end up with some invalid samples outside of the circle, but already much less than sampling the original area light, and the bounding rectangle is easy to sample from.
{F13990125}
The above technique is only applied to rectangle area lights, ellipse area light still suffers from poor sampling. We could apply a similar technique to ellipse area lights, that is, find the
smallest regular shape (rectangle, circle, or ellipse) that covers the intersection (or maybe not the smallest but easy to compute).
For disk area light, we consider the relative position of both circles. Denoting `dist` as the distance between the centre of two circles, and `r1`, `r2` their radii. If `dist > r1 + r2`, the area light is completely invisible, we directly return `false`. If `dist < abs(r1 - r2)`, the smaller circle lies inside the larger one, and we sample whichever circle is smaller. Otherwise, the two circles intersect, we compute the bounding rectangle of the intersection, in which case `axis_u`, `len_u`, `axis_v`, `len_v` needs to be computed anew. Depending on the distance between the two circles, `len_v` is either the diameter of the smaller circle or the length of the common chord.
|{F13990211,height=195}|{F13990225,height=195}|{F13990274,height=195}|{F13990210,height=195}
|`dist > r1 + r2`|`dist < abs(r1 - r2)`|`dist^2 < abs(r1^2 - r2^2)`|`dist^2 > abs(r1^2 - r2^2)`
For ellipse area light, it's hard to find the smallest bounding shape of the intersection, therefore, we compute the bounding rectangle of the ellipse itself, then treat it as a rectangle light.
|{F13990386,height=195}|{F13990385,height=195}|{F13990387,height=195}
We also check the areas of the bounding rectangle of the intersection, the ellipse (disk) light, and the spread circle, then draw samples from the smallest shape of the three. For ellipse light, this also detects where one shape lies inside the other. I am not sure if we should add this measure to rectangle area light and sample from the spread circle when it has smaller area, as we seem to have a better sampling technique for rectangular (uniformly sample the solid angle). Maybe we could add [area-preserving parameterization for spherical
ellipse](https://arxiv.org/pdf/1805.09048.pdf) in the future.
**Limitation**:
At some point we switch from sampling the ellipse to sampling the rectangle, depending on the area of the both, and there seems to be a visible line (with |slope| =1) on the final rendering
which demonstrate at which point we switch between the two methods. We could see that the new sampling method clearly has lower variance near the boundaries, but close to that visible line,
the rectangle sampling method seems to have larger variance. I could not spot any bug in the implementation, and I am not sure if this happens because different sampling patterns for ellipse and rectangle are used.
|Before (256spp)|After (256spp)
|{F13996995}|{F13996998}

Differential Revision: https://developer.blender.org/D16694
2022-12-07 18:21:55 +01:00
Brecht Van Lommel
5270610b29 Fix Cycles uninitialized variables in mesh light sampling
Causing wrong renders and differences between platforms.
2022-12-05 20:20:51 +01:00
Weizhen Huang
f646a4f22c Cleanup: renaming tan_spread to cot_half_spread to avoid ambiguity
Differential Revision: https://developer.blender.org/D16695
2022-12-05 17:04:04 +01:00
Weizhen Huang
ee89f213de Cycles: improve many lights sampling using light tree
Uses a light tree to more effectively sample scenes with many lights. This can
significantly reduce noise, at the cost of a somewhat longer render time per
sample.

Light tree sampling is enabled by default. It can be disabled in the Sampling >
Lights panel. Scenes using light clamping or ray visibility tricks may render
different as these are biased techniques that depend on the sampling strategy.

The implementation is currently disabled on AMD HIP. This is planned to be fixed
before the release.

Implementation by Jeffrey Liu, Weizhen Huang, Alaska and Brecht Van Lommel.

Ref T77889
2022-12-05 16:09:03 +01:00
Brecht Van Lommel
0731d78d00 Cycles: remove shadow pass
This was not working well in non-trivial scenes before the light tree, and now
it is even harder to make it work well with the light tree. It would average the
with equal weight for every light object regardless of intensity or distance, and
be quite noisy due to not working with multiple importance sampling.

We may restore this if were enough good use cases for the previous implementation,
but let's wait and see what the feedback is.

Some uses cases for this have been replaced by the shadow catcher passes, which
did not exist when this was added.

Ref T77889
2022-12-05 15:52:10 +01:00
Brecht Van Lommel
948f13a8e7 Cleanup: compiler warning 2022-12-02 19:13:38 +01:00
Weizhen Huang
e028662f78 Cycles: store axis and length of an area light instead of their product 2022-12-02 15:23:09 +01:00
Brecht Van Lommel
396b407c7d Cycles: new setting and heuristics for mesh light importance sampling
Materials now have an enum to set the emission sampling method, to be
either None, Auto, Front, Back or Front & Back. This replace the
previous "Multiple Importance Sample" option.

Auto is the new default, and uses a heuristic to estimate the emitted
light intensity to determine of the mesh should be considered as a light
for sampling. Shaders sometimes have a bit of emission but treating them
as a light source is not worth the memory/performance overhead.

The Front/Back settings are not important yet, but will help when a
light tree is added. In that case setting emission to Front only on
closed meshes can help ignore emission from inside the mesh interior that
does not contribute anything.

Includes contributions by Brecht Van Lommel and Alaska.

Ref T77889
2022-11-30 21:19:51 +01:00