UnityTexture2D.ReadPixels 无法从渲染纹理正确读取

问题描述 投票:0回答:1

基本上我想要一个可以在运行时截图到缩略图的功能。

这是我在 2022.3 年 URP

RenderPipelineManager.endCameraRendering
之后运行的代码:

    private void TakeScreenshot(int w, int h)
    {
        shouldTakeScreenshot = false;

        RenderTexture rt = RenderTexture.GetTemporary(w, h, 16, RenderTextureFormat.ARGB32);
        Camera.main.targetTexture = rt;

        Texture2D t = new Texture2D(rt.width, rt.height, TextureFormat.ARGB32, false);

        //RenderTexture.active = rt;
        //Graphics.CopyTexture(rt, t);
        t.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);

        RenderTexture.ReleaseTemporary(Camera.main.targetTexture);
        Camera.main.targetTexture = null;
        //RenderTexture.active = null;

        //t.Apply();
        //ri.texture = t;

        screenshotBytes = ImageConversion.EncodeToJPG(t, 25);
    }

我有一个完全有效的

TakeScreenshot()
来拍摄屏幕尺寸屏幕截图,代码与上面相同,没有所有注释。

主要问题是:

没有所有注释,它确实输出了我想要的大小,但它不是这样缩放的

enter image description here

它尝试不通过注释来释放 RenderTexture

        //RenderTexture.ReleaseTemporary(Camera.main.targetTexture);
        //Camera.main.targetTexture = null;

主摄像头中的渲染纹理似乎正确,我该怎么办?

enter image description here


我遇到的其他问题是:

我看了这么多解决方案,都有

RenderTexture.active = rt;
, 但一旦我取消注释,它只是一个黑屏,与
Graphics.CopyTexture(rt, t);
相同,但它是灰色的。

c# unity-game-engine rendering urp
1个回答
0
投票

据我所知,如果未将

RenderTexture
设置为活动状态,
ReadPixels
将直接从屏幕上读取。

您在检查器中观察到的结果实际上仅在代码完成后才渲染到帧末尾的临时渲染纹理中。

通常您需要以下额外步骤:

  • 强制相机渲染到渲染纹理中
  • 激活渲染纹理

所以像这样

private void TakeScreenshot(int w, int h)
{
    shouldTakeScreenshot = false;
    var previousRT = RenderTexture.active;

    var rt = RenderTexture.GetTemporary(w, h, 16, RenderTextureFormat.ARGB32);
    Camera.main.targetTexture = rt;
    RenderTexture.active = rt;

    // Required to actually fill the rt
    Camera.Render();

    var t = new Texture2D(w, h, TextureFormat.ARGB32, false);

    t.ReadPixels(new Rect(0, 0, w, h), 0, 0);
    RenderTexture.ReleaseTemporary(rt);
    Camera.main.targetTexture = null;
    RenderTexture.active = previousRT;

    t.Apply();

    screenshotBytes = ImageConversion.EncodeToJPG(t, 25);
}
© www.soinside.com 2019 - 2024. All rights reserved.