Save Depth map as EXR

I found similar questions in the forum, but no answer seems to work.

I need to save the depth buffer in an image, in order to do that, I’m using a CaptureComponent2D with the Capture Source set as “SceneDepth in R” and this is the code I use:

IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
	static TSharedPtr<IImageWrapper> ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::EXR);
	ImageWrapper->SetRaw(Image.GetData(), Image.GetAllocatedSize(), Width, Height, ERGBFormat::GrayF, 32);
	TArray64<uint8> ImgData = ImageWrapper->GetCompressed(0);
FFileHelper::SaveArrayToFile(ImgData, *Filename);

I tried all combination of ERGBFormat and bitDepth, the only combo that doesn’t crash the editor is GrayF 32 or GrayF 16, but this results in an empty EXR file.

As a side note, with the same code, I am able to save FinalColor in RGB or DeviceDepth in RGB, with a different ERGBFormat clearly.

From what I can see, everybody is using a similar code, so I am not sure what I’m doing wrong or maybe I’m not interpreting the meaning of these settings in the right way.

Thanks

1 Like

I’ll post the code for future reference in case someone else needs it

void ACaptureCamera::SaveSnapshot(UTextureRenderTarget2D* renderTarget, FString fileName)
{
	FString path = FPaths::ConvertRelativePathToFull(FPaths::ProjectContentDir()) + "Snapshots/";
	SavePicture(renderTarget, path + fileName + ".EXR");
}

void ACaptureCamera::SavePicture(UTextureRenderTarget2D* RenderTarget, FString Filename)
{
	if (RenderTarget == nullptr) return;

	TArray<FLinearColor> RawPixels;
	FTextureRenderTargetResource* RenderTargetResource = RenderTarget->GameThread_GetRenderTargetResource();
	if (RenderTargetResource->ReadLinearColorPixels(RawPixels) == true)
	{
		TArray64<uint8> ImgData = RawPixelToPicture(RawPixels, RenderTarget->SizeX, RenderTarget->SizeY);
		FFileHelper::SaveArrayToFile(ImgData, *Filename);
	}
}

TArray64<uint8> ACaptureCamera::RawPixelToPicture(const TArray<FLinearColor>& RawPixels, int Width, int Height)
{
	if (RawPixels.Num() == 0 || RawPixels.Num() != Width * Height)
		return TArray64<uint8>();

	IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
	static TSharedPtr<IImageWrapper> ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::EXR);
	SIZE_T allocatedSize = RawPixels.GetAllocatedSize() * 8;
	ImageWrapper->SetRaw(RawPixels.GetData(), allocatedSize, Width, Height, ERGBFormat::RGBAF, 32);
	TArray64<uint8> ImgData = ImageWrapper->GetCompressed();
	return ImgData;
}
1 Like