2
$\begingroup$

Let's say have an array of CSV-style RG values, something like this:

[0.1,0.5,
0.2,0.7,
0.4,0.8
0.8,0.5]

Here, the odd elements are always red, and the even ones are green.

Is there a way to display the values sequentially, where every frame would use both the red and green values in an emission shader? Thanks in advance.

$\endgroup$
3
  • $\begingroup$ Do you mean you want the red and green values combined into a single color used in one shader, or that you want separate red and green emission shaders. The first could be done with a python script that advances the current frame, sets the R and G of a combineRGB node and keyframes the result. $\endgroup$ Jan 31, 2022 at 19:36
  • $\begingroup$ @MartyFouts Yes, i want to combine the values into a single color. How would the python script for this look? $\endgroup$
    – Hutts
    Jan 31, 2022 at 19:40
  • $\begingroup$ answer tested and added $\endgroup$ Jan 31, 2022 at 20:10

1 Answer 1

3
$\begingroup$

One Way to Do It

This is a question where a judicious mix of Python and preparation go along way.

You could write python to create an object, add an emission shader to it, and give the shader a combineRGB node and there are question here that will show you how to do that.

But instead, let's manually add this material to the active object, making it the active material:

Emission shader with Combine RGB node

Now we can use your array to add keyframes periodically setting the red and green values from the array:

import bpy

# https://blender.stackexchange.com/questions/252346/display-array-value-as-emission-material-using-python-console-or-script
# An array of R and G values for the emission shader.
rg = [
    0.1,0.5,
    0.2,0.7,
    0.4,0.8,
    0.8,0.5,
]

frame_insert = 1 # Start adding frames here
frame_delta = 12 # every Nth frame

# Assume the active object's active material already has an emission shader
# that has a Combine RGB node, so get these things.    
object = bpy.context.active_object
material = object.active_material
nodes = material.node_tree.nodes
node = nodes["Combine RGB"]


# Walk through the array, adding keyframes
for index in range(0, len(rg), 2):
    node.inputs[0].default_value = rg[index]
    node.inputs[0].keyframe_insert('default_value', frame = frame_insert)
    # Delete the below line if you want interpolation
    node.inputs[0].keyframe_insert('default_value', frame = frame_insert + frame_delta - 1)
    node.inputs[1].default_value = rg[index+1]
    node.inputs[1].keyframe_insert('default_value', frame = frame_insert)
    # Delete the below line if you want interpolation
    node.inputs[1].keyframe_insert('default_value', frame = frame_insert + frame_delta - 1)
    frame_insert += frame_delta

How it Works

frame_insert is initially set to the first frame where you want a keyframe for the pair of values.

frame_delta is set to the spacing of lighting changes. You can set this to one and get a really annoying flicker, but if you do see the bit about why two keyframes are added for each change.

Next, we rely on wanting to do this with the active object's active material, so there are four lines of code that find the object, the material, and the CombineRGB node. If you want to create these things, this is where you would do it.

The loop assumes the array in the format from your question. You'll need to change the loop parameters and indexing if you want to use a different format.

The key feature is that the Red input of the Combine RGB node can be set by setting the node's inputs[0].default_value, and likewise the Green input is on inputs[1]. So we set the value and add the keyframe, using keyframe_insert.

The reason to advance to just before the next place we want to add a keyframe, is to keep the intensity constant over the whole interval. There are other ways to do this, but this is the simplest in this context. If you want to let Blender's animation interpolation vary the value, delete the two keyframe_insert calls that use frame_insert + frame_delta -1. Definitely delete them if you want set frame_delta to 1.

$\endgroup$

You must log in to answer this question.

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