Commit: 21854575a4ede7d0c16fbe31ac90e66493f607fe Author: Brecht Van Lommel Date: Sun May 12 13:41:23 2019 +0200 Branches: master https://developer.blender.org/rB21854575a4ede7d0c16fbe31ac90e66493f607fe
Cycles/Eevee: unify light strength and color Cycles lights now use strength and color properties of the light outside of the shading nodes, just like Eevee. The shading nodes then act as a multiplier on this, and become optional unless textures, fallof or other effects are desired. Backwards compatibility is not exact, as we can't be sure which renderer the .blend was designed for or even if it was designed for a single one. If the render engine in the active scene is set to Cycles, lights are converted to ensure overall light strength remains the same, and removing unnecessary shader node setups that only included a single emission node. If the engine is set to Eevee, we increase strength to remove the automatic 100x multiplier that was there to match Cycles. Differential Revision: https://developer.blender.org/D4588 =================================================================== M intern/cycles/blender/addon/ui.py M intern/cycles/blender/blender_object.cpp M intern/cycles/blender/blender_shader.cpp M intern/cycles/kernel/kernel_emission.h M intern/cycles/kernel/kernel_types.h M intern/cycles/render/light.cpp M intern/cycles/render/light.h M source/blender/blenkernel/BKE_blender_version.h M source/blender/blenloader/intern/versioning_cycles.c M source/blender/draw/engines/eevee/eevee_lights.c M source/blender/editors/object/object_add.c M source/blender/editors/space_node/node_edit.c =================================================================== diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 0845f567056..9714067b08e 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -1341,6 +1341,10 @@ class CYCLES_LIGHT_PT_light(CyclesButtonsPanel, Panel): col = layout.column() + col.prop(light, "color") + col.prop(light, "energy") + col.separator() + if light.type in {'POINT', 'SUN', 'SPOT'}: col.prop(light, "shadow_soft_size", text="Size") elif light.type == 'AREA': @@ -1384,8 +1388,7 @@ class CYCLES_LIGHT_PT_nodes(CyclesButtonsPanel, Panel): layout = self.layout light = context.light - if not panel_node_draw(layout, light, 'OUTPUT_LIGHT', 'Surface'): - layout.prop(light, "color") + panel_node_draw(layout, light, 'OUTPUT_LIGHT', 'Surface') class CYCLES_LIGHT_PT_spot(CyclesButtonsPanel, Panel): diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 00f53804e38..1094ff37afb 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -182,6 +182,10 @@ void BlenderSync::sync_light(BL::Object &b_parent, } } + /* strength */ + light->strength = get_float3(b_light.color()); + light->strength *= BL::PointLight(b_light).energy(); + /* location and (inverted!) direction */ light->co = transform_get_column(&tfm, 3); light->dir = -transform_get_column(&tfm, 2); diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index a08f767f964..8321d0c088c 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -1409,16 +1409,9 @@ void BlenderSync::sync_lights(BL::Depsgraph &b_depsgraph, bool update_all) add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree); } else { - float strength = 1.0f; - - if (b_light.type() == BL::Light::type_POINT || b_light.type() == BL::Light::type_SPOT || - b_light.type() == BL::Light::type_AREA) { - strength = 100.0f; - } - EmissionNode *emission = new EmissionNode(); - emission->color = get_float3(b_light.color()); - emission->strength = strength; + emission->color = make_float3(1.0f, 1.0f, 1.0f); + emission->strength = 1.0f; graph->add(emission); ShaderNode *out = graph->output(); diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h index f2eaa7b50a5..34300543f91 100644 --- a/intern/cycles/kernel/kernel_emission.h +++ b/intern/cycles/kernel/kernel_emission.h @@ -90,6 +90,11 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, eval *= ls->eval_fac; + if (ls->lamp != LAMP_NONE) { + const ccl_global KernelLight *klight = &kernel_tex_fetch(__lights, ls->lamp); + eval *= make_float3(klight->strength[0], klight->strength[1], klight->strength[2]); + } + return eval; } diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 7d4f655a32e..4070d5a8992 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -1455,6 +1455,8 @@ typedef struct KernelLight { int samples; float max_bounces; float random; + float strength[3]; + float pad1; Transform tfm; Transform itfm; union { diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp index d4c233e3bb3..ef4bd4260c9 100644 --- a/intern/cycles/render/light.cpp +++ b/intern/cycles/render/light.cpp @@ -114,6 +114,8 @@ NODE_DEFINE(Light) type_enum.insert("spot", LIGHT_SPOT); SOCKET_ENUM(type, "Type", type_enum, LIGHT_POINT); + SOCKET_COLOR(strength, "Strength", make_float3(1.0f, 1.0f, 1.0f)); + SOCKET_POINT(co, "Co", make_float3(0.0f, 0.0f, 0.0f)); SOCKET_VECTOR(dir, "Dir", make_float3(0.0f, 0.0f, 0.0f)); @@ -162,6 +164,9 @@ void Light::tag_update(Scene *scene) bool Light::has_contribution(Scene *scene) { + if (strength == make_float3(0.0f, 0.0f, 0.0f)) { + return false; + } if (is_portal) { return false; } @@ -672,7 +677,6 @@ void LightManager::device_update_points(Device *, DeviceScene *dscene, Scene *sc float3 co = light->co; Shader *shader = (light->shader) ? light->shader : scene->default_light; int shader_id = scene->shader_manager->get_shader_id(shader); - int samples = light->samples; int max_bounces = light->max_bounces; float random = (float)light->random_id * (1.0f / (float)0xFFFFFFFF); @@ -697,7 +701,10 @@ void LightManager::device_update_points(Device *, DeviceScene *dscene, Scene *sc } klights[light_index].type = light->type; - klights[light_index].samples = samples; + klights[light_index].samples = light->samples; + klights[light_index].strength[0] = light->strength.x; + klights[light_index].strength[1] = light->strength.y; + klights[light_index].strength[2] = light->strength.z; if (light->type == LIGHT_POINT) { shader_id &= ~SHADER_AREA_LIGHT; diff --git a/intern/cycles/render/light.h b/intern/cycles/render/light.h index 66732000f3b..a7bffde7a8d 100644 --- a/intern/cycles/render/light.h +++ b/intern/cycles/render/light.h @@ -42,6 +42,7 @@ class Light : public Node { Light(); LightType type; + float3 strength; float3 co; float3 dir; diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index 74d33a9c275..a36ead4630e 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -27,7 +27,7 @@ * \note Use #STRINGIFY() rather than defining with quotes. */ #define BLENDER_VERSION 280 -#define BLENDER_SUBVERSION 63 +#define BLENDER_SUBVERSION 64 /** Several breakages with 280, e.g. collections vs layers. */ #define BLENDER_MINVERSION 280 #define BLENDER_MINSUBVERSION 0 diff --git a/source/blender/blenloader/intern/versioning_cycles.c b/source/blender/blenloader/intern/versioning_cycles.c index 2bd379c6f19..7616e62af9f 100644 --- a/source/blender/blenloader/intern/versioning_cycles.c +++ b/source/blender/blenloader/intern/versioning_cycles.c @@ -49,6 +49,12 @@ static float *cycles_node_socket_float_value(bNodeSocket *socket) return &socket_data->value; } +static float *cycles_node_socket_rgba_value(bNodeSocket *socket) +{ + bNodeSocketValueRGBA *socket_data = socket->default_value; + return socket_data->value; +} + static IDProperty *cycles_properties_from_ID(ID *id) { IDProperty *idprop = IDP_GetProperties(id, false); @@ -291,6 +297,87 @@ static void image_node_colorspace(bNode *node) } } +static void light_emission_node_to_energy(Light *light, float *energy, float color[3]) +{ + *energy = 1.0; + copy_v3_fl(color, 1.0f); + + /* If nodetree has animation or drivers, don't try to convert. */ + bNodeTree *ntree = light->nodetree; + if (ntree == NULL || ntree->adt) { + return; + } + + /* Find emission node */ + bNode *output_node = ntreeShaderOutputNode(ntree, SHD_OUTPUT_CYCLES); + if (output_node == NULL) { + return; + } + + bNode *emission_node = NULL; + for (bNodeLink *link = ntree->links.first; link; link = link->next) { + if (link->tonode == output_node && link->fromnode->type == SH_NODE_EMISSION) { + emission_node = link->fromnode; + break; + } + } + + if (emission_node == NULL) { + return; + } + + /* Don't convert if anything is linked */ + bNodeSocket *strength_socket = nodeFindSocket(emission_node, SOCK_IN, "Strength"); + bNodeSocket *color_socket = nodeFindSocket(emission_node, SOCK_IN, "Color"); + + if ((strength_socket->flag & SOCK_IN_USE) || (color_socket->flag & SOCK_IN_USE)) { + return; + } + + float *strength_value = cycles_node_socket_float_value(strength_socket); + float *color_value = cycles_node_socket_rgba_value(color_socket); + + *energy = *strength_value; + copy_v3_v3(color, color_value); + + *strength_value = 1.0f; + copy_v4_fl(color_value, 1.0f); + light->use_nodes = false; +} + +static void light_emission_unify(Light *light, const char *engine) +{ + if (light->type != LA_SUN) { + light->energy *= 100.0f; + } + + /* Attempt to extract constant energy and color from nodes. */ + bool use_nodes = light->use_nodes; + float energy, color[3]; + light_emission_node_to_energy(light, &energy, color); + + if (STREQ(engine, "CYCLES")) { + if (use_nodes) { + /* Energy extracted from nodes */ + light->energy = 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; + } + else { + light->energy = 100.0f; + } + } + } + else { + /* Disable nodes if scene was configured for Eevee */ + light->use_nodes = false; + } +} + void blo_do_versions_cycles(FileData *UNUSED(fd), Library *UNUSED(lib), Main *bmain) { /* Particle shape shared with Eevee. */ @@ -364,4 +451,14 @@ void do_versions_after_linking_cycles(Main *bmain) } FOREACH_NODETREE_END; } + + if (!MAIN_VERSION_ATLEAST(bmain, 280, 64)) { + /* Unfiy Cycles and Eevee settings. */ + Scene *scene = bmain->scenes.first; + const char *engine = (scene) ? scene->r.engine : "CYCLES"; + + for (Light *light = bmain->lights.first; light; light = light->id.next) { + light_emission_unify(light, engine); + } + } } diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c index 6e6c23205fe..0e24115f849 100644 --- a/source/blender/draw/engines/eevee/eevee_lights.c +++ b/source/blender/draw/engines/eevee/eevee_lights.c @@ -645,7 +645,7 @@ float light_attenuation_radius_get(Light *la, float light_threshold) /* Compute max light power. */ float power = max_fff(la->r, la->g, la->b); - power *= fabsf(la->energy); + power *= fabsf(la->energy / 100.0f); power *= max_ff(1.0f, la->spec_fac); /* Compute the distance (using the inverse square law) * at which the light power reaches the light_ @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list [email protected] https://lists.blender.org/mailman/listinfo/bf-blender-cvs
