Change a Driver based on which Scene is being Rendered I am looking to drive a property in a material node based on the current Scene when rendering. The purpose would be to mix between two different parts of the node tree so that one Scene renders one input of a Mix node, and the other scene renders the other. The objects the material is on exist in one scene, and a group instance of the objects exists in the other scene.

The reason for using different Scenes is that part of the material is regular shaders that need to be GPU rendered, and part are OSL shaders that need to be CPU rendered. So the only difference between the scenes is that one has the device set to GPU and the other CPU.

I know that I could make copies of the objects/materials and so have a different material on the OSL version, but this gets cumbersome as i'll need to re-copy the objects or re-create the whole scene every time I change an object. This is too inefficient while still working on the project. The Group instance means that any changes I make to the models are instantly updated in the other scene, and lets me use the Group to control which models are rendered in the OSL scene at all.

Is this possible?
It is possible to script drivers. Normally if you use a scripted expression as a driver, you can use any function that is defined in any script and added to driver namespace: 



import bpy

def f():
    if bpy.context.scene.name == 'Scene.001':
        return 1
    else:
        return 0

bpy.app.driver_namespace['f'] = f


'Register' would need to be checked in the Text Editor also the script needs to have .py extension and Auto Run Python Scripts must be enabled for the function to exist every time the file is reloaded. 

However apparently this does not work with driving material node properties because Blender's drivers seem to be broken in this area. 

It would probably be possible to script an app handler that would take care of it, but at this point I would suggest to simply use a script to switch the mix nodes in all of your materials before rendering. Since this extra step takes only a few seconds it might be easier to have less complexity and you could possibly get away with only one scene as well. You could give the Mix node some specific name in every material like for example "OSL_mix"(in the n panel of the Node Editor). Then you could run this to change the values of the nodes with that name in all your materials at once:

import bpy

for m in bpy.data.materials:
    for n in m.node_tree.nodes:
        if n.name == "OSL_mix":
            n.inputs[0].default_value=1 # or 0


For your convenience you could change the render setting with the script as well by adding something like:

bpy.context.scene.cycles.device = 'CPU' # or 'GPU'
bpy.context.scene.cycles.shading_system = True # that's the OSL 
bpy.context.scene.cycles.samples = 1000 


Or something like that. You can just change what you want in the render settings and copy the command from the Info panel.

I would just have two scripts like that to switch between CPU-OSL and GPU rendering.

I hope that might be a convenient enough workaround.