9
$\begingroup$

I'd like to write a little piece of code which splits a frame into a few tiles and uses all available devices to render the still image. It seems like the Blender developers are working on such a feature, but this seems to be quite far in the future: http://wiki.blender.org/index.php/Dev:2.6/Source/Render/Cycles/Devices.

Because I render images which are composited into photographs (resolution about 5300 x 3800) I want to use all the resources I have available (CPU & GPU in main workstation, CPU in laptop and CPU in old desktop). I have found the documentation for the command line (http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Command_Line), but it doesn't specify the options I need (tile mode, tile size x and y, number of tiles to render).

Does anybody know how to do this?

$\endgroup$
2

1 Answer 1

8
$\begingroup$

AFAIK, there is no option to set tile sizes directly from the command line.

However, you could use the python api to do this, and execute a python script in blender from the command line. (see this question)

To set tile sizes from python, you can use
bpy.context.scene.render.tile_x and bpy.context.scene.render.tile_y.

Tile order can be set with bpy.data.scenes["Scene"].cycles.tile_order.
This can be set to 'CENTER', 'RIGHT_TO_LEFT', 'LEFT_TO_RIGHT', 'TOP_TO_BOTTOM', or 'BOTTOM_TO_TOP'

An example script to set the tile size to 32x32 and set the order to Right to Left:

import bpy

for scene in bpy.data.scenes:
    scene.render.tile_x = 32
    scene.render.tile_y = 32
    scene.cycles.tile_order = 'RIGHT_TO_LEFT'

Note that it loops through each scene to set these properties globally. (see this)
You can run this from the command line with

blender --background /path/to/my.blend --python /path/to/script.py --render-anim
# or the short version:
blender -b /path/to/my.blend -P /path/to/script.py -a

Borders:

AFAIK, it's not possible to tell blender to only render n amount of tiles, when n is less than the total tiles needed to render the complete image. (blender does print a new line to stdout for every tile that is rendered, so you might be able to make some hack to stop blender once n tiles have been rendered, but I don't know if you could save output.)

Because of this, you might be better off using the Render Border; this will allow you to exactly define what section of the image to render.
You could then call blender to render repeatedly, using a script to pass different render border dimensions to do your own "tile render".

You can enable border with bpy.data.scenes["Scene"].render.use_border = True

The border region is defined by four values between 0 and 1 corresponding to the locations of the four sides of the render border relative to the camera where 0 is the left or bottom edge of the camera, and 1 is the right or top edge.

You can set the min and max xy values for the camera border with

bpy.data.scenes["Scene"].render.border_max_x
bpy.data.scenes["Scene"].render.border_min_x
bpy.data.scenes["Scene"].render.border_max_y
bpy.data.scenes["Scene"].render.border_min_y

You may also want to enable Crop to border with bpy.data.scenes["Scene"].render.use_crop_to_border = True

So to render half of the image vertically, you could run this:

import bpy

for scene in bpy.data.scenes:

    scene.render.use_border = True
    scene.render.use_crop_to_border = True
    #this sets the render border to the left half of the camera. 
    #to render the right half, set max_x to 1 and min_x to .5
    scene.render.border_max_x = .5
    scene.render.border_min_x = 0
    scene.render.border_min_y = 0
    scene.render.border_max_y = 1
    scene.render.tile_x = 32
    scene.render.tile_y = 32
#then render:
bpy.ops.render.render()

Note that to set the viewport border you must use this instead, but you most likely are interested in camera border as viewport border is only relevant for using the realtime rendering feature. (see this post for more info)

Seeds:

This does not answer your question about tiles, but as you mentioned you want to do this for rendering on multiple machines, I thought I would mention this.

You could also combine different Cycles renders by using the Seed value. (See this post for more info)

This also is a good way to remove fireflies.

$\endgroup$
4
  • $\begingroup$ I can't get scene.render.tile_x = 32 to work with Blender 2.79 - does anybody know if the naming and/or functionality changed? $\endgroup$
    – A. Tropics
    Commented Apr 17, 2018 at 12:23
  • $\begingroup$ @A.Tropics Works for me, any error message? Also, you don't have the auto tile size addon enabled by any chance, do you? $\endgroup$
    – gandalf3
    Commented Apr 18, 2018 at 2:38
  • $\begingroup$ auto tile size is disabled, no error message. The crazy thing is, my script did work with 2.77, but doesn't any more. One thing I thought about: My code is added to bpy.app.handlers.render_pre, so it gets called before rendering. When I run the script manually, the tiles setting in the GUI changes. Maybe the code does work, but the tile size gets overwritten again afterwards? Is there any way I can test for this? I would look in the source code but I don't know where to start. $\endgroup$
    – A. Tropics
    Commented Apr 20, 2018 at 8:19
  • $\begingroup$ Remember that there are two things that refer to tile size: render only a portion of the screen that you define and the internal slice that the cycles engine uses to render the frame in pieces (tile size from the render engine). Note: This will become invalid with Blender 3.0 which does not use tiles to render, but renders the whole frame, the addon autotile_size will become obsolete with that release. $\endgroup$ Commented Jul 13, 2021 at 1:46

You must log in to answer this question.

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