您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
141 行
5.8 KiB
141 行
5.8 KiB
using System;
|
|
using UnityEngine;
|
|
using UnityEditor;
|
|
using UnityEngine.Rendering;
|
|
using UnityEngine.Experimental.Rendering.HDPipeline;
|
|
|
|
namespace UnityEditor.Experimental.Rendering {
|
|
|
|
public class VolumeTextureTool : EditorWindow
|
|
{
|
|
private Texture2D sourceTexture = null;
|
|
private string assetPath;
|
|
private string assetDirectory;
|
|
|
|
private int tileSize = 0;
|
|
|
|
private static GUIContent windowTitle = new GUIContent("Create 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("Tools/HDRP Volumetric System/Create Volume Texture")]
|
|
static void Init()
|
|
{
|
|
VolumeTextureTool window = (VolumeTextureTool)EditorWindow.GetWindow(typeof(VolumeTextureTool));
|
|
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, null);
|
|
EditorGUI.indentLevel++;
|
|
sourceTexture = ( EditorGUILayout.ObjectField((UnityEngine.Object)sourceTexture, typeof(Texture2D), false, null) as Texture2D);
|
|
EditorGUI.indentLevel--;
|
|
tileSize = EditorGUILayout.IntField(tileSizeLabel, tileSize, null);
|
|
|
|
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, null);
|
|
}
|
|
|
|
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();
|
|
}
|
|
}
|
|
}
|
|
}
|