res-avatar-unity/Assets/RalivDynamicPenetrationSystem/Plugins/Xiexes-Unity-Shaders-development/Editor/XSTextureMerger.cs

240 lines
6.5 KiB
C#
Raw Permalink Normal View History

2023-07-16 02:51:23 +00:00
//Script created by Merlin and Xiexe.
using System.Collections;
using System.IO;
using UnityEditor;
using UnityEngine;
namespace XSToonDynamicPenetration {
public class XSTextureMerger : EditorWindow {
private enum resolutions {
Tiny_256x256,
Small_512x512,
Medium_1024x1024,
Large_2048x2048,
VeryLarge_4096x4096,
Why_8192x8192
}
private enum EChannels {
None,
Red,
Green,
Blue,
Alpha
}
private enum ETextures {
None,
Tex1,
Tex2,
Tex3,
Tex4
}
private Texture2D[] textures = new Texture2D[4];
private EChannels[] texChannels = new EChannels[4];
private ETextures[] pickTexture = new ETextures[4];
private bool[] invertChannel = new bool[4];
private static int srcTex;
private resolutions res;
private Vector2 scrollPos;
private static int resolution;
private static string finalFilePath;
private static Color outColor;
private static Color[] texColors = new Color[4];
private static float progress;
[MenuItem("Tools/Xiexe/XSToon/Texture Merger")]
static public void Init() {
XSTextureMerger window = EditorWindow.GetWindow<XSTextureMerger>(false, "XSToon: Texture Merger", true);
window.minSize = new Vector2(500, 300);
window.maxSize = new Vector2(500, 500);
}
public void OnGUI() {
scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
GUILayout.BeginHorizontal();
GUILayout.Space(105);
XSStyles.doLabel("1");
GUILayout.Space(105);
XSStyles.doLabel("2");
GUILayout.Space(105);
XSStyles.doLabel("3");
GUILayout.Space(105);
XSStyles.doLabel("4");
GUILayout.EndHorizontal();
XSStyles.SeparatorThin();
GUILayout.BeginHorizontal();
for (int i = 0; i < 4; i++) {
EditorGUIUtility.labelWidth = 0.01f;
textures[i] = (Texture2D) EditorGUILayout.ObjectField(new GUIContent("", ""), textures[i], typeof(Texture2D), true);
}
GUILayout.EndHorizontal();
float oldLabelWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = 40;
GUIStyle headerStyle = EditorStyles.boldLabel;
headerStyle.alignment = TextAnchor.UpperLeft;
headerStyle.fontStyle = FontStyle.Bold;
headerStyle.stretchWidth = true;
XSStyles.SeparatorThin();
EditorGUILayout.BeginHorizontal();
GUILayout.Label("Output Channel:", headerStyle);
GUILayout.Label("R", headerStyle);
GUILayout.Label("G", headerStyle);
GUILayout.Label("B", headerStyle);
GUILayout.Label("A", headerStyle);
EditorGUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("Src Texture:");
GUILayout.Space(20);
for (int i = 0; i < 4; i++) {
pickTexture[i] = (ETextures) EditorGUILayout.EnumPopup("", pickTexture[i]);
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("Src Channel:");
GUILayout.Space(17);
for (int i = 0; i < 4; i++) {
texChannels[i] = (EChannels) EditorGUILayout.EnumPopup("", texChannels[i]);
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("Invert Channel:");
for (int i = 0; i < 4; i++) {
invertChannel[i] = EditorGUILayout.Toggle("", invertChannel[i]);
}
GUILayout.EndHorizontal();
GUILayout.Space(20);
EditorGUILayout.EndScrollView();
//Button and Resolution
GUILayout.BeginVertical();
XSStyles.doLabel("Resolution");
GUILayout.BeginHorizontal();
GUILayout.Space(175);
res = (resolutions) EditorGUILayout.EnumPopup("", res);
GUILayout.Space(175);
GUILayout.EndHorizontal();
if (GUILayout.Button("Merge Channels")) {
if (progress < 2) {
EditorUtility.DisplayProgressBar("XSToon Texture Merger", "Merging and compressing new texture...", (float) (progress / 2));
}
//Set target textures to be ReadWriteable
for (int i = 0; i < textures.Length; i++) {
if (textures[i] == null)
break;
string texturePath = AssetDatabase.GetAssetPath(textures[i]);
TextureImporter texture = (TextureImporter) TextureImporter.GetAtPath(texturePath);
if (texture != null) {
texture.isReadable = true;
texture.SaveAndReimport();
}
}
switch (res) {
case resolutions.Tiny_256x256:
resolution = 256;
break;
case resolutions.Small_512x512:
resolution = 512;
break;
case resolutions.Medium_1024x1024:
resolution = 1024;
break;
case resolutions.Large_2048x2048:
resolution = 2048;
break;
case resolutions.VeryLarge_4096x4096:
resolution = 4096;
break;
case resolutions.Why_8192x8192:
resolution = 8192;
break;
}
XSStyles.findAssetPath(finalFilePath);
finalFilePath = EditorUtility.SaveFilePanel("Save Merged Texture", finalFilePath + "/Textures/", "mergedTex.png", "png");
Texture2D newTexture = new Texture2D(resolution, resolution, TextureFormat.RGBA32, false);
//Get Colors textures and write them to the proper channel
for (int y = 0; y < resolution; y++) {
for (int x = 0; x < resolution; x++) {
float u = x / (float) resolution;
float v = y / (float) resolution;
// Grab out the texture values into an array for later lookup. Could probably just be done at the moment the texture color is needed.
for (int i = 0; i < textures.Length; i++) {
if (textures[i] != null) {
texColors[i] = textures[i].GetPixelBilinear(u, v);
} else {
texColors[i] = new Color(0, 0, 0, 1);
}
}
Color outputColor = new Color(0, 0, 0, 1);
// Iterate the output RGBA channels
for (int i = 0; i < 4; i++) {
// Convert the enums to indices we can use. 'None' will turn into -1 which will be discarded as invalid.
int srcTexIdx = ((int) pickTexture[i]) - 1;
int srcChannelIdx = ((int) texChannels[i]) - 1;
// Go through each channel in the output color and assign it
if (srcTexIdx >= 0 && srcChannelIdx >= 0) {
outputColor[i] = texColors[srcTexIdx][srcChannelIdx];
//Allow you to invert specific channels.
if (invertChannel[i]) {
outputColor[i] = 1f - outputColor[i];
}
}
}
newTexture.SetPixel(x, y, outputColor);
}
}
progress += 1;
newTexture.Apply();
ExportTexture(newTexture);
}
GUILayout.Space(10);
GUILayout.EndVertical();
EditorGUIUtility.labelWidth = oldLabelWidth;
}
private static void ExportTexture(Texture2D newTexture) {
var pngData = newTexture.EncodeToPNG();
if (pngData != null) {
File.WriteAllBytes(finalFilePath, pngData);
AssetDatabase.Refresh();
}
progress += 1;
EditorUtility.ClearProgressBar();
}
}
}