Files
JJBB/Assets/Project/Script/Shader/Editor/T4MSwapEditor.cs

228 lines
8.7 KiB
C#
Raw Normal View History

2024-08-23 15:49:34 +08:00
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;
}
}