Lights: change sun light size to be specified as angle
authorTim Stullich <tstullich>
Wed, 15 May 2019 12:45:33 +0000 (14:45 +0200)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Wed, 15 May 2019 14:07:50 +0000 (16:07 +0200)
This is the angular diameter as seen from earth, which is between 0.526° and
0.545° in reality. Sharing the size with other light types did not make much
sense and meant the unit was unclear.

Differential Revision: https://developer.blender.org/D4819

12 files changed:
intern/cycles/blender/addon/properties.py
intern/cycles/blender/addon/ui.py
intern/cycles/blender/blender_object.cpp
intern/cycles/render/light.cpp
intern/cycles/render/light.h
release/scripts/startup/bl_ui/properties_data_light.py
release/scripts/startup/bl_ui/space_view3d.py
source/blender/blenkernel/intern/light.c
source/blender/blenloader/intern/versioning_280.c
source/blender/draw/engines/eevee/eevee_lights.c
source/blender/makesdna/DNA_light_types.h
source/blender/makesrna/intern/rna_light.c

index 6da88a7..f376eb8 100644 (file)
@@ -1490,7 +1490,7 @@ class CyclesPreferences(bpy.types.AddonPreferences):
                 break
 
         if not found_device:
-            col = box.column(align=True);
+            col = box.column(align=True)
             col.label(text="No compatible GPUs found for path tracing", icon='INFO')
             col.label(text="Cycles will render on the CPU", icon='BLANK1')
             return
index 9714067..5ff8836 100644 (file)
@@ -1345,8 +1345,10 @@ class CYCLES_LIGHT_PT_light(CyclesButtonsPanel, Panel):
         col.prop(light, "energy")
         col.separator()
 
-        if light.type in {'POINT', 'SUN', 'SPOT'}:
+        if light.type in {'POINT', 'SPOT'}:
             col.prop(light, "shadow_soft_size", text="Size")
+        elif light.type == 'SUN':
+            col.prop(light, "angle")
         elif light.type == 'AREA':
             col.prop(light, "shape", text="Shape")
             sub = col.column(align=True)
