🎞

【Unity】深度画像を保存する

2021/08/11に公開

はじめに

深度画像を実装に利用したり,Game Viewに描画する方法はネット上に散見されるのですが,画像ファイルとして保存するのに苦労したので,その方法を共有したいと思います.

深度値を取得する

RenderTextureFormat.Depthは,深度値をRenderTextureにレンダリングするために使用されます.また,画像ファイルとして保存するため,カメラのレンダリング先をRenderTextureに変更します.以下に,深度値取得に必要なスクリプトを記載します.今回は,キャプチャ用のカメラをメインカメラとは別に用意することを想定しています.

CaptureCamera.depthTextureMode = DepthTextureMode.Depth;
CaptureCamera.targetTexture = new RenderTexture(width, height, 16, RenderTextureFormat.Depth);

画像ファイルとして保存する

深度バッファは直接アクセスできないため,Shaderを使ってReadPixelsでエンコードできる形に変換する必要があります.変換には,Graphics.Blitを利用します.保存用のソースコードは次のようになります.

private IEnumerator Depth_Capture(Texture2D tex, Camera camera)
{
    yield return new WaitForEndOfFrame();

    // RenderTexture.active = camera.targetTexture; // これは無理
    RenderTexture.active = new RenderTexture(tex.width, tex.height, 16);
    Graphics.Blit(camera.targetTexture, RenderTexture.active);

    tex.ReadPixels(new Rect(0, 0, camera.targetTexture.width, camera.targetTexture.height), 0, 0);
    tex.Apply();

    byte[] bytes = tex.EncodeToPNG();
    File.WriteAllBytes(@"capture\" + frame + ".png", bytes);

    yield break;
}

このコルーチンの使い方は,以前のブログに詳しく書いてます.

(おまけ)Shaderでポストエフェクト

Graphics.Blitでは,Shaderを使ってテクスチャにポストエフェクトをかけることもできます.

Graphics.Blit(camera.targetTexture, RenderTexture.active, material);

参考文献

Using Depth Textures
How to access rendered depth buffer properly?
【Unity】カメラのレンダリング対象の変更と、Blitによるレンダリングについて
【Unity】【シェーダ】カメラから見た深度を描画する

GitHubで編集を提案

Discussion