# 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

  `camera_override`

    Type: | `Object`, (readonly)

  `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: | `RenderResult`

  `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

  `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

`bpy_struct.id_data` |

Inherited Functions

`bpy_struct.as_pointer` `bpy_struct.driver_add` `bpy_struct.driver_remove` `bpy_struct.get` `bpy_struct.is_property_hidden` `bpy_struct.is_property_overridable_library` `bpy_struct.is_property_readonly` `bpy_struct.is_property_set` `bpy_struct.items` `bpy_struct.keyframe_delete` | `bpy_struct.keyframe_insert` `bpy_struct.keys` `bpy_struct.path_from_id` `bpy_struct.path_resolve` `bpy_struct.pop` `bpy_struct.property_overridable_library_set` `bpy_struct.property_unset` `bpy_struct.type_recast` `bpy_struct.values`