#if UNITY_EDITOR
using UnityEngine;
using UnityEngine.Rendering;
using UnityEditor;
using System.IO;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEditor.SceneManagement;
using UnityEngine.SceneManagement;
using System.Diagnostics;
using System.Linq;
public class ftShaderTweaks : ScriptableWizard
{
public bool bicubic;
public bool bicubicShadow;
public bool shadowBlend;
public bool falloff;
public bool falloffDeferred;
bool initialized = false;
//bool agree = false;
string includeGIPath;
string includeShadowPath;
string includeLightPath;
string includeDeferredPath;
string shadersDir;
string ftSignatureBegin = "//";
string ftSignatureBicubic = "//";
string ftSignatureShadowmask = "//";
string ftSignatureEnd = "//";
string unityLightmapReadCode = "half3 bakedColor = DecodeLightmap(bakedColorTex);";
//string unityLightMatrixDecl = "unityShadowCoord4x4 unity_WorldToLight;";
string unityDefineLightAtten = "#define UNITY_LIGHT_ATTENUATION(destName, input, worldPos) ";
string unityGetShadowCoord = "unityShadowCoord3 lightCoord = mul(unity_WorldToLight, unityShadowCoord4(worldPos, 1)).xyz;";
string unityGetShadowCoord4 = "unityShadowCoord4 lightCoord = mul(unity_WorldToLight, unityShadowCoord4(worldPos, 1));";
string unityGetShadow = "fixed shadow = UNITY_SHADOW_ATTENUATION(input, worldPos);";
string ftLightFalloff = "fixed destName = ftLightFalloff(unity_WorldToLight, worldPos)";
//string unityLightFalloffNew = "UnitySpotAttenuate(lightCoord.xyz)";
//string ftLightFalloffNew = "ftLightFalloff(unity_WorldToLight, worldPos)";
//string unityLightFalloffNew2 = "UnitySpotAttenuate(worldPos)";
//string ftLightFalloffNew2 = "ftLightFalloff(unity_WorldToLight, worldPos)";
string unitySpotFalloffDeferred = "atten *= tex2D (_LightTextureB0,";
string ftSpotFalloffDeferred = "atten *= ftLightFalloff(_LightPos, wpos);";
string unityPointFalloffDeferred = "float atten = tex2D (_LightTextureB0, ";
string ftPointFalloffDeferred = "float atten = ftLightFalloff(_LightPos, wpos);";
string unityShadowMaskRead = "UNITY_SAMPLE_TEX2D(unity_ShadowMask";
string ftShadowMaskRead = "ftBicubicSampleShadow(unity_ShadowMask";
string unityShadowMaskRead2 = "UNITY_SAMPLE_TEX2D_SAMPLER(unity_ShadowMask";
string ftShadowMaskRead2 = "ftBicubicSampleShadow2(unity_ShadowMask";
string unityShadowMaskBlend = "min(realtimeShadowAttenuation, bakedShadowAttenuation)";
string ftShadowMaskBlend = "(realtimeShadowAttenuation * bakedShadowAttenuation)";
//string ftLightFalloffDeferred = "#define LIGHT_ATTENUATION ftLightFalloff(unity_WorldToLight, worldPos) * SHADOW_ATTENUATION(a))";
void OnInspectorUpdate()
{
Repaint();
}
void CopyInclude(string shadersDir)
{
var edPath = ftLightmaps.GetEditorPath();
File.Copy(edPath + "shaderSrc/ftrace.cginc", shadersDir + "/ftrace.cginc", true);
}
bool RevertFile(string fname)
{
var reader = new StreamReader(fname);
if (reader == null)
{
UnityEngine.Debug.LogError("Can't open " + fname);
return false;
}
var lines = new List();
bool inBlock = false;
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
if (line.StartsWith(ftSignatureBegin))
{
inBlock = true;
}
else if (line.StartsWith(ftSignatureEnd))
{
inBlock = false;
}
else if (!inBlock)
{
lines.Add(line);
}
}
reader.Close();
var writer = new StreamWriter(fname, false);
if (writer == null)
{
UnityEngine.Debug.LogError("Can't open " + fname);
return false;
}
for(int i=0; i();
lines.Add(ftSignatureBegin);
lines.Add(ftSignatureBicubic);
lines.Add("#define USEFTRACE\n");
lines.Add("#ifdef USEFTRACE");
lines.Add("#include \"ftrace.cginc\"");
lines.Add("#endif");
lines.Add(ftSignatureEnd);
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
if (line.StartsWith(ftSignatureBicubic))
{
UnityEngine.Debug.Log("Already patched");
patched = true;
break;
}
else if (line.Trim() == unityLightmapReadCode)
{
lines.Add(ftSignatureBegin);
lines.Add("#ifdef USEFTRACE");
lines.Add(" half3 bakedColor = ftLightmapBicubic(data.lightmapUV.xy);");
lines.Add("#else");
lines.Add(ftSignatureEnd);
lines.Add(unityLightmapReadCode);
lines.Add(ftSignatureBegin);
lines.Add("#endif");
lines.Add(ftSignatureEnd);
}
else
{
lines.Add(line);
}
}
reader.Close();
if (!patched)
{
if (!File.Exists(includeGIPath + "_backup")) File.Copy(includeGIPath, includeGIPath + "_backup");
var writer = new StreamWriter(includeGIPath, false);
if (writer == null)
{
UnityEngine.Debug.LogError("Can't open " + includeGIPath);
bicubic = false;
return;
}
for(int i=0; i();
lines.Add(ftSignatureBegin);
lines.Add(ftSignatureBicubic);
lines.Add("#define USEFTRACE\n");
lines.Add("#ifdef USEFTRACE");
lines.Add("#include \"ftrace.cginc\"");
lines.Add("#endif");
lines.Add(ftSignatureEnd);
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
if (line.StartsWith(ftSignatureBicubic))
{
UnityEngine.Debug.Log("Already patched");
patched = true;
break;
}
else if (line.IndexOf(unityShadowMaskRead) >= 0)
{
lines.Add(ftSignatureBegin);
lines.Add("#ifdef USEFTRACE");
lines.Add(line.Replace(unityShadowMaskRead, ftShadowMaskRead));
lines.Add("#else");
lines.Add(ftSignatureEnd);
lines.Add(line);
lines.Add(ftSignatureBegin);
lines.Add("#endif");
lines.Add(ftSignatureEnd);
}
else if (line.IndexOf(unityShadowMaskRead2) >= 0)
{
lines.Add(ftSignatureBegin);
lines.Add("#ifdef USEFTRACE");
lines.Add(line.Replace(unityShadowMaskRead2, ftShadowMaskRead2));
lines.Add("#else");
lines.Add(ftSignatureEnd);
lines.Add(line);
lines.Add(ftSignatureBegin);
lines.Add("#endif");
lines.Add(ftSignatureEnd);
}
else
{
lines.Add(line);
}
}
reader.Close();
if (!patched)
{
if (!File.Exists(includeShadowPath + "_backup")) File.Copy(includeShadowPath, includeShadowPath + "_backup");
var writer = new StreamWriter(includeShadowPath, false);
if (writer == null)
{
UnityEngine.Debug.LogError("Can't open " + includeShadowPath);
bicubicShadow = false;
return;
}
for(int i=0; i();
lines.Add(ftSignatureBegin);
lines.Add(ftSignatureShadowmask);
lines.Add("#define USEFTRACE\n");
lines.Add("#ifdef USEFTRACE");
lines.Add("#include \"ftrace.cginc\"");
lines.Add("#endif");
lines.Add(ftSignatureEnd);
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
if (line.StartsWith(ftSignatureShadowmask))
{
UnityEngine.Debug.Log("Already patched");
patched = true;
break;
}
else if (line.IndexOf(unityShadowMaskBlend) >= 0)
{
lines.Add(ftSignatureBegin);
lines.Add("#ifdef USEFTRACE");
lines.Add(line.Replace(unityShadowMaskBlend, ftShadowMaskBlend));
lines.Add("#else");
lines.Add(ftSignatureEnd);
lines.Add(line);
lines.Add(ftSignatureBegin);
lines.Add("#endif");
lines.Add(ftSignatureEnd);
}
else
{
lines.Add(line);
}
}
reader.Close();
if (!patched)
{
if (!File.Exists(includeShadowPath + "_backup")) File.Copy(includeShadowPath, includeShadowPath + "_backup");
var writer = new StreamWriter(includeShadowPath, false);
if (writer == null)
{
UnityEngine.Debug.LogError("Can't open " + includeShadowPath);
shadowBlend = false;
return;
}
for(int i=0; i();
lines.Add(ftSignatureBegin);
lines.Add("#define USEFTRACE\n");
lines.Add("#ifdef USEFTRACE");
lines.Add("#include \"ftrace.cginc\"");
lines.Add("#endif");
lines.Add(ftSignatureEnd);
int lastIfdef = 0;
int lastEndif = 0;
int lastDefine = 0;
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
//if (line.IndexOf(unityLightFalloffNew) >= 0)
//{
// lines.Add(ftSignatureBegin);
// lines.Add("/*");
// lines.Add(ftSignatureEnd);
//
// lines.Add(line);
//
// lines.Add(ftSignatureBegin);
// lines.Add("*/");
// lines.Add(line.Replace(unityLightFalloffNew, ftLightFalloffNew));
// lines.Add(ftSignatureEnd);
// continue;
//}
//else if (line.IndexOf(unityLightFalloffNew2) >= 0)
//{
// lines.Add(ftSignatureBegin);
// lines.Add("/*");
// lines.Add(ftSignatureEnd);
//
// lines.Add(line);
//
// lines.Add(ftSignatureBegin);
// lines.Add("*/");
// lines.Add(line.Replace(unityLightFalloffNew2, ftLightFalloffNew2));
// lines.Add(ftSignatureEnd);
// continue;
//}
if (line.IndexOf("#if") >= 0) lastIfdef = lines.Count;
if (line.IndexOf("define UNITY_LIGHT_ATTENUATION") >= 0 || line.IndexOf("define LIGHT_ATTENUATION") >= 0)
{
lastDefine = lines.Count;
}
if (line.IndexOf("#endif") >= 0) lastEndif = lines.Count;
if (line.StartsWith(ftSignatureBegin))
{
UnityEngine.Debug.Log("Already patched");
patched = true;
break;
}
else
{
if (lastEndif == lines.Count && lastDefine > lastIfdef) // we should be at the endif of light atten declaration
{
string ifdefLine = lines[lastIfdef];
string defineLine = lines[lastDefine];
if (defineLine.IndexOf("define UNITY_LIGHT_ATTENUATION") >= 0)
{
if ((ifdefLine.IndexOf("POINT") >= 0 || ifdefLine.IndexOf("SPOT") >= 0) &&
ifdefLine.IndexOf("POINT_COOKIE") < 0 && ifdefLine.IndexOf("SPOT_COOKIE") < 0)
{
// Forward point light
lines.Insert(lastDefine, ftSignatureBegin);
lines.Insert(lastDefine + 1, "/*");
lines.Insert(lastDefine + 2, ftSignatureEnd);
lines.Add(ftSignatureBegin);
lines.Add("*/");
if (ifdefLine.IndexOf("POINT") >= 0)
{
//lines.Add(unityLightMatrixDecl);
lines.Add(unityDefineLightAtten + "\\");
lines.Add(unityGetShadowCoord + "\\");
lines.Add(unityGetShadow + "\\");
lines.Add(ftLightFalloff + " * shadow;");
}
else if (ifdefLine.IndexOf("SPOT") >= 0)
{
lines.Add(unityDefineLightAtten + "\\");
lines.Add(unityGetShadowCoord4 + "\\");
lines.Add(unityGetShadow + "\\");
lines.Add(ftLightFalloff + " * (lightCoord.z > 0) * UnitySpotCookie(lightCoord) * shadow;");
}
lines.Add(ftSignatureEnd);
}
}
//else if (defineLine.IndexOf("define LIGHT_ATTENUATION") >= 0)
// {
// if (ifdefLine.IndexOf("POINT") >= 0)
// {
// // Deferred point light
// lines.Insert(lastDefine, ftSignatureBegin);
// lines.Insert(lastDefine + 1, "/*");
// lines.Insert(lastDefine + 2, ftSignatureEnd);
// lines.Insert(lastDefine + 4, ftSignatureBegin);
// lines.Insert(lastDefine + 5, "*/");
// if (ifdefLine.IndexOf("POINT") >= 0)
// {
// lines.Add(ftLightFalloffDeferred);
// }
// lines.Add(ftSignatureEnd);
// }
// }
}
lines.Add(line);
}
}
reader.Close();
if (!patched)
{
if (!File.Exists(includeLightPath + "_backup")) File.Copy(includeLightPath, includeLightPath + "_backup");
var writer = new StreamWriter(includeLightPath, false);
if (writer == null)
{
UnityEngine.Debug.LogError("Can't open " + includeLightPath);
falloff = false;
return;
}
for(int i=0; i();
lines.Add(ftSignatureBegin);
lines.Add("#define USEFTRACE\n");
lines.Add("#ifdef USEFTRACE");
lines.Add("#include \"ftrace.cginc\"");
lines.Add("#endif");
lines.Add(ftSignatureEnd);
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
if (line.StartsWith(ftSignatureBegin))
{
UnityEngine.Debug.Log("Already patched");
patched = true;
break;
}
else if (line.IndexOf(unitySpotFalloffDeferred) >= 0)
{
lines.Add(ftSignatureBegin);
lines.Add("/*");
lines.Add(ftSignatureEnd);
lines.Add(line);
lines.Add(ftSignatureBegin);
lines.Add("*/");
lines.Add(ftSpotFalloffDeferred);
lines.Add(ftSignatureEnd);
}
else if (line.IndexOf(unityPointFalloffDeferred) >= 0)
{
lines.Add(ftSignatureBegin);
lines.Add("/*");
lines.Add(ftSignatureEnd);
lines.Add(line);
lines.Add(ftSignatureBegin);
lines.Add("*/");
lines.Add(ftPointFalloffDeferred);
lines.Add(ftSignatureEnd);
}
else
{
lines.Add(line);
}
}
reader.Close();
if (!patched)
{
if (!File.Exists(includeDeferredPath + "_backup")) File.Copy(includeDeferredPath, includeDeferredPath + "_backup");
var writer = new StreamWriter(includeDeferredPath, false);
if (writer == null)
{
UnityEngine.Debug.LogError("Can't open " + includeDeferredPath);
falloffDeferred = false;
return;
}
for(int i=0; i