質問するログイン新規登録
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

635閲覧

[Unity] 深度画像の出力の方法 How to output depth image

taiki_inoue

総合スコア5

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2024/01/17 07:54

0

0

実現したいこと

点群データを集めるためのシミュレーション環境を作る目的で最近Unityを勉強し始めた者です.深度画像を手に入れたいと思っています

説明

現時点できていること
C#スクリプト(PassDepth.cs)でカメラからのRGB, depthの情報をそれぞれcolorBuffer, depthBufferに割り当ててcolorRenderTexture, depthRenderTextureの2つを作成しました.Quadを作成し,depthRenderTextureを用いたMaterialを用いて深度バッファが正しくdepthRenderTextureに読み込まれていることを確認しました.

解決したいこと
上記のように作成したdepthRenderTextureを深度画像としてPNGファイルで保存することを試みましたが,シーンビューのような画像は得られず真っ白な画像が保存されました.

おそらく深度がdepthRenderTextureに反映されていないと思ったがどのように改善すればよいのか分かりません.用いたソースコードとスクリーンショットを以下に載せます.解決の手助けをしてくだされば幸いです.

該当のソースコード

PassDepth.cs

1using System.Collections; 2using System.Collections.Generic; 3using System.IO; 4 5using UnityEngine; 6 7public class PassDepth : MonoBehaviour 8{ 9 [SerializeField] 10 public Camera camera; 11 [SerializeField] 12 public RenderTexture colorRenderTexture; 13 [SerializeField] 14 public RenderTexture depthRenderTexture; 15 16 // Start is called before the first frame update 17 void Start() 18 { 19 var colorBuffer = colorRenderTexture.colorBuffer; 20 var depthBuffer = depthRenderTexture.depthBuffer; 21 22 camera.SetTargetBuffers(colorBuffer, depthBuffer); 23 24 } 25 26 // Update is called once per frame 27 void Update() 28 { 29 Graphics.SetRenderTarget(colorRenderTexture); 30 camera.Render(); 31 } 32}

QuadにアッタチするMaterialを作成する際に用いたShader

MyUnlit.shader

1Shader "Unlit/MyUnlit" 2{ 3 Properties 4 { 5 _MainTex ("Texture", 2D) = "white" {} 6 } 7 SubShader 8 { 9 Tags { "RenderType"="Opaque" } 10 LOD 100 11 12 Pass 13 { 14 CGPROGRAM 15 #pragma vertex vert 16 #pragma fragment frag 17 18 #include "UnityCG.cginc" 19 20 struct appdata 21 { 22 float4 vertex : POSITION; 23 float2 uv : TEXCOORD0; 24 }; 25 26 struct v2f 27 { 28 float2 uv : TEXCOORD0; 29 float4 vertex : SV_POSITION; 30 }; 31 32 sampler2D _MainTex; 33 float4 _MainTex_ST; 34 35 v2f vert (appdata v) 36 { 37 v2f o; 38 o.vertex = UnityObjectToClipPos(v.vertex); 39 o.uv = TRANSFORM_TEX(v.uv, _MainTex); 40 41 return o; 42 } 43 44 fixed4 frag (v2f i) : SV_Target 45 { 46 // sample the texture 47 fixed4 col = tex2D(_MainTex, i.uv); 48 col.g = col.r; 49 col.b = col.r; 50 51 return col; 52 } 53 ENDCG 54 } 55 } 56} 57

深度をPNG保存する際に試みたソースコード

Texture2D tex = new Texture2D(RenderTextureRef.width, RenderTextureRef.height, TextureFormat.RGB24, false); RenderTexture.active = RenderTextureRef; tex.ReadPixels(new Rect(0, 0, RenderTextureRef.width, RenderTextureRef.height), 0, 0); tex.Apply(); //RenderTexture.active = null; // Encode texture into PNG byte[] bytes = tex.EncodeToPNG(); Object.Destroy(tex); //Write to a file in the project folder File.WriteAllBytes(Application.dataPath + "/../DepthRenderTexture.png", bytes);

私のUnity画面のスクリーンショット

イメージ説明
イメージ説明

保存された画像

イメージ説明

長文となってしまい申し訳ありません.Unity初心者なのでささいなアドバイスでもありがたいです.よろしくお願いいたします.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

How to get pixel value of depth Texture from script ? - Questions & Answers - Unity Discussions」で言及されているように、デプスバッファをいったん別のカラーバッファ上にレンダリングしなおしてやる必要がありそうですね。
レンダリング用のシェーダーは、ご質問者さんのUnlit/MyUnlitをそのまま流用できそうです。下記のようなコードならいかがでしょうか。

C#

1 Texture2D tex = new Texture2D(RenderTextureRef.width, RenderTextureRef.height, TextureFormat.RGB24, false); 2 3 // 現在のレンダーターゲットを覚えておく 4 RenderTexture currentTarget = RenderTexture.active; 5 6 // texと同サイズのRenderTextureを用意する 7 RenderTexture depthTexture = RenderTexture.GetTemporary(RenderTextureRef.width, RenderTextureRef.height); 8 9 // 深度をカラーバッファ上にレンダリングするためのマテリアルを作る 10 Material blitMaterial = new Material(Shader.Find("Unlit/MyUnlit")); 11 12 // RenderTextureRefをdepthTexture上にレンダリングする 13 Graphics.Blit(RenderTextureRef, depthTexture, blitMaterial); 14 15 // Blitによって現在のレンダーターゲットはdepthTextureに切り替わっているので、その内容をtexに読み取る 16 tex.ReadPixels(new Rect(0, 0, RenderTextureRef.width, RenderTextureRef.height), 0, 0); 17 tex.Apply(); 18 19 // レンダーターゲットを元に戻す 20 RenderTexture.active = currentTarget; 21 22 // depthTexture、blitMaterialはもう不要なので削除する 23 RenderTexture.ReleaseTemporary(depthTexture); 24 Object.Destroy(blitMaterial); 25 26 // Encode texture into PNG 27 byte[] bytes = tex.EncodeToPNG(); 28 Object.Destroy(tex); 29 30 //Write to a file in the project folder 31 File.WriteAllBytes(Application.dataPath + "/../DepthRenderTexture.png", bytes);

投稿2024/01/18 20:47

Bongo

総合スコア10816

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

taiki_inoue

2024/01/19 00:17

ありがとうございます!試してみたところ深度画像を入手することができました.本当にありがとうございます.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問