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

Unity:如何在执行Texture2D.ReadPixels前缩小Render Texture获取全画面截图

解决Unity Camera截图缩放后仅显示局部的问题

你的问题根源在于直接修改ReadPixels的读取尺寸时,只是从屏幕截取了对应大小的局部区域,而非对整个画面进行缩放。针对高频(30ms一次)低质量截图的需求,推荐两种高效的实现方式:

方法一:CPU端缩放Texture2D(适合简单场景)

先读取全屏画面,再通过GPU拷贝完成纹理缩放,完整保留整个视野:

public class CameraRenderToImage : MonoBehaviour
{
    // 目标截图尺寸,可按需调整
    public int targetWidth = 320;
    public int targetHeight = 240;
    private Texture2D fullScreenTex;
    private Texture2D scaledTex;

    void Start()
    {
        TimeStamp.SetStart();
        Camera.onPostRender += OnPostRenderCallback;
        // 提前创建纹理,避免频繁GC
        fullScreenTex = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
        scaledTex = new Texture2D(targetWidth, targetHeight, TextureFormat.RGB24, false);
    }
    
    void OnPostRenderCallback(Camera cam)
    {
        if (TimeStamp.HasMoreThanThisEllapsed(30))
        {
            TimeStamp.SetStart();

            // 读取全屏画面
            fullScreenTex.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
            fullScreenTex.Apply();

            // 缩放到目标尺寸(GPU层面拷贝,性能优于CPU缩放)
            scaledTex.Resize(targetWidth, targetHeight);
            Graphics.CopyTexture(fullScreenTex, scaledTex);
            scaledTex.Apply();

            // 保存缩放后的纹理
            byte[] bytes = scaledTex.EncodeToPNG();
            System.IO.File.WriteAllBytes("check_me_out.png", bytes);
            TimeStamp.Tok("Encode to PNG and Save");
        }
    }

    void OnDestroy()
    {
        Camera.onPostRender -= OnPostRenderCallback;
        // 销毁纹理释放资源
        Destroy(fullScreenTex);
        Destroy(scaledTex);
    }
}

方法二:GPU端通过RenderTexture下采样(性能更优,适合高频捕获)

让Camera直接渲染到小尺寸RenderTexture,由GPU完成画面缩放,避免CPU端额外开销,更适合30ms间隔的高频截图场景:

public class CameraRenderToImage : MonoBehaviour
{
    public int targetWidth = 320;
    public int targetHeight = 240;
    private RenderTexture renderTex;
    private Texture2D outputTex;

    void Start()
    {
        TimeStamp.SetStart();
        Camera.onPostRender += OnPostRenderCallback;
        
        // 创建小尺寸RenderTexture,设置过滤模式优化缩放效果
        renderTex = new RenderTexture(targetWidth, targetHeight, 24);
        renderTex.filterMode = FilterMode.Bilinear;
        
        outputTex = new Texture2D(targetWidth, targetHeight, TextureFormat.RGB24, false);
        // 将当前Camera的渲染目标切换为小尺寸RenderTexture
        GetComponent<Camera>().targetTexture = renderTex;
    }
    
    void OnPostRenderCallback(Camera cam)
    {
        if (TimeStamp.HasMoreThanThisEllapsed(30))
        {
            TimeStamp.SetStart();

            // 激活RenderTexture并读取像素
            RenderTexture.active = renderTex;
            outputTex.ReadPixels(new Rect(0, 0, targetWidth, targetHeight), 0, 0);
            outputTex.Apply();
            RenderTexture.active = null;

            // 保存处理后的纹理
            byte[] bytes = outputTex.EncodeToPNG();
            System.IO.File.WriteAllBytes("check_me_out.png", bytes);
            TimeStamp.Tok("Encode to PNG and Save");
        }
    }

    void OnDestroy()
    {
        Camera.onPostRender -= OnPostRenderCallback;
        // 恢复Camera默认渲染目标
        GetComponent<Camera>().targetTexture = null;
        Destroy(renderTex);
        Destroy(outputTex);
    }
}

关键提示

  • 优先选择方法二,GPU缩放性能远高于CPU操作,能有效降低高频截图带来的性能压力
  • 提前创建并复用纹理对象,避免每帧创建新纹理导致的GC抖动
  • 可通过调整FilterMode控制缩放质量:FilterMode.Point适合像素风格画面,FilterMode.Bilinear适合平滑过渡的场景

内容的提问来源于stack exchange,提问作者aarelovich

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 08:45:49