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?


3 Answers 3


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


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'

  • 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, 2016 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, 2016 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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .