| 352 | |
| 353 | |
| 354 | def setup_render(out_path, samples, device, view, exposure_ev=0.0): |
| 355 | scene = bpy.context.scene |
| 356 | scene.render.engine = 'CYCLES' |
| 357 | scene.render.resolution_x = RES_X |
| 358 | scene.render.resolution_y = RES_Y |
| 359 | scene.render.resolution_percentage = 100 |
| 360 | scene.render.image_settings.file_format = 'PNG' |
| 361 | scene.render.image_settings.color_mode = 'RGB' |
| 362 | scene.render.image_settings.color_depth = '8' |
| 363 | scene.render.filepath = out_path |
| 364 | |
| 365 | scene.cycles.samples = samples |
| 366 | scene.cycles.use_denoising = True |
| 367 | try: |
| 368 | scene.cycles.denoiser = 'OPENIMAGEDENOISE' |
| 369 | except Exception: |
| 370 | pass |
| 371 | |
| 372 | # Film / color management. 'Standard' = pass-through (clip to [0,1]), |
| 373 | # 'AgX' = Blender 4+ default DRT (soft sigmoid, preserves highlights). |
| 374 | # Pass --view AgX to compare against Bloom's AgX tonemap. |
| 375 | scene.view_settings.view_transform = view |
| 376 | scene.view_settings.exposure = exposure_ev |
| 377 | |
| 378 | # GPU if requested and available |
| 379 | if device != "CPU": |
| 380 | prefs = bpy.context.preferences.addons['cycles'].preferences |
| 381 | try: |
| 382 | prefs.compute_device_type = device # METAL on macOS, CUDA/OPTIX on Linux/Win |
| 383 | prefs.get_devices() |
| 384 | for d in prefs.devices: |
| 385 | d.use = True |
| 386 | scene.cycles.device = 'GPU' |
| 387 | print(f"[cycles_reference] using GPU device type: {device}") |
| 388 | except Exception as e: |
| 389 | print(f"[cycles_reference] GPU setup failed ({e}); falling back to CPU", file=sys.stderr) |
| 390 | scene.cycles.device = 'CPU' |
| 391 | else: |
| 392 | scene.cycles.device = 'CPU' |
| 393 | |
| 394 | |
| 395 | # --------------------------------------------------------------------------- |