C# 从rendertexture(非主摄影机)截图,以精确匹配sprite(在3D空间中)-Unity

C# 从rendertexture(非主摄影机)截图,以精确匹配sprite(在3D空间中)-Unity,c#,unity3d,C#,Unity3d,如何调整或以其他方式设置屏幕截图,以获得3D空间中特定精灵的精确尺寸(因此,使用SpriteEnder的游戏对象) 渲染摄影机设置在精灵的正上方,但精灵边界外有一些空白空间。我不知道如何精确地调整rendercamera的视口 这是场景的样子。(实际上,这是我当前场景的一个快速简化版本,用来展示我的特定问题)是的,我正在尝试在运行时拍摄一个特定的屏幕截图。主摄影机处于任意角度,但渲染摄影机可以居中于精灵渲染器。换句话说,我正在拍摄的屏幕截图看起来就像下图右下角相机预览中的截图。如何裁剪(或调整视

如何调整或以其他方式设置屏幕截图,以获得3D空间中特定精灵的精确尺寸(因此,使用SpriteEnder的游戏对象)

渲染摄影机设置在精灵的正上方,但精灵边界外有一些空白空间。我不知道如何精确地调整rendercamera的视口

这是场景的样子。(实际上,这是我当前场景的一个快速简化版本,用来展示我的特定问题)是的,我正在尝试在运行时拍摄一个特定的屏幕截图。主摄影机处于任意角度,但渲染摄影机可以居中于精灵渲染器。换句话说,我正在拍摄的屏幕截图看起来就像下图右下角相机预览中的截图。如何裁剪(或调整视口以排除)超出精灵渲染器大小的额外部分

您可以在世界空间中调整平截头体的大小:

float frustumHeight = 2.0f * distance * Mathf.Tan(camera.fieldOfView * 0.5f * Mathf.Deg2Rad);
float frustrumWidth = frustumHeight * camera.aspect;
然后,如果你知道这幅画的高度和宽度(以世界单位表示),你就可以计算出它占据屏幕中心部分的大小:

float widthPortion = paintingWidth / frustrumWidth;
float heightPortion = paintingHeight / frustrumHeight;
然后您就知道要隐藏渲染器中心的多少部分:

float leftRightCrop = (1f-widthPortion)/2f;
float topBottomCrop = (1f-heightPortion)/2f;
因此,要从相机的渲染纹理复制它,可以在
OnPostRender
中执行此操作:

RenderTexture currentRT = RenderTexture.active;
RenderTexture.active = Cam.targetTexture;
 
Cam.Render();

int croppedPixelWidth = widthPortion*camera.pixelWidth;
int croppedPixelHeight = heightPortion*camera.pixelHeight;

int leftPixelPadding = leftRightCrop*camera.pixelWidth;
int bottomPixelPadding = topBottomCrop*camera.pixelHeight;

Texture2D cropped = new Texture2D(croppedPixelWidth, croppedPixelHeight);
cropped.ReadPixels(new Rect(
        leftPixelPadding, 
        bottomPixelPadding, 
        leftPixelPadding + croppedPixelWidth, 
        bottomPixelPadding + croppedPixelHeight), 0, 0);

cropped.Apply();

RenderTexture.active = currentRT;
或者像@ina使用的那样

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;

public class SpritePerfectScreenshot : MonoBehaviour
{

    bool ScreenshotIt;
    float widthPortion; float heightPortion;
    float leftRightCrop; float topBottomCrop;
    Camera camera;

    public void TakeScreencap(Camera c,float distance,float pw,float ph)
    {
        camera = c;c.enabled = true;

        SetItUp(distance, pw, ph);
    }

    void SetItUp(float distance,float paintingWidth,float paintingHeight)
    {
        float frustrumHeight = 2.0f * distance * Mathf.Tan(camera.fieldOfView * 0.5f * Mathf.Deg2Rad);
        float frustrumWidth = frustrumHeight * camera.aspect;

          widthPortion =  (paintingWidth / frustrumWidth);
          heightPortion = (paintingHeight / frustrumHeight);

          leftRightCrop =   (1f -  widthPortion) / 2f;
          topBottomCrop =  (1f -  heightPortion) / 2f;


        ScreenshotIt = true;
        print("SetItUp " + distance);
    }

    private void OnPostRender()
    {
        if (ScreenshotIt)
        {
            int croppedPixelWidth =(int) (widthPortion * camera.pixelWidth);
            int croppedPixelHeight =(int) (heightPortion * camera.pixelHeight);

            int leftPixelPadding =(int)( leftRightCrop * camera.pixelWidth);
            int bottomPixelPadding =(int)( topBottomCrop * camera.pixelHeight);

            print(croppedPixelWidth + " " + croppedPixelHeight);

            Texture2D cropped = new Texture2D(croppedPixelWidth, croppedPixelHeight);
            cropped.ReadPixels(new Rect(
        leftPixelPadding,
        bottomPixelPadding,
        leftPixelPadding + croppedPixelWidth,
        bottomPixelPadding + croppedPixelHeight), 0, 0);
            cropped.Apply();

            string uuid = UUID.GetUUID(); string localPath = Application.persistentDataPath + "/" + uuid + ".png";

#if !UNITY_EDITOR
            NativeGallery.SaveImageToGallery(cropped.EncodeToPNG(), "A Beautiful Letter",uuid);
#else
            File.WriteAllBytes(localPath,cropped.EncodeToPNG());
            print(localPath);
#endif 

            //TODO server (?)

            ScreenshotIt = false;camera.enabled = false;
        }
    }
}

将纹理调整到正确的大小会有帮助吗?一般来说,请添加您的代码,这样我们就可以重现这个问题。您可以用一些屏幕截图显示现在正在发生什么,以及您希望发生什么吗?@derHugo不一定,因为我正在尝试裁剪精灵本身。我试图在3D世界空间中拍摄一个屏幕截图,不过是从一个以精灵渲染器为中心的自上而下的相机拍摄的,而不是2D空间,更新了一些设置屏幕截图,这些设置屏幕截图可能会试图澄清这种多相机的情况。这是一个使相机
正交的选项吗?
?嗨!我认为问题可能是因为图像四元组可能没有正确的单位比例单位?实际上,我不确定是否在最终readpixel中正确实现了该区域….
Texture2D image=new Texture2D(camera.targetTexture.width,camera.targetTexture.height)`image.ReadPixels(新矩形(camera.pixelWidth*leftRightCrop*0.25f,camera.pixelHeight*topBottomCrop*0.25f,leftRightCrop*camera.pixelWidth,topBottomCrop*camera.pixelHeight),0,0)`@我编辑了我的答案,在底部包括了如何使用它。我还更改了
\uuuuu Crop
变量以使其更有用,因此请务必注意这些更改。