You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Godot 3.5中拍摄视口外区域的像素完美截图?

Godot 3.5 基于ReferenceRect的像素完美截图实现方案

核心思路

要实现像素完美截图,关键是让渲染区域与目标截图区域1:1对应。要么临时调整主窗口/相机适配ReferenceRect的区域,要么用独立Viewport单独渲染指定区域,两种方案都能满足开发阶段的需求。


方案一:开发阶段临时调整主窗口(简易快速)

适合快速测试,直接通过调整主窗口大小和相机位置,让视口完全覆盖ReferenceRect的区域后截图。

实现步骤

  1. 获取ReferenceRect的全局区域(转换为根节点坐标系下的位置和尺寸)
  2. 重置相机缩放为1(保证像素1:1映射),并移动相机到区域中心
  3. 调整主窗口尺寸匹配ReferenceRect的大小
  4. 延迟一帧等待窗口/相机更新,然后截图
  5. 可选:截图后恢复原窗口和相机参数

代码示例

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单独渲染目标区域,适合需要保留主窗口状态的场景。

实现步骤

  1. 创建临时Viewport,设置尺寸与ReferenceRect一致
  2. 复制主相机参数到Viewport的相机,调整相机位置到区域中心
  3. 让Viewport完成一次渲染后,从其纹理中提取截图
  4. 清理临时节点

代码示例

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 06:55:09