index 1094ff3..c07e896 100644 (file)
@@ -149,7 +149,7 @@ void BlenderSync::sync_light(BL::Object &b_parent,
     // }
     case BL::Light::type_SUN: {
       BL::SunLight b_sun_light(b_light);
-      light->size = b_sun_light.shadow_soft_size();
+      light->angle = b_sun_light.angle();
       light->type = LIGHT_DISTANT;
       break;
     }
index ef4bd42..5c3f1c3 100644 (file)
@@ -398,11 +398,18 @@ void LightManager::device_update_distribution(Device *,
     distribution[offset].lamp.size = light->size;
     totarea += lightarea;
 
-    if (light->size > 0.0f && light->use_mis)
-      use_lamp_mis = true;
-    if (light->type == LIGHT_BACKGROUND) {
+    if (light->type == LIGHT_DISTANT) {
+      use_lamp_mis |= (light->angle > 0.0f && light->use_mis);
+    }
+    else if (light->type == LIGHT_POINT || light->type == LIGHT_SPOT) {
+      use_lamp_mis |= (light->size > 0.0f && light->use_mis);
+    }
+    else if (light->type == LIGHT_AREA) {
+      use_lamp_mis |= light->use_mis;
+    }
+    else if (light->type == LIGHT_BACKGROUND) {
       num_background_lights++;
-      background_mis = light->use_mis;
+      background_mis |= light->use_mis;
     }
 
     light_index++;
@@ -725,8 +732,8 @@ void LightManager::device_update_points(Device *, DeviceScene *dscene, Scene *sc
     else if (light->type == LIGHT_DISTANT) {
       shader_id &= ~SHADER_AREA_LIGHT;
 
-      float radius = light->size;
-      float angle = atanf(radius);
+      float angle = light->angle / 2.0f;
+      float radius = tanf(angle);
       float cosangle = cosf(angle);
       float area = M_PI_F * radius * radius;
       float invarea = (area > 0.0f) ? 1.0f / area : 1.0f;
index a7bffde..79450ea 100644 (file)
@@ -47,6 +47,7 @@ class Light : public Node {
 
   float3 dir;
   float size;
+  float angle;
 
   float3 axisu;
   float sizeu;
index 3d78b3a..376b756 100644 (file)
@@ -101,8 +101,10 @@ class DATA_PT_EEVEE_light(DataButtonsPanel, Panel):
 
         col.separator()
 
-        if light.type in {'POINT', 'SPOT', 'SUN'}:
+        if light.type in {'POINT', 'SPOT'}:
             col.prop(light, "shadow_soft_size", text="Radius")
+        elif light.type == 'SUN':
+            col.prop(light, "angle")
         elif light.type == 'AREA':
             col.prop(light, "shape")
 
index 1b833d0..35b3747 100644 (file)
@@ -2312,12 +2312,19 @@ class VIEW3D_MT_object_context_menu(Menu):
                     props.data_path_item = "data.size_y"
                     props.header_text = "Light Size Y: %.3f"
 
-            elif light.type in {'SPOT', 'POINT', 'SUN'}:
+            elif light.type in {'SPOT', 'POINT'}:
                 props = layout.operator("wm.context_modal_mouse", text="Radius")
                 props.data_path_iter = "selected_editable_objects"
                 props.data_path_item = "data.shadow_soft_size"
                 props.header_text = "Light Radius: %.3f"
 
+            elif light.type == 'SUN':
+                props = layout.operator("wm.context_modal_mouse", text="Angle")
+                props.data_path_iter = "selected_editable_objects"
+                props.data_path_item = "data.angle"
+                props.header_text = "Light Angle: %.3f"
+
+
             if light.type == 'SPOT':
                 layout.separator()
 
index 05b2eb8..1c3acb6 100644 (file)
@@ -80,6 +80,7 @@ void BKE_light_init(Light *la)
   la->contact_thickness = 0.2f;
   la->spec_fac = 1.0f;
   la->att_dist = 40.0f;
+  la->sun_angle = DEG2RADF(0.526f);
 
   curvemapping_initialize(la->curfalloff);
 }
index 9d8fa2d..526931d 100644 (file)
@@ -3418,5 +3418,12 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
     LISTBASE_FOREACH (bArmature *, arm, &bmain->armatures) {
       arm->flag &= ~(ARM_FLAG_UNUSED_7 | ARM_FLAG_UNUSED_9);
     }
+
+    /* Initializes sun lights with the new angular diameter property */
+    if (!DNA_struct_elem_find(fd->filesdna, "Light", "float", "sun_angle")) {
+      LISTBASE_FOREACH (Light *, light, &bmain->lights) {
+        light->sun_angle = 2.0f * atanf(light->area_size);
+      }
+    }
   }
 }
index 730372b..f64cd34 100644 (file)
@@ -672,6 +672,9 @@ static void light_shape_parameters_set(EEVEE_Light *evli, const Light *la, float
       evli->sizey = max_ff(0.003f, la->area_size * scale[1] * 0.5f);
     }
   }
+  else if (la->type == LA_SUN) {
+    evli->radius = max_ff(0.001f, tanf(la->sun_angle / 2.0f));
+  }
   else {
     evli->radius = max_ff(0.001f, la->area_size);
   }
index 6bd118b..5e88105 100644 (file)
@@ -66,6 +66,9 @@ typedef struct Light {
   short area_shape;
   float area_size, area_sizey, area_sizez;
 
+  float sun_angle;
+  char _pad3[4];
+
   /* texact is for buttons */
   short texact, shadhalostep;
 
index da2b575..54c8049 100644 (file)
@@ -545,12 +545,20 @@ static void rna_def_spot_light(BlenderRNA *brna)
 static void rna_def_sun_light(BlenderRNA *brna)
 {
   StructRNA *srna;
+  PropertyRNA *prop;
 
   srna = RNA_def_struct(brna, "SunLight", "Light");
   RNA_def_struct_sdna(srna, "Light");
   RNA_def_struct_ui_text(srna, "Sun Light", "Constant direction parallel ray Light");
   RNA_def_struct_ui_icon(srna, ICON_LIGHT_SUN);
 
+  prop = RNA_def_property(srna, "angle", PROP_FLOAT, PROP_ANGLE);
+  RNA_def_property_float_sdna(prop, NULL, "sun_angle");
+  RNA_def_property_float_default(prop, DEG2RADF(0.526f));
+  RNA_def_property_range(prop, DEG2RADF(0.0f), DEG2RADF(180.0f));
+  RNA_def_property_ui_text(prop, "Angle", "Angular diameter of the Sun as seen from the Earth");
+  RNA_def_property_update(prop, 0, "rna_Light_update");
+
   rna_def_light_energy(srna, true);
   rna_def_light_shadow(srna, true);
 }