如何在Godot 3.5中拍摄视口外区域的像素完美截图?
Godot 3.5 基于ReferenceRect的像素完美截图实现方案
核心思路
要实现像素完美截图,关键是让渲染区域与目标截图区域1:1对应。要么临时调整主窗口/相机适配ReferenceRect的区域,要么用独立Viewport单独渲染指定区域,两种方案都能满足开发阶段的需求。
方案一:开发阶段临时调整主窗口(简易快速)
适合快速测试,直接通过调整主窗口大小和相机位置,让视口完全覆盖ReferenceRect的区域后截图。
实现步骤
- 获取ReferenceRect的全局区域(转换为根节点坐标系下的位置和尺寸)
- 重置相机缩放为1(保证像素1:1映射),并移动相机到区域中心
- 调整主窗口尺寸匹配ReferenceRect的大小
- 延迟一帧等待窗口/相机更新,然后截图
- 可选:截图后恢复原窗口和相机参数
代码示例
func _on_screenshot_btn_pressed(): # 替换为你的ReferenceRect节点路径 var ref_rect = $ReferenceRect # 获取ReferenceRect在全局坐标系下的区域 var target_rect = ref_rect.get_global_rect() # 保存原窗口大小和相机参数(可选,用于恢复) var original_window_size = OS.window_size var original_camera_pos = $Camera2D.position var original_camera_zoom = $Camera2D.zoom # 配置相机为像素完美模式 var camera = $Camera2D camera.zoom = Vector2(1, 1) camera.position = target_rect.position + target_rect.size / 2 # 调整窗口尺寸匹配目标区域 OS.window_size = target_rect.size # 等待一帧让系统完成窗口和相机调整 yield(Engine.get_main_loop(), "idle_frame") # 截取当前视口并保存 var screenshot = get_viewport().get_texture().get_data() screenshot.save_png("res://screenshots/" + str(OS.get_ticks_msec()) + ".png") # 恢复原窗口和相机参数(可选) OS.window_size = original_window_size camera.position = original_camera_pos camera.zoom = original_camera_zoom
方案二:用独立Viewport渲染(不影响主窗口)
更稳妥的方案,无需修改主窗口,通过临时创建Viewport单独渲染目标区域,适合需要保留主窗口状态的场景。
实现步骤
- 创建临时Viewport,设置尺寸与ReferenceRect一致
- 复制主相机参数到Viewport的相机,调整相机位置到区域中心
- 让Viewport完成一次渲染后,从其纹理中提取截图
- 清理临时节点
代码示例
func _on_screenshot_btn_pressed(): var ref_rect = $ReferenceRect var target_rect = ref_rect.get_global_rect() # 创建临时Viewport var render_viewport = Viewport.new() render_viewport.size = target_rect.size render_viewport.render_target_v_flip = true # 修正Y轴翻转问题 render_viewport.render_target_update_mode = Viewport.UPDATE_ONCE # 仅渲染一次 get_tree().get_root().add_child(render_viewport) # 复制主相机到Viewport(或直接创建新相机) var camera = $Camera2D.duplicate() camera.zoom = Vector2(1, 1) camera.position = target_rect.position + target_rect.size / 2 render_viewport.add_child(camera) # 等待Viewport完成渲染 yield(Engine.get_main_loop(), "idle_frame") # 获取并保存截图 var screenshot = render_viewport.get_texture().get_data() screenshot.save_png("res://screenshots/" + str(OS.get_ticks_msec()) + ".png") # 清理临时节点 render_viewport.queue_free()
注意事项
- 确保ReferenceRect的尺寸为整数像素,可开启编辑器的网格对齐功能辅助调整,避免小数导致的模糊
- 相机缩放必须设为
Vector2(1,1),否则会破坏像素1:1的映射关系 - 优先保存为PNG格式,避免压缩导致的画质损失
内容的提问来源于stack exchange,提问作者cak3_lover
相关产品推荐
相关产品推荐

