2023-06-14 16:52:36 +10:00
|
|
|
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: Apache-2.0 */
|
2022-11-30 20:17:45 +01:00
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include "kernel/light/common.h"
|
|
|
|
|
|
|
|
|
|
CCL_NAMESPACE_BEGIN
|
|
|
|
|
|
|
|
|
|
ccl_device_inline bool point_light_sample(const ccl_global KernelLight *klight,
|
2023-05-24 18:56:58 +02:00
|
|
|
const float2 rand,
|
2022-11-30 20:17:45 +01:00
|
|
|
const float3 P,
|
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 |
| -------- | -------- | -------- |
|  |  |  |
The behavior stays the same when `radius = 0`.
| This patch | Previous behavior |
| -------- | -------- |
|  |  |
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|
|||||
Pull Request: https://projects.blender.org/blender/blender/pulls/108506
2023-06-20 12:23:05 +02:00
|
|
|
const float3 N,
|
|
|
|
|
const int shader_flags,
|
2022-11-30 20:17:45 +01:00
|
|
|
ccl_private LightSample *ls)
|
|
|
|
|
{
|
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 |
| -------- | -------- | -------- |
|  |  |  |
The behavior stays the same when `radius = 0`.
| This patch | Previous behavior |
| -------- | -------- |
|  |  |
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|
|||||
Pull Request: https://projects.blender.org/blender/blender/pulls/108506
2023-06-20 12:23:05 +02:00
|
|
|
float3 lightN = P - klight->co;
|
|
|
|
|
const float d_sq = len_squared(lightN);
|
|
|
|
|
const float d = sqrtf(d_sq);
|
|
|
|
|
lightN /= d;
|
|
|
|
|
|
|
|
|
|
const float r_sq = sqr(klight->spot.radius);
|
|
|
|
|
|
|
|
|
|
float cos_theta;
|
|
|
|
|
if (d_sq > r_sq) {
|
|
|
|
|
const float one_minus_cos = sin_sqr_to_one_minus_cos(r_sq / d_sq);
|
2023-08-23 17:25:27 +02:00
|
|
|
ls->D = sample_uniform_cone(-lightN, one_minus_cos, rand, &cos_theta, &ls->pdf);
|
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 |
| -------- | -------- | -------- |
|  |  |  |
The behavior stays the same when `radius = 0`.
| This patch | Previous behavior |
| -------- | -------- |
|  |  |
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|
|||||
Pull Request: https://projects.blender.org/blender/blender/pulls/108506
2023-06-20 12:23:05 +02:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
const bool has_transmission = (shader_flags & SD_BSDF_HAS_TRANSMISSION);
|
|
|
|
|
if (has_transmission) {
|
|
|
|
|
ls->D = sample_uniform_sphere(rand);
|
|
|
|
|
ls->pdf = M_1_2PI_F * 0.5f;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
sample_cos_hemisphere(N, rand, &ls->D, &ls->pdf);
|
|
|
|
|
}
|
|
|
|
|
cos_theta = -dot(ls->D, lightN);
|
2022-11-30 20:17:45 +01:00
|
|
|
}
|
|
|
|
|
|
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 |
| -------- | -------- | -------- |
|  |  |  |
The behavior stays the same when `radius = 0`.
| This patch | Previous behavior |
| -------- | -------- |
|  |  |
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|
|||||
Pull Request: https://projects.blender.org/blender/blender/pulls/108506
2023-06-20 12:23:05 +02:00
|
|
|
/* Law of cosines. */
|
|
|
|
|
ls->t = d * cos_theta - copysignf(safe_sqrtf(r_sq - d_sq + d_sq * sqr(cos_theta)), d_sq - r_sq);
|
|
|
|
|
|
|
|
|
|
ls->P = P + ls->D * ls->t;
|
2022-11-30 20:17:45 +01:00
|
|
|
|
2023-07-07 17:15:18 +02:00
|
|
|
ls->eval_fac = klight->spot.eval_fac;
|
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 |
| -------- | -------- | -------- |
|  |  |  |
The behavior stays the same when `radius = 0`.
| This patch | Previous behavior |
| -------- | -------- |
|  |  |
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|
|||||
Pull Request: https://projects.blender.org/blender/blender/pulls/108506
2023-06-20 12:23:05 +02:00
|
|
|
if (r_sq == 0) {
|
|
|
|
|
/* Use intensity instead of radiance for point light. */
|
|
|
|
|
ls->eval_fac /= sqr(ls->t);
|
2023-07-15 15:45:06 +10:00
|
|
|
/* `ls->Ng` is not well-defined for point light, so use the incoming direction instead. */
|
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 |
| -------- | -------- | -------- |
|  |  |  |
The behavior stays the same when `radius = 0`.
| This patch | Previous behavior |
| -------- | -------- |
|  |  |
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|
|||||
Pull Request: https://projects.blender.org/blender/blender/pulls/108506
2023-06-20 12:23:05 +02:00
|
|
|
ls->Ng = -ls->D;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
ls->Ng = normalize(ls->P - klight->co);
|
|
|
|
|
/* Remap sampled point onto the sphere to prevent precision issues with small radius. */
|
|
|
|
|
ls->P = ls->Ng * klight->spot.radius + klight->co;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const Transform itfm = klight->itfm;
|
|
|
|
|
const float2 uv = map_to_sphere(transform_direction(&itfm, ls->Ng));
|
|
|
|
|
/* NOTE: Return barycentric coordinates in the same notation as Embree and OptiX. */
|
|
|
|
|
ls->u = uv.y;
|
|
|
|
|
ls->v = 1.0f - uv.x - uv.y;
|
2022-11-30 20:17:45 +01:00
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
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 |
| -------- | -------- | -------- |
|  |  |  |
The behavior stays the same when `radius = 0`.
| This patch | Previous behavior |
| -------- | -------- |
|  |  |
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|
|||||
Pull Request: https://projects.blender.org/blender/blender/pulls/108506
2023-06-20 12:23:05 +02:00
|
|
|
ccl_device_forceinline float point_light_pdf(
|
|
|
|
|
const float d_sq, const float r_sq, const float3 N, const float3 D, const uint32_t path_flag)
|
|
|
|
|
{
|
|
|
|
|
if (d_sq > r_sq) {
|
|
|
|
|
return M_1_2PI_F / sin_sqr_to_one_minus_cos(r_sq / d_sq);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const bool has_transmission = (path_flag & PATH_RAY_MIS_HAD_TRANSMISSION);
|
|
|
|
|
return has_transmission ? M_1_2PI_F * 0.5f : pdf_cos_hemisphere(N, D);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-25 12:22:25 +02:00
|
|
|
ccl_device_forceinline void point_light_mnee_sample_update(const ccl_global KernelLight *klight,
|
|
|
|
|
ccl_private LightSample *ls,
|
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 |
| -------- | -------- | -------- |
|  |  |  |
The behavior stays the same when `radius = 0`.
| This patch | Previous behavior |
| -------- | -------- |
|  |  |
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|
|||||
Pull Request: https://projects.blender.org/blender/blender/pulls/108506
2023-06-20 12:23:05 +02:00
|
|
|
const float3 P,
|
|
|
|
|
const float3 N,
|
|
|
|
|
const uint32_t path_flag)
|
2022-11-30 20:17:45 +01:00
|
|
|
{
|
|
|
|
|
ls->D = normalize_len(ls->P - P, &ls->t);
|
|
|
|
|
|
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 |
| -------- | -------- | -------- |
|  |  |  |
The behavior stays the same when `radius = 0`.
| This patch | Previous behavior |
| -------- | -------- |
|  |  |
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|
|||||
Pull Request: https://projects.blender.org/blender/blender/pulls/108506
2023-06-20 12:23:05 +02:00
|
|
|
const float radius = klight->spot.radius;
|
2022-11-30 20:17:45 +01:00
|
|
|
|
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 |
| -------- | -------- | -------- |
|  |  |  |
The behavior stays the same when `radius = 0`.
| This patch | Previous behavior |
| -------- | -------- |
|  |  |
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|
|||||
Pull Request: https://projects.blender.org/blender/blender/pulls/108506
2023-06-20 12:23:05 +02:00
|
|
|
if (radius > 0) {
|
|
|
|
|
const float d_sq = len_squared(P - klight->co);
|
|
|
|
|
const float r_sq = sqr(radius);
|
|
|
|
|
const float t_sq = sqr(ls->t);
|
|
|
|
|
|
|
|
|
|
ls->pdf = point_light_pdf(d_sq, r_sq, N, ls->D, path_flag);
|
|
|
|
|
|
|
|
|
|
/* NOTE : preserve pdf in area measure. */
|
|
|
|
|
ls->pdf *= 0.5f * fabsf(d_sq - r_sq - t_sq) / (radius * ls->t * t_sq);
|
|
|
|
|
|
|
|
|
|
ls->Ng = normalize(ls->P - klight->co);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2023-07-07 17:15:18 +02:00
|
|
|
ls->eval_fac = klight->spot.eval_fac;
|
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 |
| -------- | -------- | -------- |
|  |  |  |
The behavior stays the same when `radius = 0`.
| This patch | Previous behavior |
| -------- | -------- |
|  |  |
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|
|||||
Pull Request: https://projects.blender.org/blender/blender/pulls/108506
2023-06-20 12:23:05 +02:00
|
|
|
|
|
|
|
|
ls->Ng = -ls->D;
|
|
|
|
|
|
|
|
|
|
/* PDF does not change. */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const Transform itfm = klight->itfm;
|
|
|
|
|
const float2 uv = map_to_sphere(transform_direction(&itfm, ls->Ng));
|
|
|
|
|
/* NOTE: Return barycentric coordinates in the same notation as Embree and OptiX. */
|
|
|
|
|
ls->u = uv.y;
|
|
|
|
|
ls->v = 1.0f - uv.x - uv.y;
|
2022-11-30 20:17:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ccl_device_inline bool point_light_intersect(const ccl_global KernelLight *klight,
|
|
|
|
|
const ccl_private Ray *ccl_restrict ray,
|
|
|
|
|
ccl_private float *t)
|
|
|
|
|
{
|
|
|
|
|
const float radius = klight->spot.radius;
|
|
|
|
|
if (radius == 0.0f) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float3 P;
|
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 |
| -------- | -------- | -------- |
|  |  |  |
The behavior stays the same when `radius = 0`.
| This patch | Previous behavior |
| -------- | -------- |
|  |  |
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|
|||||
Pull Request: https://projects.blender.org/blender/blender/pulls/108506
2023-06-20 12:23:05 +02:00
|
|
|
return ray_sphere_intersect(ray->P, ray->D, ray->tmin, ray->tmax, klight->co, radius, &P, t);
|
2022-11-30 20:17:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ccl_device_inline bool point_light_sample_from_intersection(
|
|
|
|
|
const ccl_global KernelLight *klight,
|
|
|
|
|
ccl_private const Intersection *ccl_restrict isect,
|
|
|
|
|
const float3 ray_P,
|
|
|
|
|
const float3 ray_D,
|
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 |
| -------- | -------- | -------- |
|  |  |  |
The behavior stays the same when `radius = 0`.
| This patch | Previous behavior |
| -------- | -------- |
|  |  |
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|
|||||
Pull Request: https://projects.blender.org/blender/blender/pulls/108506
2023-06-20 12:23:05 +02:00
|
|
|
const float3 N,
|
|
|
|
|
const uint32_t path_flag,
|
2022-11-30 20:17:45 +01:00
|
|
|
ccl_private LightSample *ccl_restrict ls)
|
|
|
|
|
{
|
2023-07-07 17:15:18 +02:00
|
|
|
ls->eval_fac = klight->spot.eval_fac;
|
2022-11-30 20:17:45 +01:00
|
|
|
|
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 |
| -------- | -------- | -------- |
|  |  |  |
The behavior stays the same when `radius = 0`.
| This patch | Previous behavior |
| -------- | -------- |
|  |  |
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|
|||||
Pull Request: https://projects.blender.org/blender/blender/pulls/108506
2023-06-20 12:23:05 +02:00
|
|
|
const float radius = klight->spot.radius;
|
2022-11-30 20:17:45 +01:00
|
|
|
|
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 |
| -------- | -------- | -------- |
|  |  |  |
The behavior stays the same when `radius = 0`.
| This patch | Previous behavior |
| -------- | -------- |
|  |  |
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|
|||||
Pull Request: https://projects.blender.org/blender/blender/pulls/108506
2023-06-20 12:23:05 +02:00
|
|
|
ls->Ng = radius > 0 ? normalize(ls->P - klight->co) : -ray_D;
|
2022-11-30 20:17:45 +01:00
|
|
|
|
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 |
| -------- | -------- | -------- |
|  |  |  |
The behavior stays the same when `radius = 0`.
| This patch | Previous behavior |
| -------- | -------- |
|  |  |
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|
|||||
Pull Request: https://projects.blender.org/blender/blender/pulls/108506
2023-06-20 12:23:05 +02:00
|
|
|
const Transform itfm = klight->itfm;
|
|
|
|
|
const float2 uv = map_to_sphere(transform_direction(&itfm, ls->Ng));
|
|
|
|
|
/* NOTE: Return barycentric coordinates in the same notation as Embree and OptiX. */
|
|
|
|
|
ls->u = uv.y;
|
|
|
|
|
ls->v = 1.0f - uv.x - uv.y;
|
2022-11-30 20:17:45 +01:00
|
|
|
|
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 |
| -------- | -------- | -------- |
|  |  |  |
The behavior stays the same when `radius = 0`.
| This patch | Previous behavior |
| -------- | -------- |
|  |  |
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|
|||||
Pull Request: https://projects.blender.org/blender/blender/pulls/108506
2023-06-20 12:23:05 +02:00
|
|
|
if (ls->t == FLT_MAX) {
|
|
|
|
|
ls->pdf = 0.0f;
|
2022-11-30 20:17:45 +01:00
|
|
|
}
|
|
|
|
|
else {
|
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 |
| -------- | -------- | -------- |
|  |  |  |
The behavior stays the same when `radius = 0`.
| This patch | Previous behavior |
| -------- | -------- |
|  |  |
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|
|||||
Pull Request: https://projects.blender.org/blender/blender/pulls/108506
2023-06-20 12:23:05 +02:00
|
|
|
ls->pdf = point_light_pdf(len_squared(ray_P - klight->co), sqr(radius), N, ray_D, path_flag);
|
2022-11-30 20:17:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2022-12-02 19:04:00 +01:00
|
|
|
|
|
|
|
|
template<bool in_volume_segment>
|
|
|
|
|
ccl_device_forceinline bool point_light_tree_parameters(const ccl_global KernelLight *klight,
|
|
|
|
|
const float3 centroid,
|
|
|
|
|
const float3 P,
|
|
|
|
|
ccl_private float &cos_theta_u,
|
|
|
|
|
ccl_private float2 &distance,
|
|
|
|
|
ccl_private float3 &point_to_centroid)
|
|
|
|
|
{
|
|
|
|
|
if (in_volume_segment) {
|
|
|
|
|
cos_theta_u = 1.0f; /* Any value in [-1, 1], irrelevant since theta = 0 */
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
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 |
| -------- | -------- | -------- |
|  |  |  |
The behavior stays the same when `radius = 0`.
| This patch | Previous behavior |
| -------- | -------- |
|  |  |
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|
|||||
Pull Request: https://projects.blender.org/blender/blender/pulls/108506
2023-06-20 12:23:05 +02:00
|
|
|
float dist_point_to_centroid;
|
|
|
|
|
point_to_centroid = safe_normalize_len(centroid - P, &dist_point_to_centroid);
|
2022-12-02 19:04:00 +01:00
|
|
|
|
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 |
| -------- | -------- | -------- |
|  |  |  |
The behavior stays the same when `radius = 0`.
| This patch | Previous behavior |
| -------- | -------- |
|  |  |
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|
|||||
Pull Request: https://projects.blender.org/blender/blender/pulls/108506
2023-06-20 12:23:05 +02:00
|
|
|
const float radius = klight->spot.radius;
|
|
|
|
|
if (dist_point_to_centroid > radius) {
|
|
|
|
|
/* Equivalent to a disk light with the same angular span. */
|
|
|
|
|
cos_theta_u = cos_from_sin(radius / dist_point_to_centroid);
|
|
|
|
|
distance = dist_point_to_centroid * make_float2(1.0f / cos_theta_u, 1.0f);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Similar to background light. */
|
|
|
|
|
cos_theta_u = -1.0f;
|
|
|
|
|
/* HACK: pack radiance scaling in the distance. */
|
|
|
|
|
distance = one_float2() * radius / M_SQRT2_F;
|
|
|
|
|
}
|
2022-12-02 19:04:00 +01:00
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-30 20:17:45 +01:00
|
|
|
CCL_NAMESPACE_END
|