We render some blend files over our renderfarm with multiple scenes in them.
We need this so we can do custom aov’s with override material in each scene.
The scenes are called:
“scene” (beauty & crypto)
“normal” (custom normal pass)
“fresnel” (custom fresnel pass)
After the rendering, we pack all of them into an exr.
So in the fresnel pass, I would like to change some settings for the walls, because I also render AO in this scene. So I want to turn the “Shadow” toggle of the walls to True, while the scene “fresnel” is rendering.
This works with this driver expression:
1 if bpy.context.scene.name == ‘Fresnel’ else 0
Now the problem is, that there are multiple warnings beneath the expression:
-Slow Python expression
-WARNING: Driver expression may not work correctly
-TIP: bpy.contex is not safe for renderfarm usage
And yes, the expression works perfectly while rendering in gui mode, but when rendering over command line obviously it doesn’t work.
So my question is, is there a way to write this in a different way, so it will work over a renderfarm?
I use this at every cmd line argument, so this shouldn be the problem.
If drivers are problematic here, I would suggest adding some Python code to a text datablock that can toggle between the two states. You can then call it from the CLI after loading the file, depending on what you want to render. Such an approach may be a bit cumbersome to create, but it does have the benefit of giving an overview of all the settings that change between scenes.
Could be a good idea to have a pre-render and post-render script fields, so we can define a script that will be executed after or before the render, no matter if we are in the UI or in the CLI/Renderfarm, that could simplify a lot of things.
Maybe is even something I may be able to add, I’ll look at it
Pre-Render Script: you point a .py file will be executed before the render, without having to code anything and with the security that it goes with the scene, not with the CLI command
Post-Render Script: you point a .py file that will be executed after the render is finished and everything is saved, without having to code anything and with the security that it goes with the scene, not with the CLI command
So implementing those fields may be even easier with the handlers that are already there
I would vote against that. If you expect people to be able to write Python scripts in the first place, then adding a few lines to register a handler shouldn’t be a problem. If you expect people to not be able to write Python scripts, the entire thing is unusable anyway.
What’s so hard about adding this to a Python file? And why would you want to have the pre-render and post-render scripts placed in two different text blocks? I was thinking along the lines of this code:
def set_scene_specific_stuff(scene: bpy.types.Scene, *, is_rendering: bool) -> None:
is_fresnel = scene.name == 'Fresnel'
# use is_fresnel and/or is_rendering to set certain properties
def render_init_func(scene: bpy.types.Scene) -> None:
def render_complete_func(scene: bpy.types.Scene) -> None:
if __name__ == '__main__':
Because I don’t expect people to be able to write a python script or even know python.
I expect to develop some tools that can do some preparation for the render for example and my artist to use those tools without having to touch a single line of code.
This exact coment:
Is common in many artists that are very good in their jobs but don’t know how to write a single line of code, and having pipeline tools that can be executed easily by artists is important.
The idea of having in separated fields is because there could be different tools for different situations and different moments, so an artist may need to share the initial script, but the final script could be different, so not ving forced to have a lot fo scripts to mix both situations is something good IMHO.
Python is great, but not everyone knows or want to know to script, giving those artists a way to use this kind of tool is something good, and making that option visible to the user is even better, how many artist know about “bpy.app.handlers.render_init” or “bpy.app.handlers.render_complete”?
For you it’s easy to use and understand, but for many people is a very complex task even to understand what “import bpy” is, and those fields would simplify that task and open the feature to a lot of users.
Read my post again: IF you assume people write Python, just give them Python code. Teach them how it works and that Python isn’t some scary monster. If you assume they do NOT know how to use Python code, don’t even bother selecting a Python text datablock, but let your tool hide away all complexity.
But the thing is that we cannot write a tool with UI and everything for each case.
If we hire an artist or a group of artists for a 2 weeks long project and they doesn’t know Python, I don’t have actual time to teach them or for them to learn Python IF they want to. Our projects are 2 weeks/ 3 weeks long in general, and on each project we need a different kind of artist and requirements.
Also, aditionally we can share our pre-render scripts to others and they could be able to use them even without knowing pythong. What I say it’s not a text block I said a .py file to be executed, they don’t need to see a single line of code, everything is hidden because of the Pre/Post render UI I tell you
I think I got it wrong. Now this should work but it isn’t.
Only the first query is working, so when “Fresnel” is the first scene it is true and when it is second or third it wont be true at all. What am I doing wrong?
That indicates that the following parameters are keyword-only. This means you have to pass is_rendering=True instead of just True. As a general rule I often require keywords for boolean parameters, because func(True, False, True) is way harder to read than func(is_rendering=True, as_background_job=False, compress=True).
And why do you set “-> None:” at the end of the definition?
That’s a type declaration, declaring that nothing is returned by that
function. I always declare types whenever possible/convenient.
What am I doing wrong?
Add some print() statements throughout your code. You’ll be able to see what it’s doing on the terminal.
As a side note, this code:
bpy.data.objects['Cube'].cycles_visibility.shadow = is_fresnel
bpy.data.objects['Cube'].cycles_visibility.shadow = False
can be simplified to this, if you want:
bpy.data.objects['Cube'].cycles_visibility.shadow = is_fresnel and is_rendering