"""Camera, lights and a plain backdrop for the pressure hatch's pictures (collection "Studio", not exported). shot(path, cam_loc, target, lens, engine) renders one picture; wip pictures use Workbench, finals Cycles.""" import bpy, math, os from mathutils import Vector FOLDER = r"D:\HADAL - The Descent\models\pressure-hatch" def studio(): sc = bpy.context.scene c = bpy.data.collections.get("Studio") if c is None: c = bpy.data.collections.new("Studio") sc.collection.children.link(c) cam = bpy.data.objects.get("PH_Camera") if cam is None: cam = bpy.data.objects.new("PH_Camera", bpy.data.cameras.new("PH_Camera")) c.objects.link(cam) sc.camera = cam for name, loc, energy, size in (("PH_Key", (-2.6, -3.4, 2.6), 260.0, 2.2), ("PH_Fill", (3.2, -2.8, 0.8), 70.0, 3.0), ("PH_Rim", (1.0, -1.2, 3.4), 110.0, 1.6), ("PH_Back", (0.0, 3.0, 0.6), 80.0, 2.0)): L = bpy.data.objects.get(name) if L is None: L = bpy.data.objects.new(name, bpy.data.lights.new(name, 'AREA')) c.objects.link(L) L.data.energy = energy L.data.size = size L.location = loc d = Vector((0, 0, 0)) - Vector(loc) L.rotation_euler = d.to_track_quat('-Z', 'Y').to_euler() w = sc.world or bpy.data.worlds.new("PH_World") sc.world = w w.use_nodes = True bg = w.node_tree.nodes.get("Background") if bg: bg.inputs[0].default_value = (0.62, 0.63, 0.64, 1.0) bg.inputs[1].default_value = 0.12 sc.render.resolution_x, sc.render.resolution_y = 1600, 1000 sc.render.resolution_percentage = 100 sc.render.film_transparent = False sc.view_settings.view_transform = 'AgX' return cam def aim(cam, loc, target, lens): cam.location = loc d = Vector(target) - Vector(loc) cam.rotation_euler = d.to_track_quat('-Z', 'Y').to_euler() cam.data.lens = lens cam.data.clip_start = 0.02 def workbench(): sc = bpy.context.scene sc.render.engine = 'BLENDER_WORKBENCH' sh = sc.display.shading sh.light = 'STUDIO' sh.color_type = 'MATERIAL' sh.show_cavity = True sh.cavity_type = 'BOTH' sh.show_shadows = True sh.background_type = 'VIEWPORT' if hasattr(sh, 'background_type') else sh.background_type sc.display.render_aa = '8' def cycles(samples=96): sc = bpy.context.scene sc.render.engine = 'CYCLES' sc.cycles.samples = samples sc.cycles.use_denoising = True try: prefs = bpy.context.preferences.addons['cycles'].preferences for t in ('OPTIX', 'CUDA', 'HIP', 'ONEAPI'): try: prefs.compute_device_type = t prefs.get_devices() if any(d.type == t for d in prefs.devices): for d in prefs.devices: d.use = d.type == t sc.cycles.device = 'GPU' break except Exception: continue except Exception: pass def shot(path, loc, target=(0.1, -0.1, 0.0), lens=50.0): cam = studio() aim(cam, loc, target, lens) sc = bpy.context.scene sc.render.filepath = path bpy.ops.render.render(write_still=True) return path