Fix wrong conversion from power to radiance of area lights #109153

Merged
Weizhen Huang merged 10 commits from weizhen/blender:fix_area_light_scaling into main 2023-07-07 17:03:09 +02:00
11 changed files with 40 additions and 21 deletions

View File

@ -290,7 +290,8 @@ ccl_device_inline bool area_light_eval(const ccl_global KernelLight *klight,
ls->D = normalize_len(*light_P - ray_P, &ls->t);
}
ls->eval_fac = 0.25f * invarea;
/* Convert radiant flux to radiance. */
ls->eval_fac = M_1_PI_F * invarea;
if (klight->area.normalize_spread > 0) {
/* Area Light spread angle attenuation */

View File

@ -167,7 +167,8 @@ LightTreeEmitter::LightTreeEmitter(Scene *scene,
measure.bbox.grow(centroid - half_extentu + half_extentv);
measure.bbox.grow(centroid - half_extentu - half_extentv);
strength *= 0.25f; /* eval_fac scaling in `area.h` */
/* Convert irradiance to radiance. */
strength *= M_1_PI_F;
}
else if (type == LIGHT_POINT) {
measure.bcone.theta_o = M_PI_F;

View File

@ -27,7 +27,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 8
#define BLENDER_FILE_SUBVERSION 9
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and show a warning if the file

View File

@ -117,6 +117,12 @@ static void light_blend_write(BlendWriter *writer, ID *id, const void *id_addres
{
Light *la = (Light *)id;
/* Forward compatibility for energy. */
la->energy_deprecated = la->energy;
if (la->type == LA_AREA) {
la->energy_deprecated /= M_PI_4;
}
/* write LibData */
BLO_write_id_struct(writer, Light, id_address, &la->id);
BKE_id_blend_write(writer, &la->id);

View File

@ -1434,7 +1434,7 @@ static void light_emission_node_to_energy(Light *light, float *energy, float col
static void light_emission_unify(Light *light, const char *engine)
{
if (light->type != LA_SUN) {
light->energy *= 100.0f;
light->energy_deprecated *= 100.0f;
}
/* Attempt to extract constant energy and color from nodes. */
@ -1445,16 +1445,16 @@ static void light_emission_unify(Light *light, const char *engine)
if (STREQ(engine, "CYCLES")) {
if (use_nodes) {
/* Energy extracted from nodes */
light->energy = energy;
light->energy_deprecated = energy;
copy_v3_v3(&light->r, color);
}
else {
/* Default cycles multipliers if there are no nodes */
if (light->type == LA_SUN) {
light->energy = 1.0f;
light->energy_deprecated = 1.0f;
}
else {
light->energy = 100.0f;
light->energy_deprecated = 100.0f;
}
}
}

View File

@ -10,6 +10,7 @@
#include "CLG_log.h"
#include "DNA_light_types.h"
#include "DNA_lightprobe_types.h"
#include "DNA_modifier_types.h"
#include "DNA_movieclip_types.h"
@ -38,8 +39,18 @@
// static CLG_LogRef LOG = {"blo.readfile.doversion"};
void do_versions_after_linking_400(FileData * /*fd*/, Main * /*bmain*/)
void do_versions_after_linking_400(FileData * /*fd*/, Main *bmain)
{
if (!MAIN_VERSION_ATLEAST(bmain, 400, 9)) {
/* Fix area light scaling. */
LISTBASE_FOREACH (Light *, light, &bmain->lights) {
light->energy = light->energy_deprecated;
if (light->type == LA_AREA) {
light->energy *= M_PI_4;
}
}
}
/**
* Versioning code until next subversion bump goes here.
*
@ -133,7 +144,8 @@ static void version_mesh_crease_generic(Main &bmain)
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (STR_ELEM(node->idname,
"GeometryNodeStoreNamedAttribute",
"GeometryNodeInputNamedAttribute")) {
"GeometryNodeInputNamedAttribute"))
{
bNodeSocket *socket = nodeFindSocket(node, SOCK_IN, "Name");
if (STREQ(socket->default_value_typed<bNodeSocketValueString>()->value, "crease")) {
STRNCPY(socket->default_value_typed<bNodeSocketValueString>()->value, "crease_edge");

View File

@ -78,9 +78,8 @@ static float light_shape_radiance_get(const Light *la, const EEVEE_Light *evli)
if (ELEM(la->area_shape, LA_AREA_DISK, LA_AREA_ELLIPSE)) {
area *= M_PI / 4.0f;
}
/* NOTE: The 4 factor is from Cycles definition of power. */
/* NOTE: Missing a factor of PI here to match Cycles. */
return 1.0f / (4.0f * area);
/* Convert radiant flux to radiance. */
return (float)M_1_PI / area;
}
case LA_SPOT:
case LA_LOCAL: {
@ -120,9 +119,7 @@ static float light_volume_radiance_factor_get(const Light *la,
float tmp = M_PI_2 / (M_PI_2 + sqrtf(area));
/* Lerp between 1.0 and the limit (1 / pi). */
float mrp_scaling = tmp + (1.0f - tmp) * M_1_PI;
/* NOTE: The 4 factor is from Cycles definition of power. */
/* NOTE: Missing a factor of PI here to match Cycles. */
power *= mrp_scaling / 4.0f;
power *= (float)M_1_PI * mrp_scaling;
break;
}
case LA_SPOT:

View File

@ -178,9 +178,8 @@ float Light::shape_radiance_get(const ::Light *la)
if (ELEM(la->area_shape, LA_AREA_DISK, LA_AREA_ELLIPSE)) {
area *= M_PI / 4.0f;
}
/* NOTE: The 4 factor is from Cycles definition of power. */
/* NOTE: Missing a factor of PI here to match Cycles. */
return 1.0f / (4.0f * area);
/* Convert radiant flux to radiance. */
return float(M_1_PI) / area;
}
case LA_SPOT:
case LA_LOCAL: {
@ -214,9 +213,7 @@ float Light::point_radiance_get(const ::Light *la)
float tmp = M_PI_2 / (M_PI_2 + sqrtf(area));
/* Lerp between 1.0 and the limit (1 / pi). */
float mrp_scaling = tmp + (1.0f - tmp) * M_1_PI;
/* NOTE: The 4 factor is from Cycles definition of power. */
/* NOTE: Missing a factor of PI here to match Cycles. */
return mrp_scaling / 4.0f;
return float(M_1_PI) * mrp_scaling;
}
case LA_SPOT:
case LA_LOCAL: {

View File

@ -21,6 +21,7 @@
.g = 1.0f, \
.b = 1.0f, \
.energy = 10.0f, \
.energy_deprecated = 10.0f, \
.spotsize = DEG2RADF(45.0f), \
.spotblend = 0.15f, \
.mode = LA_SHADOW, \

View File

@ -89,6 +89,8 @@ typedef struct Light {
/* Deprecated. */
struct Ipo *ipo DNA_DEPRECATED; /* Old animation system. */
float energy_deprecated DNA_DEPRECATED;
float _pad2;
} Light;
/* **************** LIGHT ********************* */

View File

@ -85,6 +85,8 @@ DNA_STRUCT_RENAME_ELEM(GreasePencil, material_array_size, material_array_num)
DNA_STRUCT_RENAME_ELEM(GreasePencilLayerFramesMapStorage, size, num)
DNA_STRUCT_RENAME_ELEM(HookModifierData, totindex, indexar_num)
DNA_STRUCT_RENAME_ELEM(Image, name, filepath)
DNA_STRUCT_RENAME_ELEM(Light, energy_new, energy)
DNA_STRUCT_RENAME_ELEM(Light, energy, energy_deprecated)
DNA_STRUCT_RENAME_ELEM(LaplacianDeformModifierData, total_verts, verts_num)
DNA_STRUCT_RENAME_ELEM(Library, name, filepath)
DNA_STRUCT_RENAME_ELEM(LineartGpencilModifierData, line_types, edge_types)