You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

85 lines
2.7 KiB
C#

/******************************************************************************/
/*
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;
}
}
}