# Best way to change a value between render layers?

I have a setup where I am re-rendering the same geometry on several different layers. I want to change a property in the geometry's material before each layer runs (probably via a driver). The goal is to render out several different passes and have them all in the compositor together.

(I am aware this is possible with Scenes and different materials, but it is a ton of work to set that up when working with assets that will be linked into a bunch of different files. The simpler method seems to be to put several material setups in the same group, then mix between different outputs for each layer.)

For Renderlayer 1, the value is 0. For layer 2, the value is 1. etc.

I can manually do this by clicking the Render button on the Render Layer node in the compositor, then manually changing the material value, then manually rendering the next layer. But I need to automate it so that I can leave it running for long renders.

It seems it should be possible to solve this problem in a couple of different ways, but it depends on the details of how the render command works.

I could make a script that sets the property to 0, starts the render of layer 1, then when that finishes sets it to 1, starts layer 2, etc. For that, I need to know how I can have a script tell when a layer finishes rendering?

Or, I could have it start the value at 0, then detect when a layer starts rendering, and change it then. Either way, it needs to be able to have a script get info about when a layer starts or finishes.

Can anyone shed some light on how this can be done, or if there's a better way to set this up?

• There is an addon, Oscurart Tools that has material overrides among its features. It might be useful for what you intend to do (and even if it's not, the python code may give you some hints about where to look at). wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/… – Gez Nov 8 '17 at 20:05
• @Gez I can't do exactly what I'm trying to do here with Oscurart, but certainly some other interesting features! – Drudge Nov 9 '17 at 8:23

I don't think there is any way to know the name of the render layer currently being rendered, which means you can't use a driver or app.handler to calculate a property that varies by render layer.

We can however, render one layer at a time, this allows us to control which layer is being rendered and to alter properties before starting to render a layer.

As an example, we can set a text object to the layer name.

import bpy

for l in bpy.context.scene.render.layers:
bpy.data.objects['Text'].data.body = l.name
bpy.ops.render.render(layer=l.name)


Note that rendering a single layer doesn't work when rendering an animation, which means you would need another loop to render multiple frames.

• Thanks, I'll give it a try. I'm not concerned with animation at the moment. Although if I was, i'd want to render the given frame for each layer, composite, save output, then render the next frame. – Drudge Nov 7 '17 at 12:40
• Can you expand a bit more about how to use Render One Layer at a time? I'm guessing I need to do something like Set driver value for layer 1, then render layer 1, then set for layer 2, etc. But I'm not clear on the proper way to do that still. – Drudge Nov 9 '17 at 8:27
• Calling bpy.ops.render.render() will render the scene. If you pass it the parameter layer='xx' then it will only render the renderlayer named "xx". So you can make changes specific to a layer and then render that one layer, no drivers used. – sambler Nov 9 '17 at 9:21
• That did it, thanks! Although I notice that when I render this way, I don't see the progress or tiles or anything. Would like to get that back somehow. But that's a matter for its own Question. – Drudge Nov 10 '17 at 10:46
• @Drudge have a look at this answer and this answer – sambler Nov 12 '17 at 0:04