Unity3d Unity的第八面墙XR:将RealityTexture保存到磁盘

Unity3d Unity的第八面墙XR:将RealityTexture保存到磁盘,unity3d,8thwall-xr,Unity3d,8thwall Xr,我试图使用以下代码将相机的提要保存到png,但它似乎无法正常工作: void RecordAndSaveFrameTexture() { if (mXr.ShouldUseRealityRGBATexture()) { SaveTextureAsPNG(mXr.GetRealityRGBATexture(), mTakeDirInfo.FullName + "/texture_" + mFrameInfo.mFrameCount.ToString() + ".pn

我试图使用以下代码将相机的提要保存到png,但它似乎无法正常工作:

void RecordAndSaveFrameTexture()
{
    if (mXr.ShouldUseRealityRGBATexture())
    {
        SaveTextureAsPNG(mXr.GetRealityRGBATexture(), mTakeDirInfo.FullName + "/texture_" + mFrameInfo.mFrameCount.ToString() + ".png");
    }
    else
    {
        SaveTextureAsPNG(mXr.GetRealityYTexture(), mTakeDirInfo.FullName + "/texture_y_" + mFrameInfo.mFrameCount.ToString() + ".png");
        SaveTextureAsPNG(mXr.GetRealityUVTexture(), mTakeDirInfo.FullName + "/texture_uv_" + mFrameInfo.mFrameCount.ToString() + ".png");
    }

}

public static void SaveTextureAsPNG(Texture2D aTexture, string aFullPath)
{
    byte[] bytes = aTexture.EncodeToPNG();
    System.IO.File.WriteAllBytes(aFullPath, bytes);
    Debug.Log("Image with Instance ID:" + aTexture.GetInstanceID() + "with dims of " + aTexture.width.ToString() + " px X " + aTexture.height + " px " + " with size of" + bytes.Length / 1024 + "Kb was saved as: " + aFullPath);
}

在非ArCore android上测试时,我得到了正确大小为480 x 640像素的黑色图像(带有随机彩色像素)。对于ArCore,它是一个0 KB的黑色图像。

直接从这些纹理创建图像无法正常工作,因为在渲染有效图像之前,该数据会通过
XRCameraYUVShader
XRACoreCamera
传递

一个选项是创建自定义版本的
XRVideoController
,它提供了对用于渲染摄影机提要的材质的访问。从那里,您的代码可以修改为:

void RecordAndSaveFrameTexture() {
  Texture2D src = xr.ShouldUseRealityRGBATexture()
      ? xr.GetRealityRGBATexture()
      : xr.GetRealityYTexture();

  RenderTexture renderTexture = new RenderTexture (src.width, src.height, 0, RenderTextureFormat.ARGB32);
  Graphics.Blit (null, renderTexture, xrMat);
  SaveTextureAsPNG(renderTexture, Application.persistentDataPath + "/texture.png");
}

public static void SaveTextureAsPNG(RenderTexture renderTexture, string aFullPath) {
  Texture2D aTexture = new Texture2D(renderTexture.width, renderTexture.height, TextureFormat.RGBA32, false);
  RenderTexture.active = renderTexture;
  aTexture.ReadPixels(new Rect(0, 0, aTexture.width, aTexture.height), 0, 0);
  RenderTexture.active = null;

  byte[] bytes = aTexture.EncodeToPNG();
  System.IO.File.WriteAllBytes(aFullPath, bytes);
}
其中
xrat
是用于渲染摄影机提要的材质

这将提供一个没有任何Unity游戏对象的相机图像。如果希望在保存的图像中显示游戏对象,可以覆盖
OnRenderImage
,以实现此目的:

void OnRenderImage(RenderTexture src, RenderTexture dest) {
    if (shouldSaveImageFrame) {
      SaveTextureAsPNG(src, Application.persistentDataPath + "/_rgbatexture.png");
      shouldSaveImageFrame = false;
    }
    Graphics.Blit (src, dest);
}

其中,
shouldSaveImageFrame
是您在其他地方设置的标志,用于防止在每一帧上保存图像。

谢谢,该方法非常有效。我在我的XrVideoController中添加了以下代码:
公共材料GetMaterial(){return xrat;}
并使用getter将材料带到我自己的脚本中,其中包含了您建议的代码