228 lines
8.7 KiB
C#
228 lines
8.7 KiB
C#
using System.IO;
|
||
using UnityEditor;
|
||
using UnityEngine;
|
||
|
||
[CustomEditor(typeof(T4MSwap))]
|
||
public class T4MSwapEditor : Editor
|
||
{
|
||
private Shader _t4MNormalShader;
|
||
private Shader _t4MShader;
|
||
private T4MSwap _target;
|
||
|
||
private void OnEnable()
|
||
{
|
||
_target = (T4MSwap) target;
|
||
_t4MShader = Shader.Find("Zhanyou/Scene/T4M 4 Textures");
|
||
_t4MNormalShader = Shader.Find("Zhanyou/Scene/T4M 4 Textures Bump");
|
||
}
|
||
|
||
public override void OnInspectorGUI()
|
||
{
|
||
base.OnInspectorGUI();
|
||
if (GUILayout.Button("Fix Channel"))
|
||
{
|
||
var channelTex = GetChannelTexture();
|
||
if (channelTex != null)
|
||
{
|
||
var temp = new Texture2D(channelTex.width, channelTex.height, TextureFormat.ARGB32, false);
|
||
for (var i = 0; i < channelTex.width; i++)
|
||
for (var j = 0; j < channelTex.height; j++)
|
||
{
|
||
var color = channelTex.GetPixel(i, j);
|
||
var r = Mathf.Clamp01(color.r);
|
||
var g = Mathf.Clamp01(color.g);
|
||
var b = Mathf.Clamp01(color.b);
|
||
var a = Mathf.Clamp01(color.a);
|
||
var total = r + g + b + a;
|
||
if (total > 0)
|
||
{
|
||
var modifier = 1f / total;
|
||
color = new Color(r, g, b, a) * modifier;
|
||
}
|
||
else
|
||
{
|
||
color.r = color.g = color.b = color.a = 0.25f;
|
||
}
|
||
|
||
temp.SetPixel(i, j, color);
|
||
}
|
||
|
||
temp.Apply();
|
||
SaveTexture(temp, channelTex);
|
||
}
|
||
}
|
||
|
||
GUILayout.Space(5f);
|
||
if (GUILayout.Button("Execute"))
|
||
{
|
||
if (_target.source != _target.target &&
|
||
ValidChannel(_target.source) &&
|
||
ValidChannel(_target.target))
|
||
{
|
||
var channelTex = GetChannelTexture();
|
||
if (channelTex != null)
|
||
{
|
||
var material = _target.targetMaterial;
|
||
var sourceChannel = _target.source - 1;
|
||
var targetChannel = _target.target - 1;
|
||
var sourceName = GetColorTexName(sourceChannel);
|
||
var targetName = GetColorTexName(targetChannel);
|
||
var sourceTex = material.GetTexture(sourceName);
|
||
var targetTex = material.GetTexture(targetName);
|
||
var sourceScale = material.GetTextureScale(sourceName);
|
||
var targetScale = material.GetTextureScale(targetName);
|
||
var sourceOffset = material.GetTextureOffset(sourceName);
|
||
var targetOffset = material.GetTextureOffset(targetName);
|
||
material.SetTexture(sourceName, targetTex);
|
||
material.SetTexture(targetName, sourceTex);
|
||
material.SetTextureScale(sourceName, targetScale);
|
||
material.SetTextureScale(targetName, sourceScale);
|
||
material.SetTextureOffset(sourceName, targetOffset);
|
||
material.SetTextureOffset(targetName, sourceOffset);
|
||
if (material.shader == _t4MNormalShader)
|
||
{
|
||
sourceName = GetNormalTexName(sourceChannel);
|
||
targetName = GetNormalTexName(targetChannel);
|
||
sourceTex = material.GetTexture(sourceName);
|
||
targetTex = material.GetTexture(targetName);
|
||
material.SetTexture(sourceName, targetTex);
|
||
material.SetTexture(targetName, sourceTex);
|
||
const string bumpVectorName = "_BumpVector";
|
||
const string glossName = "_Gloss";
|
||
var bumpStrength = material.GetColor(bumpVectorName);
|
||
var gloss = material.GetColor(glossName);
|
||
var sourceBump = GetChannelColor(bumpStrength, sourceChannel);
|
||
var targetBump = GetChannelColor(bumpStrength, targetChannel);
|
||
var sourceGloss = GetChannelColor(gloss, sourceChannel);
|
||
var targetGloss = GetChannelColor(gloss, targetChannel);
|
||
SetChannelColor(ref bumpStrength, sourceChannel, targetBump);
|
||
SetChannelColor(ref bumpStrength, targetChannel, sourceBump);
|
||
SetChannelColor(ref gloss, sourceChannel, targetGloss);
|
||
SetChannelColor(ref gloss, targetChannel, sourceGloss);
|
||
material.SetColor(bumpVectorName, bumpStrength);
|
||
material.SetColor(glossName, gloss);
|
||
}
|
||
|
||
var temp = new Texture2D(channelTex.width, channelTex.height, TextureFormat.ARGB32, false);
|
||
for (var i = 0; i < channelTex.width; i++)
|
||
for (var j = 0; j < channelTex.height; j++)
|
||
{
|
||
var color = channelTex.GetPixel(i, j);
|
||
var sourcePixel = GetChannelColor(color, sourceChannel);
|
||
var targetPixel = GetChannelColor(color, targetChannel);
|
||
SetChannelColor(ref color, targetChannel, sourcePixel);
|
||
SetChannelColor(ref color, sourceChannel, targetPixel);
|
||
temp.SetPixel(i, j, color);
|
||
}
|
||
|
||
temp.Apply();
|
||
SaveTexture(temp, channelTex);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError("通道设定错误");
|
||
}
|
||
}
|
||
}
|
||
|
||
private Texture2D GetChannelTexture()
|
||
{
|
||
Texture2D result = null;
|
||
var material = _target.targetMaterial;
|
||
if (material != null)
|
||
if (material.shader == _t4MShader || material.shader == _t4MNormalShader)
|
||
{
|
||
var channelTex = _target.targetMaterial.GetTexture("_Control") as Texture2D;
|
||
if (channelTex != null)
|
||
{
|
||
// 强制替换文件编码格式为ARGB32,防止异常
|
||
var assetPath = AssetDatabase.GetAssetPath(channelTex);
|
||
var importer = AssetImporter.GetAtPath(assetPath) as TextureImporter;
|
||
if (importer == null)
|
||
{
|
||
Debug.LogError(string.Format("无法获得贴图{0}的TextureImporter!", assetPath));
|
||
}
|
||
else
|
||
{
|
||
// 暂时没有必要使用GetPlatformTextureSettings
|
||
importer.textureFormat = TextureImporterFormat.ARGB32;
|
||
importer.textureCompression = TextureImporterCompression.Uncompressed;
|
||
importer.SaveAndReimport();
|
||
result = channelTex;
|
||
}
|
||
}
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
private void SaveTexture(Texture2D temp, Texture2D channelTex)
|
||
{
|
||
var assetPath = AssetDatabase.GetAssetPath(channelTex);
|
||
assetPath = Application.dataPath + Path.DirectorySeparatorChar +
|
||
assetPath.Substring("Assets/".Length);
|
||
var bytes = temp.EncodeToPNG();
|
||
DestroyImmediate(temp);
|
||
File.WriteAllBytes(assetPath, bytes);
|
||
EditorUtility.SetDirty(_target.targetMaterial);
|
||
AssetDatabase.SaveAssets();
|
||
AssetDatabase.Refresh();
|
||
}
|
||
|
||
private bool ValidChannel(int channel)
|
||
{
|
||
return channel > 0 && channel < 5;
|
||
}
|
||
|
||
private float GetChannelColor(Color color, int channel)
|
||
{
|
||
var result = 0f;
|
||
switch (channel)
|
||
{
|
||
case 0:
|
||
result = color.r;
|
||
break;
|
||
case 1:
|
||
result = color.g;
|
||
break;
|
||
case 2:
|
||
result = color.b;
|
||
break;
|
||
case 3:
|
||
result = color.a;
|
||
break;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
private void SetChannelColor(ref Color color, int channel, float value)
|
||
{
|
||
switch (channel)
|
||
{
|
||
case 0:
|
||
color.r = value;
|
||
break;
|
||
case 1:
|
||
color.g = value;
|
||
break;
|
||
case 2:
|
||
color.b = value;
|
||
break;
|
||
case 3:
|
||
color.a = value;
|
||
break;
|
||
}
|
||
}
|
||
|
||
private string GetColorTexName(int channel)
|
||
{
|
||
return "_Splat" + channel;
|
||
}
|
||
|
||
private string GetNormalTexName(int channel)
|
||
{
|
||
return "_BumpSplat" + channel;
|
||
}
|
||
} |