您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

142 行
5.8 KiB

using System;
using UnityEngine;
using UnityEditor;
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
namespace UnityEditor.Experimental.Rendering
{
public class DensityVolumeTextureTool : EditorWindow
{
private Texture2D sourceTexture = null;
private string assetPath;
private string assetDirectory;
private int tileSize = 0;
private static GUIContent windowTitle = new GUIContent("Create Density Volume Texture");
private static GUIContent textureLabel = new GUIContent("Slice Texture");
private static GUIContent tileSizeLabel = new GUIContent("Texture Slice Size", "Dimensions of the created 3D Texture in pixels. Width, Height and Depth are all the same size");
private static GUIContent createLabel = new GUIContent("Create 3D Texture");
[MenuItem("Window/Rendering/Density Volume Texture Tool")]
static void Init()
{
DensityVolumeTextureTool window = (DensityVolumeTextureTool)EditorWindow.GetWindow(typeof(DensityVolumeTextureTool));
window.titleContent = windowTitle;
window.Show();
}
private bool IsTileSizeValid()
{
int textureWidth = sourceTexture.width;
int textureHeight = sourceTexture.height;
return (tileSize > 0 && (textureWidth * textureHeight >= (tileSize*tileSize*tileSize)));
}
void OnGUI()
{
EditorGUILayout.LabelField(textureLabel);
EditorGUI.indentLevel++;
sourceTexture = ( EditorGUILayout.ObjectField((UnityEngine.Object)sourceTexture, typeof(Texture2D), false, null) as Texture2D);
EditorGUI.indentLevel--;
tileSize = EditorGUILayout.IntField(tileSizeLabel, tileSize);
bool validData = (sourceTexture != null && IsTileSizeValid());
bool create = false;
if (!validData)
{
if (tileSize > 0)
{
EditorGUILayout.HelpBox(String.Format("Source Texture too small to generate a volume Texture of {0}x{0}x{0} size", tileSize), MessageType.Warning);
}
else
{
EditorGUILayout.HelpBox("Tile size must be larger than 0", MessageType.Warning);
}
}
using (new EditorGUI.DisabledScope(!validData))
{
create = GUILayout.Button(createLabel);
}
if (create)
{
assetPath = AssetDatabase.GetAssetPath(sourceTexture);
assetDirectory = System.IO.Directory.GetParent(assetPath).ToString();
//Check if the texture is set to read write.
//Only need to do this since CopyTexture is currently broken on D3D11
//So need to make sure there is a CPU copy ready to copy to the 3D Texture
//The fix for this is coming soon. Need to revist once it's in.
TextureImporter importer = TextureImporter.GetAtPath(assetPath) as TextureImporter;
if (importer && !importer.isReadable)
{
importer.isReadable = true;
importer.SaveAndReimport();
}
BuildVolumeTexture();
}
}
private void BuildVolumeTexture()
{
//Check if the object we want to create is already in the AssetDatabase
string volumeTextureAssetPath = assetDirectory + "/" + sourceTexture.name + "_Texture3D.asset";
bool createNewAsset = false;
Texture3D volumeTexture = AssetDatabase.LoadAssetAtPath(volumeTextureAssetPath, typeof(Texture3D)) as Texture3D;
//If we already have the asset then we are just updating it. make sure it's the right size.
if (!volumeTexture || volumeTexture.width != tileSize || volumeTexture.height != tileSize || volumeTexture.depth != tileSize)
{
volumeTexture = new Texture3D(tileSize, tileSize, tileSize, sourceTexture.format, false);
volumeTexture.filterMode = sourceTexture.filterMode;
volumeTexture.mipMapBias = 0;
volumeTexture.anisoLevel = 0;
volumeTexture.wrapMode = sourceTexture.wrapMode;
volumeTexture.wrapModeU = sourceTexture.wrapModeU;
volumeTexture.wrapModeV = sourceTexture.wrapModeV;
volumeTexture.wrapModeW = sourceTexture.wrapModeW;
createNewAsset = true;
}
//Only need to do this since CopyTexture is currently broken on D3D11
//Proper fix on it's way for 18.3 or 19.1
Color [] colorArray = new Color[0];
int yTiles = sourceTexture.height / tileSize;
int xTiles = sourceTexture.width / tileSize;
for (int i = yTiles - 1; i >= 0; i--)
{
for (int j = 0; j < xTiles; j++)
{
Color [] sourceTile = sourceTexture.GetPixels(j * tileSize, i * tileSize, tileSize, tileSize);
Array.Resize(ref colorArray, colorArray.Length + sourceTile.Length);
Array.Copy(sourceTile, 0, colorArray, colorArray.Length - sourceTile.Length, sourceTile.Length);
}
}
volumeTexture.SetPixels(colorArray);
volumeTexture.Apply();
if (createNewAsset)
{
AssetDatabase.CreateAsset(volumeTexture, volumeTextureAssetPath);
}
else
{
AssetDatabase.SaveAssets();
//Asset can be currently used by Density Volume Manager so trigger refresh
DensityVolumeManager.manager.TriggerVolumeAtlasRefresh();
}
}
}
}