RenderEngine(bpy_struct)¶
Simple Render Engine¶
import bpy
import bgl
class CustomRenderEngine(bpy.types.RenderEngine):
# These three members are used by blender to set up the
# RenderEngine; define its internal name, visible name and capabilities.
bl_idname = "CUSTOM"
bl_label = "Custom"
bl_use_preview = True
# Init is called whenever a new render engine instance is created. Multiple
# instances may exist at the same time, for example for a viewport and final
# render.
def __init__(self):
self.scene_data = None
self.draw_data = None
# When the render engine instance is destroy, this is called. Clean up any
# render engine data here, for example stopping running render threads.
def __del__(self):
pass
# This is the method called by Blender for both final renders (F12) and
# small preview for materials, world and lights.
def render(self, depsgraph):
scene = depsgraph.scene
scale = scene.render.resolution_percentage / 100.0
self.size_x = int(scene.render.resolution_x * scale)
self.size_y = int(scene.render.resolution_y * scale)
# Fill the render result with a flat color. The framebuffer is
# defined as a list of pixels, each pixel itself being a list of
# R,G,B,A values.
if self.is_preview:
color = [0.1, 0.2, 0.1, 1.0]
else:
color = [0.2, 0.1, 0.1, 1.0]
pixel_count = self.size_x * self.size_y
rect = [color] * pixel_count
# Here we write the pixel values to the RenderResult
result = self.begin_result(0, 0, self.size_x, self.size_y)
layer = result.layers[0].passes["Combined"]
layer.rect = rect
self.end_result(result)
# For viewport renders, this method gets called once at the start and
# whenever the scene or 3D viewport changes. This method is where data
# should be read from Blender in the same thread. Typically a render
# thread will be started to do the work while keeping Blender responsive.
def view_update(self, context, depsgraph):
region = context.region
view3d = context.space_data
scene = depsgraph.scene
# Get viewport dimensions
dimensions = region.width, region.height
if not self.scene_data:
# First time initialization
self.scene_data = []
first_time = True
# Loop over all datablocks used in the scene.
for datablock in depsgraph.ids:
pass
else:
first_time = False
# Test which datablocks changed
for update in depsgraph.updates:
print("Datablock updated: ", update.id.name)
# Test if any material was added, removed or changed.
if depsgraph.id_type_updated('MATERIAL'):
print("Materials updated")
# Loop over all object instances in the scene.
if first_time or depsgraph.id_type_updated('OBJECT'):
for instance in depsgraph.object_instances:
pass
# For viewport renders, this method is called whenever Blender redraws
# the 3D viewport. The renderer is expected to quickly draw the render
# with OpenGL, and not perform other expensive work.
# Blender will draw overlays for selection and editing on top of the
# rendered image automatically.
def view_draw(self, context, depsgraph):
region = context.region
scene = depsgraph.scene
# Get viewport dimensions
dimensions = region.width, region.height
# Bind shader that converts from scene linear to display space,
bgl.glEnable(bgl.GL_BLEND)
bgl.glBlendFunc(bgl.GL_ONE, bgl.GL_ONE_MINUS_SRC_ALPHA)
self.bind_display_space_shader(scene)
if not self.draw_data or self.draw_data.dimensions != dimensions:
self.draw_data = CustomDrawData(dimensions)
self.draw_data.draw()
self.unbind_display_space_shader()
bgl.glDisable(bgl.GL_BLEND)
class CustomDrawData:
def __init__(self, dimensions):
# Generate dummy float image buffer
self.dimensions = dimensions
width, height = dimensions
pixels = [0.1, 0.2, 0.1, 1.0] * width * height
pixels = bgl.Buffer(bgl.GL_FLOAT, width * height * 4, pixels)
# Generate texture
self.texture = bgl.Buffer(bgl.GL_INT, 1)
bgl.glGenTextures(1, self.texture)
bgl.glActiveTexture(bgl.GL_TEXTURE0)
bgl.glBindTexture(bgl.GL_TEXTURE_2D, self.texture[0])
bgl.glTexImage2D(bgl.GL_TEXTURE_2D, 0, bgl.GL_RGBA16F, width, height, 0, bgl.GL_RGBA, bgl.GL_FLOAT, pixels)
bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_LINEAR)
bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_LINEAR)
bgl.glBindTexture(bgl.GL_TEXTURE_2D, 0)
# Bind shader that converts from scene linear to display space,
# use the scene's color management settings.
shader_program = bgl.Buffer(bgl.GL_INT, 1)
bgl.glGetIntegerv(bgl.GL_CURRENT_PROGRAM, shader_program)
# Generate vertex array
self.vertex_array = bgl.Buffer(bgl.GL_INT, 1)
bgl.glGenVertexArrays(1, self.vertex_array)
bgl.glBindVertexArray(self.vertex_array[0])
texturecoord_location = bgl.glGetAttribLocation(shader_program[0], "texCoord")
position_location = bgl.glGetAttribLocation(shader_program[0], "pos")
bgl.glEnableVertexAttribArray(texturecoord_location)
bgl.glEnableVertexAttribArray(position_location)
# Generate geometry buffers for drawing textured quad
position = [0.0, 0.0, width, 0.0, width, height, 0.0, height]
position = bgl.Buffer(bgl.GL_FLOAT, len(position), position)
texcoord = [0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0]
texcoord = bgl.Buffer(bgl.GL_FLOAT, len(texcoord), texcoord)
self.vertex_buffer = bgl.Buffer(bgl.GL_INT, 2)
bgl.glGenBuffers(2, self.vertex_buffer)
bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vertex_buffer[0])
bgl.glBufferData(bgl.GL_ARRAY_BUFFER, 32, position, bgl.GL_STATIC_DRAW)
bgl.glVertexAttribPointer(position_location, 2, bgl.GL_FLOAT, bgl.GL_FALSE, 0, None)
bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vertex_buffer[1])
bgl.glBufferData(bgl.GL_ARRAY_BUFFER, 32, texcoord, bgl.GL_STATIC_DRAW)
bgl.glVertexAttribPointer(texturecoord_location, 2, bgl.GL_FLOAT, bgl.GL_FALSE, 0, None)
bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, 0)
bgl.glBindVertexArray(0)
def __del__(self):
bgl.glDeleteBuffers(2, self.vertex_buffer)
bgl.glDeleteVertexArrays(1, self.vertex_array)
bgl.glBindTexture(bgl.GL_TEXTURE_2D, 0)
bgl.glDeleteTextures(1, self.texture)
def draw(self):
bgl.glActiveTexture(bgl.GL_TEXTURE0)
bgl.glBindTexture(bgl.GL_TEXTURE_2D, self.texture[0])
bgl.glBindVertexArray(self.vertex_array[0])
bgl.glDrawArrays(bgl.GL_TRIANGLE_FAN, 0, 4)
bgl.glBindVertexArray(0)
bgl.glBindTexture(bgl.GL_TEXTURE_2D, 0)
# RenderEngines also need to tell UI Panels that they are compatible with.
# We recommend to enable all panels marked as BLENDER_RENDER, and then
# exclude any panels that are replaced by custom panels registered by the
# render engine, or that are not supported.
def get_panels():
exclude_panels = {
'VIEWLAYER_PT_filter',
'VIEWLAYER_PT_layer_passes',
}
panels = []
for panel in bpy.types.Panel.__subclasses__():
if hasattr(panel, 'COMPAT_ENGINES') and 'BLENDER_RENDER' in panel.COMPAT_ENGINES:
if panel.__name__ not in exclude_panels:
panels.append(panel)
return panels
def register():
# Register the RenderEngine
bpy.utils.register_class(CustomRenderEngine)
for panel in get_panels():
panel.COMPAT_ENGINES.add('CUSTOM')
def unregister():
bpy.utils.unregister_class(CustomRenderEngine)
for panel in get_panels():
if 'CUSTOM' in panel.COMPAT_ENGINES:
panel.COMPAT_ENGINES.remove('CUSTOM')
if __name__ == "__main__":
register()
base class — bpy_struct
-
class
bpy.types.
RenderEngine
(bpy_struct)¶ Render engine
-
bl_idname
¶ Type: string, default “”, (never None)
-
bl_label
¶ Type: string, default “”, (never None)
-
bl_use_eevee_viewport
¶ Uses Eevee for viewport shading in LookDev shading mode
Type: boolean, default False
-
bl_use_postprocess
¶ Apply compositing on render results
Type: boolean, default False
-
bl_use_preview
¶ Render engine supports being used for rendering previews of materials, lights and worlds
Type: boolean, default False
-
bl_use_save_buffers
¶ Support render to an on disk buffer during rendering
Type: boolean, default False
-
bl_use_shading_nodes_custom
¶ Don’t expose Cycles and Eevee shading nodes in the node editor user interface, so own nodes can be used instead
Type: boolean, default True
-
bl_use_spherical_stereo
¶ Support spherical stereo camera models
Type: boolean, default False
-
is_animation
¶ Type: boolean, default False
-
is_preview
¶ Type: boolean, default False
-
layer_override
¶ Type: boolean array of 20 items, default (False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False)
-
render
¶ Type: RenderSettings
, (readonly)
-
resolution_x
¶ Type: int in [-inf, inf], default 0, (readonly)
-
resolution_y
¶ Type: int in [-inf, inf], default 0, (readonly)
-
tile_x
¶ Type: int in [0, inf], default 0
-
tile_y
¶ Type: int in [0, inf], default 0
-
use_highlight_tiles
¶ Type: boolean, default False
-
update
(data=None, depsgraph=None)¶ Export scene data for render
-
render
(depsgraph) Render scene into an image
-
bake
(depsgraph, object, pass_type, pass_filter, object_id, pixel_array, num_pixels, depth, result)¶ Bake passes
Parameters: - pass_type (enum in ['COMBINED', 'AO', 'SHADOW', 'NORMAL', 'UV', 'ROUGHNESS', 'EMIT', 'ENVIRONMENT', 'DIFFUSE', 'GLOSSY', 'TRANSMISSION', 'SUBSURFACE']) – Pass, Pass to bake
- pass_filter (int in [0, inf]) – Pass Filter, Filter to combined, diffuse, glossy, transmission and subsurface passes
- object_id (int in [0, inf]) – Object Id, Id of the current object being baked in relation to the others
- num_pixels (int in [0, inf]) – Number of Pixels, Size of the baking batch
- depth (int in [0, inf]) – Pixels depth, Number of channels
-
view_update
(context, depsgraph)¶ Update on data changes for viewport render
-
view_draw
(context, depsgraph)¶ Draw viewport render
-
update_script_node
(node=None)¶ Compile shader script node
-
update_render_passes
(scene=None, renderlayer=None)¶ Update the render passes that will be generated
-
tag_redraw
()¶ Request redraw for viewport rendering
-
tag_update
()¶ Request update call for viewport rendering
-
begin_result
(x, y, w, h, layer="", view="")¶ Create render result to write linear floating point render layers and passes
Parameters: - x (int in [0, inf]) – X
- y (int in [0, inf]) – Y
- w (int in [0, inf]) – Width
- h (int in [0, inf]) – Height
- layer (string, (optional, never None)) – Layer, Single layer to get render result for
- view (string, (optional, never None)) – View, Single view to get render result for
Returns: Result
Return type:
-
update_result
(result)¶ Signal that pixels have been updated and can be redrawn in the user interface
Parameters: result ( RenderResult
) – Result
-
end_result
(result, cancel=False, highlight=False, do_merge_results=False)¶ All pixels in the render result have been set and are final
Parameters: - result (
RenderResult
) – Result - cancel (boolean, (optional)) – Cancel, Don’t mark tile as done, don’t merge results unless forced
- highlight (boolean, (optional)) – Highlight, Don’t mark tile as done yet
- do_merge_results (boolean, (optional)) – Merge Results, Merge results even if cancel=true
- result (
-
add_pass
(name, channels, chan_id, layer="")¶ Add a pass to the render layer
Parameters: - name (string, (never None)) – Name, Name of the Pass, without view or channel tag
- channels (int in [0, inf]) – Channels
- chan_id (string, (never None)) – Channel IDs, Channel names, one character per channel
- layer (string, (optional, never None)) – Layer, Single layer to add render pass to
-
get_result
()¶ Get final result for non-pixel operations
Returns: Result Return type: RenderResult
-
test_break
()¶ Test if the render operation should been canceled, this is a fast call that should be used regularly for responsiveness
Returns: Break Return type: boolean
-
active_view_get
()¶ active_view_get
Returns: View, Single view active Return type: string, (never None)
-
active_view_set
(view)¶ active_view_set
Parameters: view (string, (never None)) – View, Single view to set as active
-
camera_shift_x
(camera, use_spherical_stereo=False)¶ camera_shift_x
Parameters: use_spherical_stereo (boolean, (optional)) – Spherical Stereo Returns: Shift X Return type: float in [0, inf]
-
camera_model_matrix
(camera, use_spherical_stereo=False)¶ camera_model_matrix
Parameters: use_spherical_stereo (boolean, (optional)) – Spherical Stereo Returns: Model Matrix, Normalized camera model matrix Return type: float multi-dimensional array of 4 * 4 items in [-inf, inf]
-
use_spherical_stereo
(camera)¶ use_spherical_stereo
Returns: Spherical Stereo Return type: boolean
-
update_stats
(stats, info)¶ Update and signal to redraw render status text
Parameters: - stats (string, (never None)) – Stats
- info (string, (never None)) – Info
-
frame_set
(frame, subframe)¶ Evaluate scene at a different frame (for motion blur)
Parameters: - frame (int in [-inf, inf]) – Frame
- subframe (float in [0, 1]) – Subframe
-
update_progress
(progress)¶ Update progress percentage of render
Parameters: progress (float in [0, 1]) – Percentage of render that’s done
-
update_memory_stats
(memory_used=0.0, memory_peak=0.0)¶ Update memory usage statistics
Parameters: - memory_used (float in [0, inf], (optional)) – Current memory usage in megabytes
- memory_peak (float in [0, inf], (optional)) – Peak memory usage in megabytes
-
report
(type, message)¶ Report info, warning or error messages
Parameters: - type (enum set in {'DEBUG', 'INFO', 'OPERATOR', 'PROPERTY', 'WARNING', 'ERROR', 'ERROR_INVALID_INPUT', 'ERROR_INVALID_CONTEXT', 'ERROR_OUT_OF_MEMORY'}) – Type
- message (string, (never None)) – Report Message
-
error_set
(message)¶ Set error message displaying after the render is finished
Parameters: message (string, (never None)) – Report Message
-
bind_display_space_shader
(scene)¶ Bind GLSL fragment shader that converts linear colors to display space colors using scene color management settings
-
unbind_display_space_shader
()¶ Unbind GLSL display space shader, must always be called after binding the shader
-
support_display_space_shader
(scene)¶ Test if GLSL display space shader is supported for the combination of graphics card and scene settings
Returns: Supported Return type: boolean
-
get_preview_pixel_size
(scene)¶ Free Blender side memory of render engine
Returns: Pixel Size Return type: int in [1, 8]
-
free_blender_memory
()¶ free_blender_memory
-
register_pass
(scene, view_layer, name, channels, chanid, type)¶ Register a render pass that will be part of the render with the current settings
Parameters: - name (string, (never None)) – Name
- channels (int in [1, 8]) – Channels
- chanid (string, (never None)) – Channel IDs
- type (enum in ['VALUE', 'VECTOR', 'COLOR']) – Type
-
classmethod
bl_rna_get_subclass
(id, default=None)¶ Parameters: id (string) – The RNA type identifier. Returns: The RNA type or default when not found. Return type: bpy.types.Struct
subclass
-
classmethod
bl_rna_get_subclass_py
(id, default=None)¶ Parameters: id (string) – The RNA type identifier. Returns: The class or default when not found. Return type: type
-
Inherited Properties
Inherited Functions