1
$\begingroup$

Hello Blender Community,

what would be the easiest way to animate a chain of lights for a Christmas tree? I'd like them to show different patterns (running up, running down, blinking alternating every second light, and so on...) and sync it to some Christmas song. And at best it would be possible to change the color for differently grouped lights. These groupings would be dependent on the selected pattern/mode.

I'm just searching for a way for not having to creating a lot of material/object-data instances and modifying each brightness values individually over and over in the graph/NLA editor. Ideally I imagine having some simplified controls like pattern/mode, speed, step, ... And in the timeline or NLA editor these would simply be triggered synchronously to the music.

I'm not sure which rendering engine I might take. My PC is not the fastest, so BRE would be better. But if cycles can make it significantly simpler, I'd be ok with using that instead. For the light type I think an emitting material will do great. There is no need for much detail.

I'm not afraid of using some math. However I think python might be a bit overhead. Please correct me if I'm wrong.

$\endgroup$
0
$\begingroup$

In the provided example it seems the light groups are driven straight from the midi file for the instruments. You can load such file in the MIDI Driver addon and assign each instrument channel an animation Action for example (like turning a group of lights on and off).

Alternatively you can use animated texture to drive the light's emission. The bulbs should be mesh lights for this purpose.

Create a texture strip with as many pixels as you have bulbs. Unwrap each bulb into it's corresponding pixel.

Animate the texture strip in a loop to create whatever color and motion pattern you desire. It's easy to do in AfterFX or similar app.

Also simple animations like switching between odd and even bulbs could be also driven with lamp objects using drivers and #frame keyword to drive the light's strength. Drivers can be copied easily between many bulbs. This approach is not that flexible though.

$\endgroup$
  • $\begingroup$ From video description: "As for the project itself modeling, texturing and rigging took around 13 days. Animating it took 7 days 8am to midnight, the method I used was a combination of keying the materials and armatures. Every time the lights fade was the materials every quick change was armature. I don't even want to know how many key frames are in this lol, this was a true monster." $\endgroup$ – cgslav Nov 19 '17 at 10:07
  • $\begingroup$ @LukeD Wow you are right, he probably keyframed it all manually.. $\endgroup$ – Jaroslav Jerryno Novotny Nov 19 '17 at 11:12
  • $\begingroup$ Those sound like great approaches. It certainly makes sense to combine them, too. I don't have much time though, so it takes a little to test. Yes, the guy from the video seems to have programmed it manually. And I don't want to spend nearly as much time, that's why I asked for a better way. $\endgroup$ – Colonel Panic Nov 21 '17 at 17:00
  • $\begingroup$ Ok, I tested some things and while I really like your approaches, it didn't solve some problems unfortunately. I don't have enough reputition to vote your answer up, but if I gain it, I'll do so. Thank you! $\endgroup$ – Colonel Panic Nov 26 '17 at 10:53
0
$\begingroup$

Ok, I've done some experiments and found that the main problem I'm having is, that there isn't an easy way to feed a single material/shader with animated values from the individual objects. There are some approaches which are not developed far enough though. Just as an instance:

https://developer.blender.org/D2057 (early stage with bugs)

Use custom properties (variable values) in the node editor (changes the property for all objects that own the material)

And I really would prefer to do the syncing within Blender itself. So you can actually divide this into two problems: 1st you need to somehow send color information to the shader. And there are some ways depending on what rendering engine is used.

For Blender Render that would be the objects color (can be found in the objects properties). You can then choose to use the "object color" within the options section of the material properties.

Now if you use Cycles that options falls away. As a slightly more complex and probably less performant solution, vertex colors can be used.

And as Jerryno suggested using an animated texture is also a great way to do complex lighting animations.

Secondly we need to animate the colors, and for that drivers would be the easiest, but least dynamic way. For a little more dynamic, scripted drivers can be written in python, which honestly helped me a lot. But for the maximum control you can write a handler for blender's handler functions.

This is just a little test script which messes around with an objects color and vertex colors:

import bpy
import math

def distance(va, vb):
    return math.sqrt( (va[0]-vb[0])**2 + (va[1]-vb[1])**2 + (va[2]-vb[2])**2 )

def MyHandler(v):
    sphere = bpy.data.objects['Sphere']
    sloc = sphere.location
     sphere.color[0] = 0.4;

    for a in bpy.data.groups['Lichterkette'].objects:
        aloc = a.location

        d = 2**(-distance(aloc, sloc) * 1) * 5

        # Color the object
        c = a.color
        c[0] = d * 1.0
        c[1] = d * 0.5
        c[2] = d * 0.05

        # Color the vertices
        if hasattr(a.data.vertex_colors, 'Col'):
            col = a.data.vertex_colors['Col']
            for poly in a.data.polygons:
                for idx in poly.loop_indices:
                    b.color[0] = d * 1.0
                    b.color[1] = d * 0.5
                    b.color[2] = d * 0.0

bpy.app.handlers.frame_change_pre.append(MyHandler)
#bpy.app.handlers.scene_update_pre.append(MyHandler)

For a reference of blender handler functions see https://docs.blender.org/api/blender_python_api_2_74_0/bpy.app.handlers.html

I'm not sure but it might also be possible to use "modal operators" but think that might make more sense for actual operators like grabbing, rotating etc.

$\endgroup$
  • $\begingroup$ Since both are vectors, distance = (vb - va).length $\endgroup$ – batFINGER Nov 26 '17 at 11:53
  • $\begingroup$ Great, thanks. I was looking for this earlier. $\endgroup$ – Colonel Panic Nov 26 '17 at 12:39

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.