8th Wall XR для Unity: сохранение RealityTexture на диск
Я пытаюсь сохранить канал камеры в 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);
}
При тестировании на Android без ArCore я получаю черные изображения (со случайными цветными пикселями) с правильным размером 480 x 640 пикселей. С ArCore это черное изображение размером 0 КБ.
1 ответ
Создание изображения из этих текстур напрямую не работает, так как эти данные передаются через XRCameraYUVShader
а также XRARCoreCamera
прежде чем действительное изображение может быть предоставлено.
Одним из вариантов является создание пользовательской версии 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);
}
куда xrMat
материал, используемый для рендеринга камеры.
Это даст изображение с камеры без каких-либо игровых объектов Unity. Если вы хотите, чтобы игровые объекты отображались на сохраненном изображении, вы можете переопределить OnRenderImage
чтобы достичь этого:
void OnRenderImage(RenderTexture src, RenderTexture dest) {
if (shouldSaveImageFrame) {
SaveTextureAsPNG(src, Application.persistentDataPath + "/_rgbatexture.png");
shouldSaveImageFrame = false;
}
Graphics.Blit (src, dest);
}
куда shouldSaveImageFrame
это флаг, который вы установили в другом месте, чтобы предотвратить сохранение изображения в каждом кадре.