Files
JJBB/Assets/Project/Script/Shader/Editor/T4MSwapEditor.cs
2024-08-23 15:49:34 +08:00

228 lines
8.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}