"""Preview renders of the Manta: studio-in-water look (dark blue world, sun from above, rim lights). Not part of the export: camera, lights and world live in the collection "_preview" (hidden from the export). Run in the open Blender: exec with g["VIEWS"] = [...] and g["ENGINE"] = 'BLENDER_EEVEE' / 'CYCLES'.""" import bpy, math, os from mathutils import Vector, Euler OUT = r"D:\HADAL - The Descent\models\tender-manta\previews" VIEWS = globals().get("VIEWS", ["hero"]) ENGINE = globals().get("ENGINE", "BLENDER_EEVEE") TAG = globals().get("TAG", "v01") RES = globals().get("RES", (1400, 900)) SAMPLES = globals().get("SAMPLES", 64) sc = bpy.context.scene pc = bpy.data.collections.get("_preview") if pc is None: pc = bpy.data.collections.new("_preview"); sc.collection.children.link(pc) def obj(name, data=None): o = bpy.data.objects.get(name) if o is None: o = bpy.data.objects.new(name, data); pc.objects.link(o) return o cam = obj("_PrevCam", bpy.data.cameras.get("_PrevCam") or bpy.data.cameras.new("_PrevCam")) sc.camera = cam def light(name, kind, energy, color, rot, loc=(0, 0, 0), size=1.0): ld = bpy.data.lights.get(name) or bpy.data.lights.new(name, kind) ld.energy = energy; ld.color = color if kind == 'SUN': ld.angle = math.radians(6) else: ld.shape = 'DISK'; ld.size = size o = obj(name, ld); o.rotation_euler = Euler(rot); o.location = loc light("_PrevSun", 'SUN', 3.2, (0.80, 0.92, 1.0), (math.radians(20), math.radians(-12), 0)) light("_PrevRim", 'AREA', 900, (0.55, 0.75, 1.0), (math.radians(-65), 0, math.radians(200)), loc=(-4, 8, 5), size=6) light("_PrevFill", 'AREA', 350, (0.70, 0.85, 1.0), (math.radians(70), 0, math.radians(-30)), loc=(6, -6, -2), size=6) w = bpy.data.worlds.get("_PrevWorld") or bpy.data.worlds.new("_PrevWorld") w.use_nodes = True bg = w.node_tree.nodes.get("Background") bg.inputs[0].default_value = (0.012, 0.045, 0.075, 1); bg.inputs[1].default_value = 1.0 sc.world = w sc.render.engine = ENGINE sc.render.resolution_x, sc.render.resolution_y = RES sc.render.resolution_percentage = 100 sc.view_settings.view_transform = 'AgX' sc.view_settings.look = 'AgX - Medium High Contrast' if 'AgX - Medium High Contrast' in [i.identifier for i in bpy.types.ColorManagedViewSettings.bl_rna.properties['look'].enum_items] else 'None' if ENGINE == 'CYCLES': sc.cycles.samples = SAMPLES sc.cycles.use_denoising = True prefs = bpy.context.preferences.addons['cycles'].preferences sc.cycles.device = 'CPU' for kind in ('OPTIX', 'CUDA', 'HIP', 'ONEAPI'): # this PC bakes and renders on HIP try: prefs.compute_device_type = kind except Exception: continue prefs.refresh_devices() if any(d.type == kind for d in prefs.devices): for d in prefs.devices: d.use = d.type == kind sc.cycles.device = 'GPU' break for c in ("MANTA | Collision (UCX)", "MANTA | Sockets"): if bpy.data.collections.get(c): bpy.data.collections[c].hide_render = True # views: (location, look-at, lens) V = { "hero": ((7.6, -9.0, 4.6), (0.0, -0.6, -0.1), 50), "ref": ((-7.0, -9.5, 6.5), (0.0, -0.2, -0.2), 50), # the reference's angle: nose toward the camera, starboard side "side": ((-13.0, -0.2, 0.0), (0.0, -0.2, 0.0), 50), "top": ((0.0, -0.2, 14.0), (0.0, -0.2, 0.0), 45), "front": ((1.5, -11.0, -0.3), (0.0, -2.5, -0.2), 50), "stern": ((-5.5, 8.5, 2.6), (0.0, 1.5, 0.0), 50), "cabin": ((2.2, -5.0, -0.6), (0.0, -2.6, -0.2), 35), "under": ((4.5, -6.5, -5.5), (0.0, -0.2, -0.4), 50), "clips": ((2.0, -2.2, 3.3), (0.0, -0.09, 1.2), 50), } for name in VIEWS: loc, at, lens = V[name] cam.location = loc d = Vector(at) - Vector(loc) cam.rotation_euler = d.to_track_quat('-Z', 'Y').to_euler() cam.data.lens = lens if name == "top": cam.rotation_euler = Euler((0, 0, 0)) sc.render.filepath = os.path.join(OUT, "%s_%s.png" % (TAG, name)) bpy.ops.render.render(write_still=True)