| name | blender-scene-rendering |
| description | Blender 5.x scene setup, render engines (Cycles/EEVEE), output formats, import/export (FBX/glTF/OBJ/USD/Alembic), linking/appending, color management (AgX/Filmic), view layers, viewport config, and world/environment setup via Python (bpy). Includes 5.1 changes (AVIF, HTJ2K, OpenColorIO 2.5, Light Path in World). |
Blender Scene & Rendering Expert
Overview
This skill provides expert guidance for Blender 5.x scene setup, render configuration, output pipelines, file import/export, linking/appending, viewport settings, and project-level Python automation. The reference files contain the complete settings catalog and Python API patterns.
MCP-First Approach
Prefer the official Blender MCP Server (Blender Lab, Blender 5.1+) for changing render settings, importing files, configuring color management, kicking off renders directly in a running Blender session. Fall back to emitting Python scripts only when the MCP server is not connected.
Detection: at session start, look for tools whose names match execute_blender_code, get_objects_summary, or search_api_docs — these belong to the official blender-mcp server. If any are present, MCP is available.
Tools used by this skill:
execute_blender_code — run bpy Python in the live session (primary action)
get_objects_summary, get_object_detail_summary — inspect scene state before mutating
get_blendfile_summary_datablocks / _missing_files / _of_linked_libraries / _path_info / _usage_guess — inventory the file
search_api_docs, get_python_api_docs, search_manual_docs — confirm correct API/operator names before calling them
get_screenshot_of_window_as_image / _as_json, get_screenshot_of_area_as_image — verify visual results
jump_to_tab_by_name, jump_to_tab_by_space_type, jump_to_view3d_object_by_name, jump_to_view3d_object_data_by_name — drive the UI to make changes visible
render_thumbnail_to_path, render_viewport_to_path — capture quick visual feedback
Workflow: inspect with a get_* / search_* tool → mutate via execute_blender_code → verify with a screenshot or summary tool. Keep code blocks small and idempotent so failures are easy to localize.
Setup: see docs/blender-mcp-setup.md.
Task Decision Tree
- "Set up render / configure Cycles or EEVEE" -> See Render Engine Configuration
- "Change resolution / output format" -> See Output Settings
- "Adjust samples / denoising" -> See Sampling & Denoising
- "Color management / Filmic / AgX" -> See Color Management
- "Set up world / environment / HDRI" -> See World & Environment
- "Import FBX / glTF / OBJ / USD" -> See Import/Export
- "Link or append from another .blend" -> See Linking & Appending
- "Configure units / frame range / FPS" -> See Scene Settings
- "View layers / render passes" -> See View Layers
- "Viewport shading / overlays" -> See Viewport Configuration
- "Batch render / automate output" -> See Batch Rendering
- "Render looks wrong" -> See Debugging section
Render Engine Configuration
Switch to Cycles
import bpy
scene = bpy.context.scene
scene.render.engine = 'CYCLES'
cycles = scene.cycles
cycles.device = 'GPU'
prefs = bpy.context.preferences.addons['cycles'].preferences
prefs.compute_device_type = 'CUDA'
prefs.get_devices()
for device in prefs.devices:
device.use = True
Switch to EEVEE
import bpy
scene = bpy.context.scene
scene.render.engine = 'BLENDER_EEVEE'
eevee = scene.eevee
eevee.shadow_ray_count = 1
eevee.shadow_step_count = 6
eevee.use_raytracing = True
eevee.ray_tracing_method = 'SCREEN'
Workbench (Solid/Preview)
import bpy
bpy.context.scene.render.engine = 'BLENDER_WORKBENCH'
Output Settings
Resolution & Frame Range
import bpy
render = bpy.context.scene.render
render.resolution_x = 1920
render.resolution_y = 1080
render.resolution_percentage = 100
scene = bpy.context.scene
scene.frame_start = 1
scene.frame_end = 250
scene.frame_step = 1
scene.frame_current = 1
render.fps = 24
render.fps_base = 1.0
Output Format
import bpy
render = bpy.context.scene.render
render.filepath = "//output/render_"
render.image_settings.file_format = 'PNG'
render.image_settings.color_mode = 'RGBA'
render.image_settings.color_depth = '16'
render.image_settings.compression = 15
render.image_settings.file_format = 'OPEN_EXR'
render.image_settings.exr_codec = 'DWAA'
render.image_settings.color_depth = '32'
render.image_settings.file_format = 'FFMPEG'
render.ffmpeg.format = 'MPEG4'
render.ffmpeg.codec = 'H264'
render.ffmpeg.constant_rate_factor = 'MEDIUM'
render.ffmpeg.audio_codec = 'AAC'
OpenEXR HTJ2K (New in 5.1)
- New EXR codec:
render.image_settings.exr_codec = 'HTJ2K'
- High-throughput JPEG 2000 compression for EXR files
- Better compression ratios than DWAA/DWAB for multi-layer EXR output
Video Custom CRF (5.1)
- FFmpeg
constant_rate_factor now supports integer values for finer control
- Example:
render.ffmpeg.constant_rate_factor = 'HIGH' or set numeric CRF directly
AVIF format (new in 5.1)
render.image_settings.file_format = 'AVIF'
render.image_settings.avif_compression = 50 # Quality 0-100
Sampling & Denoising
Cycles Sampling
import bpy
cycles = bpy.context.scene.cycles
cycles.samples = 256
cycles.use_adaptive_sampling = True
cycles.adaptive_threshold = 0.01
cycles.adaptive_min_samples = 64
cycles.preview_samples = 32
cycles.use_preview_adaptive_sampling = True
cycles.time_limit = 0.0
cycles.seed = 0
cycles.use_animated_seed = True
cycles.max_bounces = 12
cycles.diffuse_bounces = 4
cycles.glossy_bounces = 4
cycles.transmission_bounces = 12
cycles.volume_bounces = 0
cycles.transparent_max_bounces = 8
cycles.caustics_reflective = False
cycles.caustics_refractive = False
cycles.sample_clamp_direct = 0.0
cycles.sample_clamp_indirect = 10.0
Denoising
import bpy
scene = bpy.context.scene
cycles = scene.cycles
scene.cycles.use_denoising = True
scene.cycles.denoiser = 'OPENIMAGEDENOISE'
scene.cycles.denoising_input_passes = 'RGB_ALBEDO_NORMAL'
scene.cycles.denoising_prefilter = 'ACCURATE'
scene.cycles.use_preview_denoising = True
scene.cycles.preview_denoiser = 'OPENIMAGEDENOISE'
scene.cycles.preview_denoising_start_sample = 1
Color Management
Configure Color Management
import bpy
cm = bpy.context.scene.view_settings
ds = bpy.context.scene.display_settings
ds.display_device = 'sRGB'
cm.view_transform = 'AgX'
cm.look = 'None'
cm.exposure = 0.0
cm.gamma = 1.0
bpy.context.scene.sequencer_colorspace_settings.name = 'sRGB'
Common view transforms:
| Transform | Use Case |
|---|
AgX | Default for Blender 4.0+/5.x, wide dynamic range |
Filmic | Legacy default, good for photorealistic scenes |
Standard | sRGB direct (UI elements, non-photorealistic) |
Raw | No transform (data passes, masks) |
World & Environment
HDRI Environment
import bpy
world = bpy.context.scene.world
if world is None:
world = bpy.data.worlds.new("World")
bpy.context.scene.world = world
world.use_nodes = True
nodes = world.node_tree.nodes
links = world.node_tree.links
nodes.clear()
bg = nodes.new('ShaderNodeBackground')
env_tex = nodes.new('ShaderNodeTexEnvironment')
env_tex.image = bpy.data.images.load("//hdri/studio.exr")
mapping = nodes.new('ShaderNodeMapping')
tex_coord = nodes.new('ShaderNodeTexCoord')
output = nodes.new('ShaderNodeOutputWorld')
links.new(tex_coord.outputs['Generated'], mapping.inputs['Vector'])
links.new(mapping.outputs['Vector'], env_tex.inputs['Vector'])
links.new(env_tex.outputs['Color'], bg.inputs['Color'])
links.new(bg.outputs['Background'], output.inputs['Surface'])
bg.inputs['Strength'].default_value = 1.0
Solid Color World
import bpy
world = bpy.context.scene.world
world.use_nodes = True
nodes = world.node_tree.nodes
bg = nodes.get('Background')
bg.inputs['Color'].default_value = (0.05, 0.05, 0.05, 1.0)
bg.inputs['Strength'].default_value = 1.0
Import/Export
Common Import Operations
import bpy
bpy.ops.import_scene.fbx(filepath="/path/to/model.fbx")
bpy.ops.import_scene.gltf(filepath="/path/to/model.glb")
bpy.ops.wm.obj_import(filepath="/path/to/model.obj")
bpy.ops.wm.usd_import(filepath="/path/to/scene.usdc")
bpy.ops.wm.alembic_import(filepath="/path/to/cache.abc")
bpy.ops.wm.stl_import(filepath="/path/to/model.stl")
bpy.ops.import_curve.svg(filepath="/path/to/graphic.svg")
Common Export Operations
import bpy
bpy.ops.export_scene.fbx(
filepath="/path/to/export.fbx",
use_selection=True,
apply_scale_options='FBX_SCALE_ALL',
axis_forward='-Z',
axis_up='Y',
use_mesh_modifiers=True,
mesh_smooth_type='FACE',
add_leaf_bones=False,
bake_anim=True,
)
bpy.ops.export_scene.gltf(
filepath="/path/to/export.glb",
export_format='GLB',
use_selection=True,
export_apply=True,
export_animations=True,
export_draco_mesh_compression_enable=False,
)
bpy.ops.wm.obj_export(
filepath="/path/to/export.obj",
export_selected_objects=True,
apply_modifiers=True,
export_uv=True,
export_normals=True,
export_materials=True,
)
bpy.ops.wm.usd_export(
filepath="/path/to/export.usdc",
selected_objects_only=True,
export_animation=True,
export_hair=True,
)
bpy.ops.wm.alembic_export(
filepath="/path/to/export.abc",
selected=True,
start=1,
end=250,
)
bpy.ops.wm.stl_export(
filepath="/path/to/export.stl",
export_selected_objects=True,
apply_modifiers=True,
)
Linking & Appending
Append (Copy into Current File)
import bpy
blend_path = "/path/to/library.blend"
with bpy.data.libraries.load(blend_path) as (data_from, data_to):
data_to.objects = ["ObjectName"]
for obj in data_to.objects:
if obj is not None:
bpy.context.collection.objects.link(obj)
with bpy.data.libraries.load(blend_path) as (data_from, data_to):
data_to.materials = ["MaterialName"]
data_to.node_groups = ["NodeGroupName"]
data_to.collections = ["CollectionName"]
data_to.worlds = ["WorldName"]
Link (Reference, Stay Connected)
import bpy
blend_path = "/path/to/library.blend"
with bpy.data.libraries.load(blend_path, link=True) as (data_from, data_to):
data_to.collections = ["CollectionName"]
for coll in data_to.collections:
if coll is not None:
bpy.context.collection.children.link(coll)
bpy.ops.object.make_override_library()
Reload / Relocate Libraries
import bpy
for lib in bpy.data.libraries:
lib.reload()
Scene Settings
Units
import bpy
unit = bpy.context.scene.unit_settings
unit.system = 'METRIC'
unit.scale_length = 1.0
unit.length_unit = 'METERS'
unit.use_separate = True
unit.temperature_unit = 'CELSIUS'
Multiple Scenes
import bpy
new_scene = bpy.data.scenes.new("MyScene")
bpy.ops.scene.new(type='FULL_COPY')
bpy.context.window.scene = bpy.data.scenes["MyScene"]
bpy.data.scenes.remove(bpy.data.scenes["MyScene"])
View Layers
Configure View Layers
import bpy
scene = bpy.context.scene
vl = scene.view_layers.new("MyLayer")
vl.layer_collection.children["CollectionName"].exclude = True
vl.use_pass_combined = True
vl.use_pass_z = True
vl.use_pass_normal = True
vl.use_pass_diffuse_color = True
vl.use_pass_glossy_color = True
vl.use_pass_emit = True
vl.use_pass_ambient_occlusion = True
vl.use_pass_shadow = True
vl.use_pass_mist = True
vl.use_pass_cryptomatte_object = True
vl.use_pass_cryptomatte_material = True
vl.use_pass_cryptomatte_asset = True
Viewport Configuration
Viewport Shading
import bpy
for area in bpy.context.screen.areas:
if area.type == 'VIEW_3D':
for space in area.spaces:
if space.type == 'VIEW_3D':
shading = space.shading
shading.type = 'MATERIAL'
shading.light = 'STUDIO'
shading.color_type = 'MATERIAL'
shading.use_scene_lights_render = True
shading.use_scene_world_render = True
break
Overlays
import bpy
for area in bpy.context.screen.areas:
if area.type == 'VIEW_3D':
for space in area.spaces:
if space.type == 'VIEW_3D':
overlay = space.overlay
overlay.show_overlays = True
overlay.show_floor = True
overlay.show_axis_x = True
overlay.show_axis_y = True
overlay.show_wireframes = False
overlay.show_face_orientation = False
overlay.show_stats = True
break
Batch Rendering
Render All Cameras
import bpy
scene = bpy.context.scene
original_camera = scene.camera
for obj in bpy.data.objects:
if obj.type == 'CAMERA':
scene.camera = obj
scene.render.filepath = f"//output/{obj.name}_"
bpy.ops.render.render(write_still=True)
scene.camera = original_camera
Render Multiple Scenes
import bpy
for scene in bpy.data.scenes:
scene.render.filepath = f"//output/{scene.name}_"
bpy.ops.render.render(write_still=True, scene=scene.name)
Render Animation
import bpy
bpy.ops.render.render(animation=True)
Debugging
Render Issues
| Problem | Cause | Fix |
|---|
| Render is black | No lights, camera pointing wrong way | Add light, check camera direction and clipping |
| Render is noisy | Low samples | Increase cycles.samples, enable denoising |
| Fireflies (bright pixels) | Caustics or unbounded light | Set sample_clamp_indirect = 10, disable caustics |
| Colors look washed out | Wrong color management | Set view transform to AgX or Filmic |
| Colors too saturated/contrasty | View transform mismatch | Try AgX with None look |
| Export missing textures | Textures not packed or paths broken | bpy.ops.file.pack_all() before export, or use export_format='GLB' |
| Import scale wrong | Unit mismatch between apps | Adjust scale_length or import scale option |
| Linked objects not updating | Library not reloaded | bpy.data.libraries["lib"].reload() |
| Viewport slow | Too many objects in rendered mode | Switch to Solid, reduce subdivision levels, use collection visibility |
| Missing render passes | Passes not enabled on view layer | Enable passes in View Layer properties |
| EEVEE looks different from Cycles | Engine differences in lighting | EEVEE Next with ray tracing enabled closes the gap |
Reference Files
references/python_api.md — Complete Python API patterns for scene/render/I/O operations
references/settings_reference.md — All render engine settings, output formats, color management options, import/export format options
Blender 5.1 Changes
OpenColorIO 2.5
- Blender 5.1 ships with OpenColorIO 2.5
- Improved color space handling and display transforms
- Better accuracy for AgX and other view transforms
Cycles Performance
- Significant rendering speedups for complex scenes
- Improved adaptive sampling convergence
EEVEE Performance
- Reduced memory usage for screen-space effects
- Faster ray tracing evaluation
Light Path in World Nodes
- Light Path node is now available in World node trees (not just materials)
- Enables per-light-type effects in environment materials