Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

RenderTexture 3D to Texture3D

Discussion in 'General Graphics' started by Cr4fter, Jul 9, 2020.

  1. Cr4fter

    Cr4fter

    Joined:
    Mar 2, 2017
    Posts:
    1
    Is it possible to Convert a Rendertexture with depth to a Texture3D? or Store the Rendertexture as a Texture3D.
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,238
    It should be possible, but it'll take a bit of extra work.

    Right now there's no way to read back a specific layer of a 3D render texture to the CPU. I've not tried, but I suspect if you tried to use
    ReadPixels
    on a render texture with volume depth, you'll always get the top slice. So instead you'll need to create a 2D render texture with the same width, height and format as the 3D one and use
    Graphics.CopyTexture()
    to copy a single layer at a time out. You can then use
    tex.ReadPixels()
    to read that 2D render texture into a
    Texture2D
    . You can then use
    GetPixels
    /
    SetPixels 
    or
    CopyTexture
    again to copy each slice from a
    Texture2D
    into a
    Texture3D
    .


    Also as an aside, you said "a render texture with depth". A render texture with depth isn't a 3D render texture, it's a render texture with a separate 2D depth buffer. To make a 3D render texture you need to create a render texture using a RenderTextureDescriptor with a
    TextureDimension.tex3D
    dimension
    and
    volumeDepth
    .
     
    Bovine and Nordjk like this.
  3. unity_LKgpBqmE7KPjcQ

    unity_LKgpBqmE7KPjcQ

    Joined:
    Dec 8, 2020
    Posts:
    1
    This worked for me.
     
    blenderfan1 likes this.
  4. JollyTheory

    JollyTheory

    Joined:
    Dec 30, 2018
    Posts:
    134
    Fastest way for even large (multiple GB) textures:
    Code (CSharp):
    1. void SaveRT3DToTexture3DAsset(RenderTexture rt3D, string pathWithoutAssetsAndExtension)
    2. {
    3.     int width = rt3D.width, height = rt3D.height, depth = rt3D.volumeDepth;
    4.     var a = new NativeArray<byte>(width * height * depth, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); //change if format is not 8 bits (i was using R8_UNorm) (create a struct with 4 bytes etc)
    5.     AsyncGPUReadback.RequestIntoNativeArray(ref a, rt3D, 0, (_) =>
    6.     {
    7.         Texture3D output = new Texture3D(width, height, depth, rt3D.graphicsFormat, TextureCreationFlags.None);
    8.         output.SetPixelData(a, 0);
    9.         output.Apply(updateMipmaps: false, makeNoLongerReadable: true);
    10.         AssetDatabase.CreateAsset(output, $"Assets/{pathWithoutAssetsAndExtension}.asset");
    11.         AssetDatabase.SaveAssetIfDirty(output);
    12.         a.Dispose();
    13.         rt3D.Release();
    14.     });
    15. }