I'm trying to adapt some Godot 3.0 capture code that will allow me to grab the contents of a SubViewport buffer as an image, but having no luck. I've put together a test project, but when I run it, the only thing I save to disk is a completely black image. I need to get the image from my viewport so that I can perform further processing on it. Did I miss something in my code?

render-offscreen-viewport.zip
6kB
extends Control

var viewport:SubViewport
@export var icon_texture:Texture2D

# Called when the node enters the scene tree for the first time.
func _ready():
	viewport = SubViewport.new()
	viewport.size = Vector2i(128, 128)
	add_child(viewport)
	
	var sprite:Sprite2D = Sprite2D.new()
	sprite.texture = icon_texture
	sprite.transform.origin = Vector2(64, 64)
	viewport.add_child(sprite)


func _on_button_pressed():
	#viewport.get_viewport().render_target_clear_mode = SubViewport.CLEAR_MODE_ONCE
	
	await RenderingServer.frame_post_draw
	var image:Image = viewport.get_viewport().get_texture().get_image()
	image.save_png("user://viewport_test.png")
  • Default update mode for viewports is UPDATE_WHEN_VISIBLE. Try forcing permanent update by switching to UPDATE_ALWAYS

    viewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS

Default update mode for viewports is UPDATE_WHEN_VISIBLE. Try forcing permanent update by switching to UPDATE_ALWAYS

viewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS