/******************************************************************************/ /* Project - MudBun Publisher - Long Bunny Labs http://LongBunnyLabs.com Author - Ming-Lun "Allen" Chou http://AllenChou.net */ /******************************************************************************/ using UnityEngine; namespace MudBun { public class TextureUtil { private static readonly int ThreadGroupSize = 32; public static Texture3D RenderTextureToTexture3D(Texture3D output, RenderTexture rt) { Vector3Int dimensions = new Vector3Int(rt.width, rt.height, rt.volumeDepth); var textureSlicer = ResourcesUtil.TextureSlicer; if (textureSlicer == null) return null; Texture2D[] slices = new Texture2D[dimensions.z]; textureSlicer.SetInt("resolution", dimensions.z); textureSlicer.SetTexture(0, "volumeTexture", rt); for (int layer = 0; layer < dimensions.z; ++layer) { var renderTexture = new RenderTexture(dimensions.x, dimensions.y, 0, RenderTextureFormat.RFloat); renderTexture.dimension = UnityEngine.Rendering.TextureDimension.Tex2D; renderTexture.enableRandomWrite = true; renderTexture.Create(); textureSlicer.SetTexture(0, "slice", renderTexture); textureSlicer.SetInt("layer", layer); textureSlicer.Dispatch(0, Mathf.CeilToInt(dimensions.x / (float) ThreadGroupSize), Mathf.CeilToInt(dimensions.y / (float)ThreadGroupSize), 1); slices[layer] = ConvertFromRenderTexture(renderTexture); } var tex = Tex3DFromTex2DArray(output, slices, dimensions); return tex; } private static Texture3D Tex3DFromTex2DArray(Texture3D output, Texture2D[] slices, Vector3Int dimensions) { if (output == null) output = new Texture3D(dimensions.x, dimensions.y, dimensions.z, TextureFormat.RFloat, false); output.filterMode = FilterMode.Trilinear; Color[] outputPixels = output.GetPixels(); for (int z = 0; z < dimensions.z; z++) { Color c = slices[z].GetPixel(0, 0); Color[] layerPixels = slices[z].GetPixels(); for (int x = 0; x < dimensions.x; x++) for (int y = 0; y < dimensions.y; y++) { outputPixels[x + dimensions.x * (y + z * dimensions.y)] = layerPixels[x + y * dimensions.x]; } } output.SetPixels(outputPixels); output.Apply(); return output; } private static Texture2D ConvertFromRenderTexture(RenderTexture rt) { Texture2D output = new Texture2D(rt.width, rt.height, TextureFormat.RFloat, false); RenderTexture.active = rt; output.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0); output.Apply(); return output; } } }