bl_info = {
"name": "Is Rendered Viewport Node",
"author": "Martynas Žiemys",
"version": (1, 0),
"blender": (4, 2, 0),
"location": "Geometry Nodes Group",
"description": "Geometry Nodes group IsRenderedViewport",
"warning": "",
"doc_url": "",
"category": "Geometry Nodes",
}
import bpy
from bpy.app.handlers import persistent
@persistent
def rendered_viewport_load_handler(dummy):
if "IsRenderedViewport" not in bpy.data.node_groups:
node_group = bpy.data.node_groups.new('IsRenderedViewport', 'GeometryNodeTree')
node_group.interface.new_socket(
"IsRenderedViewport",
in_out="OUTPUT",
socket_type='NodeSocketBool'
)
outNode = node_group.nodes.new('NodeGroupOutput')
bpy.msgbus.clear_by_owner(bpy.context.workspace)
def on_workspace_change(*args):
print("Workspace changed!")
bpy.msgbus.clear_by_owner(bpy.context.window_manager)
group = bpy.data.node_groups["IsRenderedViewport"]
rendered_input = group.nodes["Group Output"].inputs[0]
areas = bpy.context.screen.areas
views = [area for area in areas if area.type == 'VIEW_3D']
if len(views) == 1:
def on_shading_change(*args):
print("Shading changed!")
group = bpy.data.node_groups["IsRenderedViewport"]
rendered_input = group.nodes["Group Output"].inputs[0]
areas = bpy.context.screen.areas
views = [area for area in areas if area.type == 'VIEW_3D']
if views[0].spaces[0].shading.type == 'RENDERED':
if not rendered_input.default_value:
rendered_input.default_value = True
else:
if rendered_input.default_value:
rendered_input.default_value = False
bpy.msgbus.subscribe_rna(
key=views[0].spaces[0].shading.path_resolve("type", False),
owner=bpy.context.window_manager,
args=(1, 2, 3),
notify=on_shading_change,
)
else:
rendered_input.default_value = False
bpy.msgbus.subscribe_rna(
key=bpy.types.WorkSpace,
owner=bpy.context.workspace,
args=(1, 2, 3),
notify=on_workspace_change,
)
on_workspace_change(1,2,3)
def register():
bpy.app.handlers.load_post.append(rendered_viewport_load_handler)
def unregister():
bpy.app.handlers.load_post.remove(rendered_viewport_load_handler)
if __name__ == "__main__":
register()
Save from Blender’s Text Editor(saves correct encoding) as something like is_rendered_viewport.py and install as add-on.
Add node menu, Group submenu:

Seems to work:

As you can see it only detects if it’s a rendered viewport, so you still need to deal with render.
It’s made as a legacy kind of add-on(bl_info in the .py) so should work in 4.1 and might not work in 4.3. Should work when loading a new scene(it creates a new node group in every loaded file if enabled though). Works only with one viewport, it should set the boolean to False if more 3d Viewports are open(you probably don’t want full thing loaded in rendered and in regular viewport).
But in my tests it takes forever to build many instances anyway, so might not be amazing. I think it’s good in cases where you are OK to wait till the instances are made and then want to navigate while they are visible, other way it’s not much different than just rendering.
In you regular viewport you might want to have simpler geometry or less of it and avoid many small triangles in relation to rendered pixel size.
For the future: if anyone wants to improve, change, use, sell or do whatever they want(permitted by GPL) with the code I share, please do. Assume GNU GPL license as required by API’s license and use as intended, don’t ask. 