I'm working on a project and I want to have a script tell a point light to change intensity at certain times.
What I'm confused about is how to do that in cycles - the sidebar data tab says it uses nodes but I can't find where those output to? When I try light_object.active_material it returns an error saying it doesn't have that attribute. Is there some other way I'm not seeing?

Edit - I was looking in the data.lamps group and I changed to data.objects and now it's not returning an error, but it says there's no active material even though there is?


You can do this by adding an event handler to the frame change event.

import bpy

def my_handler(scene):

    fm = bpy.data.scenes['Scene'].frame_current

    if fm >= 1:
        lampStrength = 100
    if fm >= 50:
        lampStrength = 200
    if fm >= 100:
        lampStrength = 300
    if fm >= 150:
        lampStrength = 400                


    print("lamp strength: " + str(lampStrength))

def register():

def unregister():

if __name__ == "__main__":

Credit for frame change portion of script here: Running a script for each frame

| improve this answer | |

One alternative is to use a Driver: https://www.blender.org/manual/animation/drivers.html .

If you are using nodes for your lamp then you probably want to put the driver on your strength property.

add driver to strength property of emission node

When you configure a driver to use a script, you have to tell blender you trust the script. This usually means you have to save the file and reload it with driver scripts enabled (this often shows up as a button in the top bar when blender notices an untrusted script in a driver).

If the script is very deterministic, you might be able to replace it with keyframes. It is possible for a python script to compute keyframes.

Consider this excerpt from http://web.purplefrog.com/~thoth/blender/python-cookbook/animate-cycles-lamp-strength.html:

import bpy

def mission1(obj):
    lamp = obj.data

    e_node = lamp.node_tree.nodes["Emission"]

    data_path = 'nodes["Emission"].inputs[1].default_value'
    for fr in [100, 130, 150, 200, 300]:
        fr2 = fr+10
        e_node.inputs[1].default_value = 20
        lamp.node_tree.keyframe_insert(data_path=data_path, frame=fr)
        e_node.inputs[1].default_value = 100
        lamp.node_tree.keyframe_insert(data_path=data_path, frame=fr2)

    for fc in lamp.node_tree.animation_data.action.fcurves:
        for kp in fc.keyframe_points:
            kp.interpolation = 'CONSTANT'

| improve this answer | |
  • 1
    $\begingroup$ Put together a driver answer for this q using a method defined to the driver namespace ... then upon testing: didn't update in the UI, nor did it update during rendering the animation, nor a still for that matter. Only clicking in the driver field did it update.. (with scripts enabled). I'm using a local build of 2.77b. Does a driver work for you on cycles point light strength? $\endgroup$ – batFINGER Jun 10 '16 at 16:09
  • $\begingroup$ holy smokes. I'm having the same difficulty batFINGER is. Time to check if this is a bug in blender. $\endgroup$ – Mutant Bob Jun 10 '16 at 16:21

Blender 2.8

CYCLES render:

import bpy

light = bpy.data.objects['Light']
light_strength = 1

light.data.use_nodes = True
light.data.node_tree.nodes['Emission'].inputs['Strength'].default_value = light_strength

EEVEE render:

import bpy

light = bpy.data.objects['Light']
light_strength = 1000

light.data.energy = light_strength
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.