Good day everyone,
this is my first post in the Unity Community forums and I hope it is respecting the rules I have absorbed so far.
I am open for all kinds of constructive advice. Since I am a beginner in Unity I do not know if this post
is in the correct section, please move it, if it is not.
Now, my endeavor is to take a screenshot which contains the depth information of a camera’s view.
Open questions:
Do I need a shader for that?
(My knowledge about shaders is very limited.)
According to the forum entry
I need a shader.
But as far as I understood the depth is a byproduct that can be accessed when the frame is rendered by a camera so why do I need a shader?
Do I get something fundamentally wrong?
(Especially with regards to my code.)
Why is the screenshot I take “blank”?
(See provided picture material.)
The following code snippet shows what I coded so far:
using System.Collections;
using System.IO;
using UnityEngine;
public class DepthTextureScreenShot : MonoBehaviour
{
public Camera camera;
public int captureWidth = 1920;
public int captureHeight = 1080;
public enum Format { RAW, JPG, PNG, PPM };
public Format format = Format.PNG;
public string folder;
private Rect rect;
private RenderTexture renderTexture;
private RenderTexture depthTexture;
private Texture2D depthScreenShot;
private int counter = 0; // image #
void LateUpdate()
{
if (Input.GetKeyDown("o"))
{
rect = new Rect(0, 0, captureWidth, captureHeight);
depthScreenShot = new Texture2D(captureWidth, captureHeight, TextureFormat.ARGB32, false);
renderTexture = new RenderTexture(captureWidth, captureHeight, 0);
depthTexture = new RenderTexture(captureWidth, captureHeight, 24, RenderTextureFormat.Depth);
RenderTexture.active = depthTexture;
Debug.Log(depthTexture.IsCreated());
camera.depthTextureMode = DepthTextureMode.Depth;
camera.SetTargetBuffers(depthTexture.colorBuffer, depthTexture.depthBuffer);
camera.targetTexture = depthTexture;
camera.Render();
depthScreenShot.ReadPixels(rect, 0, 0);
depthScreenShot.Apply();
string fileName = UniqueFilename((int)rect.width, (int)rect.height, "l");
WriteScreenShotToFile(depthScreenShot, fileName);
//cleaning up
camera.targetTexture = null;
RenderTexture.active = null;
Destroy(depthScreenShot);
}
}
void WriteScreenShotToFile(Texture2D screenShot, string filename)
{
// pull in our file header/data bytes for the specified image format (has to be done from main thread)
byte[] fileHeader = null;
byte[] fileData = null;
if (format == Format.RAW)
{
fileData = screenShot.GetRawTextureData();
}
else if (format == Format.PNG)
{
fileData = screenShot.EncodeToPNG();
}
else if (format == Format.JPG)
{
fileData = screenShot.EncodeToJPG();
}
else // ppm
{
// create a file header for ppm formatted file
string headerStr = string.Format("P6\n{0} {1}\n255\n", rect.width, rect.height);
fileHeader = System.Text.Encoding.ASCII.GetBytes(headerStr);
fileData = screenShot.GetRawTextureData();
}
new System.Threading.Thread(() =>
{
// create file and write optional header with image bytes
var f = System.IO.File.Create(filename);
if (fileHeader != null) f.Write(fileHeader, 0, fileHeader.Length);
f.Write(fileData, 0, fileData.Length);
f.Close();
Debug.Log(string.Format("Wrote screenshot {0} of size {1}", filename, fileData.Length));
}).Start();
}
private string UniqueFilename(int width, int height, string camPointOfView)
{
// if folder not specified by now use a good default
if (folder == null || folder.Length == 0)
{
folder = Application.dataPath;
if (Application.isEditor)
{
// put screenshots in folder above asset path so unity doesn't index the files
var stringPath = folder + "/..";
folder = Path.GetFullPath(stringPath);
}
folder += "/screenshots";
// make sure directory exists
System.IO.Directory.CreateDirectory(folder);
// count number of files of specified format in folder
string mask = string.Format("depth_{0}x{1}*.{2}", width, height, format.ToString().ToLower());
counter = Directory.GetFiles(folder, mask, SearchOption.TopDirectoryOnly).Length;
}
// use width, height, and counter for unique file name
var filename = string.Format("{0}/depth_{1}x{2}_{3}_{4}.{5}", folder, width, height, counter, camPointOfView, format.ToString().ToLower());
// up counter for next call
++counter;
// return unique filename
return filename;
}
}
Thank you for your time!
Kind regards
BL