Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions _render_no_outputfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import bpy, os, time, json, glob

project_dir = 'C:/Users/downl/Documents/New project/hermes-agent'
frames_dir = project_dir + '/render_frames'
scene = bpy.context.scene

# === COMPOSITOR WITHOUT OUTPUTFILE ===
if scene.compositing_node_group:
bpy.data.node_groups.remove(scene.compositing_node_group)

cg = bpy.data.node_groups.new('FinalComp', 'CompositorNodeTree')
scene.compositing_node_group = cg
scene.render.use_compositing = True

# Nodes (NO OutputFile - just chain to scene output)
rl = cg.nodes.new('CompositorNodeRLayers'); rl.location = (0, 100)
glare = cg.nodes.new('CompositorNodeGlare'); glare.location = (250, 200)
glare.inputs['Strength'].default_value = 3.0
glare.inputs['Size'].default_value = 10.0
glare.inputs['Iterations'].default_value = 6
glare.inputs['Highlights Threshold'].default_value = 0.2

rgb = cg.nodes.new('CompositorNodeRGB'); rgb.location = (250, -200)
rgb.outputs['Color'].default_value = (1.0, 1.0, 1.0, 1.0)

alpha = cg.nodes.new('CompositorNodeAlphaOver'); alpha.location = (500, 100)
alpha.inputs['Fac'].default_value = 0.0

# LINKS
cg.links.new(rl.outputs['Image'], glare.inputs['Image'])
cg.links.new(glare.outputs['Image'], alpha.inputs['Background'])
cg.links.new(rgb.outputs['Color'], alpha.inputs['Foreground'])
# Alpha output goes to scene render result (no terminal node needed in 5.2)

# Keyframe
fac = alpha.inputs['Fac']
fac.default_value = 0.0; fac.keyframe_insert('default_value', frame=1)
fac.keyframe_insert('default_value', frame=130)
fac.default_value = 1.0; fac.keyframe_insert('default_value', frame=180)

# Scene settings (PNG output)
scene.render.resolution_x = 1920
scene.render.resolution_y = 1080
scene.frame_start = 1; scene.frame_end = 180
scene.render.fps = 24; scene.render.film_transparent = False
scene.render.use_motion_blur = False
scene.render.filepath = frames_dir + '/frame_'
scene.render.image_settings.file_format = 'PNG'
scene.render.image_settings.color_mode = 'RGBA'

bpy.ops.wm.save_as_mainfile(filepath=project_dir + '/city_destruction.blend')

# === RENDER ===
print('RENDERING 180 frames (no OutputFile node)...')
t0 = time.time()
bpy.ops.render.render(animation=True)
t1 = time.time()

pngs = sorted(glob.glob(frames_dir + '/frame_[0-9][0-9][0-9][0-9].png'))
result = {
'frames': len(pngs),
'duration': round(t1 - t0, 1),
}
if pngs:
sizes = set(os.path.getsize(f) for f in pngs)
result['unique_sizes'] = len(sizes)
result['size_range'] = [min(sizes), max(sizes)]
result['sample'] = [(os.path.basename(f), os.path.getsize(f)) for f in [pngs[0], pngs[len(pngs)//2], pngs[-1]]]

print('DONE:' + json.dumps(result))
91 changes: 91 additions & 0 deletions _setup_compositor_final.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import bpy, os, json

scene = bpy.context.scene

# Remove old compositor and create simplified one WITHOUT OutputFile
if scene.compositing_node_group:
bpy.data.node_groups.remove(scene.compositing_node_group)

cg = bpy.data.node_groups.new('CityDestructionComp', 'CompositorNodeTree')
scene.compositing_node_group = cg
scene.render.use_compositing = True

# Nodes
rl = cg.nodes.new('CompositorNodeRLayers')
rl.location = (0, 100)

glare = cg.nodes.new('CompositorNodeGlare')
glare.location = (250, 200)
glare.inputs['Strength'].default_value = 3.0
glare.inputs['Size'].default_value = 10.0
glare.inputs['Iterations'].default_value = 6
glare.inputs['Highlights Threshold'].default_value = 0.2

rgb = cg.nodes.new('CompositorNodeRGB')
rgb.location = (250, -200)
rgb.outputs['Color'].default_value = (1.0, 1.0, 1.0, 1.0)

alpha = cg.nodes.new('CompositorNodeAlphaOver')
alpha.location = (500, 100)
alpha.inputs['Fac'].default_value = 0.0

# NO OutputFile - just connect alpha output to... nothing?
# In Blender 5.2, the last node in chain defines compositor output
# But without Composite node, how does it work?

# Actually, in Blender 5.2 compositor auto-applies the node tree
# to the render result. Let's add a Viewer node as terminal
# instead of OutputFile.
viewer = cg.nodes.new('CompositorNodeViewer')
viewer.location = (750, 100)

# Links
cg.links.new(rl.outputs['Image'], glare.inputs['Image'])
cg.links.new(glare.outputs['Image'], alpha.inputs['Background'])
cg.links.new(rgb.outputs['Color'], alpha.inputs['Foreground'])
cg.links.new(alpha.outputs['Image'], viewer.inputs['Image'])

# Keyframe Fac
fac = alpha.inputs['Fac']
fac.default_value = 0.0
fac.keyframe_insert('default_value', frame=1)
fac.keyframe_insert('default_value', frame=130)
fac.keyframe_insert('default_value', frame=131) # hold at 0
fac.default_value = 1.0
fac.keyframe_insert('default_value', frame=180)

result = {
'nodes': [n.name for n in cg.nodes],
'links_count': len(cg.links),
'success': True
}

print('COMPOSITOR:' + json.dumps(result, default=str))

# Now render a test frame
scene.render.filepath = 'render_frames/frame_'
scene.render.image_settings.file_format = 'PNG'
scene.render.image_settings.color_mode = 'RGBA'
scene.frame_set(90)

# Quick Eevee optimization
scene.eevee.use_gtao = False
scene.eevee.use_bloom = False # using compositor glare instead
scene.render.use_motion_blur = False

bpy.ops.render.render(write_still=True, scene=scene.name)

# Check output
out_path = 'render_frames/frame_0090.png'
if os.path.exists(out_path):
result['test_frame_size'] = os.path.getsize(out_path)
result['test_frame_path'] = out_path
else:
# Check what files appeared
import glob
pngs = sorted(glob.glob('render_frames/frame_0*.png'))
result['new_files'] = [f for f in pngs[-3:]]
if result['new_files']:
result['test_frame_size'] = os.path.getsize(result['new_files'][-1])

print('TEST:' + json.dumps(result, default=str))
Loading
Loading