Cycles/EEVEE: change point light to double-sided sphere light #108506
|
@ -325,6 +325,20 @@ float light_diffuse(LightData ld, vec3 N, vec3 V, vec4 l_vector)
|
||||||
|
|
||||||
return ltc_evaluate_disk(N, V, mat3(1.0), points);
|
return ltc_evaluate_disk(N, V, mat3(1.0), points);
|
||||||
}
|
}
|
||||||
|
else if (ld.l_type == POINT) {
|
||||||
|
if (l_vector.w < ld.l_radius) {
|
||||||
|
/* Inside, treat as hemispherical light. */
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Outside, treat as disk light spanning the same solid angle. */
|
||||||
|
/* The result is the same as passing the scaled radius to #ltc_evaluate_disk_simple (see
|
||||||
|
* #light_specular), using simplified math here. */
|
||||||
|
float r_sqr = sqr(ld.l_radius / l_vector.w);
|
||||||
|
vec3 L = l_vector.xyz / l_vector.w;
|
||||||
|
return r_sqr * diffuse_sphere_integral(dot(N, L), r_sqr);
|
||||||
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
float radius = ld.l_radius;
|
float radius = ld.l_radius;
|
||||||
radius /= (ld.l_type == SUN) ? 1.0 : l_vector.w;
|
radius /= (ld.l_type == SUN) ? 1.0 : l_vector.w;
|
||||||
|
@ -347,11 +361,21 @@ float light_specular(LightData ld, vec4 ltc_mat, vec3 N, vec3 V, vec4 l_vector)
|
||||||
|
|
||||||
return ltc_evaluate_quad(corners, vec3(0.0, 0.0, 1.0));
|
return ltc_evaluate_quad(corners, vec3(0.0, 0.0, 1.0));
|
||||||
}
|
}
|
||||||
|
else if (ld.l_type == POINT && l_vector.w < ld.l_radius) {
|
||||||
|
/* Inside the sphere light, integrate over the hemisphere. */
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
bool is_ellipse = (ld.l_type == AREA_ELLIPSE);
|
bool is_ellipse = (ld.l_type == AREA_ELLIPSE);
|
||||||
float radius_x = is_ellipse ? ld.l_sizex : ld.l_radius;
|
float radius_x = is_ellipse ? ld.l_sizex : ld.l_radius;
|
||||||
float radius_y = is_ellipse ? ld.l_sizey : ld.l_radius;
|
float radius_y = is_ellipse ? ld.l_sizey : ld.l_radius;
|
||||||
|
|
||||||
|
if (ld.l_type == POINT) {
|
||||||
|
/* Sphere light spans a larger angle than a disk light with the same radius (sin -> tan). */
|
||||||
|
radius_x *= inversesqrt(1.0 - sqr(radius_x / l_vector.w));
|
||||||
|
radius_y *= inversesqrt(1.0 - sqr(radius_y / l_vector.w));
|
||||||
|
}
|
||||||
|
|
||||||
vec3 L = (ld.l_type == SUN) ? -ld.l_forward : l_vector.xyz;
|
vec3 L = (ld.l_type == SUN) ? -ld.l_forward : l_vector.xyz;
|
||||||
vec3 Px = ld.l_right;
|
vec3 Px = ld.l_right;
|
||||||
vec3 Py = ld.l_up;
|
vec3 Py = ld.l_up;
|
||||||
|
|
|
@ -106,7 +106,20 @@ float light_diffuse(sampler2DArray utility_tx,
|
||||||
vec3 L,
|
vec3 L,
|
||||||
float dist)
|
float dist)
|
||||||
{
|
{
|
||||||
if (is_directional || !is_area_light(ld.type)) {
|
if (ld.type == LIGHT_POINT) {
|
||||||
|
if (dist < ld._radius) {
|
||||||
|
/* Inside, treat as hemispherical light. */
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Outside, treat as disk light spanning the same solid angle. */
|
||||||
|
/* The result is the same as passing the scaled radius to #ltc_evaluate_disk_simple (see
|
||||||
|
* #light_ltc), using simplified math here. */
|
||||||
|
float r_sqr = sqr(ld._radius / dist);
|
||||||
|
return r_sqr * ltc_diffuse_sphere_integral(utility_tx, dot(N, L), r_sqr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (is_directional || ld.type == LIGHT_SPOT) {
|
||||||
float radius = ld._radius / dist;
|
float radius = ld._radius / dist;
|
||||||
return ltc_evaluate_disk_simple(utility_tx, radius, dot(N, L));
|
return ltc_evaluate_disk_simple(utility_tx, radius, dot(N, L));
|
||||||
}
|
}
|
||||||
|
@ -147,7 +160,11 @@ float light_ltc(sampler2DArray utility_tx,
|
||||||
float dist,
|
float dist,
|
||||||
vec4 ltc_mat)
|
vec4 ltc_mat)
|
||||||
{
|
{
|
||||||
if (is_directional || ld.type != LIGHT_RECT) {
|
if (ld.type == LIGHT_POINT && dist < ld._radius) {
|
||||||
|
/* Inside the sphere light, integrate over the hemisphere. */
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
else if (is_directional || ld.type != LIGHT_RECT) {
|
||||||
vec3 Px = ld._right;
|
vec3 Px = ld._right;
|
||||||
vec3 Py = ld._up;
|
vec3 Py = ld._up;
|
||||||
|
|
||||||
|
@ -156,8 +173,17 @@ float light_ltc(sampler2DArray utility_tx,
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 points[3];
|
vec3 points[3];
|
||||||
points[0] = Px * -ld._area_size_x + Py * -ld._area_size_y;
|
if (ld.type == LIGHT_POINT) {
|
||||||
points[1] = Px * ld._area_size_x + Py * -ld._area_size_y;
|
/* Sphere light spans a larger angle than a disk light with the same radius (sin -> tan). */
|
||||||
weizhen marked this conversation as resolved
Outdated
|
|||||||
|
float radius = ld._radius * inversesqrt(1.0 - sqr(ld._radius / dist));
|
||||||
|
|
||||||
|
points[0] = Px * -radius + Py * -radius;
|
||||||
|
points[1] = Px * radius + Py * -radius;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
points[0] = Px * -ld._area_size_x + Py * -ld._area_size_y;
|
||||||
|
points[1] = Px * ld._area_size_x + Py * -ld._area_size_y;
|
||||||
|
}
|
||||||
points[2] = -points[0];
|
points[2] = -points[0];
|
||||||
|
|
||||||
points[0] += L * dist;
|
points[0] += L * dist;
|
||||||
|
|
Loading…
Reference in New Issue
This
sin -> tan
is a bit cryptic. It could help if it was a full sentence.