- 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](../../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
```python
import bpy
scene = bpy.context.scene
scene.render.engine = 'CYCLES'
# Device: CPU or GPU
cycles = scene.cycles
cycles.device = 'GPU'
# GPU compute device type
prefs = bpy.context.preferences.addons['cycles'].preferences
prefs.compute_device_type = 'CUDA' # CUDA, OPTIX, HIP, METAL, ONEAPI
prefs.get_devices() # Refresh device list
for device in prefs.devices:
device.use = True # Enable all available devices
```
### Switch to EEVEE
```python
import bpy
scene = bpy.context.scene
scene.render.engine = 'BLENDER_EEVEE' # Blender 4.x+/5.x EEVEE
eevee = scene.eevee
# Shadows
eevee.shadow_ray_count = 1
eevee.shadow_step_count = 6
# Ray tracing
eevee.use_raytracing = True
eevee.ray_tracing_method = 'SCREEN' # SCREEN or FULL
# Emission transparency (for emissive materials that need alpha blending)
# Set per-material: material.surface_render_method = 'BLENDED'
# Ambient Occlusion (baked into lighting in EEVEE)
```
### Workbench (Solid/Preview)
```python
import bpy
bpy.context.scene.render.engine = 'BLENDER_WORKBENCH'
```
## Output Settings
### Resolution & Frame Range
```python
import bpy
render = bpy.context.scene.render
# Resolution
render.resolution_x = 1920
render.resolution_y = 1080
render.resolution_percentage = 100
# Frame range
scene = bpy.context.scene
scene.frame_start = 1
scene.frame_end = 250
scene.frame_step = 1
scene.frame_current = 1
# FPS
render.fps = 24
render.fps_base = 1.0 # Actual FPS = fps / fps_base
```
### Output Format
```python
import bpy
render = bpy.context.scene.render
render.filepath = "//output/render_" # // = relative to .blend file
# Image format
# Image format
render.image_settings.file_format = 'PNG' # PNG, JPEG, OPEN_EXR, OPEN_EXR_MULTILAYER, TIFF, BMP, HDR, FFMPEG, AVIF (5.1)
render.image_settings.color_mode = 'RGBA' # BW, RGB, RGBA
render.image_settings.color_depth = '16' # 8, 16 (PNG/TIFF), 16/32 (EXR)
render.image_settings.compression = 15 # PNG compression 0-100
# EXR settings
render.image_settings.file_format = 'OPEN_EXR'
render.image_settings.exr_codec = 'DWAA' # NONE, PXR24, ZIP, PIZ, RLE, ZIPS, DWAA, DWAB
render.image_settings.color_depth = '32'
# Video (FFmpeg)
render.image_settings.file_format = 'FFMPEG'
render.ffmpeg.format = 'MPEG4' # MPEG4, MKV, WEBM, AVI, QUICKTIME
render.ffmpeg.codec = 'H264' # H264, MPEG4, WEBM, PNG, HUFFYUV, DNXHD, FFV1
render.ffmpeg.constant_rate_factor = 'MEDIUM' # NONE, LOSSLESS, PERC_LOSSLESS, HIGH, MEDIUM, LOW, LOWEST
render.ffmpeg.audio_codec = 'AAC' # NONE, AAC, AC3, FLAC, MP2, MP3, OPUS, PCM, VORBIS
```
### OpenEXR HTJ2K (New in 5.1)
1. New EXR codec: `render.image_settings.exr_codec = 'HTJ2K'`
2. High-throughput JPEG 2000 compression for EXR files
3. Better compression ratios than DWAA/DWAB for multi-layer EXR output
### Video Custom CRF (5.1)
1. FFmpeg `constant_rate_factor` now supports integer values for finer control
2. 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
```python
import bpy
cycles = bpy.context.scene.cycles
# Render samples
cycles.samples = 256
cycles.use_adaptive_sampling = True
cycles.adaptive_threshold = 0.01 # Lower = higher quality
cycles.adaptive_min_samples = 64
# Viewport samples
cycles.preview_samples = 32
cycles.use_preview_adaptive_sampling = True
# Time limit (0 = disabled)
cycles.time_limit = 0.0
# Seed
cycles.seed = 0
cycles.use_animated_seed = True # Different seed per frame
# Light paths
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
# Caustics
cycles.caustics_reflective = False
cycles.caustics_refractive = False
# Clamping (reduce fireflies)
cycles.sample_clamp_direct = 0.0 # 0 = disabled
cycles.sample_clamp_indirect = 10.0
```
### Denoising
```python
import bpy
scene = bpy.context.scene
cycles = scene.cycles
# Render denoising
scene.cycles.use_denoising = True
scene.cycles.denoiser = 'OPENIMAGEDENOISE' # OPENIMAGEDENOISE or OPTIX
scene.cycles.denoising_input_passes = 'RGB_ALBEDO_NORMAL' # RGB, RGB_ALBEDO, RGB_ALBEDO_NORMAL
scene.cycles.denoising_prefilter = 'ACCURATE' # NONE, FAST, ACCURATE
# Viewport denoising
scene.cycles.use_preview_denoising = True
scene.cycles.preview_denoiser = 'OPENIMAGEDENOISE'
scene.cycles.preview_denoising_start_sample = 1
```
## Color Management
### Configure Color Management
```python
import bpy
cm = bpy.context.scene.view_settings
ds = bpy.context.scene.display_settings
# Display device
ds.display_device = 'sRGB' # sRGB, None
# View transform
cm.view_transform = 'AgX' # Standard, Filmic, AgX, Raw, False Color
cm.look = 'None' # None, AgX - Punchy, AgX - Golden, etc.
# Exposure and gamma
cm.exposure = 0.0
cm.gamma = 1.0
# Sequencer color space
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
```python
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()
# Background + Environment Texture
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
```python
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
```python
import bpy
# FBX
bpy.ops.import_scene.fbx(filepath="/path/to/model.fbx")
# glTF / GLB
bpy.ops.import_scene.gltf(filepath="/path/to/model.glb")
# OBJ
bpy.ops.wm.obj_import(filepath="/path/to/model.obj")
# USD
bpy.ops.wm.usd_import(filepath="/path/to/scene.usdc")
# Alembic
bpy.ops.wm.alembic_import(filepath="/path/to/cache.abc")
# STL
bpy.ops.wm.stl_import(filepath="/path/to/model.stl")
# SVG
bpy.ops.import_curve.svg(filepath="/path/to/graphic.svg")
```
### Common Export Operations
```python
import bpy
# FBX
bpy.ops.export_scene.fbx(
filepath="/path/to/export.fbx",
use_selection=True, # Export selected only
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,
)
# glTF / GLB
bpy.ops.export_scene.gltf(
filepath="/path/to/export.glb",
export_format='GLB', # GLB (binary), GLTF_SEPARATE, GLTF_EMBEDDED
use_selection=True,
export_apply=True, # Apply modifiers
export_animations=True,
export_draco_mesh_compression_enable=False,
)
# OBJ
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,
)
# USD
bpy.ops.wm.usd_export(
filepath="/path/to/export.usdc",
selected_objects_only=True,
export_animation=True,
export_hair=True,
)
# Alembic
View on GitHub