Add Bakery back
This commit is contained in:
16
Assets/Editor/x64/Bakery/scripts/BakeryEditorAssembly.asmdef
Normal file
16
Assets/Editor/x64/Bakery/scripts/BakeryEditorAssembly.asmdef
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "BakeryEditorAssembly",
|
||||
"references": [
|
||||
"BakeryRuntimeAssembly"
|
||||
],
|
||||
"optionalUnityReferences": [],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 290dd5870d0ead646bcb6ea5c6a60af5
|
||||
timeCreated: 1551814754
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
24
Assets/Editor/x64/Bakery/scripts/ftAdditionalConfig.cs
Normal file
24
Assets/Editor/x64/Bakery/scripts/ftAdditionalConfig.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
public class ftAdditionalConfig
|
||||
{
|
||||
// Affects texture import settings for lightmaps
|
||||
public const bool mipmapLightmaps = false;
|
||||
|
||||
// Shader eval coeff * gaussian convolution coeff
|
||||
// ... replaced with more typical convolution coeffs
|
||||
// Used for legacy light probes
|
||||
public const float irradianceConvolutionL0 = 0.2820947917f;
|
||||
public const float irradianceConvolutionL1 = 0.32573500793527993f;//0.4886025119f * 0.7346029443286334f;
|
||||
public const float irradianceConvolutionL2_4_5_7 = 0.2731371076480198f;//0.29121293321402086f * 1.0925484306f;
|
||||
public const float irradianceConvolutionL2_6 = 0.07884789131313001f;//0.29121293321402086f * 0.3153915652f;
|
||||
public const float irradianceConvolutionL2_8 = 0.1365685538240099f;//0.29121293321402086f * 0.5462742153f;
|
||||
|
||||
// Used for L1 light probes and volumes
|
||||
public const float convL0 = 1;
|
||||
public const float convL1 = 0.9f; // approx convolution
|
||||
|
||||
// Use PNG instead of TGA for shadowmasks, directions and L1 maps
|
||||
public const bool preferPNG = false;
|
||||
}
|
||||
12
Assets/Editor/x64/Bakery/scripts/ftAdditionalConfig.cs.meta
Normal file
12
Assets/Editor/x64/Bakery/scripts/ftAdditionalConfig.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1da9342d2a59abd49a8dfb8aa73a87b3
|
||||
timeCreated: 1596818791
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
6640
Assets/Editor/x64/Bakery/scripts/ftBuildGraphics.cs
Normal file
6640
Assets/Editor/x64/Bakery/scripts/ftBuildGraphics.cs
Normal file
File diff suppressed because it is too large
Load Diff
8
Assets/Editor/x64/Bakery/scripts/ftBuildGraphics.cs.meta
Normal file
8
Assets/Editor/x64/Bakery/scripts/ftBuildGraphics.cs.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1f3ae15d674398b46a90bf2c1aced7ac
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
1019
Assets/Editor/x64/Bakery/scripts/ftBuildLights.cs
Normal file
1019
Assets/Editor/x64/Bakery/scripts/ftBuildLights.cs
Normal file
File diff suppressed because it is too large
Load Diff
8
Assets/Editor/x64/Bakery/scripts/ftBuildLights.cs.meta
Normal file
8
Assets/Editor/x64/Bakery/scripts/ftBuildLights.cs.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6d2a81f0f9d2d0c49bc8e08c6e18e72c
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
54
Assets/Editor/x64/Bakery/scripts/ftClearMenu.cs
Normal file
54
Assets/Editor/x64/Bakery/scripts/ftClearMenu.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEngine.SceneManagement;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class ftClearMenu
|
||||
{
|
||||
[MenuItem("Bakery/Utilities/Clear baked data", false, 44)]
|
||||
private static void ClearBakedData()
|
||||
{
|
||||
int val = EditorUtility.DisplayDialogComplex("Bakery", "Clear all Bakery data for currently loaded scenes?", "Clear data", "Clear all (data and settings)", "Cancel");
|
||||
if (val == 0)
|
||||
{
|
||||
var newStorages = new List<GameObject>();
|
||||
var sceneCount = SceneManager.sceneCount;
|
||||
for(int i=0; i<sceneCount; i++)
|
||||
{
|
||||
var scene = SceneManager.GetSceneAt(i);
|
||||
if (!scene.isLoaded) continue;
|
||||
var go = ftLightmaps.FindInScene("!ftraceLightmaps", scene);
|
||||
if (go == null) continue;
|
||||
var storage = go.GetComponent<ftLightmapsStorage>();
|
||||
if (storage != null)
|
||||
{
|
||||
var newGO = new GameObject();
|
||||
var newStorage = newGO.AddComponent<ftLightmapsStorage>();
|
||||
ftLightmapsStorage.CopySettings(storage, newStorage);
|
||||
newStorages.Add(newGO);
|
||||
}
|
||||
Undo.DestroyObjectImmediate(go);
|
||||
}
|
||||
LightmapSettings.lightmaps = new LightmapData[0];
|
||||
for(int i=0; i<newStorages.Count; i++)
|
||||
{
|
||||
newStorages[i].name = "!ftraceLightmaps";
|
||||
}
|
||||
}
|
||||
else if (val == 1)
|
||||
{
|
||||
var sceneCount = SceneManager.sceneCount;
|
||||
for(int i=0; i<sceneCount; i++)
|
||||
{
|
||||
var scene = SceneManager.GetSceneAt(i);
|
||||
if (!scene.isLoaded) continue;
|
||||
var go = ftLightmaps.FindInScene("!ftraceLightmaps", scene);
|
||||
if (go == null) continue;
|
||||
Undo.DestroyObjectImmediate(go);
|
||||
}
|
||||
LightmapSettings.lightmaps = new LightmapData[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
12
Assets/Editor/x64/Bakery/scripts/ftClearMenu.cs.meta
Normal file
12
Assets/Editor/x64/Bakery/scripts/ftClearMenu.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6976907e066f1824581718bc451446bc
|
||||
timeCreated: 1534329905
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
505
Assets/Editor/x64/Bakery/scripts/ftClient.cs
Normal file
505
Assets/Editor/x64/Bakery/scripts/ftClient.cs
Normal file
@@ -0,0 +1,505 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor.SceneManagement;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
|
||||
public class ftClient
|
||||
{
|
||||
public const byte SERVERTASK_COPY = 0;
|
||||
public const byte SERVERTASK_FTRACE = 1;
|
||||
public const byte SERVERTASK_FTRACERTX = 2;
|
||||
public const byte SERVERTASK_COMBINEMASKS = 3;
|
||||
|
||||
public const byte SERVERTASK_DENOISE5 = 4;
|
||||
public const byte SERVERTASK_DENOISE6 = 5;
|
||||
public const byte SERVERTASK_DENOISE7 = 6;
|
||||
public const byte SERVERTASK_DENOISEOIDN = 7;
|
||||
|
||||
public const byte SERVERTASK_HF2HDR = 8;
|
||||
public const byte SERVERTASK_RGBA2TGA = 9;
|
||||
public const byte SERVERTASK_SEAMFIX = 10;
|
||||
|
||||
public const byte SERVERTASK_LMREBAKE = 11;
|
||||
public const byte SERVERTASK_LMREBAKESIMPLE = 12;
|
||||
public const byte SERVERTASK_LODGEN = 13;
|
||||
public const byte SERVERTASK_LODGENINIT = 14;
|
||||
public const byte SERVERTASK_GIPARAMS = 15;
|
||||
public const byte SERVERTASK_RECEIVEFILE = 16;
|
||||
public const byte SERVERTASK_REPORTSTATUS = 17;
|
||||
public const byte SERVERTASK_SETSCENENAME = 18;
|
||||
public const byte SERVERTASK_GETDATA = 19;
|
||||
public const byte SERVERTASK_GETDATAREADY = 20;
|
||||
|
||||
public const byte SERVERERROR_IDLE = 0;
|
||||
public const byte SERVERERROR_COPY = 1;
|
||||
public const byte SERVERERROR_EXEC = 2;
|
||||
public const byte SERVERERROR_APPERR = 3;
|
||||
public const byte SERVERERROR_GIPARAMS = 4;
|
||||
public const byte SERVERERROR_NOTIMPLEMENTED = 5;
|
||||
public const byte SERVERERROR_UNKNOWNTASK = 6;
|
||||
public const byte SERVERERROR_BUSY = 7;
|
||||
public const byte SERVERERROR_UNKNOWN = 8;
|
||||
public const byte SERVERERROR_SCENENAMETOOLONG = 9;
|
||||
public const byte SERVERERROR_FILENOTFOUND = 10;
|
||||
public const byte SERVERERROR_FILEHASZEROSIZE = 11;
|
||||
public const byte SERVERERROR_NOMEM = 12;
|
||||
public const byte SERVERERROR_INCORRECT = 13;
|
||||
public const byte SERVERERROR_INCORRECTFILENAME = 14;
|
||||
public const byte SERVERERROR_WRITEFAILED = 15;
|
||||
public const byte SERVERERROR_INCORRECTARGS = 16;
|
||||
public const byte SERVERERROR_FILESIZE = 17;
|
||||
public const byte SERVERERROR_STATUSLIMIT = 18;
|
||||
|
||||
public static string serverAddress = "127.0.0.1";
|
||||
const int serverPort = 27777;
|
||||
public static bool connectedToServer = false;
|
||||
public static string lastServerMsg = "Server: no data";
|
||||
public static string lastServerScene = ""; // last baked scene
|
||||
public static int lastServerErrorCode = 0;
|
||||
public static bool lastServerMsgIsError = false;
|
||||
public static bool serverGetDataMode = false; // if we're in download mode or status polling mode
|
||||
public static bool serverMustRefreshData = false; // if ready to apply downloaded data
|
||||
|
||||
static string lastServerFile = ""; // last file loaded via GETDATA on the server
|
||||
static int lastServerFileHash = 0;
|
||||
static int lastServerFileSize = 0;
|
||||
static double timeToUpdateServerStatus = 0;
|
||||
static double serverStatusInterval = 1000.0;
|
||||
static double serverConnectionTimeout = 2000.0;
|
||||
|
||||
static Socket statusSocket;
|
||||
//static System.Threading.Thread statusThread;
|
||||
static IEnumerator statusProc;
|
||||
|
||||
public static Dictionary<string, byte> app2serverTask = new Dictionary<string, byte>
|
||||
{
|
||||
{"ftrace", SERVERTASK_FTRACE},
|
||||
{"ftraceRTX", SERVERTASK_FTRACERTX},
|
||||
{"combineMasks", SERVERTASK_COMBINEMASKS},
|
||||
|
||||
{"denoiserLegacy", SERVERTASK_DENOISE5},
|
||||
{"denoiser", SERVERTASK_DENOISE6},
|
||||
{"denoiser72", SERVERTASK_DENOISE7},
|
||||
{"denoiseOIDN", SERVERTASK_DENOISEOIDN},
|
||||
|
||||
{"halffloat2hdr", SERVERTASK_HF2HDR},
|
||||
{"rgba2tga", SERVERTASK_RGBA2TGA},
|
||||
{"seamfixer", SERVERTASK_SEAMFIX},
|
||||
{"lmrebake (simple)", SERVERTASK_LMREBAKESIMPLE},
|
||||
{"lmrebake", SERVERTASK_LMREBAKE}
|
||||
|
||||
};
|
||||
public static List<string> serverFileList, serverGetFileList;
|
||||
public static int serverGetFileIterator = 0;
|
||||
|
||||
|
||||
public static IEnumerator UpdateConnection()//WaitForMessages()
|
||||
{
|
||||
var ipAdd = System.Net.IPAddress.Parse(serverAddress);
|
||||
var remoteEP = new IPEndPoint(ipAdd, 27777);
|
||||
var request = new byte[1];
|
||||
request[0] = SERVERTASK_REPORTSTATUS;
|
||||
var requestGet = new byte[5];
|
||||
requestGet[0] = SERVERTASK_GETDATAREADY;
|
||||
int numTasks = 1;
|
||||
var taskGet = new byte[1];
|
||||
var nullByte = new byte[1];
|
||||
taskGet[0] = SERVERTASK_GETDATA;
|
||||
nullByte[0] = 0;
|
||||
|
||||
lastServerMsg = "Connecting...";
|
||||
lastServerErrorCode = 0;
|
||||
lastServerMsgIsError = false;
|
||||
var status = new byte[256];
|
||||
byte[] fileBuffer = null;
|
||||
bool waitingForGet = false;
|
||||
|
||||
while (connectedToServer)
|
||||
{
|
||||
if (statusSocket != null)
|
||||
{
|
||||
statusSocket.Close();
|
||||
statusSocket = null;
|
||||
}
|
||||
|
||||
waitingForGet = false;
|
||||
|
||||
|
||||
// Attempt connecting to server
|
||||
bool connectionInProgress = true;
|
||||
bool connectionError = false;
|
||||
double timeout = ftRenderLightmap.GetTimeMs() + serverConnectionTimeout;
|
||||
while(connectionInProgress)
|
||||
{
|
||||
connectionInProgress = false;
|
||||
try
|
||||
{
|
||||
if (statusSocket == null)
|
||||
{
|
||||
statusSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
statusSocket.Blocking = false;
|
||||
statusSocket.Connect(remoteEP);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (statusSocket.Poll(0, SelectMode.SelectError))
|
||||
{
|
||||
connectionError = true;
|
||||
break;
|
||||
}
|
||||
if (!statusSocket.Poll(0, SelectMode.SelectWrite) && ftRenderLightmap.GetTimeMs() < timeout)
|
||||
{
|
||||
connectionInProgress = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(SocketException s)
|
||||
{
|
||||
if (s.ErrorCode == 10035) // WSAEWOULDBLOCK
|
||||
{
|
||||
connectionInProgress = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
connectionError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (connectionInProgress) yield return null;
|
||||
}
|
||||
statusSocket.Blocking = true;
|
||||
|
||||
// Send request(s)
|
||||
try
|
||||
{
|
||||
if (connectionError) throw new SocketException();
|
||||
if (serverGetDataMode && serverGetFileList == null) serverGetDataMode = false;
|
||||
if (serverGetDataMode && serverGetFileList.Count <= serverGetFileIterator)
|
||||
{
|
||||
serverMustRefreshData = true;
|
||||
serverGetDataMode = false;
|
||||
}
|
||||
if (serverGetDataMode)
|
||||
{
|
||||
var fname = serverGetFileList[serverGetFileIterator];
|
||||
if (lastServerFile != fname)
|
||||
{
|
||||
int len = fname.Length;
|
||||
statusSocket.Send(System.BitConverter.GetBytes(numTasks));
|
||||
statusSocket.Send(taskGet);
|
||||
statusSocket.Send(System.BitConverter.GetBytes(len));
|
||||
statusSocket.Send(Encoding.ASCII.GetBytes(fname));
|
||||
statusSocket.Send(nullByte);
|
||||
statusSocket.Close();
|
||||
|
||||
statusSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
statusSocket.Connect(remoteEP);
|
||||
statusSocket.Send(request);
|
||||
#if BAKERY_NETDEBUG
|
||||
Debug.Log("Request sent (load file " + fname + ")");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
fileBuffer = new byte[lastServerFileSize];
|
||||
System.Buffer.BlockCopy(System.BitConverter.GetBytes(lastServerFileHash), 0, requestGet, 1, 4);
|
||||
statusSocket.Send(requestGet);
|
||||
#if BAKERY_NETDEBUG
|
||||
Debug.Log("Request sent (get file)");
|
||||
#endif
|
||||
waitingForGet = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
statusSocket.Send(request);
|
||||
#if BAKERY_NETDEBUG
|
||||
Debug.Log("Request sent");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
catch(SocketException s)
|
||||
{
|
||||
lastServerMsg = "Failed to get data from server (" + s.ErrorCode + ")";
|
||||
lastServerMsgIsError = true;
|
||||
lastServerErrorCode = 0;
|
||||
|
||||
Debug.LogError(lastServerMsg);
|
||||
statusSocket.Close();
|
||||
statusSocket = null;
|
||||
statusProc = null;
|
||||
//statusThread = null;
|
||||
connectedToServer = false;
|
||||
//return;
|
||||
yield break;
|
||||
}
|
||||
|
||||
#if BAKERY_NETDEBUG
|
||||
Debug.Log("Waiting for server to respond");
|
||||
#endif
|
||||
|
||||
int serverErrCode = 0;
|
||||
int appCode = 0;
|
||||
int appErrCode = 0;
|
||||
int textLen = 0;
|
||||
int fileReady = 0;
|
||||
int fileHash = 0;
|
||||
int fileSize = 0;
|
||||
string text = "";
|
||||
string fileNameReady = "";
|
||||
|
||||
int byteCount = 0;
|
||||
bool interrupted = false;
|
||||
double maxTimeToReceive = 10.0;
|
||||
double timeToInterrupt = ftRenderLightmap.GetTimeMs() + maxTimeToReceive;
|
||||
|
||||
while(!interrupted)
|
||||
{
|
||||
if (ftRenderLightmap.GetTimeMs() > timeToInterrupt)
|
||||
{
|
||||
timeToInterrupt = ftRenderLightmap.GetTimeMs() + maxTimeToReceive;
|
||||
yield return null;
|
||||
}
|
||||
//while(statusSocket.Available == 0) yield return null;
|
||||
//while(!statusSocket.Poll(0, SelectMode.SelectRead)) yield return null;
|
||||
try
|
||||
{
|
||||
//while(true)
|
||||
//{
|
||||
if (waitingForGet)
|
||||
{
|
||||
int bytesReceived = statusSocket.Receive(fileBuffer, byteCount, fileBuffer.Length - byteCount, SocketFlags.None);
|
||||
byteCount += bytesReceived;
|
||||
//Debug.Log("Received " + bytesReceived);
|
||||
if (bytesReceived == 0) interrupted = true;//break;
|
||||
}
|
||||
else
|
||||
{
|
||||
byteCount = statusSocket.Receive(status);
|
||||
//break;
|
||||
interrupted = true;
|
||||
}
|
||||
//}
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (waitingForGet)
|
||||
{
|
||||
Debug.LogError("Error getting file from server - retrying");
|
||||
lastServerFile = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
lastServerMsg = "Server disconnected";
|
||||
lastServerMsgIsError = true;
|
||||
lastServerErrorCode = 0;
|
||||
|
||||
Debug.LogError(lastServerMsg);
|
||||
statusSocket.Close();
|
||||
statusSocket = null;
|
||||
//statusThread = null;
|
||||
statusProc = null;
|
||||
connectedToServer = false;
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (byteCount > 0)
|
||||
{
|
||||
if (waitingForGet)
|
||||
{
|
||||
Debug.Log("Data received: " + byteCount);
|
||||
var ext = lastServerFile.Substring(lastServerFile.Length-3).ToLower();
|
||||
string outPath;
|
||||
if (ext == "lz4" || ext == "dds")
|
||||
{
|
||||
outPath = ftRenderLightmap.scenePath + "/" + lastServerFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
outPath = "Assets/" + ftRenderLightmap.outputPath + "/" + lastServerFile;
|
||||
}
|
||||
BinaryWriter bw = null;
|
||||
try
|
||||
{
|
||||
bw = new BinaryWriter(File.Open(outPath, FileMode.Create));
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.LogError("Failed writing " + outPath);
|
||||
}
|
||||
if (bw != null)
|
||||
{
|
||||
bw.Write(fileBuffer);
|
||||
bw.Close();
|
||||
Debug.Log("File saved: " + outPath);
|
||||
}
|
||||
yield return null;
|
||||
serverGetFileIterator++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (byteCount == 150)
|
||||
{
|
||||
serverErrCode = System.BitConverter.ToInt32(status, 0);
|
||||
appCode = System.BitConverter.ToInt32(status, 4);
|
||||
appErrCode = System.BitConverter.ToInt32(status, 8);
|
||||
textLen = status[12];
|
||||
fileReady = status[13];
|
||||
fileHash = System.BitConverter.ToInt32(status, 14);
|
||||
fileSize = System.BitConverter.ToInt32(status, 18);
|
||||
if (textLen > 0)
|
||||
{
|
||||
text = Encoding.ASCII.GetString(status, 22, textLen);
|
||||
}
|
||||
if (fileReady > 0)
|
||||
{
|
||||
fileNameReady = Encoding.ASCII.GetString(status, 22 + textLen + 1, fileReady);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
serverErrCode = SERVERERROR_UNKNOWN;
|
||||
Debug.LogError("Unrecognized response size: " + byteCount);
|
||||
}
|
||||
//if (serverErrCode != 0)
|
||||
{
|
||||
var serverMsg = "Server: " + ftErrorCodes.TranslateServer(serverErrCode, appCode, appErrCode);
|
||||
bool isError = serverErrCode != SERVERERROR_IDLE && serverErrCode != SERVERERROR_BUSY;
|
||||
if (isError)
|
||||
{
|
||||
Debug.LogError(serverMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if BAKERY_NETDEBUG
|
||||
Debug.Log(serverMsg);
|
||||
#else
|
||||
if (lastServerMsg != serverMsg) Debug.Log(serverMsg);
|
||||
#endif
|
||||
}
|
||||
lastServerMsg = serverMsg;
|
||||
lastServerMsgIsError = isError;
|
||||
lastServerErrorCode = serverErrCode;
|
||||
lastServerScene = text;
|
||||
lastServerFile = fileNameReady;
|
||||
lastServerFileHash = fileHash;
|
||||
lastServerFileSize = fileSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!serverGetDataMode)
|
||||
{
|
||||
//var sleepTime = timeToUpdateServerStatus - curTime;
|
||||
//if (sleepTime > 0) System.Threading.Thread.Sleep((int)sleepTime);
|
||||
while(true)
|
||||
{
|
||||
var curTime = ftRenderLightmap.GetTimeMs();
|
||||
if (curTime >= timeToUpdateServerStatus) break;
|
||||
yield return null;
|
||||
}
|
||||
|
||||
timeToUpdateServerStatus = ftRenderLightmap.GetTimeMs() + serverStatusInterval;
|
||||
}
|
||||
}
|
||||
|
||||
statusSocket.Close();
|
||||
statusSocket = null;
|
||||
//statusThread = null;
|
||||
statusProc = null;
|
||||
}
|
||||
|
||||
public static void Disconnect()
|
||||
{
|
||||
if (statusSocket != null)
|
||||
{
|
||||
statusSocket.Close();
|
||||
statusSocket = null;
|
||||
}
|
||||
|
||||
statusProc = null;
|
||||
/*if (statusThread != null)
|
||||
{
|
||||
statusThread.Abort();
|
||||
statusThread = null;
|
||||
}*/
|
||||
|
||||
connectedToServer = false;
|
||||
serverGetDataMode = false;
|
||||
}
|
||||
|
||||
public static void ConnectToServer()
|
||||
{
|
||||
try
|
||||
{
|
||||
Disconnect();
|
||||
connectedToServer = true;
|
||||
|
||||
timeToUpdateServerStatus = 0;
|
||||
//statusThread = new System.Threading.Thread(WaitForMessages);
|
||||
//statusThread.Start();
|
||||
statusProc = UpdateConnection();
|
||||
statusProc.MoveNext();
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.LogError("Failed getting data from server");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool SendRenderSequence(byte[] renderSequence)
|
||||
{
|
||||
Socket soc = null;
|
||||
var ipAdd = System.Net.IPAddress.Parse(serverAddress);
|
||||
var remoteEP = new IPEndPoint(ipAdd, serverPort);
|
||||
|
||||
for(int i=0; i<serverFileList.Count; i++)
|
||||
{
|
||||
var fsoc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
fsoc.Connect(remoteEP);
|
||||
if (!fsoc.Poll(0, SelectMode.SelectWrite)) return false;
|
||||
|
||||
var sceneFile = File.ReadAllBytes(ftRenderLightmap.scenePath + "/" + serverFileList[i]);
|
||||
int headerSize = 5 + serverFileList[i].Length + 1;
|
||||
var buff = new byte[sceneFile.Length + headerSize];
|
||||
|
||||
int numTasks = 1;
|
||||
System.Buffer.BlockCopy(System.BitConverter.GetBytes(numTasks), 0, buff, 0, 4);
|
||||
buff[4] = SERVERTASK_RECEIVEFILE;
|
||||
buff[5] = (byte)serverFileList[i].Length;
|
||||
for(int j=0; j<serverFileList[i].Length; j++) buff[6+j] = (byte)serverFileList[i][j];
|
||||
System.Buffer.BlockCopy(sceneFile, 0, buff, headerSize, sceneFile.Length);
|
||||
|
||||
fsoc.Send(buff);
|
||||
fsoc.Close();
|
||||
}
|
||||
|
||||
soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
soc.Connect(remoteEP);
|
||||
if (!soc.Poll(0, SelectMode.SelectWrite)) return false;
|
||||
soc.Send(renderSequence);
|
||||
soc.Close();
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void ServerGetData(List<string> fileList)
|
||||
{
|
||||
serverGetFileList = fileList;
|
||||
serverGetFileIterator = 0;
|
||||
serverGetDataMode = true;
|
||||
}
|
||||
|
||||
public static void Update()
|
||||
{
|
||||
if (statusProc != null) statusProc.MoveNext();
|
||||
}
|
||||
}
|
||||
|
||||
12
Assets/Editor/x64/Bakery/scripts/ftClient.cs.meta
Normal file
12
Assets/Editor/x64/Bakery/scripts/ftClient.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 500a77e47a646b24581261ad5e43fe3d
|
||||
timeCreated: 1552557323
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
82
Assets/Editor/x64/Bakery/scripts/ftCreateMenu.cs
Normal file
82
Assets/Editor/x64/Bakery/scripts/ftCreateMenu.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
public class ftCreateMenu
|
||||
{
|
||||
[MenuItem("Bakery/Create/Directional Light", false, 20)]
|
||||
private static void CreateDirectionalLight()
|
||||
{
|
||||
var go = new GameObject();
|
||||
Undo.RegisterCreatedObjectUndo(go, "Create Bakery light");
|
||||
go.AddComponent<BakeryDirectLight>();
|
||||
go.name = "DirectLight";
|
||||
var ecam = SceneView.lastActiveSceneView.camera.transform;
|
||||
go.transform.position = ecam.position + ecam.forward;
|
||||
go.transform.eulerAngles = new Vector3(50, -30, 0);
|
||||
var arr = new GameObject[1];
|
||||
arr[0] = go;
|
||||
Selection.objects = arr;
|
||||
}
|
||||
|
||||
[MenuItem("Bakery/Create/Skylight", false, 20)]
|
||||
private static void CreateSkyLight()
|
||||
{
|
||||
var go = new GameObject();
|
||||
Undo.RegisterCreatedObjectUndo(go, "Create Bakery light");
|
||||
go.AddComponent<BakerySkyLight>();
|
||||
go.name = "Skylight";
|
||||
var ecam = SceneView.lastActiveSceneView.camera.transform;
|
||||
go.transform.position = ecam.position + ecam.forward;
|
||||
var arr = new GameObject[1];
|
||||
arr[0] = go;
|
||||
Selection.objects = arr;
|
||||
}
|
||||
|
||||
[MenuItem("Bakery/Create/Point Light", false, 20)]
|
||||
private static void CreatePointLight()
|
||||
{
|
||||
var go = new GameObject();
|
||||
Undo.RegisterCreatedObjectUndo(go, "Create Bakery light");
|
||||
go.AddComponent<BakeryPointLight>();
|
||||
go.name = "PointLight";
|
||||
var ecam = SceneView.lastActiveSceneView.camera.transform;
|
||||
go.transform.position = ecam.position + ecam.forward;
|
||||
var arr = new GameObject[1];
|
||||
arr[0] = go;
|
||||
Selection.objects = arr;
|
||||
}
|
||||
|
||||
[MenuItem("Bakery/Create/Area Light (Example)", false, 20)]
|
||||
private static void CreateAreaLight()
|
||||
{
|
||||
var go = GameObject.CreatePrimitive(PrimitiveType.Quad);
|
||||
Undo.RegisterCreatedObjectUndo(go, "Create Bakery light");
|
||||
go.AddComponent<BakeryLightMesh>();
|
||||
go.name = "AreaLight";
|
||||
var ecam = SceneView.lastActiveSceneView.camera.transform;
|
||||
go.transform.position = ecam.position + ecam.forward;
|
||||
var bakeryRuntimePath = ftLightmaps.GetRuntimePath();
|
||||
var mat = AssetDatabase.LoadAssetAtPath(bakeryRuntimePath + "ftDefaultAreaLightMat.mat", typeof(Material)) as Material;
|
||||
go.GetComponent<MeshRenderer>().material = mat;
|
||||
var arr = new GameObject[1];
|
||||
arr[0] = go;
|
||||
Selection.objects = arr;
|
||||
}
|
||||
|
||||
[MenuItem("Bakery/Create/Spotlight", false, 20)]
|
||||
private static void CreateSpotLight()
|
||||
{
|
||||
var go = new GameObject();
|
||||
Undo.RegisterCreatedObjectUndo(go, "Create Bakery light");
|
||||
var light = go.AddComponent<BakeryPointLight>();
|
||||
light.projMode = BakeryPointLight.ftLightProjectionMode.Cookie;
|
||||
var bakeryRuntimePath = ftLightmaps.GetRuntimePath();
|
||||
light.cookie = AssetDatabase.LoadAssetAtPath(bakeryRuntimePath + "ftUnitySpotTexture.bmp", typeof(Texture2D)) as Texture2D;
|
||||
go.name = "SpotLight";
|
||||
var ecam = SceneView.lastActiveSceneView.camera.transform;
|
||||
go.transform.position = ecam.position + ecam.forward;
|
||||
var arr = new GameObject[1];
|
||||
arr[0] = go;
|
||||
Selection.objects = arr;
|
||||
}
|
||||
}
|
||||
12
Assets/Editor/x64/Bakery/scripts/ftCreateMenu.cs.meta
Normal file
12
Assets/Editor/x64/Bakery/scripts/ftCreateMenu.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1b37b47c815251d4290ee5b16dec9c70
|
||||
timeCreated: 1527799006
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
56
Assets/Editor/x64/Bakery/scripts/ftDDS.cs
Normal file
56
Assets/Editor/x64/Bakery/scripts/ftDDS.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
public class ftDDS
|
||||
{
|
||||
public static byte[] ddsHeaderFloat4 = new byte[]
|
||||
{
|
||||
0x44, 0x44, 0x53, 0x20, 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x08, 0x00, 0xF0, 0x00, 0x00, 0x00,
|
||||
0x40, 0x01, 0x00, 0x00, 0x00, 0xC0, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||
0x04, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
public static byte[] ddsHeaderHalf4 = new byte[]
|
||||
{
|
||||
0x44, 0x44, 0x53, 0x20, 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x08, 0x00, 0xCD, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x68, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||
0x04, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
public static byte[] ddsHeaderRGBA8 = new byte[]
|
||||
{
|
||||
0x44, 0x44, 0x53, 0x20, 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x08, 0x00, 0x00, 0x02, 0x00, 0x00,
|
||||
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||
0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00,
|
||||
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x10, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
public static byte[] ddsHeaderR32F = new byte[]
|
||||
{
|
||||
0x44, 0x44, 0x53, 0x20, 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x13, 0x00, 0x00, 0x00, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||
0x04, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
}
|
||||
12
Assets/Editor/x64/Bakery/scripts/ftDDS.cs.meta
Normal file
12
Assets/Editor/x64/Bakery/scripts/ftDDS.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7651ced8d6837974980b54a8c065ca41
|
||||
timeCreated: 1526839491
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
41
Assets/Editor/x64/Bakery/scripts/ftDefine.cs
Normal file
41
Assets/Editor/x64/Bakery/scripts/ftDefine.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
#if UNITY_EDITOR
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
using UnityEditor.Build;
|
||||
|
||||
[InitializeOnLoad]
|
||||
#if UNITY_2017_4_OR_NEWER
|
||||
public class ftDefine : IActiveBuildTargetChanged
|
||||
#else
|
||||
public class ftDefine
|
||||
#endif
|
||||
{
|
||||
static void AddDefine()
|
||||
{
|
||||
var platform = EditorUserBuildSettings.selectedBuildTargetGroup;
|
||||
var defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(platform);
|
||||
if (!defines.Contains("BAKERY_INCLUDED"))
|
||||
{
|
||||
if (defines.Length > 0) defines += ";";
|
||||
defines += "BAKERY_INCLUDED";
|
||||
PlayerSettings.SetScriptingDefineSymbolsForGroup(platform, defines);
|
||||
}
|
||||
}
|
||||
|
||||
static ftDefine()
|
||||
{
|
||||
AddDefine();
|
||||
}
|
||||
|
||||
#if UNITY_2017_4_OR_NEWER
|
||||
public int callbackOrder { get { return 0; } }
|
||||
public void OnActiveBuildTargetChanged(BuildTarget previousTarget, BuildTarget newTarget)
|
||||
{
|
||||
AddDefine();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
12
Assets/Editor/x64/Bakery/scripts/ftDefine.cs.meta
Normal file
12
Assets/Editor/x64/Bakery/scripts/ftDefine.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 993d44f6e3c171944a748e43ca064632
|
||||
timeCreated: 1584625781
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
248
Assets/Editor/x64/Bakery/scripts/ftDetectSettings.cs
Normal file
248
Assets/Editor/x64/Bakery/scripts/ftDetectSettings.cs
Normal file
@@ -0,0 +1,248 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEngine.SceneManagement;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
public class ftDetectSettings
|
||||
{
|
||||
[DllImport ("frender", CallingConvention=CallingConvention.Cdecl)]
|
||||
public static extern System.IntPtr RunLocalProcess([MarshalAs(UnmanagedType.LPWStr)]string commandline, bool setWorkDir);
|
||||
|
||||
[DllImport ("frender", CallingConvention=CallingConvention.Cdecl)]
|
||||
public static extern bool IsProcessFinished(System.IntPtr proc);
|
||||
|
||||
[DllImport ("frender", CallingConvention=CallingConvention.Cdecl)]
|
||||
public static extern int GetProcessReturnValueAndClose(System.IntPtr proc);
|
||||
|
||||
[DllImport ("simpleProgressBar", CallingConvention=CallingConvention.Cdecl)]
|
||||
public static extern int simpleProgressBarShow(string header, string msg, float percent, float step);
|
||||
|
||||
[DllImport ("simpleProgressBar", CallingConvention=CallingConvention.Cdecl)]
|
||||
public static extern bool simpleProgressBarCancelled();
|
||||
|
||||
[DllImport ("simpleProgressBar", CallingConvention=CallingConvention.Cdecl)]
|
||||
public static extern void simpleProgressBarEnd();
|
||||
|
||||
static IEnumerator progressFunc;
|
||||
static int lastReturnValue = -1;
|
||||
static bool userCanceled = false;
|
||||
|
||||
static bool runsRTX, runsNonRTX, runsOptix5, runsOptix6, runsOptix7, runsOIDN;
|
||||
|
||||
const string progressHeader = "Detecting compatible configuration";
|
||||
|
||||
static void ShowProgress(string msg, float percent)
|
||||
{
|
||||
simpleProgressBarShow(progressHeader, msg, percent, 0);
|
||||
}
|
||||
|
||||
[MenuItem("Bakery/Utilities/Detect optimal settings", false, 54)]
|
||||
public static void DetectCompatSettings()
|
||||
{
|
||||
progressFunc = DetectCoroutine();
|
||||
EditorApplication.update += DetectUpdate;
|
||||
}
|
||||
|
||||
static IEnumerator DetectCoroutine()
|
||||
{
|
||||
float stages = 6;
|
||||
float step = 1.0f / stages;
|
||||
float progress = 0;
|
||||
IEnumerator crt;
|
||||
|
||||
ShowProgress("Testing: RTX ray-tracing", progress);
|
||||
crt = ProcessCoroutine("ftraceRTX.exe /sun hwtestdata light 4 0 0 direct0.bin");
|
||||
while (crt.MoveNext()) yield return null;
|
||||
if (userCanceled) yield break;
|
||||
runsRTX = lastReturnValue==0;
|
||||
progress += step;
|
||||
|
||||
ShowProgress("Testing: non-RTX ray-tracing", progress);
|
||||
crt = ProcessCoroutine("ftrace.exe /sun hwtestdata light 4 0 0 direct0.bin");
|
||||
while (crt.MoveNext()) yield return null;
|
||||
if (userCanceled) yield break;
|
||||
runsNonRTX = lastReturnValue==0;
|
||||
progress += step;
|
||||
|
||||
ShowProgress("Testing: OptiX 5.1 denoiser", progress);
|
||||
crt = ProcessCoroutine("denoiserLegacy c hwtestdata/image.lz4 hwtestdata/image.lz4 16 0");
|
||||
while (crt.MoveNext()) yield return null;
|
||||
if (userCanceled) yield break;
|
||||
runsOptix5 = lastReturnValue==0;
|
||||
progress += step;
|
||||
|
||||
ShowProgress("Testing: OptiX 6.0 denoiser", progress);
|
||||
crt = ProcessCoroutine("denoiser c hwtestdata/image.lz4 hwtestdata/image.lz4 16 0");
|
||||
while (crt.MoveNext()) yield return null;
|
||||
if (userCanceled) yield break;
|
||||
runsOptix6 = lastReturnValue==0;
|
||||
progress += step;
|
||||
|
||||
ShowProgress("Testing: OptiX 7.2 denoiser", progress);
|
||||
crt = ProcessCoroutine("denoiser72 c hwtestdata/image.lz4 hwtestdata/image.lz4 16 0");
|
||||
while (crt.MoveNext()) yield return null;
|
||||
if (userCanceled) yield break;
|
||||
runsOptix7 = lastReturnValue==0;
|
||||
progress += step;
|
||||
|
||||
ShowProgress("Testing: OpenImageDenoise", progress);
|
||||
crt = ProcessCoroutine("denoiserOIDN c hwtestdata/image.lz4 hwtestdata/image.lz4 16 0");
|
||||
while (crt.MoveNext()) yield return null;
|
||||
if (userCanceled) yield break;
|
||||
runsOIDN = lastReturnValue==0;
|
||||
progress += step;
|
||||
|
||||
simpleProgressBarEnd();
|
||||
|
||||
if (!runsRTX && !runsNonRTX)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Error", "Both RTX and non-RTX lightmapper failed to run. Make sure you are using NVIDIA GPU and the drivers are up to date.", "OK");
|
||||
yield break;
|
||||
}
|
||||
|
||||
string str = "Testing results:\n\n";
|
||||
str += "RTX ray-tracing: " + (runsRTX ? "yes" : "no") + "\n";
|
||||
str += "Non-RTX ray-tracing: " + (runsNonRTX ? "yes" : "no") + "\n";
|
||||
str += "OptiX 5.1 denoiser: " + (runsOptix5 ? "yes" : "no") + "\n";
|
||||
str += "OptiX 6.0 denoiser: " + (runsOptix6 ? "yes" : "no") + "\n";
|
||||
str += "OptiX 7.2 denoiser: " + (runsOptix7 ? "yes" : "no") + "\n";
|
||||
str += "OpenImageDenoise: " + (runsOIDN ? "yes" : "no") + "\n";
|
||||
|
||||
str += "\n";
|
||||
str += "Recommended RTX mode: ";
|
||||
if (runsRTX && runsNonRTX)
|
||||
{
|
||||
str += "ON if you are using a GPU with RT acceleration (e.g. 2xxx or 3xxx GeForce series), OFF otherwise.\n";
|
||||
}
|
||||
else if (runsRTX)
|
||||
{
|
||||
str += "ON\n";
|
||||
}
|
||||
else if (runsNonRTX)
|
||||
{
|
||||
str += "OFF\n";
|
||||
}
|
||||
|
||||
str += "\n";
|
||||
str += "Recommended denoiser: ";
|
||||
if (runsOptix5)
|
||||
{
|
||||
// OptiX 5.1 has stable quality since release, but not supported on 30XX
|
||||
str += "OptiX 5.1\n";
|
||||
}
|
||||
else if (runsOIDN)
|
||||
{
|
||||
// OIDN is stable and pretty good, but might be slower
|
||||
str += "OpenImageDenoise\n";
|
||||
}
|
||||
// OptiX 6 and 7.2 should run on 30XX, but quality is sometimes questionable IF driver is newer than 442.50
|
||||
// as the network is now part of the driver.
|
||||
// On older drivers they should work similar to 5.1.
|
||||
else if (runsOptix7)
|
||||
{
|
||||
str += "OptiX 7.2\n";
|
||||
}
|
||||
else if (runsOptix6)
|
||||
{
|
||||
str += "OptiX 6.0\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
str += "all denoiser tests failed. Try updating GPU drivers.\n";
|
||||
}
|
||||
|
||||
var bakeryRuntimePath = ftLightmaps.GetRuntimePath();
|
||||
var gstorage = AssetDatabase.LoadAssetAtPath(bakeryRuntimePath + "ftGlobalStorage.asset", typeof(ftGlobalStorage)) as ftGlobalStorage;
|
||||
if (gstorage == null) Debug.LogError("Can't find global storage");
|
||||
var storage = ftRenderLightmap.FindRenderSettingsStorage();
|
||||
|
||||
if (gstorage != null)
|
||||
{
|
||||
gstorage.foundCompatibleSetup = true;
|
||||
gstorage.gpuName = SystemInfo.graphicsDeviceName;
|
||||
gstorage.runsNonRTX = runsNonRTX;
|
||||
gstorage.alwaysEnableRTX = false;
|
||||
gstorage.runsOptix5 = runsOptix5;
|
||||
gstorage.runsOptix6 = runsOptix6;
|
||||
gstorage.runsOptix7 = runsOptix7;
|
||||
gstorage.runsOIDN = runsOIDN;
|
||||
}
|
||||
|
||||
if (!EditorUtility.DisplayDialog("Results", str, "OK", "Set recommended as default"))
|
||||
{
|
||||
if (runsRTX && runsNonRTX)
|
||||
{
|
||||
gstorage.renderSettingsRTXMode = EditorUtility.DisplayDialog("Question", "Does your GPU have RT cores (set RTX mode as default)?", "Yes", "No");
|
||||
}
|
||||
else if (runsRTX)
|
||||
{
|
||||
gstorage.renderSettingsRTXMode = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
gstorage.renderSettingsRTXMode = false;
|
||||
}
|
||||
|
||||
if (runsOptix5)
|
||||
{
|
||||
gstorage.renderSettingsDenoiserType = (int)ftGlobalStorage.DenoiserType.Optix5;
|
||||
}
|
||||
else if (runsOIDN)
|
||||
{
|
||||
gstorage.renderSettingsDenoiserType = (int)ftGlobalStorage.DenoiserType.OpenImageDenoise;
|
||||
}
|
||||
else if (runsOptix7)
|
||||
{
|
||||
gstorage.renderSettingsDenoiserType = (int)ftGlobalStorage.DenoiserType.Optix7;
|
||||
}
|
||||
else if (runsOptix6)
|
||||
{
|
||||
gstorage.renderSettingsDenoiserType = (int)ftGlobalStorage.DenoiserType.Optix6;
|
||||
}
|
||||
|
||||
EditorUtility.SetDirty(gstorage);
|
||||
Debug.Log("Default settings saved");
|
||||
|
||||
if (storage != null)
|
||||
{
|
||||
storage.renderSettingsRTXMode = gstorage.renderSettingsRTXMode;
|
||||
storage.renderSettingsDenoiserType = gstorage.renderSettingsDenoiserType;
|
||||
}
|
||||
}
|
||||
|
||||
var bakery = ftRenderLightmap.instance != null ? ftRenderLightmap.instance : new ftRenderLightmap();
|
||||
bakery.LoadRenderSettings();
|
||||
}
|
||||
|
||||
static void DetectUpdate()
|
||||
{
|
||||
if (!progressFunc.MoveNext())
|
||||
{
|
||||
EditorApplication.update -= DetectUpdate;
|
||||
}
|
||||
}
|
||||
|
||||
static IEnumerator ProcessCoroutine(string cmd)
|
||||
{
|
||||
var exeProcess = RunLocalProcess(cmd, true);
|
||||
if (exeProcess == (System.IntPtr)null)
|
||||
{
|
||||
lastReturnValue = -1;
|
||||
yield break;
|
||||
}
|
||||
while(!IsProcessFinished(exeProcess))
|
||||
{
|
||||
yield return null;
|
||||
userCanceled = simpleProgressBarCancelled();
|
||||
if (userCanceled)
|
||||
{
|
||||
simpleProgressBarEnd();
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
lastReturnValue = GetProcessReturnValueAndClose(exeProcess);
|
||||
}
|
||||
}
|
||||
|
||||
12
Assets/Editor/x64/Bakery/scripts/ftDetectSettings.cs.meta
Normal file
12
Assets/Editor/x64/Bakery/scripts/ftDetectSettings.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: afee4282908768e4a8b35d3e5754110c
|
||||
timeCreated: 1605465718
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
418
Assets/Editor/x64/Bakery/scripts/ftDirectLightInspector.cs
Normal file
418
Assets/Editor/x64/Bakery/scripts/ftDirectLightInspector.cs
Normal file
@@ -0,0 +1,418 @@
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
[CustomEditor(typeof(BakeryDirectLight))]
|
||||
[CanEditMultipleObjects]
|
||||
public class ftDirectLightInspector : UnityEditor.Editor
|
||||
{
|
||||
SerializedProperty ftraceLightColor;
|
||||
SerializedProperty ftraceLightIntensity;
|
||||
SerializedProperty ftraceLightShadowSpread;
|
||||
SerializedProperty ftraceLightSamples;
|
||||
SerializedProperty ftraceLightBitmask;
|
||||
SerializedProperty ftraceLightBakeToIndirect;
|
||||
SerializedProperty ftraceLightShadowmask;
|
||||
SerializedProperty ftraceLightShadowmaskDenoise;
|
||||
SerializedProperty ftraceLightIndirectIntensity;
|
||||
SerializedProperty ftraceLightTexture, ftraceLightCSTilingX, ftraceLightCSTilingY, ftraceLightCSOffsetX, ftraceLightCSOffsetY;
|
||||
|
||||
ftLightmapsStorage storage;
|
||||
|
||||
bool isHDRP = false;
|
||||
|
||||
public enum BakeWhat
|
||||
{
|
||||
DirectAndIndirect = 0,
|
||||
IndirectOnly = 1,
|
||||
IndirectAndShadowmask = 2
|
||||
};
|
||||
|
||||
static public string[] directContributionIndirectOptions = new string[] {"Direct And Indirect", "Indirect Only", "Shadowmask and Indirect (not applicable in Indirect mode)"};
|
||||
|
||||
static string[] selStrings = new string[] {"0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16",
|
||||
"17","18","19","20","21","22","23","24","25","26","27","28","29","30"};//,"31"};
|
||||
|
||||
void InitSerializedProperties(SerializedObject obj)
|
||||
{
|
||||
ftraceLightColor = obj.FindProperty("color");
|
||||
ftraceLightIntensity = obj.FindProperty("intensity");
|
||||
ftraceLightIndirectIntensity = obj.FindProperty("indirectIntensity");
|
||||
ftraceLightShadowSpread = obj.FindProperty("shadowSpread");
|
||||
ftraceLightSamples = obj.FindProperty("samples");
|
||||
ftraceLightBitmask = obj.FindProperty("bitmask");
|
||||
ftraceLightBakeToIndirect = obj.FindProperty("bakeToIndirect");
|
||||
ftraceLightShadowmask = obj.FindProperty("shadowmask");
|
||||
ftraceLightShadowmaskDenoise = obj.FindProperty("shadowmaskDenoise");
|
||||
ftraceLightTexture = obj.FindProperty("cloudShadow");
|
||||
ftraceLightCSTilingX = obj.FindProperty("cloudShadowTilingX");
|
||||
ftraceLightCSTilingY = obj.FindProperty("cloudShadowTilingY");
|
||||
ftraceLightCSOffsetX = obj.FindProperty("cloudShadowOffsetX");
|
||||
ftraceLightCSOffsetY = obj.FindProperty("cloudShadowOffsetY");
|
||||
|
||||
isHDRP = (target as BakeryDirectLight).GetComponent("HDAdditionalLightData") != null;
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
InitSerializedProperties(serializedObject);
|
||||
}
|
||||
|
||||
void SetHDRPLight(Light l)
|
||||
{
|
||||
l.intensity *= Mathf.PI;
|
||||
|
||||
var hdrpLight = l.GetComponent("HDAdditionalLightData");
|
||||
if (hdrpLight == null)
|
||||
{
|
||||
Debug.LogWarning("HDRP: no HDAdditionalLightData");
|
||||
return;
|
||||
}
|
||||
var so = new SerializedObject(hdrpLight);
|
||||
if (so == null)
|
||||
{
|
||||
Debug.LogWarning("HDRP: no SerializedObject");
|
||||
return;
|
||||
}
|
||||
|
||||
SerializedProperty hdrpInt2 = so.FindProperty("m_Intensity");
|
||||
if (hdrpInt2 == null)
|
||||
{
|
||||
Debug.LogWarning("HDRP: no m_Intensity");
|
||||
return;
|
||||
}
|
||||
hdrpInt2.floatValue = l.intensity;
|
||||
|
||||
so.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
void GetLinearLightParameters(Light light, out float lightR, out float lightG, out float lightB, out float lightInt)
|
||||
{
|
||||
if (PlayerSettings.colorSpace != ColorSpace.Linear)
|
||||
{
|
||||
lightInt = light.intensity;
|
||||
lightR = light.color.r;
|
||||
lightG = light.color.g;
|
||||
lightB = light.color.b;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GraphicsSettings.lightsUseLinearIntensity)
|
||||
{
|
||||
lightR = Mathf.Pow(light.color.r * light.intensity, 2.2f);
|
||||
lightG = Mathf.Pow(light.color.g * light.intensity, 2.2f);
|
||||
lightB = Mathf.Pow(light.color.b * light.intensity, 2.2f);
|
||||
lightInt = Mathf.Max(Mathf.Max(lightR, lightG), lightB);
|
||||
lightR /= lightInt;
|
||||
lightG /= lightInt;
|
||||
lightB /= lightInt;
|
||||
}
|
||||
else
|
||||
{
|
||||
lightInt = light.intensity;
|
||||
lightR = light.color.linear.r;
|
||||
lightG = light.color.linear.g;
|
||||
lightB = light.color.linear.b;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI() {
|
||||
//if (showFtrace)
|
||||
//{
|
||||
OnEnable();
|
||||
serializedObject.Update();
|
||||
|
||||
EditorGUILayout.PropertyField(ftraceLightColor, new GUIContent("Color", "Color of the light"));
|
||||
EditorGUILayout.PropertyField(ftraceLightIntensity, new GUIContent("Intensity", "Color multiplier (Lux / Pi)"));
|
||||
EditorGUILayout.PropertyField(ftraceLightShadowSpread, new GUIContent("Shadow spread", "Controls shadow blurriness from 0 to 1"));
|
||||
EditorGUILayout.PropertyField(ftraceLightSamples, new GUIContent("Shadow samples", "The amount of rays tested for this light. Rays are emitted from lightmap texel towards the light, distributed conically. Radius of the cone depends on Shadow Spread."));
|
||||
|
||||
//ftraceLightBitmask.intValue = EditorGUILayout.MaskField(new GUIContent("Bitmask", "Lights only affect renderers with overlapping bits"), ftraceLightBitmask.intValue, selStrings);
|
||||
int prevVal = ftraceLightBitmask.intValue;
|
||||
int newVal = EditorGUILayout.MaskField(new GUIContent("Bitmask", "Lights only affect renderers with overlapping bits"), ftraceLightBitmask.intValue, selStrings);
|
||||
if (prevVal != newVal) ftraceLightBitmask.intValue = newVal;
|
||||
|
||||
/*
|
||||
EditorGUILayout.PropertyField(ftraceLightBakeToIndirect, new GUIContent("Bake to indirect", "Add direct contribution from this light to indirect-only lightmaps"));
|
||||
if (ftraceLightBakeToIndirect.boolValue && ftraceLightShadowmask.boolValue) ftraceLightShadowmask.boolValue = false;
|
||||
|
||||
EditorGUILayout.PropertyField(ftraceLightShadowmask, new GUIContent("Shadowmask", "Enable mixed lighting. Static shadows from this light will be baked, and real-time light will cast shadows from dynamic objects."));
|
||||
if (ftraceLightBakeToIndirect.boolValue && ftraceLightShadowmask.boolValue) ftraceLightBakeToIndirect.boolValue = false;
|
||||
*/
|
||||
|
||||
if (storage == null) storage = ftRenderLightmap.FindRenderSettingsStorage();
|
||||
var rmode = storage.renderSettingsUserRenderMode;
|
||||
if (rmode != (int)ftRenderLightmap.RenderMode.FullLighting)
|
||||
{
|
||||
BakeWhat contrib;
|
||||
if (ftraceLightShadowmask.boolValue)
|
||||
{
|
||||
contrib = BakeWhat.IndirectAndShadowmask;
|
||||
}
|
||||
else if (ftraceLightBakeToIndirect.boolValue)
|
||||
{
|
||||
contrib = BakeWhat.DirectAndIndirect;
|
||||
}
|
||||
else
|
||||
{
|
||||
contrib = BakeWhat.IndirectOnly;
|
||||
}
|
||||
var prevContrib = contrib;
|
||||
|
||||
if (rmode == (int)ftRenderLightmap.RenderMode.Indirect)
|
||||
{
|
||||
contrib = (BakeWhat)EditorGUILayout.Popup("Baked contribution", (int)contrib, directContributionIndirectOptions);
|
||||
}
|
||||
else if (rmode == (int)ftRenderLightmap.RenderMode.Shadowmask)
|
||||
{
|
||||
contrib = (BakeWhat)EditorGUILayout.EnumPopup("Baked contribution", contrib);
|
||||
}
|
||||
|
||||
if (prevContrib != contrib)
|
||||
{
|
||||
if (contrib == BakeWhat.IndirectOnly)
|
||||
{
|
||||
ftraceLightShadowmask.boolValue = false;
|
||||
ftraceLightBakeToIndirect.boolValue = false;
|
||||
}
|
||||
else if (contrib == BakeWhat.IndirectAndShadowmask)
|
||||
{
|
||||
ftraceLightShadowmask.boolValue = true;
|
||||
ftraceLightBakeToIndirect.boolValue = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ftraceLightShadowmask.boolValue = false;
|
||||
ftraceLightBakeToIndirect.boolValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (ftraceLightShadowmask.boolValue)
|
||||
{
|
||||
EditorGUILayout.PropertyField(ftraceLightShadowmaskDenoise, new GUIContent("Denoise shadowmask", "Apply denoising to shadowmask texture. For sharp shadows it may be unnecessary."));
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(ftraceLightIndirectIntensity, new GUIContent("Indirect intensity", "Non-physical GI multiplier for this light"));
|
||||
|
||||
EditorGUILayout.PropertyField(ftraceLightTexture, new GUIContent("Texture projection", "Tiled projected texture"));
|
||||
if (ftraceLightTexture.objectReferenceValue != null)
|
||||
{
|
||||
EditorGUILayout.PropertyField(ftraceLightCSTilingX, new GUIContent("Tiling U", "Cloud shadow U tiling"));
|
||||
EditorGUILayout.PropertyField(ftraceLightCSTilingY, new GUIContent("Tiling V", "Cloud shadow V tiling"));
|
||||
EditorGUILayout.PropertyField(ftraceLightCSOffsetX, new GUIContent("Offset U", "Cloud shadow U tiling"));
|
||||
EditorGUILayout.PropertyField(ftraceLightCSOffsetY, new GUIContent("Offset V", "Cloud shadow V tiling"));
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
//}
|
||||
|
||||
|
||||
bool showError = false;
|
||||
string why = "";
|
||||
|
||||
bool shadowmaskNoDynamicLight = false;
|
||||
|
||||
foreach(BakeryDirectLight selectedLight in targets)
|
||||
{
|
||||
bool match = true;
|
||||
|
||||
var light = selectedLight.GetComponent<Light>();
|
||||
if (light == null)
|
||||
{
|
||||
if (ftraceLightShadowmask.boolValue) shadowmaskNoDynamicLight = true;
|
||||
continue;
|
||||
}
|
||||
if (!light.enabled)
|
||||
{
|
||||
if (ftraceLightShadowmask.boolValue) shadowmaskNoDynamicLight = true;
|
||||
}
|
||||
var so = new SerializedObject(selectedLight);
|
||||
InitSerializedProperties(so);
|
||||
|
||||
if (light.type != LightType.Directional)
|
||||
{
|
||||
match = false;
|
||||
why = "real-time light is not direct";
|
||||
}
|
||||
|
||||
if (light.bounceIntensity != ftraceLightIndirectIntensity.floatValue)
|
||||
{
|
||||
match = false;
|
||||
why = "indirect intensity doesn't match";
|
||||
}
|
||||
|
||||
var clr = ftraceLightColor.colorValue;
|
||||
float eps = 1.0f / 255.0f;
|
||||
float lightR, lightG, lightB, lightInt;
|
||||
float fr, fg, fb;
|
||||
float fintensity = ftraceLightIntensity.floatValue;
|
||||
if (isHDRP) fintensity *= Mathf.PI;
|
||||
if (PlayerSettings.colorSpace == ColorSpace.Linear)
|
||||
{
|
||||
fr = clr.linear.r;// * fintensity;
|
||||
fg = clr.linear.g;// * fintensity;
|
||||
fb = clr.linear.b;// * fintensity;
|
||||
}
|
||||
else
|
||||
{
|
||||
fr = clr.r;
|
||||
fg = clr.g;
|
||||
fb = clr.b;
|
||||
}
|
||||
GetLinearLightParameters(light, out lightR, out lightG, out lightB, out lightInt);
|
||||
|
||||
if (GraphicsSettings.lightsUseLinearIntensity || PlayerSettings.colorSpace != ColorSpace.Linear)
|
||||
{
|
||||
if (Mathf.Abs(lightR - fr) > eps || Mathf.Abs(lightG - fg) > eps || Mathf.Abs(lightB - fb) > eps)
|
||||
{
|
||||
match = false;
|
||||
why = "color doesn't match";
|
||||
}
|
||||
else if (Mathf.Abs(lightInt - fintensity) > eps)
|
||||
{
|
||||
match = false;
|
||||
why = "intensity doesn't match";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
eps *= Mathf.Max(lightInt, fintensity);
|
||||
if (Mathf.Abs(lightR*lightInt - fr*fintensity) > eps ||
|
||||
Mathf.Abs(lightG*lightInt - fg*fintensity) > eps ||
|
||||
Mathf.Abs(lightB*lightInt - fb*fintensity) > eps)
|
||||
{
|
||||
match = false;
|
||||
why = "intensity doesn't match";
|
||||
}
|
||||
}
|
||||
|
||||
if (!match)
|
||||
{
|
||||
showError = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (shadowmaskNoDynamicLight)
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Warning: shadowmask needs enabled real-time light to work");
|
||||
}
|
||||
|
||||
if (showError)
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Real-time light doesn't match lightmap: " + why);
|
||||
if (GUILayout.Button("Match lightmapped to real-time"))
|
||||
{
|
||||
foreach(BakeryDirectLight selectedLight in targets)
|
||||
{
|
||||
var light = selectedLight.GetComponent<Light>();
|
||||
if (light == null) continue;
|
||||
//if (!light.enabled) continue;
|
||||
var so = new SerializedObject(selectedLight);
|
||||
InitSerializedProperties(so);
|
||||
|
||||
if (PlayerSettings.colorSpace != ColorSpace.Linear)
|
||||
{
|
||||
ftraceLightColor.colorValue = light.color;
|
||||
ftraceLightIntensity.floatValue = light.intensity;
|
||||
}
|
||||
else if (!GraphicsSettings.lightsUseLinearIntensity)
|
||||
{
|
||||
float lightR, lightG, lightB, lightInt;
|
||||
GetLinearLightParameters(light, out lightR, out lightG, out lightB, out lightInt);
|
||||
ftraceLightColor.colorValue = new Color(lightR, lightG, lightB);
|
||||
ftraceLightIntensity.floatValue = lightInt;
|
||||
}
|
||||
else
|
||||
{
|
||||
ftraceLightColor.colorValue = light.color;
|
||||
ftraceLightIntensity.floatValue = light.intensity;
|
||||
}
|
||||
ftraceLightIndirectIntensity.floatValue = light.bounceIntensity;
|
||||
if (isHDRP) ftraceLightIntensity.floatValue /= Mathf.PI;
|
||||
|
||||
so.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
if (GUILayout.Button("Match real-time to lightmapped"))
|
||||
{
|
||||
foreach(BakeryDirectLight selectedLight in targets)
|
||||
{
|
||||
var light = selectedLight.GetComponent<Light>();
|
||||
if (light == null) continue;
|
||||
//if (!light.enabled) continue;
|
||||
var so = new SerializedObject(selectedLight);
|
||||
InitSerializedProperties(so);
|
||||
|
||||
Undo.RecordObject(light, "Change light");
|
||||
if (PlayerSettings.colorSpace != ColorSpace.Linear)
|
||||
{
|
||||
light.color = ftraceLightColor.colorValue;
|
||||
light.intensity = ftraceLightIntensity.floatValue;
|
||||
}
|
||||
else if (!GraphicsSettings.lightsUseLinearIntensity)
|
||||
{
|
||||
float fr, fg, fb;
|
||||
float fintensity = ftraceLightIntensity.floatValue;
|
||||
var clr = ftraceLightColor.colorValue;
|
||||
fr = clr.linear.r;// * fintensity;
|
||||
fg = clr.linear.g;// * fintensity;
|
||||
fb = clr.linear.b;// * fintensity;
|
||||
|
||||
fr = Mathf.Pow(fr * fintensity, 1.0f / 2.2f);
|
||||
fg = Mathf.Pow(fg * fintensity, 1.0f / 2.2f);
|
||||
fb = Mathf.Pow(fb * fintensity, 1.0f / 2.2f);
|
||||
float fint = Mathf.Max(Mathf.Max(fr, fg), fb);
|
||||
fr /= fint;
|
||||
fg /= fint;
|
||||
fb /= fint;
|
||||
light.color = new Color(fr, fg, fb);
|
||||
light.intensity = fint;
|
||||
}
|
||||
else
|
||||
{
|
||||
light.color = ftraceLightColor.colorValue;
|
||||
light.intensity = ftraceLightIntensity.floatValue;
|
||||
}
|
||||
light.type = LightType.Directional;
|
||||
light.bounceIntensity = ftraceLightIndirectIntensity.floatValue;
|
||||
if (isHDRP) SetHDRPLight(light);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (PlayerSettings.colorSpace == ColorSpace.Linear)
|
||||
{
|
||||
if (!GraphicsSettings.lightsUseLinearIntensity)
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Warning: project is not set up to use linear light intensity.");
|
||||
EditorGUILayout.LabelField("GraphicsSettings.lightsUseLinearIntensity should be TRUE.");
|
||||
if (GUILayout.Button("Fix"))
|
||||
{
|
||||
GraphicsSettings.lightsUseLinearIntensity = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Project is using linear light intensity. This is nice.");
|
||||
if (GUILayout.Button("Change to non-linear"))
|
||||
{
|
||||
GraphicsSettings.lightsUseLinearIntensity = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a4eb21edcc395a419e2da3246fcbc15
|
||||
timeCreated: 1525273871
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
265
Assets/Editor/x64/Bakery/scripts/ftErrorCodes.cs
Normal file
265
Assets/Editor/x64/Bakery/scripts/ftErrorCodes.cs
Normal file
@@ -0,0 +1,265 @@
|
||||
#if UNITY_EDITOR
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class ftErrorCodes
|
||||
{
|
||||
static Dictionary<int, string> ftraceMap = new Dictionary<int, string>
|
||||
{
|
||||
{1, "Unknown error. See .ftracelog.txt for details."},
|
||||
{2, "Error selecting pass"},
|
||||
{5120, "Can't open lms.bin"},
|
||||
{984, "lmlod.bin doesn't match lms.bin"},
|
||||
{500, "Can't load geometry data. See .ftracelog.txt for details."},
|
||||
{501, "Can't load UVGBuffer smooth position"},
|
||||
{502, "Can't load UVGBuffer face normal"},
|
||||
{505, "Can't load trimarks.bin"},
|
||||
{5005, "Can't load sky.bin"},
|
||||
{500599, "Can't load ao.bin"},
|
||||
{5005991, "Can't load sss.bin"},
|
||||
{507, "Can't load vbtraceUV0.bin"},
|
||||
{508, "Can't load UVGBuffer tangent"},
|
||||
{550, "Can't load light data. See .ftracelog.txt for details."},
|
||||
{557, "Can't load alpha IDs. See .ftracelog.txt for details."},
|
||||
{512, "Can't load compositing data. See .ftracelog.txt for details."},
|
||||
{51298, "Can't open addao.bin"},
|
||||
{875, "Can't load heightmap. See .ftracelog.txt for details."},
|
||||
{90, "Can't load normal to compose. See .ftracelog.txt for details."},
|
||||
{91, "Can't load lightmap to compose. See .ftracelog.txt for details."},
|
||||
{909, "No enabled CUDA devices. See .ftracelog.txt for details."},
|
||||
{910, "Can't load direction to compose. See .ftracelog.txt for details."},
|
||||
{92, "Can't load lightmap to compose. See .ftracelog.txt for details."},
|
||||
{920, "Can't load lightmap to compose. See .ftracelog.txt for details."},
|
||||
{921, "Can't load emission. See .ftracelog.txt for details."},
|
||||
{93, "Can't load lightmap to compose. See .ftracelog.txt for details."},
|
||||
{94, "Can't load lightmap. See .ftracelog.txt for details."},
|
||||
{940, "Can't read direction for GI. See .ftracelog.txt for details."},
|
||||
{95, "Can't read lightmap for GI. See .ftracelog.txt for details."},
|
||||
{510, "Can't write composed lightmap. See .ftracelog.txt for details."},
|
||||
{514, "Can't write composed lightmap. See .ftracelog.txt for details."},
|
||||
{7500, "Can't load UVGBuffer normal or position"},
|
||||
{5090, "Can't decompress UVGBuffer normal"},
|
||||
{5091, "Can't decompress UVGBuffer position"},
|
||||
{5092, "Can't decompress UVGBuffer smooth position"},
|
||||
{5093, "Can't decompress UVGBuffer face normal"},
|
||||
{5083, "Can't decompress UVGBuffer tangent"},
|
||||
{7007, "Can't load direct.bin"},
|
||||
{7771, "Can't read sky texture"},
|
||||
{7772, "Can't read light texture"},
|
||||
{888, "No texture name for cubemaplight"},
|
||||
{8008, "Can't load direct lighting."},
|
||||
{1000, "Can't read albedo for GI. See .ftracelog.txt for details."},
|
||||
{1001, "Can't read lightmap for GI. See .ftracelog.txt for details."},
|
||||
{1007, "Can't read direction for GI. See .ftracelog.txt for details."},
|
||||
{1888, "Failed to initialize"},
|
||||
{10000, "Can't load gi.bin"},
|
||||
};
|
||||
|
||||
static Dictionary<int, string> combineMasksMap = new Dictionary<int, string>
|
||||
{
|
||||
{23, "Can't load texture"},
|
||||
{501, "Can't write file. See console for details."},
|
||||
{5, "Failed to save TGA file. See console for details."},
|
||||
{55, "Failed to save PNG file. See console for details."}
|
||||
};
|
||||
|
||||
static Dictionary<int, string> denoiserMap = new Dictionary<int, string>
|
||||
{
|
||||
{2, "Incorrect arguments"},
|
||||
{3, "Incorrect tile size. Must be between 64 and 8192"},
|
||||
{500, "Can't load texture. See console for details."},
|
||||
{5001, "Can't load texture. See console for details."},
|
||||
{5002, "Can't load texture. See console for details."},
|
||||
{5003, "Can't load texture. See console for details."},
|
||||
{4, "Incorrect tile size. Must be width%tile == height%tile == 0"},
|
||||
{501, "Can't write file. See console for details."},
|
||||
{505, "Unknown error (old driver?)"}
|
||||
};
|
||||
|
||||
static Dictionary<int, string> h2hMap = new Dictionary<int, string>
|
||||
{
|
||||
{23, "Can't load texture. See console for details."},
|
||||
{2, "Failed to get image data from DDS. See console for details."},
|
||||
{3, "Failed to init D3D11"},
|
||||
{4, "Failed to convert"},
|
||||
{45, "Failed to transform pixels"},
|
||||
{5, "Failed to save HDR file. See console for details."}
|
||||
};
|
||||
|
||||
static Dictionary<int, string> i2tMap = new Dictionary<int, string>
|
||||
{
|
||||
{1, "Incorrect arguments"},
|
||||
{2, "Can't read file. See console for details."},
|
||||
{3, "Can't write file. See console for details."},
|
||||
{4, "IES file is not valid. See console for details."},
|
||||
{5, "IES file uses unknown symmetry mode. See console for details."}
|
||||
};
|
||||
|
||||
static Dictionary<int, string> seamfixerMap = new Dictionary<int, string>
|
||||
{
|
||||
{1, "Incorrect arguments"},
|
||||
{2, "Failed to init D3D11"},
|
||||
{501, "Can't load vbtraceTex.bin"},
|
||||
{10, "Can't load lms.bin"},
|
||||
{600, "Can't load lightmap"},
|
||||
{22, "Can't create D3D11 resource"},
|
||||
{3, "Can't create D3D11 resource"},
|
||||
{4, "Can't allocate RAM texture"},
|
||||
{8, "Can't save texture. See console for details."}
|
||||
};
|
||||
|
||||
static Dictionary<int, string> lmrMap = new Dictionary<int, string>
|
||||
{
|
||||
{2, "Failed to init D3D11 or create resource"},
|
||||
{3, "Can't create D3D11 resource"},
|
||||
{601, "Can't load lodmask"},
|
||||
{602, "Can't decompress lodmask (unexpected size)"},
|
||||
{32, "Can't create mip texture"},
|
||||
{33, "Can't create mip render target"},
|
||||
{34, "Can't create mip shader resource view"},
|
||||
{4, "Can't allocate RAM mip texture"},
|
||||
{8, "Can't save texture"}
|
||||
};
|
||||
|
||||
static Dictionary<int, string> serverMap = new Dictionary<int, string>
|
||||
{
|
||||
{ftClient.SERVERERROR_IDLE, "Idle"},
|
||||
{ftClient.SERVERERROR_COPY, "File copying failed"},
|
||||
{ftClient.SERVERERROR_GIPARAMS, "Failed to generate GI parameters"},
|
||||
{ftClient.SERVERERROR_NOTIMPLEMENTED, "Feature is not implemented"},
|
||||
{ftClient.SERVERERROR_UNKNOWNTASK, "Unknown task submitted"},
|
||||
{ftClient.SERVERERROR_SCENENAMETOOLONG, "Scene name is too long"},
|
||||
{ftClient.SERVERERROR_FILENOTFOUND, "File not found"},
|
||||
{ftClient.SERVERERROR_FILEHASZEROSIZE, "File has zero size"},
|
||||
{ftClient.SERVERERROR_NOMEM, "Out of memory"},
|
||||
{ftClient.SERVERERROR_INCORRECT, "Incorrect request"},
|
||||
{ftClient.SERVERERROR_INCORRECTFILENAME, "Incorrect filename"},
|
||||
{ftClient.SERVERERROR_WRITEFAILED, "write failed"},
|
||||
{ftClient.SERVERERROR_INCORRECTARGS, "incorrect arguments"},
|
||||
{ftClient.SERVERERROR_FILESIZE, "file size is too large"},
|
||||
{ftClient.SERVERERROR_STATUSLIMIT, "status message can't fit filename"}
|
||||
};
|
||||
|
||||
static Dictionary<int, string> serverAppMap = new Dictionary<int, string>
|
||||
{
|
||||
{ftClient.SERVERTASK_FTRACE, "ftrace"},
|
||||
{ftClient.SERVERTASK_FTRACERTX, "ftraceRTX"},
|
||||
{ftClient.SERVERTASK_COMBINEMASKS, "combineMasks"},
|
||||
|
||||
{ftClient.SERVERTASK_DENOISE5, "denoiserLegacy"},
|
||||
{ftClient.SERVERTASK_DENOISE6, "denoiser"},
|
||||
{ftClient.SERVERTASK_DENOISE7, "denoiser72"},
|
||||
{ftClient.SERVERTASK_DENOISEOIDN, "denoiserOIDN"},
|
||||
|
||||
{ftClient.SERVERTASK_HF2HDR, "halffloat2hdr"},
|
||||
{ftClient.SERVERTASK_RGBA2TGA, "rgba2tga"},
|
||||
{ftClient.SERVERTASK_SEAMFIX, "seamfixer"}
|
||||
};
|
||||
|
||||
public static string TranslateFtrace(int code, bool rtx)
|
||||
{
|
||||
bool unknown = false;
|
||||
string text;
|
||||
if (!ftraceMap.TryGetValue(code, out text))
|
||||
{
|
||||
unknown = true;
|
||||
text = "Unknown error";
|
||||
}
|
||||
text += " (" + code + ")";
|
||||
if (unknown || code == 1)
|
||||
{
|
||||
text += "\n\nPossibly incompatible RTX mode? Try running Bakery -> Utilities -> Detect optimal settings.";
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
public static string TranslateCombineMasks(int code)
|
||||
{
|
||||
string text;
|
||||
if (!combineMasksMap.TryGetValue(code, out text)) text = "Unknown error";
|
||||
return text + " (" + code + ")";
|
||||
}
|
||||
|
||||
public static string TranslateDenoiser(int code)
|
||||
{
|
||||
string text;
|
||||
if (!denoiserMap.TryGetValue(code, out text)) text = "Unknown error";
|
||||
return text + " (" + code + ")";
|
||||
}
|
||||
|
||||
public static string TranslateH2H(int code)
|
||||
{
|
||||
string text;
|
||||
if (!h2hMap.TryGetValue(code, out text)) text = "Unknown error";
|
||||
return text + " (" + code + ")";
|
||||
}
|
||||
|
||||
public static string TranslateI2T(int code)
|
||||
{
|
||||
string text;
|
||||
if (!i2tMap.TryGetValue(code, out text)) text = "Unknown error";
|
||||
return text + " (" + code + ")";
|
||||
}
|
||||
|
||||
public static string TranslateSeamfixer(int code)
|
||||
{
|
||||
string text;
|
||||
if (!seamfixerMap.TryGetValue(code, out text)) text = "Unknown error";
|
||||
return text + " (" + code + ")";
|
||||
}
|
||||
|
||||
public static string TranslateLMRebake(int code)
|
||||
{
|
||||
string text;
|
||||
if (!lmrMap.TryGetValue(code, out text)) text = "Unknown error";
|
||||
return text + " (" + code + ")";
|
||||
}
|
||||
|
||||
public static string TranslateServerApp(int app)
|
||||
{
|
||||
string text;
|
||||
if (!serverAppMap.TryGetValue(app, out text)) text = "Unknown executable " + " (" + app + ")";
|
||||
return text;
|
||||
}
|
||||
|
||||
public static string TranslateServer(int code, int app=0, int appCode=0)
|
||||
{
|
||||
string text;
|
||||
if (code == ftClient.SERVERERROR_BUSY)
|
||||
{
|
||||
text = "Busy (" + app + "/" + appCode + ")";
|
||||
}
|
||||
else if (code == ftClient.SERVERERROR_APPERR)
|
||||
{
|
||||
var appName = TranslateServerApp(app);
|
||||
text = appName + " error: " + Translate(appName, appCode);
|
||||
}
|
||||
else if (code == ftClient.SERVERERROR_EXEC)
|
||||
{
|
||||
text = "Failed to run " + TranslateServerApp(app);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!serverMap.TryGetValue(code, out text)) text = "Unknown error (" + code + ")";
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
public static string Translate(string app, int code)
|
||||
{
|
||||
if (app == "ftrace") return TranslateFtrace(code, false);
|
||||
if (app == "ftraceRTX") return TranslateFtrace(code, true);
|
||||
if (app == "combineMasks") return TranslateCombineMasks(code);
|
||||
if (app == "denoiser") return TranslateDenoiser(code);
|
||||
if (app == "denoiser72") return TranslateDenoiser(code);
|
||||
if (app == "denoiserLegacy") return TranslateDenoiser(code);
|
||||
if (app == "denoiserOIDN") return TranslateDenoiser(code);
|
||||
if (app == "halffloat2hdr") return TranslateH2H(code);
|
||||
if (app == "ies2tex") return TranslateI2T(code);
|
||||
if (app == "rgba2tga") return TranslateCombineMasks(code);
|
||||
if (app == "seamfixer") return TranslateSeamfixer(code);
|
||||
return ""+code;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
12
Assets/Editor/x64/Bakery/scripts/ftErrorCodes.cs.meta
Normal file
12
Assets/Editor/x64/Bakery/scripts/ftErrorCodes.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 54cb23fa553d8b4479e0374ee0f9c502
|
||||
timeCreated: 1540538557
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,29 @@
|
||||
#if UNITY_EDITOR
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections;
|
||||
|
||||
// For reasons unknown Unity will reset all shader variables set by Shader.SetGlobal... if you save a scene
|
||||
// So here is a hack to fix it
|
||||
public class ftFixResettingsGlobalsOnSave : SaveAssetsProcessor
|
||||
{
|
||||
static void ProcUpdate()
|
||||
{
|
||||
if (BakeryVolume.globalVolume != null) BakeryVolume.globalVolume.Awake(); // set global volume again
|
||||
EditorApplication.update -= ProcUpdate; // remove the callback
|
||||
}
|
||||
|
||||
static string[] OnWillSaveAssets(string[] paths)
|
||||
{
|
||||
// Only do anything if there is a global volume in the scene
|
||||
if (BakeryVolume.globalVolume != null)
|
||||
{
|
||||
EditorApplication.update += ProcUpdate; // wait for the next editor update
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bd16f24f4abb61548aeac9a94c816e3a
|
||||
timeCreated: 1606027586
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
91
Assets/Editor/x64/Bakery/scripts/ftLMGroupInspector.cs
Normal file
91
Assets/Editor/x64/Bakery/scripts/ftLMGroupInspector.cs
Normal file
@@ -0,0 +1,91 @@
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[CustomEditor(typeof(BakeryLightmapGroup))]
|
||||
[CanEditMultipleObjects]
|
||||
public class ftLMGroupInspector : UnityEditor.Editor
|
||||
{
|
||||
SerializedProperty ftraceResolution;
|
||||
SerializedProperty ftraceMode;
|
||||
SerializedProperty ftraceRenderMode;
|
||||
SerializedProperty ftraceRenderDirMode;
|
||||
SerializedProperty ftraceAtlasPacker;
|
||||
SerializedProperty ftraceBitmask;
|
||||
SerializedProperty ftraceThickness;
|
||||
SerializedProperty ftraceSSS;
|
||||
SerializedProperty ftraceSSSSamples;
|
||||
SerializedProperty ftraceSSSDensity;
|
||||
SerializedProperty ftraceSSSColor;
|
||||
SerializedProperty ftraceFakeShadowBias;
|
||||
SerializedProperty ftraceTransparentSelfShadow;
|
||||
SerializedProperty ftraceFlipNormal;
|
||||
|
||||
static string[] selStrings = new string[] {"0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16",
|
||||
"17","18","19","20","21","22","23","24","25","26","27","28","29","30"};//,"31"};
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
ftraceResolution = serializedObject.FindProperty("resolution");
|
||||
ftraceMode = serializedObject.FindProperty("mode");
|
||||
ftraceRenderMode = serializedObject.FindProperty("renderMode");
|
||||
ftraceRenderDirMode = serializedObject.FindProperty("renderDirMode");
|
||||
ftraceAtlasPacker = serializedObject.FindProperty("atlasPacker");
|
||||
ftraceBitmask = serializedObject.FindProperty("bitmask");
|
||||
//ftraceThickness = serializedObject.FindProperty("aoIsThickness");
|
||||
ftraceSSS = serializedObject.FindProperty("computeSSS");
|
||||
ftraceSSSSamples = serializedObject.FindProperty("sssSamples");
|
||||
ftraceSSSDensity = serializedObject.FindProperty("sssDensity");
|
||||
ftraceSSSColor = serializedObject.FindProperty("sssColor");
|
||||
ftraceFakeShadowBias = serializedObject.FindProperty("fakeShadowBias");
|
||||
ftraceTransparentSelfShadow = serializedObject.FindProperty("transparentSelfShadow");
|
||||
ftraceFlipNormal = serializedObject.FindProperty("flipNormal");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI() {
|
||||
serializedObject.Update();
|
||||
|
||||
EditorGUILayout.LabelField("Bakery lightmap group parameters");
|
||||
EditorGUILayout.Space();
|
||||
|
||||
if (ftraceMode.intValue != 2)
|
||||
{
|
||||
var prev = ftraceResolution.intValue;
|
||||
ftraceResolution.intValue = (int)Mathf.ClosestPowerOfTwo(EditorGUILayout.IntSlider("Resolution", ftraceResolution.intValue, 1, 8192));
|
||||
if (ftraceResolution.intValue != prev) EditorUtility.SetDirty(target);
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(ftraceMode, new GUIContent("Packing mode", "Determines how lightmaps are packed. In Simple mode they are not packed, and all objects sharing this group are drawn on top of each other. This is desired in case they were all unwrapped together and do not overlap. If UVs of different objects overlap, choose PackAtlas to arrange their lightmaps together into a single packed atlas."));
|
||||
|
||||
EditorGUILayout.PropertyField(ftraceRenderMode, new GUIContent("Render Mode", ""));
|
||||
|
||||
EditorGUILayout.PropertyField(ftraceRenderDirMode, new GUIContent("Directional mode", ""));
|
||||
|
||||
EditorGUILayout.PropertyField(ftraceAtlasPacker, new GUIContent("Atlas packer", ""));
|
||||
|
||||
ftraceBitmask.intValue = EditorGUILayout.MaskField(new GUIContent("Bitmask", "Lights only affect renderers with overlapping bits"), ftraceBitmask.intValue, selStrings);
|
||||
|
||||
EditorGUILayout.LabelField("");
|
||||
EditorGUILayout.LabelField("Experimental");
|
||||
|
||||
//EditorGUILayout.PropertyField(ftraceThickness, new GUIContent("Calculate AO as thickness", ""));
|
||||
EditorGUILayout.PropertyField(ftraceSSS, new GUIContent("Subsurface scattering", ""));
|
||||
if (ftraceSSS.boolValue)
|
||||
{
|
||||
EditorGUILayout.PropertyField(ftraceSSSSamples, new GUIContent("Samples", ""));
|
||||
EditorGUILayout.PropertyField(ftraceSSSDensity, new GUIContent("Density", ""));
|
||||
EditorGUILayout.PropertyField(ftraceSSSColor, new GUIContent("Color", ""));
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(ftraceFakeShadowBias, new GUIContent("Normal offset", "Fake normal offset for surface samples. Might be useful when applying very strong normal maps."));
|
||||
EditorGUILayout.PropertyField(ftraceTransparentSelfShadow, new GUIContent("Transparent selfshadow", "Start rays behind the surface so it doesn't cast shadows on self. Might be useful for translucent foliage."));
|
||||
EditorGUILayout.PropertyField(ftraceFlipNormal, new GUIContent("Flip normal", "Treat faces as flipped."));
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
|
||||
12
Assets/Editor/x64/Bakery/scripts/ftLMGroupInspector.cs.meta
Normal file
12
Assets/Editor/x64/Bakery/scripts/ftLMGroupInspector.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c93be7cc95a299b4391dc97ea53e9348
|
||||
timeCreated: 1526381774
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
166
Assets/Editor/x64/Bakery/scripts/ftLMGroupSelectorInspector.cs
Normal file
166
Assets/Editor/x64/Bakery/scripts/ftLMGroupSelectorInspector.cs
Normal file
@@ -0,0 +1,166 @@
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEditor.SceneManagement;
|
||||
|
||||
[CustomEditor(typeof(BakeryLightmapGroupSelector))]
|
||||
[CanEditMultipleObjects]
|
||||
public class ftLMGroupSelectorInspector : UnityEditor.Editor
|
||||
{
|
||||
SerializedProperty ftraceAsset;
|
||||
SerializedProperty ftraceOverride;
|
||||
SerializedProperty ftraceResolution;
|
||||
|
||||
string newName = null;
|
||||
int newRes = 512;
|
||||
int newMask = 1;
|
||||
BakeryLightmapGroup.ftLMGroupMode newMode = BakeryLightmapGroup.ftLMGroupMode.PackAtlas;
|
||||
BakeryLightmapGroup.RenderDirMode newDirMode = BakeryLightmapGroup.RenderDirMode.Auto;
|
||||
|
||||
static string[] selStrings = new string[] {"0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16",
|
||||
"17","18","19","20","21","22","23","24","25","26","27","28","29","30"};//,"31"};
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
ftraceAsset = serializedObject.FindProperty("lmgroupAsset");
|
||||
ftraceOverride = serializedObject.FindProperty("instanceResolutionOverride");
|
||||
ftraceResolution = serializedObject.FindProperty("instanceResolution");
|
||||
}
|
||||
|
||||
void ForceSavePrefabOverride(UnityEngine.Object[] targets)
|
||||
{
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
foreach(BakeryLightmapGroupSelector obj in targets)
|
||||
{
|
||||
PrefabUtility.RecordPrefabInstancePropertyModifications(obj);
|
||||
EditorUtility.SetDirty(obj);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI() {
|
||||
serializedObject.Update();
|
||||
|
||||
//if (!ftraceAsset.hasMultipleDifferentValues)
|
||||
{
|
||||
EditorGUILayout.LabelField("These lightmap parameters affect the object and its children");
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var selectedLMGroup = EditorGUILayout.ObjectField(new GUIContent("Lightmap group", "Select ftrace lightmap group asset"),
|
||||
ftraceAsset.objectReferenceValue, typeof(BakeryLightmapGroup), false);
|
||||
var changed = EditorGUI.EndChangeCheck();
|
||||
|
||||
if (ftraceAsset.hasMultipleDifferentValues) EditorGUILayout.LabelField("(Different values in selection)");
|
||||
|
||||
if (changed)
|
||||
{
|
||||
foreach(BakeryLightmapGroupSelector obj in targets)
|
||||
{
|
||||
Undo.RecordObject(obj, "Change LMGroup");
|
||||
obj.lmgroupAsset = selectedLMGroup;
|
||||
ForceSavePrefabOverride(targets);
|
||||
}
|
||||
}
|
||||
|
||||
if (ftraceAsset.objectReferenceValue != null)
|
||||
{
|
||||
var group = ftraceAsset.objectReferenceValue as BakeryLightmapGroup;
|
||||
|
||||
if (group.mode != BakeryLightmapGroup.ftLMGroupMode.PackAtlas && ftraceOverride.boolValue)
|
||||
{
|
||||
ftraceOverride.boolValue = false;
|
||||
ForceSavePrefabOverride(targets);
|
||||
}
|
||||
|
||||
//EditorGUILayout.LabelField("Packed atlas: " + (group.mode == BakeryLightmapGroup.ftLMGroupMode.PackAtlas ? "yes" : "no"));
|
||||
var modeString = "Packing: ";
|
||||
if (group.mode == BakeryLightmapGroup.ftLMGroupMode.OriginalUV) {
|
||||
modeString += "original UV";
|
||||
} else if (group.mode == BakeryLightmapGroup.ftLMGroupMode.PackAtlas) {
|
||||
modeString += "packed atlas";
|
||||
} else {
|
||||
modeString += "vertex";
|
||||
}
|
||||
EditorGUILayout.LabelField(modeString);
|
||||
|
||||
modeString = "Directional: ";
|
||||
if (group.renderDirMode == BakeryLightmapGroup.RenderDirMode.Auto) {
|
||||
modeString += "auto";
|
||||
} else if (group.renderDirMode == BakeryLightmapGroup.RenderDirMode.None) {
|
||||
modeString += "none";
|
||||
} else if (group.renderDirMode == BakeryLightmapGroup.RenderDirMode.BakedNormalMaps) {
|
||||
modeString += "baked normal maps";
|
||||
} else if (group.renderDirMode == BakeryLightmapGroup.RenderDirMode.DominantDirection) {
|
||||
modeString += "dominant direction";
|
||||
} else if (group.renderDirMode == BakeryLightmapGroup.RenderDirMode.RNM) {
|
||||
modeString += "RNM";
|
||||
} else if (group.renderDirMode == BakeryLightmapGroup.RenderDirMode.SH) {
|
||||
modeString += "SH";
|
||||
}
|
||||
EditorGUILayout.LabelField(modeString);
|
||||
|
||||
if (group.mode != BakeryLightmapGroup.ftLMGroupMode.Vertex)
|
||||
{
|
||||
EditorGUILayout.LabelField("Resolution: " + (ftraceOverride.boolValue ? (ftraceResolution.intValue + " (atlas: " + group.resolution + ")") : (group.resolution)+""));
|
||||
}
|
||||
|
||||
if (group.mode == BakeryLightmapGroup.ftLMGroupMode.PackAtlas)
|
||||
{
|
||||
EditorGUILayout.PropertyField(ftraceOverride, new GUIContent("Override resolution", "Manually set the resolution of this object in the atlas"));
|
||||
if (ftraceOverride.boolValue)
|
||||
{
|
||||
ftraceResolution.intValue = EditorGUILayout.IntSlider("Resolution", ftraceResolution.intValue, 1, 8192);
|
||||
ForceSavePrefabOverride(targets);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Create new lightmap group:");
|
||||
if (newName == null) newName = "LMGroup_" + target.name;
|
||||
newName = EditorGUILayout.TextField("Name", newName);
|
||||
EditorGUILayout.PrefixLabel("Packing mode");
|
||||
newMode = (BakeryLightmapGroup.ftLMGroupMode)EditorGUILayout.EnumPopup(newMode);
|
||||
if (newMode != BakeryLightmapGroup.ftLMGroupMode.Vertex)
|
||||
{
|
||||
newRes = (int)Mathf.ClosestPowerOfTwo(EditorGUILayout.IntSlider("Resolution", newRes, 1, 8192));
|
||||
}
|
||||
EditorGUILayout.PrefixLabel("Directional mode");
|
||||
newDirMode = (BakeryLightmapGroup.RenderDirMode)EditorGUILayout.EnumPopup(newDirMode);
|
||||
newMask = EditorGUILayout.MaskField(new GUIContent("Bitmask", "Lights only affect renderers with overlapping bits"), newMask, selStrings);
|
||||
if (GUILayout.Button("Create new"))
|
||||
{
|
||||
BakeryLightmapGroup newGroup = ScriptableObject.CreateInstance<BakeryLightmapGroup>();
|
||||
newGroup.resolution = newRes;
|
||||
newGroup.bitmask = newMask;
|
||||
newGroup.mode = newMode;
|
||||
newGroup.renderDirMode = newDirMode;
|
||||
|
||||
string fname;
|
||||
var activeScene = SceneManager.GetActiveScene();
|
||||
if (activeScene.path.Length > 0)
|
||||
{
|
||||
fname = Path.GetDirectoryName(activeScene.path) + "/" + newName;
|
||||
}
|
||||
else
|
||||
{
|
||||
fname = "Assets/" + newName;
|
||||
}
|
||||
|
||||
AssetDatabase.CreateAsset(newGroup, fname + ".asset");
|
||||
AssetDatabase.SaveAssets();
|
||||
ftraceAsset.objectReferenceValue = newGroup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 84f0a0db10ed05349987b7b2a49c345e
|
||||
timeCreated: 1526384098
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
671
Assets/Editor/x64/Bakery/scripts/ftLightMeshInspector.cs
Normal file
671
Assets/Editor/x64/Bakery/scripts/ftLightMeshInspector.cs
Normal file
@@ -0,0 +1,671 @@
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
[CustomEditor(typeof(BakeryLightMesh))]
|
||||
[CanEditMultipleObjects]
|
||||
public class ftLightMeshInspector : UnityEditor.Editor
|
||||
{
|
||||
SerializedProperty ftraceLightColor;
|
||||
SerializedProperty ftraceLightIntensity;
|
||||
SerializedProperty ftraceLightIndirectIntensity;
|
||||
SerializedProperty ftraceLightTexture;
|
||||
SerializedProperty ftraceLightCutoff;
|
||||
SerializedProperty ftraceLightSamples;
|
||||
SerializedProperty ftraceLightSamples2;
|
||||
SerializedProperty ftraceLightBitmask;
|
||||
SerializedProperty ftraceLightSelfShadow;
|
||||
SerializedProperty ftraceLightBakeToIndirect;
|
||||
|
||||
static string ftLightShaderName = "Bakery/Light";
|
||||
|
||||
ftLightmapsStorage storage;
|
||||
|
||||
int texCached = -1;
|
||||
|
||||
static string[] selStrings = new string[] {"0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16",
|
||||
"17","18","19","20","21","22","23","24","25","26","27","28","29","30"};//,"31"};
|
||||
|
||||
void InitSerializedProperties(SerializedObject obj)
|
||||
{
|
||||
ftraceLightColor = obj.FindProperty("color");
|
||||
ftraceLightTexture = obj.FindProperty("texture");
|
||||
ftraceLightIntensity = obj.FindProperty("intensity");
|
||||
ftraceLightIndirectIntensity = obj.FindProperty("indirectIntensity");
|
||||
ftraceLightCutoff = obj.FindProperty("cutoff");
|
||||
ftraceLightSamples = obj.FindProperty("samples");
|
||||
ftraceLightSamples2 = obj.FindProperty("samples2");
|
||||
ftraceLightBitmask = obj.FindProperty("bitmask");
|
||||
ftraceLightSelfShadow = obj.FindProperty("selfShadow");
|
||||
ftraceLightBakeToIndirect = obj.FindProperty("bakeToIndirect");
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
InitSerializedProperties(serializedObject);
|
||||
}
|
||||
|
||||
void TestPreviewRefreshProperty(ref int cached, int newVal)
|
||||
{
|
||||
if (cached >= 0)
|
||||
{
|
||||
if (cached != newVal)
|
||||
{
|
||||
BakeryLightMesh.lightsChanged = 2;
|
||||
}
|
||||
}
|
||||
cached = newVal;
|
||||
}
|
||||
|
||||
void TestPreviewRefreshProperty(ref int cached, UnityEngine.Object newVal)
|
||||
{
|
||||
if (newVal == null)
|
||||
{
|
||||
TestPreviewRefreshProperty(ref cached, 0);
|
||||
return;
|
||||
}
|
||||
TestPreviewRefreshProperty(ref cached, newVal.GetInstanceID());
|
||||
}
|
||||
|
||||
void GetLinearLightParameters(Light light, out float lightR, out float lightG, out float lightB, out float lightInt)
|
||||
{
|
||||
if (PlayerSettings.colorSpace != ColorSpace.Linear)
|
||||
{
|
||||
lightInt = light.intensity;
|
||||
lightR = light.color.r;
|
||||
lightG = light.color.g;
|
||||
lightB = light.color.b;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GraphicsSettings.lightsUseLinearIntensity)
|
||||
{
|
||||
lightR = Mathf.Pow(light.color.r * light.intensity, 2.2f);
|
||||
lightG = Mathf.Pow(light.color.g * light.intensity, 2.2f);
|
||||
lightB = Mathf.Pow(light.color.b * light.intensity, 2.2f);
|
||||
lightInt = Mathf.Max(Mathf.Max(lightR, lightG), lightB);
|
||||
lightR /= lightInt;
|
||||
lightG /= lightInt;
|
||||
lightB /= lightInt;
|
||||
}
|
||||
else
|
||||
{
|
||||
lightInt = light.intensity;
|
||||
lightR = light.color.linear.r;
|
||||
lightG = light.color.linear.g;
|
||||
lightB = light.color.linear.b;
|
||||
}
|
||||
}
|
||||
|
||||
public static Vector2 GetAreaLightSize(Light obj)
|
||||
{
|
||||
Vector2 areaSize = obj.areaSize;
|
||||
|
||||
var hdrpLight = obj.GetComponent("HDAdditionalLightData");
|
||||
if (hdrpLight != null)
|
||||
{
|
||||
var so = new SerializedObject(hdrpLight);
|
||||
if (so != null)
|
||||
{
|
||||
var hdrpLightTypeExtent = so.FindProperty("m_PointlightHDType");
|
||||
var hdrpLightTypeExtent2 = so.FindProperty("m_AreaLightShape");
|
||||
if (hdrpLightTypeExtent != null && hdrpLightTypeExtent2 != null)
|
||||
{
|
||||
int extendedLightType = hdrpLightTypeExtent.intValue;
|
||||
int extendedLightType2 = hdrpLightTypeExtent2.intValue;
|
||||
if (extendedLightType == 1 && // area
|
||||
extendedLightType2 == 0) // rectangle
|
||||
{
|
||||
var hdrpLightShapeWidth = so.FindProperty("m_ShapeWidth");
|
||||
var hdrpLightShapeHeight = so.FindProperty("m_ShapeHeight");
|
||||
areaSize = new Vector2(hdrpLightShapeWidth != null ? hdrpLightShapeWidth.floatValue : 1,
|
||||
hdrpLightShapeHeight != null ? hdrpLightShapeHeight.floatValue : 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError(obj.name + " HDRP light type unsupported: " + extendedLightType + ", " + extendedLightType2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return areaSize;
|
||||
}
|
||||
|
||||
public static Vector3[] GetAreaLightCorners(Light obj)
|
||||
{
|
||||
var areaSize = GetAreaLightSize(obj);
|
||||
|
||||
var t = obj.transform;
|
||||
var pos = t.position;
|
||||
var right = t.right;
|
||||
var up = t.up;
|
||||
var extents = areaSize * 0.5f;
|
||||
var corners = new Vector3[4];
|
||||
corners[0] = pos - right * extents.x - up * extents.y;
|
||||
corners[1] = pos - right * extents.x + up * extents.y;
|
||||
corners[2] = pos + right * extents.x + up * extents.y;
|
||||
corners[3] = pos + right * extents.x - up * extents.y;
|
||||
|
||||
return corners;
|
||||
}
|
||||
|
||||
public static bool IsArea(Light obj)
|
||||
{
|
||||
var hdrpLight = obj.GetComponent("HDAdditionalLightData");
|
||||
if (hdrpLight != null)
|
||||
{
|
||||
var so = new SerializedObject(hdrpLight);
|
||||
if (so != null)
|
||||
{
|
||||
var hdrpLightTypeExtent = so.FindProperty("m_PointlightHDType");
|
||||
var hdrpLightTypeExtent2 = so.FindProperty("m_AreaLightShape");
|
||||
if (hdrpLightTypeExtent != null && hdrpLightTypeExtent2 != null)
|
||||
{
|
||||
int extendedLightType = hdrpLightTypeExtent.intValue;
|
||||
int extendedLightType2 = hdrpLightTypeExtent2.intValue;
|
||||
if (extendedLightType == 1 && // area
|
||||
extendedLightType2 == 0) // rectangle
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return obj.type == LightType.Area;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI() {
|
||||
//if (showFtrace)
|
||||
{
|
||||
OnEnable();
|
||||
serializedObject.Update();
|
||||
|
||||
TestPreviewRefreshProperty(ref texCached, ftraceLightTexture.objectReferenceValue);
|
||||
|
||||
EditorGUILayout.PropertyField(ftraceLightColor, new GUIContent("Color", "Color of the light"));
|
||||
EditorGUILayout.PropertyField(ftraceLightIntensity, new GUIContent("Intensity", "Color multiplier"));
|
||||
EditorGUILayout.PropertyField(ftraceLightTexture, new GUIContent("Texture", "Texture"));
|
||||
EditorGUILayout.PropertyField(ftraceLightCutoff, new GUIContent("Cutoff", "Lighting distance limit. For maximum physical corectness set to a very high value. Using smaller values is useful for faster render times and to match real-time lights. Bakery uses Skyforge falloff to maintain balance between correct inverse-squared attenuation and practical limits (https://habr.com/company/mailru/blog/248873/)"));
|
||||
|
||||
if (ftraceLightSelfShadow.boolValue)
|
||||
{
|
||||
EditorGUILayout.PropertyField(ftraceLightSamples2, new GUIContent("Samples Near", "The amount of rays traced hemispherically in the proximity of this mesh. Set to 0 to only trace with 'Samples Far'."));
|
||||
}
|
||||
else
|
||||
{
|
||||
ftraceLightSamples2.intValue = 0;
|
||||
}
|
||||
EditorGUILayout.PropertyField(ftraceLightSamples, new GUIContent("Samples Far", "The amount of sample points generated on the surface of this mesh. Distant mesh lights are approximated as clouds of directed half-point lights."));
|
||||
|
||||
//ftraceLightBitmask.intValue = EditorGUILayout.MaskField(new GUIContent("Bitmask", "Lights only affect renderers with overlapping bits"), ftraceLightBitmask.intValue, selStrings);
|
||||
int prevVal = ftraceLightBitmask.intValue;
|
||||
int newVal = EditorGUILayout.MaskField(new GUIContent("Bitmask", "Lights only affect renderers with overlapping bits"), ftraceLightBitmask.intValue, selStrings);
|
||||
if (prevVal != newVal) ftraceLightBitmask.intValue = newVal;
|
||||
|
||||
EditorGUILayout.PropertyField(ftraceLightSelfShadow, new GUIContent("Self shadow", "Determines if light mesh itself casts shadows."));
|
||||
|
||||
//EditorGUILayout.PropertyField(ftraceLightBakeToIndirect, new GUIContent("Bake to indirect", "Add direct contribution from this light to indirect-only lightmaps"));
|
||||
|
||||
if (storage == null) storage = ftRenderLightmap.FindRenderSettingsStorage();
|
||||
var rmode = storage.renderSettingsUserRenderMode;
|
||||
if (rmode != (int)ftRenderLightmap.RenderMode.FullLighting)
|
||||
{
|
||||
ftDirectLightInspector.BakeWhat contrib;
|
||||
if (ftraceLightBakeToIndirect.boolValue)
|
||||
{
|
||||
contrib = ftDirectLightInspector.BakeWhat.DirectAndIndirect;
|
||||
}
|
||||
else
|
||||
{
|
||||
contrib = ftDirectLightInspector.BakeWhat.IndirectOnly;
|
||||
}
|
||||
var prevContrib = contrib;
|
||||
|
||||
contrib = (ftDirectLightInspector.BakeWhat)EditorGUILayout.Popup("Baked contribution", (int)contrib, ftSkyLightInspector.directContributionOptions);
|
||||
|
||||
if (prevContrib != contrib)
|
||||
{
|
||||
if (contrib == ftDirectLightInspector.BakeWhat.IndirectOnly)
|
||||
{
|
||||
ftraceLightBakeToIndirect.boolValue = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ftraceLightBakeToIndirect.boolValue = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(ftraceLightIndirectIntensity, new GUIContent("Indirect intensity", "Non-physical GI multiplier for this light"));
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
bool showError = false;
|
||||
string showErrorText = "";
|
||||
bool isAreaLight = false;
|
||||
bool isMesh = false;
|
||||
|
||||
var materialValid = new bool[targets.Length];
|
||||
int iterator = -1;
|
||||
int numMaterialValid = targets.Length;
|
||||
|
||||
foreach(BakeryLightMesh selectedLight in targets)
|
||||
{
|
||||
iterator++;
|
||||
var so = new SerializedObject(selectedLight);
|
||||
InitSerializedProperties(so);
|
||||
|
||||
var mr = selectedLight.GetComponent<MeshRenderer>();
|
||||
var mf = selectedLight.GetComponent<MeshFilter>();
|
||||
var areaLight = selectedLight.GetComponent<Light>();
|
||||
if (areaLight != null && !IsArea(areaLight)) areaLight = null;
|
||||
|
||||
if (mr == null && areaLight == null)
|
||||
{
|
||||
showError = true;
|
||||
showErrorText = "Error: no mesh renderer";
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mf == null && areaLight == null)
|
||||
{
|
||||
showError = true;
|
||||
showErrorText = "Error: no mesh filter";
|
||||
continue;
|
||||
}
|
||||
|
||||
float intensity = ftraceLightIntensity.floatValue;
|
||||
var clr = ftraceLightColor.colorValue;
|
||||
|
||||
if (areaLight != null)
|
||||
{
|
||||
bool match = true;
|
||||
string why = "";
|
||||
isAreaLight = true;
|
||||
|
||||
float eps = 1.0f / 255.0f;
|
||||
float lightR, lightG, lightB, lightInt;
|
||||
float fr, fg, fb;
|
||||
if (PlayerSettings.colorSpace == ColorSpace.Linear)
|
||||
{
|
||||
fr = clr.linear.r;// * fintensity;
|
||||
fg = clr.linear.g;// * fintensity;
|
||||
fb = clr.linear.b;// * fintensity;
|
||||
}
|
||||
else
|
||||
{
|
||||
fr = clr.r;
|
||||
fg = clr.g;
|
||||
fb = clr.b;
|
||||
}
|
||||
GetLinearLightParameters(areaLight, out lightR, out lightG, out lightB, out lightInt);
|
||||
|
||||
if (GraphicsSettings.lightsUseLinearIntensity || PlayerSettings.colorSpace != ColorSpace.Linear)
|
||||
{
|
||||
if (Mathf.Abs(lightR - fr) > eps || Mathf.Abs(lightG - fg) > eps || Mathf.Abs(lightB - fb) > eps)
|
||||
{
|
||||
match = false;
|
||||
why = "color doesn't match";
|
||||
}
|
||||
else if (Mathf.Abs(lightInt - intensity) > eps)
|
||||
{
|
||||
match = false;
|
||||
why = "intensity doesn't match";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
eps *= Mathf.Max(lightInt, intensity);
|
||||
if (Mathf.Abs(lightR*lightInt - fr*intensity) > eps ||
|
||||
Mathf.Abs(lightG*lightInt - fg*intensity) > eps ||
|
||||
Mathf.Abs(lightB*lightInt - fb*intensity) > eps)
|
||||
{
|
||||
match = false;
|
||||
why = "intensity doesn't match";
|
||||
}
|
||||
}
|
||||
|
||||
if (Mathf.Abs(ftraceLightCutoff.floatValue - areaLight.range * 1.5f) > 0.01f)
|
||||
{
|
||||
match = false;
|
||||
why = "range doesn't match";
|
||||
}
|
||||
|
||||
if (ftraceLightSelfShadow.boolValue)
|
||||
{
|
||||
match = false;
|
||||
why = "area light is not self-shadowed.";
|
||||
}
|
||||
|
||||
if (areaLight.bounceIntensity != ftraceLightIndirectIntensity.floatValue)
|
||||
{
|
||||
match = false;
|
||||
why = "indirect intensity doesn't match";
|
||||
}
|
||||
|
||||
if (!match)
|
||||
{
|
||||
//EditorGUILayout.Space();
|
||||
//EditorGUILayout.LabelField("Real-time light doesn't match lightmap: " + why);
|
||||
showError = true;
|
||||
showErrorText = "Area light doesn't match lightmap: " + why;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
materialValid[iterator] = true;
|
||||
Material singleMat = null;
|
||||
var mats = mr.sharedMaterials;
|
||||
|
||||
if (mats.Length == 0 || mats[0] == null)
|
||||
{
|
||||
showError = true;
|
||||
showErrorText = "Error: no materials set";
|
||||
continue;
|
||||
}
|
||||
|
||||
isMesh = true;
|
||||
|
||||
for(int i=0; i<mats.Length; i++)
|
||||
{
|
||||
var mat = mats[i];
|
||||
if (singleMat == null) singleMat = mat;
|
||||
if (mat != null && mat != singleMat)
|
||||
{
|
||||
showError = true;
|
||||
showErrorText = "Error: different materials in mesh";
|
||||
//match = false;
|
||||
materialValid[iterator] = false;
|
||||
numMaterialValid--;
|
||||
break;
|
||||
}
|
||||
if (mat == null)
|
||||
{
|
||||
showError = true;
|
||||
showErrorText = "Error: mesh doesn't have all materials set";
|
||||
//match = false;
|
||||
materialValid[iterator] = false;
|
||||
numMaterialValid--;
|
||||
break;
|
||||
}
|
||||
bool usesftlight = mat.shader.name == ftLightShaderName;
|
||||
bool usesUnlitColor = mat.shader.name == "Unlit/Color";
|
||||
bool usesUnlitTexture = mat.shader.name == "Unlit/Texture";
|
||||
if (!usesftlight && !usesUnlitColor && !usesUnlitTexture)
|
||||
{
|
||||
showError = true;
|
||||
showErrorText = "Warning: material should output unlit color";
|
||||
//match = false;
|
||||
materialValid[iterator] = false;
|
||||
numMaterialValid--;
|
||||
break;
|
||||
}
|
||||
if (intensity > 1 && !usesftlight)
|
||||
{
|
||||
showError = true;
|
||||
showErrorText = "Warning: intensity > 1, but not using Bakery Light shader";
|
||||
//match = false;
|
||||
break;
|
||||
}
|
||||
var mclr = mat.HasProperty("_Color") ? mat.color : Color.white;
|
||||
float eps = 0.5f/255.0f;
|
||||
if (Mathf.Abs(mclr.r - clr.r) > eps || Mathf.Abs(mclr.g - clr.g) > eps || Mathf.Abs(mclr.b - clr.b) > eps)
|
||||
{
|
||||
showError = true;
|
||||
showErrorText = "Error: light color doesn't match material color";
|
||||
//match = false;
|
||||
break;
|
||||
}
|
||||
if (usesftlight && Mathf.Abs(mat.GetFloat("intensity") - intensity) > 0.001f)
|
||||
{
|
||||
showError = true;
|
||||
showErrorText = "Error: light intensity doesn't match material intensity";
|
||||
//match = false;
|
||||
break;
|
||||
}
|
||||
if (ftraceLightTexture.objectReferenceValue == null && mat.HasProperty("_MainTex") && mat.GetTexture("_MainTex")!=null)
|
||||
{
|
||||
showError = true;
|
||||
showErrorText = "Error: textures don't match";
|
||||
//match = false;
|
||||
break;
|
||||
}
|
||||
if (ftraceLightTexture.objectReferenceValue != null && (!mat.HasProperty("_MainTex") || mat.GetTexture("_MainTex") != ftraceLightTexture.objectReferenceValue))
|
||||
{
|
||||
showError = true;
|
||||
showErrorText = "Error: textures don't match";
|
||||
//match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//if (match) return;
|
||||
}
|
||||
|
||||
|
||||
if (showError)
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField(showErrorText);
|
||||
EditorGUILayout.Space();
|
||||
|
||||
string txt;
|
||||
if (numMaterialValid > 0)
|
||||
{
|
||||
if (isMesh && !isAreaLight)
|
||||
{
|
||||
txt = "Match light to material";
|
||||
}
|
||||
else if (!isMesh && isAreaLight)
|
||||
{
|
||||
txt = "Match lightmapped to area light";
|
||||
}
|
||||
else
|
||||
{
|
||||
txt = "Match lights to meshes/area lights";
|
||||
}
|
||||
if (GUILayout.Button(txt))
|
||||
{
|
||||
//iterator = 0;
|
||||
foreach(BakeryLightMesh selectedLight in targets)
|
||||
{
|
||||
//iterator++;
|
||||
var so = new SerializedObject(selectedLight);
|
||||
InitSerializedProperties(so);
|
||||
|
||||
var mr = selectedLight.GetComponent<MeshRenderer>();
|
||||
var areaLight = selectedLight.GetComponent<Light>();
|
||||
if (mr == null && areaLight == null) continue;
|
||||
|
||||
if (areaLight != null)
|
||||
{
|
||||
if (PlayerSettings.colorSpace != ColorSpace.Linear)
|
||||
{
|
||||
ftraceLightColor.colorValue = areaLight.color;
|
||||
ftraceLightIntensity.floatValue = areaLight.intensity;
|
||||
}
|
||||
else if (!GraphicsSettings.lightsUseLinearIntensity)
|
||||
{
|
||||
float lightR, lightG, lightB, lightInt;
|
||||
GetLinearLightParameters(areaLight, out lightR, out lightG, out lightB, out lightInt);
|
||||
ftraceLightColor.colorValue = new Color(lightR, lightG, lightB);
|
||||
ftraceLightIntensity.floatValue = lightInt;
|
||||
}
|
||||
else
|
||||
{
|
||||
ftraceLightColor.colorValue = areaLight.color;
|
||||
ftraceLightIntensity.floatValue = areaLight.intensity;
|
||||
}
|
||||
ftraceLightCutoff.floatValue = areaLight.range * 1.5f;
|
||||
ftraceLightSelfShadow.boolValue = false;
|
||||
ftraceLightIndirectIntensity.floatValue = areaLight.bounceIntensity;
|
||||
so.ApplyModifiedProperties();
|
||||
continue;
|
||||
}
|
||||
|
||||
var mats = mr.sharedMaterials;
|
||||
if (mats.Length == 0 || mats[0] == null) continue;
|
||||
|
||||
var mat = mats[0];
|
||||
if (mat.shader.name == ftLightShaderName)
|
||||
{
|
||||
ftraceLightTexture.objectReferenceValue = mat.mainTexture;
|
||||
ftraceLightColor.colorValue = mat.color;
|
||||
ftraceLightIntensity.floatValue = mat.GetFloat("intensity");
|
||||
}
|
||||
else if (mat.shader.name == "Unlit/Color")
|
||||
{
|
||||
ftraceLightTexture.objectReferenceValue = null;
|
||||
ftraceLightColor.colorValue = mat.color;
|
||||
ftraceLightIntensity.floatValue = 1;
|
||||
}
|
||||
else if (mat.shader.name == "Unlit/Texture")
|
||||
{
|
||||
ftraceLightTexture.objectReferenceValue = mat.mainTexture;
|
||||
ftraceLightColor.colorValue = Color.white;//mat.color;
|
||||
ftraceLightIntensity.floatValue = 1;
|
||||
}
|
||||
so.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//if (mats.Length == 0) return;
|
||||
//if (mats[0] == null) return;
|
||||
|
||||
if (isMesh && !isAreaLight)
|
||||
{
|
||||
txt = "Match material to light";
|
||||
}
|
||||
else if (!isMesh && isAreaLight)
|
||||
{
|
||||
txt = "Match area light to lightmapped";
|
||||
}
|
||||
else
|
||||
{
|
||||
txt = "Match meshes/area lights to lightmapped";
|
||||
}
|
||||
if (GUILayout.Button(txt))
|
||||
{
|
||||
foreach(BakeryLightMesh selectedLight in targets)
|
||||
{
|
||||
//iterator++;
|
||||
var so = new SerializedObject(selectedLight);
|
||||
InitSerializedProperties(so);
|
||||
|
||||
var mr = selectedLight.GetComponent<MeshRenderer>();
|
||||
var areaLight = selectedLight.GetComponent<Light>();
|
||||
if (mr == null && areaLight == null) continue;
|
||||
|
||||
if (areaLight != null)
|
||||
{
|
||||
Undo.RecordObject(areaLight, "Change light");
|
||||
if (PlayerSettings.colorSpace != ColorSpace.Linear)
|
||||
{
|
||||
areaLight.color = ftraceLightColor.colorValue;
|
||||
areaLight.intensity = ftraceLightIntensity.floatValue;
|
||||
}
|
||||
else if (!GraphicsSettings.lightsUseLinearIntensity)
|
||||
{
|
||||
var clr = ftraceLightColor.colorValue;
|
||||
float fintensity = ftraceLightIntensity.floatValue;
|
||||
float fr = clr.linear.r;// * fintensity;
|
||||
float fg = clr.linear.g;// * fintensity;
|
||||
float fb = clr.linear.b;// * fintensity;
|
||||
|
||||
fr = Mathf.Pow(fr * fintensity, 1.0f / 2.2f);
|
||||
fg = Mathf.Pow(fg * fintensity, 1.0f / 2.2f);
|
||||
fb = Mathf.Pow(fb * fintensity, 1.0f / 2.2f);
|
||||
float fint = Mathf.Max(Mathf.Max(fr, fg), fb);
|
||||
fr /= fint;
|
||||
fg /= fint;
|
||||
fb /= fint;
|
||||
areaLight.color = new Color(fr, fg, fb);
|
||||
areaLight.intensity = fint;
|
||||
}
|
||||
else
|
||||
{
|
||||
areaLight.color = ftraceLightColor.colorValue;
|
||||
areaLight.intensity = ftraceLightIntensity.floatValue;
|
||||
}
|
||||
areaLight.bounceIntensity = ftraceLightIndirectIntensity.floatValue;
|
||||
continue;
|
||||
}
|
||||
|
||||
var mats = mr.sharedMaterials;
|
||||
if (mats.Length == 0 || mats[0] == null) continue;
|
||||
|
||||
float intensity = ftraceLightIntensity.floatValue;
|
||||
|
||||
var mat = mats[0];
|
||||
Undo.RecordObject(mat, "Change material");
|
||||
if (intensity > 1)
|
||||
{
|
||||
if (mat.shader.name != ftLightShaderName) mat.shader = Shader.Find(ftLightShaderName);
|
||||
mat.color = ftraceLightColor.colorValue;
|
||||
mat.mainTexture = ftraceLightTexture.objectReferenceValue as Texture2D;
|
||||
mat.SetFloat("intensity", intensity);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ftraceLightTexture.objectReferenceValue == null)
|
||||
{
|
||||
if (mat.shader.name != ftLightShaderName && mat.shader.name != "Unlit/Color") mat.shader = Shader.Find(ftLightShaderName);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mat.shader.name != ftLightShaderName && mat.shader.name != "Unlit/Texture") mat.shader = Shader.Find(ftLightShaderName);
|
||||
}
|
||||
mat.mainTexture = ftraceLightTexture.objectReferenceValue as Texture2D;
|
||||
if (mat.shader.name == ftLightShaderName)
|
||||
{
|
||||
mat.color = ftraceLightColor.colorValue;
|
||||
mat.SetFloat("intensity", intensity);
|
||||
}
|
||||
else
|
||||
{
|
||||
mat.color = ftraceLightColor.colorValue * intensity;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (PlayerSettings.colorSpace == ColorSpace.Linear)
|
||||
{
|
||||
if (!GraphicsSettings.lightsUseLinearIntensity)
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Warning: project is not set up to use linear light intensity.");
|
||||
EditorGUILayout.LabelField("GraphicsSettings.lightsUseLinearIntensity should be TRUE.");
|
||||
if (GUILayout.Button("Fix"))
|
||||
{
|
||||
GraphicsSettings.lightsUseLinearIntensity = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Project is using linear light intensity. This is nice.");
|
||||
if (GUILayout.Button("Change to non-linear"))
|
||||
{
|
||||
GraphicsSettings.lightsUseLinearIntensity = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c2b4c5d630c305d44a44bc6a7fb96344
|
||||
timeCreated: 1525465024
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
202
Assets/Editor/x64/Bakery/scripts/ftLightingDataGen.cs
Normal file
202
Assets/Editor/x64/Bakery/scripts/ftLightingDataGen.cs
Normal file
@@ -0,0 +1,202 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
#if UNITY_EDITOR
|
||||
|
||||
using UnityEngine.Rendering;
|
||||
using System.Reflection;
|
||||
|
||||
public class ftLightingDataGen
|
||||
{
|
||||
// Generates LightingDataAsset for all lights with baked occlusionMaskChannel
|
||||
public static bool GenerateShadowmaskLightingData(string outName, ref List<Light> lights, bool subtractive)
|
||||
{
|
||||
Debug.Log("Generating LightingDataAsset for " + lights.Count + " lights");
|
||||
|
||||
bool success = true;
|
||||
try
|
||||
{
|
||||
PropertyInfo inspectorModeInfo = typeof(SerializedObject).GetProperty("inspectorMode", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
var edPath = ftLightmaps.GetEditorPath();
|
||||
#if UNITY_2017_1_OR_NEWER
|
||||
var bytesP0 = File.ReadAllBytes(edPath + "lightingDataChunks/LightingData_2017_1_part0.bin");
|
||||
var bytesP1 = File.ReadAllBytes(edPath + "lightingDataChunks/LightingData_2017_1_part1.bin");
|
||||
var bytesP2 = File.ReadAllBytes(edPath + "lightingDataChunks/LightingData_2017_1_part2.bin");
|
||||
var bytesP3 = File.ReadAllBytes(edPath + "lightingDataChunks/LightingData_2017_1_part3.bin");
|
||||
#else
|
||||
var bytesP0 = File.ReadAllBytes(edPath + "lightingDataChunks/LightingData_5_6_part0.bin");
|
||||
var bytesP1 = File.ReadAllBytes(edPath + "lightingDataChunks/LightingData_5_6_part1.bin");
|
||||
var bytesP2 = File.ReadAllBytes(edPath + "lightingDataChunks/LightingData_5_6_part2.bin");
|
||||
var bytesP3 = File.ReadAllBytes(edPath + "lightingDataChunks/LightingData_5_6_part3.bin");
|
||||
#endif
|
||||
var f = new BinaryWriter(File.Open(outName, FileMode.Create));
|
||||
f.Write(bytesP0);
|
||||
#if UNITY_2017_1_OR_NEWER
|
||||
f.Write(52 + 28 * lights.Count - 28);
|
||||
f.Write(bytesP1);
|
||||
f.Write(572 + 28 * lights.Count - 28);
|
||||
#else
|
||||
f.Write(160 + 28 * lights.Count - 28);
|
||||
f.Write(bytesP1);
|
||||
f.Write(552 + 28 * lights.Count - 28);
|
||||
#endif
|
||||
f.Write(bytesP2);
|
||||
f.Write(lights.Count);
|
||||
for(int i=0; i<lights.Count; i++)
|
||||
{
|
||||
var so = new SerializedObject(lights[i]);
|
||||
inspectorModeInfo.SetValue(so, InspectorMode.Debug, null);
|
||||
long fileid = so.FindProperty("m_LocalIdentfierInFile").longValue;
|
||||
f.Write(fileid);
|
||||
f.Write(0);
|
||||
f.Write(0);
|
||||
}
|
||||
f.Write(lights.Count);
|
||||
for(int i=0; i<lights.Count; i++)
|
||||
{
|
||||
var so = new SerializedObject(lights[i]);
|
||||
var channel = so.FindProperty("m_BakingOutput").FindPropertyRelative("occlusionMaskChannel").intValue;
|
||||
|
||||
int val1 = subtractive ? 0 : -1;
|
||||
int val2 = subtractive ? 131076 : 131080;
|
||||
|
||||
f.Write(val1);
|
||||
f.Write(channel);
|
||||
f.Write(val2);
|
||||
}
|
||||
f.Write(bytesP3);
|
||||
f.Close();
|
||||
}
|
||||
catch
|
||||
{
|
||||
ftRenderLightmap.DebugLogError("Failed to generate LightingDataAsset");
|
||||
success = false;
|
||||
throw;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
#if UNITY_2017_3_OR_NEWER
|
||||
#else
|
||||
// Patches existing LightingDataAsset shadowmask channels
|
||||
public static bool PatchShadowmaskLightingData(string inName, string outName, ref Dictionary<long,long> inID2OutID, ref Dictionary<long,int> outIDChannel, bool subtractive)
|
||||
{
|
||||
try
|
||||
{
|
||||
var bytesIn = File.ReadAllBytes(inName);
|
||||
|
||||
var lightCount = inID2OutID.Count;
|
||||
if (lightCount == 0) return false;
|
||||
|
||||
var inIDsAsBytes = new byte[lightCount][];
|
||||
var outIDsAsBytes = new byte[lightCount][];
|
||||
var outChannelsAsBytes = new byte[lightCount][];
|
||||
var matches = new int[lightCount];
|
||||
int counter = 0;
|
||||
foreach(var pair in inID2OutID)
|
||||
{
|
||||
inIDsAsBytes[counter] = BitConverter.GetBytes(pair.Key);
|
||||
outIDsAsBytes[counter] = BitConverter.GetBytes(pair.Value);
|
||||
outChannelsAsBytes[counter] = BitConverter.GetBytes(outIDChannel[pair.Value]);
|
||||
counter++;
|
||||
}
|
||||
|
||||
int replaced = 0;
|
||||
int firstAddressReplaced = bytesIn.Length;
|
||||
var lightsAsWritten = new int[lightCount];
|
||||
int lightsAsWrittenCounter = 0;
|
||||
for(int i=0; i<bytesIn.Length; i++)
|
||||
{
|
||||
var val = bytesIn[i];
|
||||
for(int j=0; j<lightCount; j++)
|
||||
{
|
||||
var expectedVal = matches[j] >= 8 ? 0 : inIDsAsBytes[j][matches[j]];
|
||||
if (val == expectedVal)
|
||||
{
|
||||
matches[j]++;
|
||||
if (matches[j] == 16)
|
||||
{
|
||||
// Matched long + 8 zeros
|
||||
// Replace fileid
|
||||
for(int k=0; k<8; k++)
|
||||
{
|
||||
//Debug.LogError("Matched " + inIDsAsBytes[j][k]+" "+outIDsAsBytes[j][k]);
|
||||
bytesIn[i - 15 + k] = outIDsAsBytes[j][k];
|
||||
}
|
||||
matches[j] = 0;
|
||||
replaced++;
|
||||
|
||||
int addr = i - 15;
|
||||
if (addr < firstAddressReplaced) firstAddressReplaced = addr;
|
||||
|
||||
lightsAsWritten[lightsAsWrittenCounter] = j;
|
||||
lightsAsWrittenCounter++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
matches[j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (firstAddressReplaced == bytesIn.Length)
|
||||
{
|
||||
ftRenderLightmap.DebugLogError("Failed to patch LightingDataAsset: unabled to replace light IDs");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lightsAsWrittenCounter != lightCount)
|
||||
{
|
||||
ftRenderLightmap.DebugLogError("Failed to patch LightingDataAsset: light count differs in temp/real scenes (" + lightsAsWrittenCounter + " vs " + lightCount + ")");
|
||||
return false;
|
||||
}
|
||||
|
||||
// IDs are patched. Now replace channels.
|
||||
|
||||
for(int i=0; i<lightsAsWrittenCounter; i++)
|
||||
{
|
||||
int id = lightsAsWritten[i];
|
||||
var channelBytes = outChannelsAsBytes[id];
|
||||
int channelStartAddr = firstAddressReplaced + 16 * lightCount + 4 + 12 * i + 4;
|
||||
if (subtractive)
|
||||
{
|
||||
for(int j=0; j<4; j++)
|
||||
{
|
||||
bytesIn[channelStartAddr + j - 4] = 0;
|
||||
}
|
||||
}
|
||||
for(int j=0; j<4; j++)
|
||||
{
|
||||
bytesIn[channelStartAddr + j] = channelBytes[j];
|
||||
}
|
||||
if (subtractive)
|
||||
{
|
||||
var val2 = BitConverter.GetBytes(131076);
|
||||
for(int j=0; j<4; j++)
|
||||
{
|
||||
bytesIn[channelStartAddr + j + 4] = val2[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var f = new BinaryWriter(File.Open(outName, FileMode.Create));
|
||||
f.Write(bytesIn);
|
||||
f.Close();
|
||||
Debug.Log("PatchShadowmaskLightingData: patched " + replaced + " lights");
|
||||
}
|
||||
catch
|
||||
{
|
||||
ftRenderLightmap.DebugLogError("Failed to patch LightingDataAsset");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
12
Assets/Editor/x64/Bakery/scripts/ftLightingDataGen.cs.meta
Normal file
12
Assets/Editor/x64/Bakery/scripts/ftLightingDataGen.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 04a9623f45d46d64b8d852e0b0ea9a81
|
||||
timeCreated: 1535032797
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
117
Assets/Editor/x64/Bakery/scripts/ftLightmappedPrefabInspector.cs
Normal file
117
Assets/Editor/x64/Bakery/scripts/ftLightmappedPrefabInspector.cs
Normal file
@@ -0,0 +1,117 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
[CustomEditor(typeof(BakeryLightmappedPrefab))]
|
||||
[CanEditMultipleObjects]
|
||||
public class ftLightmappedPrefabInspector : UnityEditor.Editor
|
||||
{
|
||||
bool allPrefabsGood = true;
|
||||
SerializedProperty isEnabled;
|
||||
|
||||
void Refresh(BakeryLightmappedPrefab selected)
|
||||
{
|
||||
allPrefabsGood = selected.IsValid() && allPrefabsGood;
|
||||
}
|
||||
|
||||
void OnPrefabInstanceUpdate(GameObject go)
|
||||
{
|
||||
allPrefabsGood = true;
|
||||
foreach(BakeryLightmappedPrefab selected in targets)
|
||||
{
|
||||
//if (go != selected.gameObject) continue;
|
||||
Refresh(selected);
|
||||
}
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
allPrefabsGood = true;
|
||||
foreach(BakeryLightmappedPrefab selected in targets)
|
||||
{
|
||||
Refresh(selected);
|
||||
}
|
||||
PrefabUtility.prefabInstanceUpdated += OnPrefabInstanceUpdate;
|
||||
isEnabled = serializedObject.FindProperty("enableBaking");
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
PrefabUtility.prefabInstanceUpdated -= OnPrefabInstanceUpdate;
|
||||
}
|
||||
|
||||
public ftLightmapsStorage FindPrefabStorage(BakeryLightmappedPrefab pref)
|
||||
{
|
||||
var p = pref.gameObject;
|
||||
var bdataName = "BakeryPrefabLightmapData";
|
||||
var pstoreT = p.transform.Find(bdataName);
|
||||
if (pstoreT == null)
|
||||
{
|
||||
var pstoreG = new GameObject();
|
||||
pstoreG.name = bdataName;
|
||||
pstoreT = pstoreG.transform;
|
||||
pstoreT.parent = p.transform;
|
||||
}
|
||||
var pstore = pstoreT.gameObject.GetComponent<ftLightmapsStorage>();
|
||||
if (pstore == null) pstore = pstoreT.gameObject.AddComponent<ftLightmapsStorage>();
|
||||
return pstore;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI() {
|
||||
|
||||
serializedObject.Update();
|
||||
var prev = isEnabled.boolValue;
|
||||
EditorGUILayout.PropertyField(isEnabled, new GUIContent("Enable baking", "Prefab contents will be patched after baking if this checkbox is on. Patched prefab will be lightmapped when instantiated in any scene."));
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
if (isEnabled.boolValue != prev)
|
||||
{
|
||||
allPrefabsGood = true;
|
||||
foreach(BakeryLightmappedPrefab selected in targets)
|
||||
{
|
||||
selected.enableBaking = isEnabled.boolValue;
|
||||
Refresh(selected);
|
||||
}
|
||||
}
|
||||
|
||||
if (allPrefabsGood)
|
||||
{
|
||||
EditorGUILayout.LabelField("Prefab connection: OK");
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach(BakeryLightmappedPrefab selected in targets)
|
||||
{
|
||||
if (selected.errorMessage.Length > 0) EditorGUILayout.LabelField("Error: " + selected.errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Load render settings from prefab"))
|
||||
{
|
||||
if (EditorUtility.DisplayDialog("Bakery", "Change current render settings to prefab?", "OK", "Cancel"))
|
||||
{
|
||||
var storage = ftRenderLightmap.FindRenderSettingsStorage();
|
||||
foreach(BakeryLightmappedPrefab pref in targets)
|
||||
{
|
||||
var prefabStorage = FindPrefabStorage(pref);
|
||||
ftLightmapsStorage.CopySettings(prefabStorage, storage);
|
||||
}
|
||||
var instance = (ftRenderLightmap)EditorWindow.GetWindow(typeof(ftRenderLightmap));
|
||||
if (instance != null) instance.LoadRenderSettings();
|
||||
}
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Save current render settings to prefab"))
|
||||
{
|
||||
if (EditorUtility.DisplayDialog("Bakery", "Save current render settings to prefab?", "OK", "Cancel"))
|
||||
{
|
||||
var storage = ftRenderLightmap.FindRenderSettingsStorage();
|
||||
foreach(BakeryLightmappedPrefab pref in targets)
|
||||
{
|
||||
var prefabStorage = FindPrefabStorage(pref);
|
||||
ftLightmapsStorage.CopySettings(storage, prefabStorage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a080b80faca4b9a4fa0a43361585c4be
|
||||
timeCreated: 1541703652
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,29 @@
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[CustomEditor(typeof(ftLightmapsStorage))]
|
||||
public class ftLightmapsStorageInspector : UnityEditor.Editor
|
||||
{
|
||||
static bool showDebug = false;
|
||||
|
||||
public override void OnInspectorGUI() {
|
||||
|
||||
EditorGUILayout.LabelField("This object stores Bakery lightmapping data");
|
||||
|
||||
if (showDebug)
|
||||
{
|
||||
if (GUILayout.Button("Hide debug info")) showDebug = false;
|
||||
DrawDefaultInspector();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GUILayout.Button("Show debug info")) showDebug = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3ebd176ebc8a2304c84bc65c23bbecd6
|
||||
timeCreated: 1541939494
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
404
Assets/Editor/x64/Bakery/scripts/ftModelPostProcessor.cs
Normal file
404
Assets/Editor/x64/Bakery/scripts/ftModelPostProcessor.cs
Normal file
@@ -0,0 +1,404 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class ftModelPostProcessorInternal : AssetPostprocessor
|
||||
{
|
||||
public virtual void UnwrapXatlas(Mesh m, UnwrapParam param)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public partial class ftModelPostProcessor : ftModelPostProcessorInternal
|
||||
{
|
||||
public static bool unwrapError = false;
|
||||
public static string lastUnwrapErrorAsset = "";
|
||||
|
||||
// Deprecated but leave it for now just in case
|
||||
public class ftSavedPadding : ScriptableObject
|
||||
{
|
||||
[SerializeField]
|
||||
public ftGlobalStorage.AdjustedMesh data;
|
||||
}
|
||||
|
||||
static ftGlobalStorage storage;
|
||||
UnwrapParam uparams;
|
||||
const int res = 1024;
|
||||
static Material mat;
|
||||
public static RenderTexture rt;
|
||||
public static Texture2D tex;
|
||||
|
||||
static Dictionary<string, bool> assetHasPaddingAdjustment = new Dictionary<string, bool>();
|
||||
static Dictionary<string, ftSavedPadding2> assetSavedPaddingAdjustment = new Dictionary<string, ftSavedPadding2>();
|
||||
|
||||
#if UNITY_2017_1_OR_NEWER
|
||||
bool deserializedSuccess = false;
|
||||
ftGlobalStorage.AdjustedMesh deserialized;
|
||||
#endif
|
||||
|
||||
public static double GetTime()
|
||||
{
|
||||
return (System.DateTime.Now.Ticks / System.TimeSpan.TicksPerMillisecond) / 1000.0;
|
||||
}
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
storage = ftLightmaps.GetGlobalStorage();
|
||||
|
||||
//ftLightmaps.AddTag("BakeryProcessed");
|
||||
}
|
||||
|
||||
void OnPreprocessModel()
|
||||
{
|
||||
Init();
|
||||
|
||||
assetHasPaddingAdjustment[assetPath] = false;
|
||||
assetSavedPaddingAdjustment[assetPath] = null;
|
||||
|
||||
if (storage == null) return;
|
||||
bool hasGlobalPaddingAdjustment = storage.modifiedAssetPathList.IndexOf(assetPath) >= 0;
|
||||
var savedAdjustment = AssetDatabase.LoadAssetAtPath(
|
||||
Path.GetDirectoryName(assetPath) + "/" + Path.GetFileNameWithoutExtension(assetPath) + "_padding.asset", typeof(ftSavedPadding2)) as ftSavedPadding2;
|
||||
if (!hasGlobalPaddingAdjustment && savedAdjustment == null) return;
|
||||
|
||||
ModelImporter importer = (ModelImporter)assetImporter;
|
||||
assetHasPaddingAdjustment[assetPath] = importer.generateSecondaryUV;
|
||||
importer.generateSecondaryUV = false; // disable built-in unwrapping for models with padding adjustment
|
||||
assetSavedPaddingAdjustment[assetPath] = savedAdjustment;
|
||||
}
|
||||
|
||||
void OnPostprocessModel(GameObject g)
|
||||
{
|
||||
ModelImporter importer = (ModelImporter)assetImporter;
|
||||
if (importer.generateSecondaryUV || assetHasPaddingAdjustment[assetPath])
|
||||
{
|
||||
if (!importer.generateSecondaryUV)
|
||||
{
|
||||
importer.generateSecondaryUV = true; // set "generate lightmap UVs" checkbox back
|
||||
EditorUtility.SetDirty(importer);
|
||||
}
|
||||
|
||||
// Auto UVs: Adjust UV padding per mesh
|
||||
//if (!storage.modifiedAssetPathList.Contains(assetPath) && g.tag == "BakeryProcessed") return;
|
||||
//if (ftLightmaps.IsModelProcessed(assetPath)) return;
|
||||
|
||||
//g.tag = "BakeryProcessed";
|
||||
var saved = assetSavedPaddingAdjustment[assetPath];
|
||||
if (saved != null)
|
||||
{
|
||||
Debug.Log("Bakery: processing auto-unwrapped asset (saved UV padding) " + assetPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("Bakery: processing auto-unwrapped asset " + assetPath);
|
||||
}
|
||||
if (storage != null) ftLightmaps.MarkModelProcessed(assetPath, true);
|
||||
|
||||
uparams = new UnwrapParam();
|
||||
UnwrapParam.SetDefaults(out uparams);
|
||||
uparams.angleError = importer.secondaryUVAngleDistortion * 0.01f;
|
||||
uparams.areaError = importer.secondaryUVAreaDistortion * 0.01f;
|
||||
uparams.hardAngle = importer.secondaryUVHardAngle;
|
||||
|
||||
#if UNITY_2017_1_OR_NEWER
|
||||
deserializedSuccess = false;
|
||||
var props = importer.extraUserProperties;
|
||||
for(int p=0; p<props.Length; p++)
|
||||
{
|
||||
if (props[p].Substring(0,7) == "#BAKERY")
|
||||
{
|
||||
var json = props[p].Substring(7);
|
||||
deserialized = JsonUtility.FromJson<ftGlobalStorage.AdjustedMesh>(json);
|
||||
deserializedSuccess = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (storage != null) storage.InitModifiedMeshMap(assetPath);
|
||||
|
||||
var tt = GetTime();
|
||||
AdjustUV(g.transform, saved);
|
||||
Debug.Log("UV adjustment time: " + (GetTime() - tt));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (storage == null) return;
|
||||
|
||||
Debug.Log("Bakery: checking for UV overlaps in " + assetPath);
|
||||
|
||||
//if (g.tag == "BakeryProcessed") g.tag = "";
|
||||
ftLightmaps.MarkModelProcessed(assetPath, true);//false);
|
||||
|
||||
// Manual UVs: check if overlapping
|
||||
CheckUVOverlap(g, assetPath);
|
||||
}
|
||||
|
||||
if (g.tag == "BakeryProcessed") g.tag = ""; // remove legacy mark
|
||||
}
|
||||
|
||||
public static bool InitOverlapCheck()
|
||||
{
|
||||
rt = new RenderTexture(res, res, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
|
||||
tex = new Texture2D(res, res, TextureFormat.ARGB32, false, true);
|
||||
var shdr = Shader.Find("Hidden/ftOverlapTest");
|
||||
if (shdr == null)
|
||||
{
|
||||
var bakeryRuntimePath = ftLightmaps.GetRuntimePath();
|
||||
shdr = AssetDatabase.LoadAssetAtPath(bakeryRuntimePath + "ftOverlapTest.shader", typeof(Shader)) as Shader;
|
||||
if (shdr == null)
|
||||
{
|
||||
Debug.Log("No overlap testing shader present");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
mat = new Material(shdr);
|
||||
return true;
|
||||
}
|
||||
|
||||
// -1 = No UVs
|
||||
// 0 = no overlaps
|
||||
// > 0 = overlapping pixels count
|
||||
public static int DoOverlapCheck(GameObject g, bool deep)
|
||||
{
|
||||
int overlap = -1;
|
||||
int overlapCounter = 0;
|
||||
|
||||
Graphics.SetRenderTarget(rt);
|
||||
GL.Clear(false, true, new Color(0,0,0,0));
|
||||
mat.SetPass(0);
|
||||
|
||||
bool hasUV1 = RenderMeshes(g.transform, deep);
|
||||
if (hasUV1)
|
||||
{
|
||||
tex.ReadPixels(new Rect(0,0,res,res), 0, 0, false);
|
||||
tex.Apply();
|
||||
|
||||
var bytes = tex.GetRawTextureData();
|
||||
overlap = 0;
|
||||
for(int i=0; i<bytes.Length; i++)
|
||||
{
|
||||
if (bytes[i] > 1)
|
||||
{
|
||||
overlapCounter++;
|
||||
if (overlapCounter > 256) // TODO: better check
|
||||
{
|
||||
overlap = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Graphics.SetRenderTarget(null);
|
||||
|
||||
return overlap == 1 ? overlapCounter : overlap;
|
||||
}
|
||||
|
||||
public static void EndOverlapCheck()
|
||||
{
|
||||
if (rt != null) rt.Release();
|
||||
if (tex != null) Object.DestroyImmediate(tex);
|
||||
}
|
||||
|
||||
public static void CheckUVOverlap(GameObject g, string assetPath)
|
||||
{
|
||||
bool canCheck = InitOverlapCheck();
|
||||
if (!canCheck) return;
|
||||
|
||||
int overlap = DoOverlapCheck(g, true);
|
||||
EndOverlapCheck();
|
||||
|
||||
if (overlap != 1 && overlap > 0)
|
||||
{
|
||||
Debug.LogWarning("[Bakery warning] " + overlap + " pixels overlap: " + assetPath);
|
||||
}
|
||||
|
||||
//var index = storage.assetList.IndexOf(assetPath);
|
||||
var index = storage.assetList.IndexOf(assetPath);
|
||||
var prevOverlap = -100;
|
||||
if (index < 0)
|
||||
{
|
||||
//index = storage.assetList.Count;
|
||||
//storage.assetList.Add(assetPath);
|
||||
index = storage.assetList.Count;
|
||||
storage.assetList.Add(assetPath);
|
||||
storage.uvOverlapAssetList.Add(overlap);
|
||||
}
|
||||
else
|
||||
{
|
||||
prevOverlap = storage.uvOverlapAssetList[index];
|
||||
storage.assetList[index] = assetPath;
|
||||
storage.uvOverlapAssetList[index] = overlap;
|
||||
}
|
||||
|
||||
if (prevOverlap != overlap)
|
||||
{
|
||||
EditorUtility.SetDirty(storage);
|
||||
EditorSceneManager.MarkAllScenesDirty();
|
||||
}
|
||||
}
|
||||
|
||||
bool ValidateMesh(Mesh m, ftGlobalStorage.Unwrapper unwrapper)
|
||||
{
|
||||
#if UNITY_2017_3_OR_NEWER
|
||||
#if UNITY_2018_4_OR_NEWER
|
||||
// Bug was fixed in 2018.3.5, but the closest define is for 2018.4
|
||||
#else
|
||||
if (m.indexFormat == UnityEngine.Rendering.IndexFormat.UInt32 && unwrapper == ftGlobalStorage.Unwrapper.Default)
|
||||
{
|
||||
Debug.LogError("Can't adjust UV padding for " + m.name + " due to Unity bug. Please set Index Format to 16-bit on the asset or use xatlas.");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
void AdjustUV(Transform t, ftSavedPadding2 saved = null)
|
||||
{
|
||||
var mf = t.GetComponent<MeshFilter>();
|
||||
if (mf != null && mf.sharedMesh != null)
|
||||
{
|
||||
var m = mf.sharedMesh;
|
||||
var nm = m.name;
|
||||
int modifiedMeshID;
|
||||
|
||||
if (saved != null)
|
||||
{
|
||||
// Get padding from asset
|
||||
int mindex = saved.data.meshName.IndexOf(nm);
|
||||
if (mindex < 0)
|
||||
{
|
||||
//Debug.LogError("Unable to find padding value for mesh " + nm);
|
||||
// This is fine. Apparently caused by parts of models being lightmapped,
|
||||
// while other parts are not baked, yet still a part of the model.
|
||||
}
|
||||
else
|
||||
{
|
||||
var padding = saved.data.padding[mindex];
|
||||
|
||||
ftGlobalStorage.Unwrapper unwrapper = ftGlobalStorage.Unwrapper.Default;
|
||||
if (saved.data.unwrapper != null && saved.data.unwrapper.Count > mindex)
|
||||
unwrapper = (ftGlobalStorage.Unwrapper)saved.data.unwrapper[mindex];
|
||||
|
||||
if (!ValidateMesh(m, unwrapper)) return;
|
||||
|
||||
uparams.packMargin = padding/1024.0f;
|
||||
Unwrap(m, uparams, unwrapper);
|
||||
}
|
||||
}
|
||||
#if UNITY_2017_1_OR_NEWER
|
||||
else if (deserializedSuccess && deserialized.meshName != null && deserialized.padding != null)
|
||||
{
|
||||
// Get padding from extraUserProperties (new)
|
||||
int mindex = deserialized.meshName.IndexOf(nm);
|
||||
if (mindex < 0)
|
||||
{
|
||||
//Debug.LogError("Unable to find padding value for mesh " + nm);
|
||||
// This is fine. Apparently caused by parts of models being lightmapped,
|
||||
// while other parts are not baked, yet still a part of the model.
|
||||
}
|
||||
else
|
||||
{
|
||||
var padding = deserialized.padding[mindex];
|
||||
|
||||
ftGlobalStorage.Unwrapper unwrapper = ftGlobalStorage.Unwrapper.Default;
|
||||
if (deserialized.unwrapper != null && deserialized.unwrapper.Count > mindex)
|
||||
unwrapper = (ftGlobalStorage.Unwrapper)deserialized.unwrapper[mindex];
|
||||
|
||||
if (!ValidateMesh(m, unwrapper)) return;
|
||||
|
||||
uparams.packMargin = padding/1024.0f;
|
||||
Unwrap(m, uparams, unwrapper);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get padding from GlobalStorage (old)
|
||||
if (storage != null && storage.modifiedMeshMap.TryGetValue(nm, out modifiedMeshID))
|
||||
{
|
||||
var padding = storage.modifiedMeshPaddingArray[modifiedMeshID];
|
||||
|
||||
ftGlobalStorage.Unwrapper unwrapper = ftGlobalStorage.Unwrapper.Default;
|
||||
if (storage.modifiedMeshUnwrapperArray != null && storage.modifiedMeshUnwrapperArray.Count > modifiedMeshID)
|
||||
unwrapper = (ftGlobalStorage.Unwrapper)storage.modifiedMeshUnwrapperArray[modifiedMeshID];
|
||||
|
||||
if (!ValidateMesh(m, unwrapper)) return;
|
||||
|
||||
uparams.packMargin = padding/1024.0f;
|
||||
Unwrap(m, uparams, unwrapper);
|
||||
}
|
||||
}
|
||||
#else
|
||||
else if (storage != null && storage.modifiedMeshMap.TryGetValue(nm, out modifiedMeshID))
|
||||
{
|
||||
var padding = storage.modifiedMeshPaddingArray[modifiedMeshID];
|
||||
|
||||
ftGlobalStorage.Unwrapper unwrapper = ftGlobalStorage.Unwrapper.Default;
|
||||
if (storage.modifiedMeshUnwrapperArray != null && storage.modifiedMeshUnwrapperArray.Count > modifiedMeshID)
|
||||
unwrapper = (ftGlobalStorage.Unwrapper)storage.modifiedMeshUnwrapperArray[modifiedMeshID];
|
||||
|
||||
if (!ValidateMesh(m, unwrapper)) return;
|
||||
|
||||
uparams.packMargin = padding/1024.0f;
|
||||
Unwrap(m, uparams, unwrapper);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Recurse
|
||||
foreach (Transform child in t)
|
||||
AdjustUV(child, saved);
|
||||
}
|
||||
|
||||
static bool RenderMeshes(Transform t, bool deep)
|
||||
{
|
||||
var mf = t.GetComponent<MeshFilter>();
|
||||
if (mf != null && mf.sharedMesh != null)
|
||||
{
|
||||
var m = mf.sharedMesh;
|
||||
//var nm = m.name;
|
||||
|
||||
bool noUV2 = (m.uv2 == null || (m.uv2.Length == 0 && m.vertexCount != 0));
|
||||
bool noUV1 = (m.uv == null || (m.uv.Length == 0 && m.vertexCount != 0));
|
||||
|
||||
if (noUV1 && noUV2) return false;
|
||||
|
||||
mat.SetFloat("uvSet", noUV2 ? 0.0f : 1.0f);
|
||||
mat.SetPass(0);
|
||||
|
||||
Graphics.DrawMeshNow(m, Vector3.zero, Quaternion.identity);
|
||||
}
|
||||
|
||||
if (!deep) return true;
|
||||
|
||||
// Recurse
|
||||
foreach (Transform child in t)
|
||||
RenderMeshes(child, deep);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Unwrap(Mesh m, UnwrapParam uparams, ftGlobalStorage.Unwrapper unwrapper)
|
||||
{
|
||||
if (unwrapper == ftGlobalStorage.Unwrapper.xatlas)
|
||||
{
|
||||
UnwrapXatlas(m, uparams);
|
||||
}
|
||||
else
|
||||
{
|
||||
var tt = GetTime();
|
||||
Unwrapping.GenerateSecondaryUVSet(m, uparams);
|
||||
if (m.uv2 == null || m.uv2.Length == 0)
|
||||
{
|
||||
Debug.LogError("Unity failed to unwrap mesh. Options: a) Use 32-bit indices and Unity >= 2018.4. b) Split it into multiple chunks. c) Disable 'Adjust UV Padding'.");
|
||||
unwrapError = true;
|
||||
lastUnwrapErrorAsset = assetPath;
|
||||
}
|
||||
Debug.Log("Unity unwrap time: " + (GetTime() - tt));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 958d625f263bc9e468b7ea865c491cef
|
||||
timeCreated: 1528661707
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
832
Assets/Editor/x64/Bakery/scripts/ftPointLightInspector.cs
Normal file
832
Assets/Editor/x64/Bakery/scripts/ftPointLightInspector.cs
Normal file
@@ -0,0 +1,832 @@
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
[CustomEditor(typeof(BakeryPointLight))]
|
||||
[CanEditMultipleObjects]
|
||||
public class ftPointLightInspector : UnityEditor.Editor
|
||||
{
|
||||
SerializedProperty ftraceLightColor;
|
||||
SerializedProperty ftraceLightIntensity;
|
||||
SerializedProperty ftraceLightShadowSpread;
|
||||
SerializedProperty ftraceLightCutoff;
|
||||
SerializedProperty ftraceLightSamples;
|
||||
SerializedProperty ftraceLightProj;
|
||||
SerializedProperty ftraceLightTexture;
|
||||
SerializedProperty ftraceLightTexture2D;
|
||||
SerializedProperty ftraceLightAngle;
|
||||
SerializedProperty ftraceLightIES;
|
||||
SerializedProperty ftraceLightBitmask;
|
||||
SerializedProperty ftraceLightBakeToIndirect;
|
||||
SerializedProperty ftraceLightRealisticFalloff;
|
||||
SerializedProperty ftraceLightShadowmask;
|
||||
SerializedProperty ftraceLightIndirectIntensity;
|
||||
SerializedProperty ftraceLightFalloffMinRadius;
|
||||
SerializedProperty ftraceLightInnerAngle;
|
||||
SerializedProperty ftraceShadowmaskGroupID;
|
||||
|
||||
UnityEngine.Object spotCookieTexture;
|
||||
|
||||
ftLightmapsStorage storage;
|
||||
|
||||
bool isHDRP = false;
|
||||
bool isLWRP = false;
|
||||
|
||||
int projModeCached = -1;
|
||||
int texCached = -1;
|
||||
int tex2DCached = -1;
|
||||
int iesCached = -1;
|
||||
|
||||
static string[] selStrings = new string[] {"0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16",
|
||||
"17","18","19","20","21","22","23","24","25","26","27","28","29","30"};//,"31"};
|
||||
|
||||
void InitSerializedProperties(SerializedObject obj)
|
||||
{
|
||||
ftraceLightColor = obj.FindProperty("color");
|
||||
ftraceLightIntensity = obj.FindProperty("intensity");
|
||||
ftraceLightIndirectIntensity = obj.FindProperty("indirectIntensity");
|
||||
ftraceLightShadowSpread = obj.FindProperty("shadowSpread");
|
||||
ftraceLightCutoff = obj.FindProperty("cutoff");
|
||||
ftraceLightAngle = obj.FindProperty("angle");
|
||||
ftraceLightInnerAngle = obj.FindProperty("innerAngle");
|
||||
ftraceLightSamples = obj.FindProperty("samples");
|
||||
ftraceLightProj = obj.FindProperty("projMode");
|
||||
ftraceLightTexture = obj.FindProperty("cubemap");
|
||||
ftraceLightTexture2D = obj.FindProperty("cookie");
|
||||
ftraceLightIES = obj.FindProperty("iesFile");
|
||||
ftraceLightBitmask = obj.FindProperty("bitmask");
|
||||
ftraceLightBakeToIndirect = obj.FindProperty("bakeToIndirect");
|
||||
ftraceLightRealisticFalloff = obj.FindProperty("realisticFalloff");
|
||||
ftraceLightShadowmask = obj.FindProperty("shadowmask");
|
||||
ftraceLightFalloffMinRadius = obj.FindProperty("falloffMinRadius");
|
||||
ftraceShadowmaskGroupID = obj.FindProperty("shadowmaskGroupID");
|
||||
|
||||
var hdrpLight = (target as BakeryPointLight).GetComponent("HDAdditionalLightData");
|
||||
isHDRP = hdrpLight != null;
|
||||
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
var rpipe = GraphicsSettings.currentRenderPipeline;
|
||||
#else
|
||||
var rpipe = GraphicsSettings.renderPipelineAsset;
|
||||
#endif
|
||||
|
||||
if (rpipe != null && (rpipe.GetType().Name.StartsWith("Lightweight") || rpipe.GetType().Name.StartsWith("Universal")))
|
||||
{
|
||||
isLWRP = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
InitSerializedProperties(serializedObject);
|
||||
|
||||
if (spotCookieTexture == null)
|
||||
{
|
||||
var bakeryRuntimePath = ftLightmaps.GetRuntimePath();
|
||||
spotCookieTexture = AssetDatabase.LoadAssetAtPath(bakeryRuntimePath + "ftUnitySpotTexture.bmp", typeof(Texture2D));
|
||||
}
|
||||
}
|
||||
|
||||
void GetLinearLightParameters(Light light, out float lightR, out float lightG, out float lightB, out float lightInt)
|
||||
{
|
||||
if (PlayerSettings.colorSpace != ColorSpace.Linear)
|
||||
{
|
||||
lightInt = light.intensity;
|
||||
lightR = light.color.r;
|
||||
lightG = light.color.g;
|
||||
lightB = light.color.b;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GraphicsSettings.lightsUseLinearIntensity)
|
||||
{
|
||||
lightR = Mathf.Pow(light.color.r * light.intensity, 2.2f);
|
||||
lightG = Mathf.Pow(light.color.g * light.intensity, 2.2f);
|
||||
lightB = Mathf.Pow(light.color.b * light.intensity, 2.2f);
|
||||
lightInt = Mathf.Max(Mathf.Max(lightR, lightG), lightB);
|
||||
lightR /= lightInt;
|
||||
lightG /= lightInt;
|
||||
lightB /= lightInt;
|
||||
}
|
||||
else
|
||||
{
|
||||
lightInt = light.intensity;
|
||||
lightR = light.color.linear.r;
|
||||
lightG = light.color.linear.g;
|
||||
lightB = light.color.linear.b;
|
||||
}
|
||||
}
|
||||
|
||||
bool CompareWithLWRP(Light l, ref string why)
|
||||
{
|
||||
if (l.type == LightType.Spot)
|
||||
{
|
||||
var so = new SerializedObject(l);
|
||||
if (so == null)
|
||||
{
|
||||
why = "no SerializedObject";
|
||||
return false;
|
||||
}
|
||||
if (ftraceLightProj.intValue != (int)BakeryPointLight.ftLightProjectionMode.Cone)
|
||||
{
|
||||
why = "spot shape doesn't match.";
|
||||
return false;
|
||||
}
|
||||
SerializedProperty innerAngle = so.FindProperty("m_InnerSpotAngle");
|
||||
if (innerAngle == null)
|
||||
{
|
||||
why = "no m_InnerSpotAngle";
|
||||
return false;
|
||||
}
|
||||
if (Mathf.Abs(((ftraceLightInnerAngle.floatValue * 0.01f) * ftraceLightAngle.floatValue) - innerAngle.floatValue) > 0.001f)
|
||||
{
|
||||
why = "inner angle doesn't match.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CompareWithHDRP(Light l, ref string why)
|
||||
{
|
||||
var hdrpLight = l.GetComponent("HDAdditionalLightData");
|
||||
if (hdrpLight == null)
|
||||
{
|
||||
why = "no HDAdditionalLightData";
|
||||
return false;
|
||||
}
|
||||
var so = new SerializedObject(hdrpLight);
|
||||
if (so == null)
|
||||
{
|
||||
why = "no SerializedObject";
|
||||
return false;
|
||||
}
|
||||
SerializedProperty hdrpLightTypeExtent = so.FindProperty("m_PointlightHDType");
|
||||
if (hdrpLightTypeExtent == null)
|
||||
{
|
||||
why = "no m_PointlightHDType";
|
||||
return false;
|
||||
}
|
||||
|
||||
int extendedLightType = hdrpLightTypeExtent.intValue;
|
||||
if (extendedLightType != 0)
|
||||
{
|
||||
why = "Only punctual sounrces are supported.\nUse rectangle/tube geometry with Light Mesh instead.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (l.type == LightType.Spot)
|
||||
{
|
||||
SerializedProperty hdrpLightSpotShape = so.FindProperty("m_SpotLightShape");
|
||||
if (hdrpLightSpotShape == null)
|
||||
{
|
||||
why = "no m_SpotLightShape";
|
||||
return false;
|
||||
}
|
||||
SerializedProperty hdrpLightInnerAngle = so.FindProperty("m_InnerSpotPercent");
|
||||
if (hdrpLightInnerAngle == null)
|
||||
{
|
||||
why = "no m_InnerSpotPercent";
|
||||
return false;
|
||||
}
|
||||
|
||||
int spotShape = hdrpLightSpotShape.intValue;
|
||||
if (spotShape != 0)
|
||||
{
|
||||
why = "Only cone spotlights are supported.";
|
||||
return false;
|
||||
}
|
||||
if (ftraceLightProj.intValue != (int)BakeryPointLight.ftLightProjectionMode.Cone)
|
||||
{
|
||||
why = "spot shape doesn't match.";
|
||||
return false;
|
||||
}
|
||||
if (Mathf.Abs(ftraceLightInnerAngle.floatValue - hdrpLightInnerAngle.floatValue) > 0.001f)
|
||||
{
|
||||
why = "inner angle doesn't match.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MatchToLWRPLight(Light l)
|
||||
{
|
||||
ftraceLightRealisticFalloff.boolValue = true;
|
||||
ftraceLightFalloffMinRadius.floatValue = 0.01f;
|
||||
if (l.type == LightType.Spot)
|
||||
{
|
||||
ftraceLightProj.intValue = (int)BakeryPointLight.ftLightProjectionMode.Cone;
|
||||
|
||||
var so = new SerializedObject(l);
|
||||
if (so == null) return;
|
||||
|
||||
SerializedProperty lightInnerAngle = so.FindProperty("m_InnerSpotAngle");
|
||||
if (lightInnerAngle == null) return;
|
||||
ftraceLightInnerAngle.floatValue = (lightInnerAngle.floatValue / ftraceLightAngle.floatValue) * 100;
|
||||
}
|
||||
}
|
||||
|
||||
void MatchToHDRPLight(Light l)
|
||||
{
|
||||
ftraceLightRealisticFalloff.boolValue = true;
|
||||
ftraceLightFalloffMinRadius.floatValue = 0.01f;
|
||||
|
||||
ftraceLightIntensity.floatValue /= Mathf.PI;
|
||||
|
||||
var hdrpLight = l.GetComponent("HDAdditionalLightData");
|
||||
if (hdrpLight == null) return;
|
||||
|
||||
var so = new SerializedObject(hdrpLight);
|
||||
if (so == null) return;
|
||||
|
||||
SerializedProperty hdrpLightTypeExtent = so.FindProperty("m_PointlightHDType");
|
||||
if (hdrpLightTypeExtent == null) return;
|
||||
|
||||
int extendedLightType = hdrpLightTypeExtent.intValue;
|
||||
if (extendedLightType != 0) return;
|
||||
|
||||
if (l.type == LightType.Spot)
|
||||
{
|
||||
SerializedProperty hdrpLightSpotShape = so.FindProperty("m_SpotLightShape");
|
||||
if (hdrpLightSpotShape == null) return;
|
||||
|
||||
int spotShape = hdrpLightSpotShape.intValue;
|
||||
if (spotShape != 0) return;
|
||||
|
||||
ftraceLightProj.intValue = (int)BakeryPointLight.ftLightProjectionMode.Cone;
|
||||
}
|
||||
|
||||
SerializedProperty hdrpLightInnerAngle = so.FindProperty("m_InnerSpotPercent");
|
||||
if (hdrpLightInnerAngle == null) return;
|
||||
ftraceLightInnerAngle.floatValue = hdrpLightInnerAngle.floatValue;
|
||||
}
|
||||
|
||||
void SetLWRPLight(Light l)
|
||||
{
|
||||
if (ftraceLightProj.enumValueIndex == (int)BakeryPointLight.ftLightProjectionMode.Cone)
|
||||
{
|
||||
var so = new SerializedObject(l);
|
||||
if (so == null) return;
|
||||
|
||||
SerializedProperty lightInnerAngle = so.FindProperty("m_InnerSpotAngle");
|
||||
if (lightInnerAngle == null) return;
|
||||
|
||||
lightInnerAngle.floatValue = (ftraceLightInnerAngle.floatValue * 0.01f) * ftraceLightAngle.floatValue;
|
||||
|
||||
so.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
|
||||
void SetHDRPLight(Light l)
|
||||
{
|
||||
#if UNITY_2019_1_OR_NEWER
|
||||
l.useBoundingSphereOverride = false;
|
||||
l.useShadowMatrixOverride = false;
|
||||
#endif
|
||||
l.intensity *= Mathf.PI;
|
||||
|
||||
var hdrpLight = l.GetComponent("HDAdditionalLightData");
|
||||
if (hdrpLight == null) return;
|
||||
|
||||
var so = new SerializedObject(hdrpLight);
|
||||
if (so == null) return;
|
||||
|
||||
SerializedProperty hdrpUnits = so.FindProperty("m_LightUnit");
|
||||
if (hdrpUnits != null) hdrpUnits.intValue = 1; // candela
|
||||
|
||||
SerializedProperty hdrpInt2 = so.FindProperty("m_Intensity");
|
||||
if (hdrpInt2 != null) hdrpInt2.floatValue = l.intensity;
|
||||
|
||||
SerializedProperty hdrpLightTypeExtent = so.FindProperty("m_PointlightHDType");
|
||||
if (hdrpLightTypeExtent == null) return;
|
||||
hdrpLightTypeExtent.intValue = 0; // punctual
|
||||
|
||||
if (ftraceLightProj.enumValueIndex == (int)BakeryPointLight.ftLightProjectionMode.Cone)
|
||||
{
|
||||
SerializedProperty hdrpLightSpotShape = so.FindProperty("m_SpotLightShape");
|
||||
if (hdrpLightSpotShape == null) return;
|
||||
hdrpLightSpotShape.intValue = 0; // cone
|
||||
}
|
||||
|
||||
SerializedProperty hdrpLightInnerAngle = so.FindProperty("m_InnerSpotPercent");
|
||||
if (hdrpLightInnerAngle == null) return;
|
||||
hdrpLightInnerAngle.floatValue = ftraceLightInnerAngle.floatValue;
|
||||
|
||||
so.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
void TestPreviewRefreshProperty(ref int cached, int newVal)
|
||||
{
|
||||
if (cached >= 0)
|
||||
{
|
||||
if (cached != newVal)
|
||||
{
|
||||
BakeryPointLight.lightsChanged = 2;
|
||||
}
|
||||
}
|
||||
cached = newVal;
|
||||
}
|
||||
|
||||
void TestPreviewRefreshProperty(ref int cached, UnityEngine.Object newVal)
|
||||
{
|
||||
if (newVal == null)
|
||||
{
|
||||
TestPreviewRefreshProperty(ref cached, 0);
|
||||
return;
|
||||
}
|
||||
TestPreviewRefreshProperty(ref cached, newVal.GetInstanceID());
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI() {
|
||||
//if (showFtrace)
|
||||
{
|
||||
OnEnable();
|
||||
|
||||
serializedObject.Update();
|
||||
|
||||
TestPreviewRefreshProperty(ref projModeCached, ftraceLightProj.intValue);
|
||||
TestPreviewRefreshProperty(ref texCached, ftraceLightTexture.objectReferenceValue);
|
||||
TestPreviewRefreshProperty(ref tex2DCached, ftraceLightTexture2D.objectReferenceValue);
|
||||
TestPreviewRefreshProperty(ref iesCached, ftraceLightIES.objectReferenceValue);
|
||||
|
||||
EditorGUILayout.PropertyField(ftraceLightColor, new GUIContent("Color", "Color of the light"));
|
||||
EditorGUILayout.PropertyField(ftraceLightIntensity, new GUIContent("Intensity", "Color multiplier (Candela / PI)"));
|
||||
EditorGUILayout.PropertyField(ftraceLightShadowSpread, new GUIContent("Shadow spread", "Controls shadow blurriness from 0 to 1"));
|
||||
|
||||
EditorGUILayout.PropertyField(ftraceLightRealisticFalloff, new GUIContent("Physical falloff", "Use inverse-squared falloff instead of Unity falloff"));
|
||||
if (ftraceLightRealisticFalloff.boolValue)
|
||||
{
|
||||
EditorGUILayout.PropertyField(ftraceLightFalloffMinRadius, new GUIContent("Falloff min size", "As point lights don't have area, at zero distance 1/(d*d) will become infinity. This value avoids this issue by assuming the light to have some minimum radius and changing the formula to 1/(d*d+R*R)."));
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(ftraceLightCutoff, new GUIContent("Range", "Lighting distance limit. When 'Physical falloff' is on, for maximum corectness set to a very high value. Using smaller values is useful for faster render times and to match real-time lights. Bakery uses Skyforge falloff to maintain balance between correct inverse-squared attenuation and practical limits (https://habr.com/company/mailru/blog/248873/)"));
|
||||
EditorGUILayout.PropertyField(ftraceLightSamples, new GUIContent("Samples", "The amount of sample points generated on the surface of this light. Point light shadows are traced towards points on a sphere (with radius = shadowSpread) around the light. "));
|
||||
EditorGUILayout.PropertyField(ftraceLightProj, new GUIContent("Projection mask", "Determines additional light masking mode."));
|
||||
|
||||
switch(ftraceLightProj.enumValueIndex)
|
||||
{
|
||||
case (int)BakeryPointLight.ftLightProjectionMode.Cookie:
|
||||
EditorGUILayout.PropertyField(ftraceLightTexture2D, new GUIContent("Cookie texture", "Texture"));
|
||||
EditorGUILayout.Slider(ftraceLightAngle, 1, 179, new GUIContent("Angle", "Angle of projection (like in spotlights)."));
|
||||
break;
|
||||
case (int)BakeryPointLight.ftLightProjectionMode.Cone:
|
||||
EditorGUILayout.Slider(ftraceLightAngle, 1, 180, new GUIContent("Outer angle"));
|
||||
EditorGUILayout.Slider(ftraceLightInnerAngle, 0, 100, new GUIContent("Inner angle percent"));
|
||||
break;
|
||||
case (int)BakeryPointLight.ftLightProjectionMode.Cubemap:
|
||||
EditorGUILayout.PropertyField(ftraceLightTexture, new GUIContent("Projected cubemap", "Cubemap"));
|
||||
break;
|
||||
case (int)BakeryPointLight.ftLightProjectionMode.IES:
|
||||
ftraceLightIES.objectReferenceValue = EditorGUILayout.ObjectField("IES file", ftraceLightIES.objectReferenceValue, typeof(UnityEngine.Object), false);
|
||||
if (ftraceLightIES.objectReferenceValue != null)
|
||||
{
|
||||
var path = AssetDatabase.GetAssetPath(ftraceLightIES.objectReferenceValue);
|
||||
if (path.Length < 4 || path.Substring(path.Length - 4).ToLower() != ".ies")
|
||||
{
|
||||
EditorUtility.DisplayDialog("Bakery", "File must have IES extension.", "OK");
|
||||
ftraceLightIES.objectReferenceValue = null;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
int prevVal = ftraceLightBitmask.intValue;
|
||||
int newVal = EditorGUILayout.MaskField(new GUIContent("Bitmask", "Lights only affect renderers with overlapping bits"), ftraceLightBitmask.intValue, selStrings);
|
||||
if (prevVal != newVal) ftraceLightBitmask.intValue = newVal;
|
||||
|
||||
/*
|
||||
EditorGUILayout.PropertyField(ftraceLightBakeToIndirect, new GUIContent("Bake to indirect", "Add direct contribution from this light to indirect-only lightmaps"));
|
||||
if (ftraceLightBakeToIndirect.boolValue && ftraceLightShadowmask.boolValue) ftraceLightShadowmask.boolValue = false;
|
||||
|
||||
EditorGUILayout.PropertyField(ftraceLightShadowmask, new GUIContent("Shadowmask", "Enable mixed lighting. Static shadows from this light will be baked, and real-time light will cast shadows from dynamic objects."));
|
||||
if (ftraceLightBakeToIndirect.boolValue && ftraceLightShadowmask.boolValue) ftraceLightBakeToIndirect.boolValue = false;
|
||||
*/
|
||||
|
||||
if (storage == null) storage = ftRenderLightmap.FindRenderSettingsStorage();
|
||||
var rmode = storage.renderSettingsUserRenderMode;
|
||||
if (rmode != (int)ftRenderLightmap.RenderMode.FullLighting)
|
||||
{
|
||||
ftDirectLightInspector.BakeWhat contrib;
|
||||
if (ftraceLightShadowmask.boolValue)
|
||||
{
|
||||
contrib = ftDirectLightInspector.BakeWhat.IndirectAndShadowmask;
|
||||
}
|
||||
else if (ftraceLightBakeToIndirect.boolValue)
|
||||
{
|
||||
contrib = ftDirectLightInspector.BakeWhat.DirectAndIndirect;
|
||||
}
|
||||
else
|
||||
{
|
||||
contrib = ftDirectLightInspector.BakeWhat.IndirectOnly;
|
||||
}
|
||||
var prevContrib = contrib;
|
||||
|
||||
if (rmode == (int)ftRenderLightmap.RenderMode.Indirect)
|
||||
{
|
||||
contrib = (ftDirectLightInspector.BakeWhat)EditorGUILayout.Popup("Baked contribution", (int)contrib, ftDirectLightInspector.directContributionIndirectOptions);
|
||||
}
|
||||
else if (rmode == (int)ftRenderLightmap.RenderMode.Shadowmask)
|
||||
{
|
||||
contrib = (ftDirectLightInspector.BakeWhat)EditorGUILayout.EnumPopup("Baked contribution", contrib);
|
||||
}
|
||||
|
||||
if (prevContrib != contrib)
|
||||
{
|
||||
if (contrib == ftDirectLightInspector.BakeWhat.IndirectOnly)
|
||||
{
|
||||
ftraceLightShadowmask.boolValue = false;
|
||||
ftraceLightBakeToIndirect.boolValue = false;
|
||||
}
|
||||
else if (contrib == ftDirectLightInspector.BakeWhat.IndirectAndShadowmask)
|
||||
{
|
||||
ftraceLightShadowmask.boolValue = true;
|
||||
ftraceLightBakeToIndirect.boolValue = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ftraceLightShadowmask.boolValue = false;
|
||||
ftraceLightBakeToIndirect.boolValue = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(ftraceLightIndirectIntensity, new GUIContent("Indirect intensity", "Non-physical GI multiplier for this light"));
|
||||
|
||||
if (ftraceLightShadowmask.boolValue)
|
||||
{
|
||||
EditorGUILayout.PropertyField(ftraceShadowmaskGroupID, new GUIContent("Shadowmask Group ID", "If set to 0, each shadowmasked light will have a separate mask. Lights sharing any other positive value will share the same mask. This is useful to avoid 4 channel limit in cases where light bounds overlap, but the overlapping part is occluded in both anyway."));
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
|
||||
bool showWarningCant = false;
|
||||
bool showError = false;
|
||||
string why = "";
|
||||
|
||||
bool shadowmaskNoDynamicLight = false;
|
||||
|
||||
foreach(BakeryPointLight selectedLight in targets)
|
||||
{
|
||||
bool match = true;
|
||||
//string why = "";
|
||||
var light = selectedLight.GetComponent<Light>();
|
||||
if (light == null)
|
||||
{
|
||||
if (ftraceLightShadowmask.boolValue) shadowmaskNoDynamicLight = true;
|
||||
continue;
|
||||
}
|
||||
if (!light.enabled)
|
||||
{
|
||||
if (ftraceLightShadowmask.boolValue) shadowmaskNoDynamicLight = true;
|
||||
}
|
||||
|
||||
if (isHDRP)
|
||||
{
|
||||
if (!ftraceLightRealisticFalloff.boolValue || Mathf.Abs(ftraceLightFalloffMinRadius.floatValue - 0.01f) > 0.0001f)
|
||||
{
|
||||
match = false;
|
||||
why = "falloff doesn't match HDRP";
|
||||
}
|
||||
else
|
||||
{
|
||||
match = CompareWithHDRP(light, ref why);
|
||||
}
|
||||
}
|
||||
|
||||
if (isLWRP)
|
||||
{
|
||||
if (!ftraceLightRealisticFalloff.boolValue || Mathf.Abs(ftraceLightFalloffMinRadius.floatValue - 0.01f) > 0.0001f)
|
||||
{
|
||||
match = false;
|
||||
why = "falloff doesn't match URP";
|
||||
}
|
||||
else
|
||||
{
|
||||
match = CompareWithLWRP(light, ref why);
|
||||
}
|
||||
}
|
||||
|
||||
var so = new SerializedObject(selectedLight);
|
||||
InitSerializedProperties(so);
|
||||
|
||||
if (ftraceLightIndirectIntensity.floatValue != light.bounceIntensity)
|
||||
{
|
||||
match = false;
|
||||
why = "indirect intensity doesn't match";
|
||||
}
|
||||
|
||||
if (ftraceLightProj.enumValueIndex == (int)BakeryPointLight.ftLightProjectionMode.IES)
|
||||
{
|
||||
showWarningCant = true;
|
||||
}
|
||||
else if (ftraceLightProj.enumValueIndex == (int)BakeryPointLight.ftLightProjectionMode.Omni)
|
||||
{
|
||||
if (light.type != LightType.Point)
|
||||
{
|
||||
match = false;
|
||||
why = "real-time light is not point";
|
||||
}
|
||||
else if (light.cookie != null)
|
||||
{
|
||||
match = false;
|
||||
why = "real-time light has cookie";
|
||||
}
|
||||
}
|
||||
else if (ftraceLightProj.enumValueIndex == (int)BakeryPointLight.ftLightProjectionMode.Cubemap)
|
||||
{
|
||||
if (light.type != LightType.Point)
|
||||
{
|
||||
match = false;
|
||||
why = "real-time light is not point";
|
||||
}
|
||||
else if (light.cookie == null)
|
||||
{
|
||||
match = false;
|
||||
why = "real-time light has no cookie";
|
||||
}
|
||||
}
|
||||
else if (ftraceLightProj.enumValueIndex == (int)BakeryPointLight.ftLightProjectionMode.Cookie)
|
||||
{
|
||||
if (light.type != LightType.Spot)
|
||||
{
|
||||
match = false;
|
||||
why = "real-time light is not spot";
|
||||
}
|
||||
else if (light.cookie == null && ftraceLightTexture2D.objectReferenceValue != spotCookieTexture)
|
||||
{
|
||||
match = false;
|
||||
why = "wrong cookie texture";
|
||||
}
|
||||
else if (light.cookie != null && ftraceLightTexture2D.objectReferenceValue != light.cookie)
|
||||
{
|
||||
match = false;
|
||||
why = "wrong cookie texture";
|
||||
}
|
||||
else if (light.spotAngle != ftraceLightAngle.floatValue)
|
||||
{
|
||||
match = false;
|
||||
why = "spot angle doesn't match";
|
||||
}
|
||||
}
|
||||
else if (ftraceLightProj.enumValueIndex == (int)BakeryPointLight.ftLightProjectionMode.Cone)
|
||||
{
|
||||
if (light.type != LightType.Spot)
|
||||
{
|
||||
match = false;
|
||||
why = "real-time light is not spot";
|
||||
}
|
||||
else if (light.spotAngle != ftraceLightAngle.floatValue)
|
||||
{
|
||||
match = false;
|
||||
why = "outer angle doesn't match";
|
||||
}
|
||||
}
|
||||
|
||||
var clr = ftraceLightColor.colorValue;
|
||||
float eps = 1.0f / 255.0f;
|
||||
float lightR, lightG, lightB, lightInt;
|
||||
float fr, fg, fb;
|
||||
float fintensity = ftraceLightIntensity.floatValue;
|
||||
if (isHDRP) fintensity *= Mathf.PI;
|
||||
if (PlayerSettings.colorSpace == ColorSpace.Linear)
|
||||
{
|
||||
fr = clr.linear.r;// * fintensity;
|
||||
fg = clr.linear.g;// * fintensity;
|
||||
fb = clr.linear.b;// * fintensity;
|
||||
}
|
||||
else
|
||||
{
|
||||
fr = clr.r;
|
||||
fg = clr.g;
|
||||
fb = clr.b;
|
||||
}
|
||||
GetLinearLightParameters(light, out lightR, out lightG, out lightB, out lightInt);
|
||||
|
||||
if (GraphicsSettings.lightsUseLinearIntensity || PlayerSettings.colorSpace != ColorSpace.Linear)
|
||||
{
|
||||
if (Mathf.Abs(lightR - fr) > eps || Mathf.Abs(lightG - fg) > eps || Mathf.Abs(lightB - fb) > eps)
|
||||
{
|
||||
match = false;
|
||||
why = "color doesn't match";
|
||||
}
|
||||
else if (Mathf.Abs(lightInt - fintensity) > eps)
|
||||
{
|
||||
match = false;
|
||||
why = "intensity doesn't match";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
eps *= Mathf.Max(lightInt, fintensity);
|
||||
if (Mathf.Abs(lightR*lightInt - fr*fintensity) > eps ||
|
||||
Mathf.Abs(lightG*lightInt - fg*fintensity) > eps ||
|
||||
Mathf.Abs(lightB*lightInt - fb*fintensity) > eps)
|
||||
{
|
||||
match = false;
|
||||
why = "intensity doesn't match";
|
||||
}
|
||||
}
|
||||
|
||||
if (Mathf.Abs(light.range - ftraceLightCutoff.floatValue) > 0.001f)
|
||||
{
|
||||
match = false;
|
||||
why = "range doesn't match";
|
||||
}
|
||||
|
||||
if (!match)
|
||||
{
|
||||
showError = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (shadowmaskNoDynamicLight)
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Warning: shadowmask needs enabled real-time light to work");
|
||||
}
|
||||
|
||||
if (showWarningCant)
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Warning: real-time light can't match baked IES light");
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
|
||||
if (showError)
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Real-time light doesn't match lightmap: " + why);
|
||||
|
||||
if (GUILayout.Button("Match lightmapped to real-time"))
|
||||
{
|
||||
foreach(BakeryPointLight selectedLight in targets)
|
||||
{
|
||||
var light = selectedLight.GetComponent<Light>();
|
||||
if (light == null) continue;
|
||||
//if (!light.enabled) continue;
|
||||
var so = new SerializedObject(selectedLight);
|
||||
InitSerializedProperties(so);
|
||||
|
||||
if (PlayerSettings.colorSpace != ColorSpace.Linear)
|
||||
{
|
||||
ftraceLightColor.colorValue = light.color;
|
||||
ftraceLightIntensity.floatValue = light.intensity;
|
||||
}
|
||||
else if (!GraphicsSettings.lightsUseLinearIntensity)
|
||||
{
|
||||
float lightR, lightG, lightB, lightInt;
|
||||
GetLinearLightParameters(light, out lightR, out lightG, out lightB, out lightInt);
|
||||
ftraceLightColor.colorValue = new Color(lightR, lightG, lightB);
|
||||
ftraceLightIntensity.floatValue = lightInt;
|
||||
}
|
||||
else
|
||||
{
|
||||
ftraceLightColor.colorValue = light.color;
|
||||
ftraceLightIntensity.floatValue = light.intensity;
|
||||
}
|
||||
ftraceLightCutoff.floatValue = light.range;
|
||||
ftraceLightAngle.floatValue = light.spotAngle;
|
||||
|
||||
if (light.type == LightType.Point)
|
||||
{
|
||||
if (light.cookie == null)
|
||||
{
|
||||
ftraceLightProj.enumValueIndex = (int)BakeryPointLight.ftLightProjectionMode.Omni;
|
||||
ftraceLightTexture.objectReferenceValue = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
ftraceLightProj.enumValueIndex = (int)BakeryPointLight.ftLightProjectionMode.Cubemap;
|
||||
ftraceLightTexture.objectReferenceValue = light.cookie;
|
||||
}
|
||||
}
|
||||
else if (light.type == LightType.Spot)
|
||||
{
|
||||
ftraceLightProj.enumValueIndex = (int)BakeryPointLight.ftLightProjectionMode.Cookie;
|
||||
if (light.cookie == null)
|
||||
{
|
||||
ftraceLightTexture2D.objectReferenceValue = spotCookieTexture;
|
||||
}
|
||||
else
|
||||
{
|
||||
ftraceLightTexture2D.objectReferenceValue = light.cookie;
|
||||
}
|
||||
}
|
||||
ftraceLightIndirectIntensity.floatValue = light.bounceIntensity;
|
||||
|
||||
if (isHDRP) MatchToHDRPLight(light);
|
||||
if (isLWRP) MatchToLWRPLight(light);
|
||||
|
||||
so.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
if (GUILayout.Button("Match real-time to lightmapped"))
|
||||
{
|
||||
foreach(BakeryPointLight selectedLight in targets)
|
||||
{
|
||||
var light = selectedLight.GetComponent<Light>();
|
||||
if (light == null) continue;
|
||||
//if (!light.enabled) continue;
|
||||
var so = new SerializedObject(selectedLight);
|
||||
InitSerializedProperties(so);
|
||||
|
||||
Undo.RecordObject(light, "Change light");
|
||||
if (PlayerSettings.colorSpace != ColorSpace.Linear)
|
||||
{
|
||||
light.color = ftraceLightColor.colorValue;
|
||||
light.intensity = ftraceLightIntensity.floatValue;
|
||||
}
|
||||
else if (!GraphicsSettings.lightsUseLinearIntensity)
|
||||
{
|
||||
var clr = ftraceLightColor.colorValue;
|
||||
float fintensity = ftraceLightIntensity.floatValue;
|
||||
float fr = clr.linear.r;// * fintensity;
|
||||
float fg = clr.linear.g;// * fintensity;
|
||||
float fb = clr.linear.b;// * fintensity;
|
||||
|
||||
fr = Mathf.Pow(fr * fintensity, 1.0f / 2.2f);
|
||||
fg = Mathf.Pow(fg * fintensity, 1.0f / 2.2f);
|
||||
fb = Mathf.Pow(fb * fintensity, 1.0f / 2.2f);
|
||||
float fint = Mathf.Max(Mathf.Max(fr, fg), fb);
|
||||
fr /= fint;
|
||||
fg /= fint;
|
||||
fb /= fint;
|
||||
light.color = new Color(fr, fg, fb);
|
||||
light.intensity = fint;
|
||||
}
|
||||
else
|
||||
{
|
||||
light.color = ftraceLightColor.colorValue;
|
||||
light.intensity = ftraceLightIntensity.floatValue;
|
||||
}
|
||||
light.range = ftraceLightCutoff.floatValue;
|
||||
light.spotAngle = ftraceLightAngle.floatValue;
|
||||
|
||||
if (ftraceLightProj.enumValueIndex == (int)BakeryPointLight.ftLightProjectionMode.Omni)
|
||||
{
|
||||
light.type = LightType.Point;
|
||||
light.cookie = null;
|
||||
}
|
||||
else if (ftraceLightProj.enumValueIndex == (int)BakeryPointLight.ftLightProjectionMode.Cubemap)
|
||||
{
|
||||
light.type = LightType.Point;
|
||||
light.cookie = ftraceLightTexture.objectReferenceValue as Cubemap;
|
||||
}
|
||||
else if (ftraceLightProj.enumValueIndex == (int)BakeryPointLight.ftLightProjectionMode.Cookie)
|
||||
{
|
||||
light.type = LightType.Spot;
|
||||
light.cookie = ftraceLightTexture.objectReferenceValue == spotCookieTexture ? null : (ftraceLightTexture.objectReferenceValue as Texture2D);
|
||||
}
|
||||
else if (ftraceLightProj.enumValueIndex == (int)BakeryPointLight.ftLightProjectionMode.Cone)
|
||||
{
|
||||
light.type = LightType.Spot;
|
||||
}
|
||||
light.bounceIntensity = ftraceLightIndirectIntensity.floatValue;
|
||||
|
||||
if (isHDRP) SetHDRPLight(light);
|
||||
if (isLWRP) SetLWRPLight(light);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (PlayerSettings.colorSpace == ColorSpace.Linear)
|
||||
{
|
||||
if (!GraphicsSettings.lightsUseLinearIntensity)
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Warning: project is not set up to use linear light intensity.");
|
||||
EditorGUILayout.LabelField("GraphicsSettings.lightsUseLinearIntensity should be TRUE.");
|
||||
if (GUILayout.Button("Fix"))
|
||||
{
|
||||
GraphicsSettings.lightsUseLinearIntensity = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Project is using linear light intensity. This is nice.");
|
||||
if (GUILayout.Button("Change to non-linear"))
|
||||
{
|
||||
GraphicsSettings.lightsUseLinearIntensity = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d965ed7d9a9a406418fe8b269b3fef30
|
||||
timeCreated: 1525513538
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
10192
Assets/Editor/x64/Bakery/scripts/ftRenderLightmap.cs
Normal file
10192
Assets/Editor/x64/Bakery/scripts/ftRenderLightmap.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dc64e635488f60747bf5e9025c593285
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
88
Assets/Editor/x64/Bakery/scripts/ftRestorePaddingMenu.cs
Normal file
88
Assets/Editor/x64/Bakery/scripts/ftRestorePaddingMenu.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
public class ftRestorePaddingMenu
|
||||
{
|
||||
[MenuItem("Bakery/Utilities/Re-adjust UV padding", false, 43)]
|
||||
private static void RestorePadding()
|
||||
{
|
||||
var bakeryRuntimePath = ftLightmaps.GetRuntimePath();
|
||||
var gstorage = AssetDatabase.LoadAssetAtPath(bakeryRuntimePath + "ftGlobalStorage.asset", typeof(ftGlobalStorage)) as ftGlobalStorage;
|
||||
|
||||
if (gstorage == null)
|
||||
{
|
||||
Debug.Log("Bakery is not initalized");
|
||||
return;
|
||||
}
|
||||
|
||||
if (EditorUtility.DisplayDialog("Bakery", "Re-unwrap and reimport lightmapped scene models to match last bake?", "OK", "Cancel"))
|
||||
{
|
||||
var sceneCount = SceneManager.sceneCount;
|
||||
int reimported = 0;
|
||||
for(int i=0; i<sceneCount; i++)
|
||||
{
|
||||
var scene = SceneManager.GetSceneAt(i);
|
||||
if (!scene.isLoaded) continue;
|
||||
var go = ftLightmaps.FindInScene("!ftraceLightmaps", scene);
|
||||
if (go == null) continue;
|
||||
var store = go.GetComponent<ftLightmapsStorage>();
|
||||
if (store == null) continue;
|
||||
|
||||
for(int j=0; j<store.modifiedAssetPathList.Count; j++)
|
||||
{
|
||||
bool updated = false;
|
||||
var path = store.modifiedAssetPathList[j];
|
||||
var data = store.modifiedAssets[j];
|
||||
int mstoreIndex = gstorage.modifiedAssetPathList.IndexOf(path);
|
||||
if (mstoreIndex < 0)
|
||||
{
|
||||
mstoreIndex = gstorage.modifiedAssetPathList.Count;
|
||||
gstorage.modifiedAssetPathList.Add(path);
|
||||
gstorage.modifiedAssets.Add(data);
|
||||
updated = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var dataExisting = gstorage.modifiedAssets[mstoreIndex];
|
||||
for(int k=0; k<data.meshName.Count; k++)
|
||||
{
|
||||
int ind = dataExisting.meshName.IndexOf( data.meshName[k] );
|
||||
if (ind >= 0)
|
||||
{
|
||||
if (dataExisting.padding[ind] != data.padding[k])
|
||||
{
|
||||
dataExisting.padding[ind] = data.padding[k];
|
||||
updated = true;
|
||||
}
|
||||
if (dataExisting.unwrapper[ind] != data.unwrapper[k])
|
||||
{
|
||||
dataExisting.unwrapper[ind] = data.unwrapper[k];
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dataExisting.meshName.Add( data.meshName[k] );
|
||||
dataExisting.padding.Add( data.padding[k] );
|
||||
dataExisting.unwrapper.Add( data.unwrapper[k] );
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (updated)
|
||||
{
|
||||
#if UNITY_2017_1_OR_NEWER
|
||||
gstorage.SyncModifiedAsset(mstoreIndex);
|
||||
#endif
|
||||
EditorUtility.SetDirty(gstorage);
|
||||
(AssetImporter.GetAtPath(path) as ModelImporter).SaveAndReimport();
|
||||
reimported++;
|
||||
}
|
||||
}
|
||||
}
|
||||
Debug.Log(reimported > 0 ? ("Updated " + reimported + " models") : "No changes detected");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1acbda60094b1b14fa803d9ce4fb88d3
|
||||
timeCreated: 1557694522
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
55
Assets/Editor/x64/Bakery/scripts/ftSavePadding.cs
Normal file
55
Assets/Editor/x64/Bakery/scripts/ftSavePadding.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
#if UNITY_EDITOR
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEngine.SceneManagement;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class ftSavePaddingMenu
|
||||
{
|
||||
[MenuItem("Bakery/Utilities/Save UV padding to asset", false, 60)]
|
||||
private static void RestorePadding()
|
||||
{
|
||||
var bakeryRuntimePath = ftLightmaps.GetRuntimePath();
|
||||
var gstorage = AssetDatabase.LoadAssetAtPath(bakeryRuntimePath + "ftGlobalStorage.asset", typeof(ftGlobalStorage)) as ftGlobalStorage;
|
||||
|
||||
if (gstorage == null)
|
||||
{
|
||||
Debug.Log("Bakery is not initalized");
|
||||
return;
|
||||
}
|
||||
|
||||
var sel = Selection.objects;
|
||||
var pathList = new List<string>();
|
||||
|
||||
for(int i=0; i<sel.Length; i++)
|
||||
{
|
||||
var path = AssetDatabase.GetAssetPath(sel[i]);
|
||||
if (path == "") continue;
|
||||
if (!pathList.Contains(path)) pathList.Add(path);
|
||||
}
|
||||
|
||||
int ctr = 0;
|
||||
for(int i=0; i<pathList.Count; i++)
|
||||
{
|
||||
var index = gstorage.modifiedAssetPathList.IndexOf(pathList[i]);
|
||||
if (index < 0)
|
||||
{
|
||||
Debug.Log("UV padding wasn't generated yet, skipping " + pathList[i]);
|
||||
continue;
|
||||
}
|
||||
var mod = gstorage.modifiedAssets[index];
|
||||
var asset = ScriptableObject.CreateInstance<ftSavedPadding2>();
|
||||
asset.data = mod;
|
||||
AssetDatabase.CreateAsset(asset, Path.GetDirectoryName(pathList[i]) + "/" + Path.GetFileNameWithoutExtension(pathList[i]) + "_padding.asset");
|
||||
Debug.Log("Created padding asset for " + pathList[i]);
|
||||
ctr++;
|
||||
}
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
Debug.Log("Created " + ctr + " UV padding assets");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
12
Assets/Editor/x64/Bakery/scripts/ftSavePadding.cs.meta
Normal file
12
Assets/Editor/x64/Bakery/scripts/ftSavePadding.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1b9bbae7393eaa04db704d80e254be86
|
||||
timeCreated: 1565341770
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
53
Assets/Editor/x64/Bakery/scripts/ftSaveSettingsMenu.cs
Normal file
53
Assets/Editor/x64/Bakery/scripts/ftSaveSettingsMenu.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
public class ftSaveSettingsMenu
|
||||
{
|
||||
[MenuItem("Bakery/Utilities/Save settings as default", false, 41)]
|
||||
private static void SaveSettings()
|
||||
{
|
||||
var bakeryRuntimePath = ftLightmaps.GetRuntimePath();
|
||||
var gstorage = AssetDatabase.LoadAssetAtPath(bakeryRuntimePath + "ftGlobalStorage.asset", typeof(ftGlobalStorage)) as ftGlobalStorage;
|
||||
|
||||
if (gstorage == null)
|
||||
{
|
||||
Debug.Log("Bakery is not initalized");
|
||||
return;
|
||||
}
|
||||
|
||||
if (EditorUtility.DisplayDialog("Bakery", "Save current scene settings as global defaults?", "OK", "Cancel"))
|
||||
{
|
||||
var storage = ftRenderLightmap.FindRenderSettingsStorage();
|
||||
ftRenderLightmap bakery = ftRenderLightmap.instance != null ? ftRenderLightmap.instance : new ftRenderLightmap();
|
||||
bakery.LoadRenderSettings();
|
||||
ftLightmapsStorage.CopySettings(storage, gstorage);
|
||||
EditorUtility.SetDirty(gstorage);
|
||||
Debug.Log("Default settings saved");
|
||||
}
|
||||
}
|
||||
|
||||
[MenuItem("Bakery/Utilities/Load default settings", false, 42)]
|
||||
private static void LoadSettings()
|
||||
{
|
||||
var bakeryRuntimePath = ftLightmaps.GetRuntimePath();
|
||||
var gstorage = AssetDatabase.LoadAssetAtPath(bakeryRuntimePath + "ftGlobalStorage.asset", typeof(ftGlobalStorage)) as ftGlobalStorage;
|
||||
|
||||
if (gstorage == null)
|
||||
{
|
||||
Debug.Log("Bakery is not initalized");
|
||||
return;
|
||||
}
|
||||
|
||||
if (EditorUtility.DisplayDialog("Bakery", "Set default baking settings for the current scene?", "OK", "Cancel"))
|
||||
{
|
||||
var storage = ftRenderLightmap.FindRenderSettingsStorage();
|
||||
ftRenderLightmap bakery = ftRenderLightmap.instance != null ? ftRenderLightmap.instance : new ftRenderLightmap();
|
||||
ftLightmapsStorage.CopySettings(gstorage, storage);
|
||||
EditorUtility.SetDirty(storage);
|
||||
bakery.LoadRenderSettings();
|
||||
Debug.Log("Default settings loaded");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
12
Assets/Editor/x64/Bakery/scripts/ftSaveSettingsMenu.cs.meta
Normal file
12
Assets/Editor/x64/Bakery/scripts/ftSaveSettingsMenu.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6977f7d9b2482ea4cbd5535e0046efab
|
||||
timeCreated: 1558111532
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Editor/x64/Bakery/scripts/ftSavedPadding2.cs
Normal file
8
Assets/Editor/x64/Bakery/scripts/ftSavedPadding2.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
public class ftSavedPadding2 : ScriptableObject
|
||||
{
|
||||
[SerializeField]
|
||||
public ftGlobalStorage.AdjustedMesh data;
|
||||
}
|
||||
12
Assets/Editor/x64/Bakery/scripts/ftSavedPadding2.cs.meta
Normal file
12
Assets/Editor/x64/Bakery/scripts/ftSavedPadding2.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f1b283dcb6cb8fb4e984405825d17555
|
||||
timeCreated: 1583479458
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
171
Assets/Editor/x64/Bakery/scripts/ftSceneView.cs
Normal file
171
Assets/Editor/x64/Bakery/scripts/ftSceneView.cs
Normal file
@@ -0,0 +1,171 @@
|
||||
#if UNITY_EDITOR
|
||||
//#if UNITY_2018_2_OR_NEWER
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
/*
|
||||
public class ftSceneView
|
||||
{
|
||||
public static void Init()
|
||||
{
|
||||
var mode = SceneView.AddCameraMode("Bakery lightmap checker", "Bakery");
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
public class ftSceneView
|
||||
{
|
||||
static Shader checkerShader;
|
||||
public static bool enabled;
|
||||
static List<Texture2D> tempTextures;
|
||||
|
||||
static void Atlas()
|
||||
{
|
||||
var fgo = GameObject.Find("!ftraceLightmaps");
|
||||
if (fgo == null) {
|
||||
fgo = new GameObject();
|
||||
fgo.name = "!ftraceLightmaps";
|
||||
fgo.hideFlags = HideFlags.HideInHierarchy;
|
||||
}
|
||||
var store = fgo.GetComponent<ftLightmapsStorage>();
|
||||
if (store == null) {
|
||||
store = fgo.AddComponent<ftLightmapsStorage>();
|
||||
}
|
||||
ftRenderLightmap.LoadStaticAtlasingSettings();
|
||||
|
||||
Debug.Log("Atlasing...");
|
||||
ftBuildGraphics.modifyLightmapStorage = false;
|
||||
ftBuildGraphics.validateLightmapStorageImmutability = false;
|
||||
var exportSceneFunc = ftBuildGraphics.ExportScene(null, false, true);
|
||||
while(exportSceneFunc.MoveNext())
|
||||
{
|
||||
//progressBarText = ftBuildGraphics.progressBarText;
|
||||
//progressBarPercent = ftBuildGraphics.progressBarPercent;
|
||||
/*if (ftBuildGraphics.userCanceled)
|
||||
{
|
||||
ProgressBarEnd();
|
||||
DestroyImmediate(go);
|
||||
foreach(var d in dynamicObjects) d.enabled = true;
|
||||
yield break;
|
||||
}*/
|
||||
//yield return null;
|
||||
}
|
||||
Debug.Log("Atlasing done");
|
||||
//ftRenderLightmap.simpleProgressBarEnd();
|
||||
ftBuildGraphics.ProgressBarEnd(true);
|
||||
}
|
||||
|
||||
static void ApplyNewProperties()
|
||||
{
|
||||
var objs = ftBuildGraphics.atlasOnlyObj;
|
||||
if (objs == null) return;
|
||||
var scaleOffset = ftBuildGraphics.atlasOnlyScaleOffset;
|
||||
var size = ftBuildGraphics.atlasOnlySize;
|
||||
var ids = ftBuildGraphics.atlasOnlyID;
|
||||
var existingLmaps = LightmapSettings.lightmaps.ToList();
|
||||
tempTextures = new List<Texture2D>();
|
||||
int maxLM = 0;
|
||||
for(int i=0; i<objs.Count; i++)
|
||||
{
|
||||
if (objs[i] == null) continue;
|
||||
objs[i].lightmapScaleOffset = scaleOffset[i];
|
||||
if (objs[i].lightmapIndex < 0 || objs[i].lightmapIndex >= existingLmaps.Count ||
|
||||
existingLmaps[objs[i].lightmapIndex] == null ||
|
||||
existingLmaps[objs[i].lightmapIndex].lightmapColor == null || existingLmaps[objs[i].lightmapIndex].lightmapColor.width != size[i])
|
||||
{
|
||||
int s = 1;//Math.Max(size[i],1);
|
||||
var tex = new Texture2D(s, s);
|
||||
tempTextures.Add(tex);
|
||||
tex.SetPixels32(new Color32[s*s]);
|
||||
tex.Apply();
|
||||
var ldata = new LightmapData();
|
||||
ldata.lightmapColor = tex;
|
||||
existingLmaps.Add(ldata);
|
||||
objs[i].lightmapIndex = existingLmaps.Count - 1;
|
||||
}
|
||||
|
||||
var prop = new MaterialPropertyBlock();
|
||||
objs[i].GetPropertyBlock(prop);
|
||||
prop.SetFloat("bakeryLightmapSize", size[i]);
|
||||
int lmid = ids[i];
|
||||
if (lmid < 1000)
|
||||
{
|
||||
if (lmid > maxLM) maxLM = lmid;
|
||||
}
|
||||
UnityEngine.Random.InitState(lmid);
|
||||
prop.SetVector("bakeryLightmapID", UnityEngine.Random.ColorHSV(0, 1, 0.3f, 0.3f, 1, 1));
|
||||
objs[i].SetPropertyBlock(prop);
|
||||
}
|
||||
|
||||
Debug.Log("Lightmap count with current settings: " + (maxLM+1));
|
||||
|
||||
LightmapSettings.lightmaps = existingLmaps.ToArray();
|
||||
}
|
||||
|
||||
//[MenuItem("Bakery/Checker/Toggle")]
|
||||
public static void ToggleChecker()
|
||||
{
|
||||
var sceneView = SceneView.lastActiveSceneView;
|
||||
if (sceneView == null)
|
||||
{
|
||||
Debug.LogError("Can't get SceneView");
|
||||
return;
|
||||
}
|
||||
if (enabled)
|
||||
{
|
||||
tempTextures = null;
|
||||
//var sceneCameras = SceneView.GetAllSceneCameras();
|
||||
//for(int i=0; i<sceneCameras.Length; i++) sceneCameras[i].renderingPath = RenderingPath.UsePlayerSettings;
|
||||
sceneView.SetSceneViewShaderReplace(null, null);
|
||||
ftLightmaps.RefreshFull();
|
||||
enabled = false;
|
||||
|
||||
var gstorage = ftLightmaps.GetGlobalStorage();
|
||||
gstorage.checkerPreviewOn = false;
|
||||
EditorUtility.SetDirty(gstorage);
|
||||
}
|
||||
else
|
||||
{
|
||||
//if (checkerShader == null)
|
||||
{
|
||||
checkerShader = Shader.Find("Hidden/ftChecker");
|
||||
if (checkerShader == null)
|
||||
{
|
||||
Debug.LogError("Can't load checker shader");
|
||||
return;
|
||||
}
|
||||
}
|
||||
sceneView.SetSceneViewShaderReplace(checkerShader, null);
|
||||
//var sceneCameras = SceneView.GetAllSceneCameras();
|
||||
//for(int i=0; i<sceneCameras.Length; i++) sceneCameras[i].renderingPath = RenderingPath.Forward;
|
||||
enabled = true;
|
||||
|
||||
var gstorage = ftLightmaps.GetGlobalStorage();
|
||||
gstorage.checkerPreviewOn = true;
|
||||
EditorUtility.SetDirty(gstorage);
|
||||
|
||||
Atlas();
|
||||
ApplyNewProperties();
|
||||
}
|
||||
sceneView.Repaint();
|
||||
}
|
||||
|
||||
//[MenuItem("Bakery/Checker/Refresh")]
|
||||
public static void RefreshChecker()
|
||||
{
|
||||
if (!enabled) return;
|
||||
Atlas();
|
||||
ApplyNewProperties();
|
||||
}
|
||||
}
|
||||
|
||||
//#endif
|
||||
#endif
|
||||
12
Assets/Editor/x64/Bakery/scripts/ftSceneView.cs.meta
Normal file
12
Assets/Editor/x64/Bakery/scripts/ftSceneView.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 875c029f22e4efd438030561aaaf38b3
|
||||
timeCreated: 1540221309
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
777
Assets/Editor/x64/Bakery/scripts/ftShaderTweaks.cs
Normal file
777
Assets/Editor/x64/Bakery/scripts/ftShaderTweaks.cs
Normal file
@@ -0,0 +1,777 @@
|
||||
#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 = "//<FTRACEV1.0>";
|
||||
string ftSignatureBicubic = "//<FTRACE_BICUBIC>";
|
||||
string ftSignatureShadowmask = "//<FTRACE_SHADOWMASK>";
|
||||
string ftSignatureEnd = "//</FTRACEV1.0>";
|
||||
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<string>();
|
||||
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.Count; i++)
|
||||
{
|
||||
writer.WriteLine(lines[i]);
|
||||
}
|
||||
writer.Close();
|
||||
//EditorUtility.DisplayDialog("Bakery", "Restart Editor to apply changes", "OK");
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnGUI()
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
try
|
||||
{
|
||||
bicubic = false;
|
||||
var entryAssembly = new StackTrace().GetFrames().Last().GetMethod().Module.Assembly;
|
||||
var managedDir = System.IO.Path.GetDirectoryName(entryAssembly.Location);
|
||||
shadersDir = managedDir + "/../CGIncludes/";
|
||||
if (!Directory.Exists(shadersDir)) shadersDir = managedDir + "/../../CGIncludes/";
|
||||
if (!Directory.Exists(shadersDir))
|
||||
{
|
||||
UnityEngine.Debug.LogError("Can't find directory: " + shadersDir);
|
||||
return;
|
||||
}
|
||||
|
||||
includeGIPath = shadersDir + "UnityGlobalIllumination.cginc";
|
||||
if (File.Exists(includeGIPath))
|
||||
{
|
||||
var reader = new StreamReader(includeGIPath);
|
||||
if (reader == null)
|
||||
{
|
||||
UnityEngine.Debug.LogError("Can't open " + includeGIPath);
|
||||
bicubic = false;
|
||||
return;
|
||||
}
|
||||
//bool patched = false;
|
||||
while (!reader.EndOfStream)
|
||||
{
|
||||
var line = reader.ReadLine();
|
||||
if (line.StartsWith(ftSignatureBegin))
|
||||
{
|
||||
UnityEngine.Debug.Log("Bicubic: already patched");
|
||||
//patched = true;
|
||||
bicubic = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
reader.Close();
|
||||
}
|
||||
|
||||
shadowBlend = false;
|
||||
includeShadowPath = shadersDir + "UnityShadowLibrary.cginc";
|
||||
if (File.Exists(includeShadowPath))
|
||||
{
|
||||
var reader = new StreamReader(includeShadowPath);
|
||||
if (reader == null)
|
||||
{
|
||||
UnityEngine.Debug.LogError("Can't open " + includeShadowPath);
|
||||
bicubicShadow = false;
|
||||
return;
|
||||
}
|
||||
//bool patched = false;
|
||||
while (!reader.EndOfStream)
|
||||
{
|
||||
var line = reader.ReadLine();
|
||||
if (line.StartsWith(ftSignatureShadowmask))
|
||||
{
|
||||
UnityEngine.Debug.Log("Shadowmask: already patched");
|
||||
//patched = true;
|
||||
shadowBlend = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
reader.Close();
|
||||
}
|
||||
|
||||
falloff = false;
|
||||
includeLightPath = shadersDir + "AutoLight.cginc";
|
||||
if (File.Exists(includeLightPath))
|
||||
{
|
||||
var reader = new StreamReader(includeLightPath);
|
||||
if (reader == null)
|
||||
{
|
||||
UnityEngine.Debug.LogError("Can't open " + includeLightPath);
|
||||
falloff = false;
|
||||
return;
|
||||
}
|
||||
//bool patched = false;
|
||||
while (!reader.EndOfStream)
|
||||
{
|
||||
var line = reader.ReadLine();
|
||||
if (line.StartsWith(ftSignatureBegin))
|
||||
{
|
||||
UnityEngine.Debug.Log("Lights: already patched");
|
||||
//patched = true;
|
||||
falloff = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
reader.Close();
|
||||
}
|
||||
falloffDeferred = false;
|
||||
includeDeferredPath = shadersDir + "UnityDeferredLibrary.cginc";
|
||||
if (File.Exists(includeDeferredPath))
|
||||
{
|
||||
var reader = new StreamReader(includeDeferredPath);
|
||||
if (reader == null)
|
||||
{
|
||||
UnityEngine.Debug.LogError("Can't open " + includeDeferredPath);
|
||||
falloffDeferred = false;
|
||||
return;
|
||||
}
|
||||
//bool patched = false;
|
||||
while (!reader.EndOfStream)
|
||||
{
|
||||
var line = reader.ReadLine();
|
||||
if (line.StartsWith(ftSignatureBegin))
|
||||
{
|
||||
UnityEngine.Debug.Log("Lights: already patched");
|
||||
//patched = true;
|
||||
falloffDeferred = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
reader.Close();
|
||||
}
|
||||
initialized = true;
|
||||
}
|
||||
catch//(System.UnauthorizedAccessException err)
|
||||
{
|
||||
GUI.Label(new Rect(10, 20, 320, 60), "Can't access Unity shader include files,\ntry running Unity as admin.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool wasBicubic = bicubic;
|
||||
//bool wasBicubicShadow = bicubicShadow;
|
||||
bool wasShadowBlend = shadowBlend;
|
||||
bool wasFalloff = falloff;
|
||||
bool wasFalloffDeferred = falloffDeferred;
|
||||
|
||||
this.minSize = new Vector2(320, 290+60);
|
||||
|
||||
GUI.Label(new Rect(10, 20, 320, 60), "These settings will modify base Unity shaders.\nAll projects opened with this version of Editor\nwill use modified shaders.");
|
||||
//agree = GUI.Toggle(new Rect(10, 65, 200, 15), agree, "I understand");
|
||||
|
||||
GUI.BeginGroup(new Rect(10, 80, 300, 260), "Options");
|
||||
if (initialized)
|
||||
{
|
||||
bicubic = GUI.Toggle(new Rect(10, 20, 280, 50), bicubic, "Use bicubic interpolation for lightmaps", "Button");
|
||||
shadowBlend = GUI.Toggle(new Rect(10, 80, 280, 50), shadowBlend, "Use multiplication for shadowmask", "Button");
|
||||
falloff = GUI.Toggle(new Rect(10, 140, 280, 50), falloff, "Use physical light falloff (Forward)", "Button");
|
||||
falloffDeferred = GUI.Toggle(new Rect(10, 200, 280, 50), falloffDeferred, "Use physical light falloff (Deferred)", "Button");
|
||||
|
||||
if (!wasBicubic && bicubic)
|
||||
{
|
||||
CopyInclude(shadersDir);
|
||||
var reader = new StreamReader(includeGIPath);
|
||||
if (reader == null)
|
||||
{
|
||||
UnityEngine.Debug.LogError("Can't open " + includeGIPath);
|
||||
bicubic = false;
|
||||
return;
|
||||
}
|
||||
bool patched = false;
|
||||
|
||||
var lines = new List<string>();
|
||||
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.Count; i++)
|
||||
{
|
||||
writer.WriteLine(lines[i]);
|
||||
}
|
||||
writer.Close();
|
||||
//EditorUtility.DisplayDialog("Bakery", "Restart Editor to apply changes", "OK");
|
||||
}
|
||||
|
||||
reader = new StreamReader(includeShadowPath);
|
||||
if (reader == null)
|
||||
{
|
||||
UnityEngine.Debug.LogError("Can't open " + includeShadowPath);
|
||||
bicubic = false;
|
||||
return;
|
||||
}
|
||||
patched = false;
|
||||
|
||||
lines = new List<string>();
|
||||
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.Count; i++)
|
||||
{
|
||||
writer.WriteLine(lines[i]);
|
||||
}
|
||||
writer.Close();
|
||||
EditorUtility.DisplayDialog("Bakery", "Restart Editor to apply changes", "OK");
|
||||
}
|
||||
}
|
||||
|
||||
if (wasBicubic && !bicubic)
|
||||
{
|
||||
bicubic = true;
|
||||
if (RevertFile(includeGIPath)) bicubic = false;
|
||||
bicubicShadow = true;
|
||||
if (RevertFile(includeShadowPath))
|
||||
{
|
||||
bicubicShadow = false;
|
||||
shadowBlend = false;
|
||||
}
|
||||
EditorUtility.DisplayDialog("Bakery", "Restart Editor to apply changes", "OK");
|
||||
}
|
||||
|
||||
if (!wasShadowBlend && shadowBlend)
|
||||
{
|
||||
CopyInclude(shadersDir);
|
||||
var reader = new StreamReader(includeShadowPath);
|
||||
if (reader == null)
|
||||
{
|
||||
UnityEngine.Debug.LogError("Can't open " + includeShadowPath);
|
||||
shadowBlend = false;
|
||||
return;
|
||||
}
|
||||
bool patched = false;
|
||||
|
||||
var lines = new List<string>();
|
||||
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.Count; i++)
|
||||
{
|
||||
writer.WriteLine(lines[i]);
|
||||
}
|
||||
writer.Close();
|
||||
EditorUtility.DisplayDialog("Bakery", "Restart Editor to apply changes", "OK");
|
||||
}
|
||||
}
|
||||
|
||||
if (wasShadowBlend && !shadowBlend)
|
||||
{
|
||||
shadowBlend = true;
|
||||
if (RevertFile(includeShadowPath)) shadowBlend = false;
|
||||
|
||||
bicubic = true;
|
||||
if (RevertFile(includeGIPath)) bicubic = false;
|
||||
|
||||
EditorUtility.DisplayDialog("Bakery", "Restart Editor to apply changes", "OK");
|
||||
}
|
||||
|
||||
if (!wasFalloff && falloff)
|
||||
{
|
||||
CopyInclude(shadersDir);
|
||||
var reader = new StreamReader(includeLightPath);
|
||||
if (reader == null)
|
||||
{
|
||||
UnityEngine.Debug.LogError("Can't open " + includeLightPath);
|
||||
falloff = false;
|
||||
return;
|
||||
}
|
||||
bool patched = false;
|
||||
|
||||
var lines = new List<string>();
|
||||
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.Count; i++)
|
||||
{
|
||||
writer.WriteLine(lines[i]);
|
||||
}
|
||||
writer.Close();
|
||||
EditorUtility.DisplayDialog("Bakery", "Restart Editor to apply changes", "OK");
|
||||
}
|
||||
}
|
||||
|
||||
if (wasFalloff && !falloff)
|
||||
{
|
||||
falloff = true;
|
||||
if (RevertFile(includeLightPath)) falloff = false;
|
||||
EditorUtility.DisplayDialog("Bakery", "Restart Editor to apply changes", "OK");
|
||||
}
|
||||
|
||||
|
||||
if (!wasFalloffDeferred && falloffDeferred)
|
||||
{
|
||||
CopyInclude(shadersDir);
|
||||
var reader = new StreamReader(includeDeferredPath);
|
||||
if (reader == null)
|
||||
{
|
||||
UnityEngine.Debug.LogError("Can't open " + includeDeferredPath);
|
||||
falloff = false;
|
||||
return;
|
||||
}
|
||||
bool patched = false;
|
||||
|
||||
var lines = new List<string>();
|
||||
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<lines.Count; i++)
|
||||
{
|
||||
writer.WriteLine(lines[i]);
|
||||
}
|
||||
writer.Close();
|
||||
EditorUtility.DisplayDialog("Bakery", "Restart Editor to apply changes", "OK");
|
||||
}
|
||||
}
|
||||
|
||||
if (wasFalloffDeferred && !falloffDeferred)
|
||||
{
|
||||
falloffDeferred = true;
|
||||
if (RevertFile(includeDeferredPath)) falloffDeferred = false;
|
||||
EditorUtility.DisplayDialog("Bakery", "Restart Editor to apply changes", "OK");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.Label(new Rect(10, 20, 250, 30), "Can't find Unity include at path: \n" + includeGIPath + ".");
|
||||
}
|
||||
GUI.EndGroup();
|
||||
}
|
||||
|
||||
[MenuItem ("Bakery/Global shader tweaks", false, 60)]
|
||||
public static void RenderLightmap () {
|
||||
ScriptableWizard.DisplayWizard("Bakery - shader tweaks", typeof(ftShaderTweaks), "RenderLightmap");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
12
Assets/Editor/x64/Bakery/scripts/ftShaderTweaks.cs.meta
Normal file
12
Assets/Editor/x64/Bakery/scripts/ftShaderTweaks.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 482c0edd4bdba214f93b66b9cf3c0f3e
|
||||
timeCreated: 1527024891
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
360
Assets/Editor/x64/Bakery/scripts/ftSkyLightInspector.cs
Normal file
360
Assets/Editor/x64/Bakery/scripts/ftSkyLightInspector.cs
Normal file
@@ -0,0 +1,360 @@
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
[CustomEditor(typeof(BakerySkyLight))]
|
||||
[CanEditMultipleObjects]
|
||||
public class ftSkyLightInspector : UnityEditor.Editor
|
||||
{
|
||||
public static Quaternion QuaternionFromMatrix(Matrix4x4 m) {
|
||||
Quaternion q = new Quaternion();
|
||||
q.w = Mathf.Sqrt( Mathf.Max( 0, 1 + m[0,0] + m[1,1] + m[2,2] ) ) / 2;
|
||||
q.x = Mathf.Sqrt( Mathf.Max( 0, 1 + m[0,0] - m[1,1] - m[2,2] ) ) / 2;
|
||||
q.y = Mathf.Sqrt( Mathf.Max( 0, 1 - m[0,0] + m[1,1] - m[2,2] ) ) / 2;
|
||||
q.z = Mathf.Sqrt( Mathf.Max( 0, 1 - m[0,0] - m[1,1] + m[2,2] ) ) / 2;
|
||||
q.x *= Mathf.Sign( q.x * ( m[2,1] - m[1,2] ) );
|
||||
q.y *= Mathf.Sign( q.y * ( m[0,2] - m[2,0] ) );
|
||||
q.z *= Mathf.Sign( q.z * ( m[1,0] - m[0,1] ) );
|
||||
return q;
|
||||
}
|
||||
|
||||
SerializedProperty ftraceLightColor;
|
||||
SerializedProperty ftraceLightIntensity;
|
||||
SerializedProperty ftraceLightTexture;
|
||||
SerializedProperty ftraceLightSamples;
|
||||
SerializedProperty ftraceLightHemi;
|
||||
SerializedProperty ftraceLightCorrectRot;
|
||||
SerializedProperty ftraceLightBitmask;
|
||||
SerializedProperty ftraceLightBakeToIndirect;
|
||||
SerializedProperty ftraceLightIndirectIntensity;
|
||||
SerializedProperty ftraceTangentSH;
|
||||
|
||||
int texCached = -1;
|
||||
|
||||
void TestPreviewRefreshProperty(ref int cached, int newVal)
|
||||
{
|
||||
if (cached >= 0)
|
||||
{
|
||||
if (cached != newVal)
|
||||
{
|
||||
BakerySkyLight.lightsChanged = 2;
|
||||
}
|
||||
}
|
||||
cached = newVal;
|
||||
}
|
||||
|
||||
void TestPreviewRefreshProperty(ref int cached, UnityEngine.Object newVal)
|
||||
{
|
||||
if (newVal == null)
|
||||
{
|
||||
TestPreviewRefreshProperty(ref cached, 0);
|
||||
return;
|
||||
}
|
||||
TestPreviewRefreshProperty(ref cached, newVal.GetInstanceID());
|
||||
}
|
||||
|
||||
static string ftSkyboxShaderName = "Bakery/Skybox";
|
||||
|
||||
ftLightmapsStorage storage;
|
||||
|
||||
static string[] selStrings = new string[] {"0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16",
|
||||
"17","18","19","20","21","22","23","24","25","26","27","28","29","30"};//,"31"};
|
||||
|
||||
static public string[] directContributionOptions = new string[] {"Direct And Indirect (recommended)", "Indirect only"};
|
||||
|
||||
bool showExperimental = false;
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
ftraceLightColor = serializedObject.FindProperty("color");
|
||||
ftraceLightIntensity = serializedObject.FindProperty("intensity");
|
||||
ftraceLightIndirectIntensity = serializedObject.FindProperty("indirectIntensity");
|
||||
ftraceLightTexture = serializedObject.FindProperty("cubemap");
|
||||
ftraceLightSamples = serializedObject.FindProperty("samples");
|
||||
ftraceLightHemi = serializedObject.FindProperty("hemispherical");
|
||||
ftraceLightCorrectRot = serializedObject.FindProperty("correctRotation");
|
||||
ftraceLightBitmask = serializedObject.FindProperty("bitmask");
|
||||
ftraceLightBakeToIndirect = serializedObject.FindProperty("bakeToIndirect");
|
||||
ftraceTangentSH = serializedObject.FindProperty("tangentSH");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI() {
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
TestPreviewRefreshProperty(ref texCached, ftraceLightTexture.objectReferenceValue);
|
||||
|
||||
EditorGUILayout.PropertyField(ftraceLightColor, new GUIContent("Color", "Sky color. Multiplies texture color."));
|
||||
EditorGUILayout.PropertyField(ftraceLightIntensity, new GUIContent("Intensity", "Color multiplier"));
|
||||
EditorGUILayout.PropertyField(ftraceLightTexture, new GUIContent("Sky texture", "Cubemap"));
|
||||
if (ftraceLightTexture.objectReferenceValue != null)
|
||||
{
|
||||
EditorGUILayout.PropertyField(ftraceLightCorrectRot, new GUIContent("Correct rotation", "Enable to have a proper match between GameObject rotation and HDRI rotation. Disabled by default for backwards compatibility."));
|
||||
var angles = (target as BakerySkyLight).transform.eulerAngles;
|
||||
EditorGUILayout.LabelField("Cubemap angles: " + angles.x + ", " + angles.y + ", " + angles.z);
|
||||
EditorGUILayout.LabelField("Rotate this GameObject to change cubemap angles.");
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
EditorGUILayout.PropertyField(ftraceLightSamples, new GUIContent("Samples", "The amount of rays tested for this light. Rays are emitted hemispherically."));
|
||||
|
||||
EditorGUILayout.PropertyField(ftraceLightHemi, new GUIContent("Hemispherical", "Only emit light from upper hemisphere"));
|
||||
|
||||
//ftraceLightBitmask.intValue = EditorGUILayout.MaskField(new GUIContent("Bitmask", "Lights only affect renderers with overlapping bits"), ftraceLightBitmask.intValue, selStrings);
|
||||
int prevVal = ftraceLightBitmask.intValue;
|
||||
int newVal = EditorGUILayout.MaskField(new GUIContent("Bitmask", "Lights only affect renderers with overlapping bits"), ftraceLightBitmask.intValue, selStrings);
|
||||
if (prevVal != newVal) ftraceLightBitmask.intValue = newVal;
|
||||
|
||||
//EditorGUILayout.PropertyField(ftraceLightBakeToIndirect, new GUIContent("Bake to indirect", "Add direct contribution from this light to indirect-only lightmaps"));
|
||||
|
||||
if (storage == null) storage = ftRenderLightmap.FindRenderSettingsStorage();
|
||||
var rmode = storage.renderSettingsUserRenderMode;
|
||||
if (rmode != (int)ftRenderLightmap.RenderMode.FullLighting)
|
||||
{
|
||||
ftDirectLightInspector.BakeWhat contrib;
|
||||
if (ftraceLightBakeToIndirect.boolValue)
|
||||
{
|
||||
contrib = ftDirectLightInspector.BakeWhat.DirectAndIndirect;
|
||||
}
|
||||
else
|
||||
{
|
||||
contrib = ftDirectLightInspector.BakeWhat.IndirectOnly;
|
||||
}
|
||||
var prevContrib = contrib;
|
||||
|
||||
contrib = (ftDirectLightInspector.BakeWhat)EditorGUILayout.Popup("Baked contribution", (int)contrib, directContributionOptions);
|
||||
|
||||
if (prevContrib != contrib)
|
||||
{
|
||||
if (contrib == ftDirectLightInspector.BakeWhat.IndirectOnly)
|
||||
{
|
||||
ftraceLightBakeToIndirect.boolValue = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ftraceLightBakeToIndirect.boolValue = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(ftraceLightIndirectIntensity, new GUIContent("Indirect intensity", "Non-physical GI multiplier for this light"));
|
||||
|
||||
showExperimental = EditorGUILayout.Foldout(showExperimental, "Experimental", EditorStyles.foldout);
|
||||
if (showExperimental)
|
||||
{
|
||||
EditorGUILayout.PropertyField(ftraceTangentSH, new GUIContent("Tangent-space SH", "Only affects single-color skylights. When baking in SH mode, harmonics will be in tangent space. Can be useful for implementing skinned model specular occlusion in custom shaders."));
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
var skyMat = RenderSettings.skybox;
|
||||
bool match = false;
|
||||
bool skyboxValid = true;
|
||||
string why = "";
|
||||
if (skyMat != null)
|
||||
{
|
||||
if (skyMat.HasProperty("_Tex") && skyMat.HasProperty("_Exposure") && skyMat.HasProperty("_Tint"))
|
||||
{
|
||||
if (skyMat.GetTexture("_Tex") == ftraceLightTexture.objectReferenceValue)
|
||||
{
|
||||
float exposure = skyMat.GetFloat("_Exposure");
|
||||
bool exposureSRGB = skyMat.shader.name == "Skybox/Cubemap";
|
||||
if (exposureSRGB)
|
||||
{
|
||||
exposure = Mathf.Pow(exposure, 2.2f); // can't detect [Gamma] keyword...
|
||||
exposure *= PlayerSettings.colorSpace == ColorSpace.Linear ? 4.59f : 2; // weird unity constant
|
||||
}
|
||||
if (Mathf.Abs(exposure - ftraceLightIntensity.floatValue) < 0.0001f)
|
||||
{
|
||||
if (skyMat.GetColor("_Tint") == ftraceLightColor.colorValue)
|
||||
{
|
||||
bool anglesMatch = true;
|
||||
var angles = (target as BakerySkyLight).transform.eulerAngles;
|
||||
Vector3 matMatrixX = Vector3.right;
|
||||
Vector3 matMatrixY = Vector3.up;
|
||||
Vector3 matMatrixZ = Vector3.forward;
|
||||
float matAngleY = 0;
|
||||
bool hasYAngle = skyMat.HasProperty("_Rotation");
|
||||
bool hasXZAngles = skyMat.HasProperty("_MatrixRight");
|
||||
if (hasYAngle) matAngleY = skyMat.GetFloat("_Rotation");
|
||||
if (hasXZAngles)
|
||||
{
|
||||
matMatrixX = skyMat.GetVector("_MatrixRight");
|
||||
matMatrixY = skyMat.GetVector("_MatrixUp");
|
||||
matMatrixZ = skyMat.GetVector("_MatrixForward");
|
||||
}
|
||||
|
||||
if (angles.y != 0 && !hasYAngle)
|
||||
{
|
||||
anglesMatch = false;
|
||||
why = "no _Rotation property, but light is rotated";
|
||||
}
|
||||
else if ((angles.x != 0 || angles.z != 0) && !hasXZAngles)
|
||||
{
|
||||
anglesMatch = false;
|
||||
why = "shader doesn't allow XZ rotation";
|
||||
}
|
||||
else
|
||||
{
|
||||
var lightQuat = (target as BakerySkyLight).transform.rotation;
|
||||
Quaternion matQuat;
|
||||
if (hasXZAngles)
|
||||
{
|
||||
var mtx = new Matrix4x4();
|
||||
mtx.SetColumn(0, new Vector4(matMatrixX.x, matMatrixX.y, matMatrixX.z, 0));
|
||||
mtx.SetColumn(1, new Vector4(matMatrixY.x, matMatrixY.y, matMatrixY.z, 0));
|
||||
mtx.SetColumn(2, new Vector4(matMatrixZ.x, matMatrixZ.y, matMatrixZ.z, 0));
|
||||
matQuat = QuaternionFromMatrix(mtx);
|
||||
}
|
||||
else
|
||||
{
|
||||
matQuat = Quaternion.Euler(0, matAngleY, 0);
|
||||
}
|
||||
|
||||
float diff = Quaternion.Angle(matQuat, lightQuat);
|
||||
//Debug.Log("d " + diff);
|
||||
if (Mathf.Abs(diff) > 0.01f)
|
||||
{
|
||||
anglesMatch = false;
|
||||
why = "angles don't match";
|
||||
}
|
||||
}
|
||||
if (anglesMatch) match = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
why = "color doesn't match";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
why = "exposure doesn't match";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
why = "texture doesn't match";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!skyMat.HasProperty("_Tex")) why += "_Tex ";
|
||||
if (!skyMat.HasProperty("_Exposure")) why += "_Exposure ";
|
||||
if (!skyMat.HasProperty("_Tint")) why += "_Tint ";
|
||||
why += "not defined";
|
||||
skyboxValid = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
why = "no skybox set";
|
||||
skyboxValid = false;
|
||||
}
|
||||
|
||||
if (!match)
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Skylight doesn't match skybox: " + why);
|
||||
EditorGUILayout.Space();
|
||||
|
||||
if (skyboxValid)
|
||||
{
|
||||
if (GUILayout.Button("Match this light to scene skybox"))
|
||||
{
|
||||
ftraceLightTexture.objectReferenceValue = skyMat.GetTexture("_Tex");
|
||||
|
||||
float exposure = skyMat.GetFloat("_Exposure");
|
||||
bool exposureSRGB = skyMat.shader.name == "Skybox/Cubemap";
|
||||
if (exposureSRGB)
|
||||
{
|
||||
exposure = Mathf.Pow(exposure, 2.2f); // can't detect [Gamma] keyword...
|
||||
exposure *= PlayerSettings.colorSpace == ColorSpace.Linear ? 4.59f : 2; // weird unity constant
|
||||
}
|
||||
ftraceLightIntensity.floatValue = exposure;
|
||||
|
||||
ftraceLightColor.colorValue = skyMat.GetColor("_Tint");
|
||||
|
||||
float matAngle = 0;
|
||||
if (skyMat.HasProperty("_Rotation")) matAngle = skyMat.GetFloat("_Rotation");
|
||||
var matQuat = Quaternion.Euler(0, matAngle, 0);
|
||||
Undo.RecordObject((target as BakerySkyLight).transform, "Rotate skylight");
|
||||
(target as BakerySkyLight).transform.rotation = matQuat;
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Match scene skybox to this light"))
|
||||
{
|
||||
var tform = (target as BakerySkyLight).transform;
|
||||
var angles = tform.eulerAngles;
|
||||
if (angles.x !=0 || angles.z !=0)
|
||||
{
|
||||
if (skyboxValid && !skyMat.HasProperty("_MatrixRight")) skyboxValid = false; // only ftrace skybox can handle xz rotation for now
|
||||
}
|
||||
|
||||
if (angles.y != 0 && skyboxValid && !skyMat.HasProperty("_Rotation")) skyboxValid = false; // needs _Rotation for Y angle
|
||||
|
||||
if (!skyboxValid)
|
||||
{
|
||||
var outputPath = ftRenderLightmap.outputPath;
|
||||
skyMat = new Material(Shader.Find(ftSkyboxShaderName));
|
||||
if (!Directory.Exists("Assets/" + outputPath))
|
||||
{
|
||||
Directory.CreateDirectory("Assets/" + outputPath);
|
||||
}
|
||||
AssetDatabase.CreateAsset(skyMat, "Assets/" + outputPath + "/" + SceneManager.GetActiveScene().name + "_skybox.asset");
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
skyMat.SetTexture("_Tex", ftraceLightTexture.objectReferenceValue as Cubemap);
|
||||
skyMat.SetFloat("_NoTexture", ftraceLightTexture.objectReferenceValue == null ? 1 : 0);
|
||||
|
||||
float exposure = ftraceLightIntensity.floatValue;
|
||||
bool exposureSRGB = skyMat.shader.name == "Skybox/Cubemap";
|
||||
if (exposureSRGB)
|
||||
{
|
||||
exposure /= PlayerSettings.colorSpace == ColorSpace.Linear ? 4.59f : 2; // weird unity constant
|
||||
exposure = Mathf.Pow(exposure, 1.0f / 2.2f); // can't detect [Gamma] keyword...
|
||||
}
|
||||
skyMat.SetFloat("_Exposure", exposure);
|
||||
|
||||
skyMat.SetColor("_Tint", ftraceLightColor.colorValue);
|
||||
|
||||
if (skyMat.HasProperty("_Rotation")) skyMat.SetFloat("_Rotation", angles.y);
|
||||
|
||||
if ((target as BakerySkyLight).correctRotation)
|
||||
{
|
||||
// transpose
|
||||
var r = tform.right;
|
||||
var u = tform.up;
|
||||
var f = tform.forward;
|
||||
if (skyMat.HasProperty("_MatrixRight")) skyMat.SetVector("_MatrixRight", new Vector3(r.x, u.x, f.x));
|
||||
if (skyMat.HasProperty("_MatrixUp")) skyMat.SetVector("_MatrixUp", new Vector3(r.y, u.y, f.y));
|
||||
if (skyMat.HasProperty("_MatrixForward")) skyMat.SetVector("_MatrixForward", new Vector3(r.z, u.z, f.z));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (skyMat.HasProperty("_MatrixRight")) skyMat.SetVector("_MatrixRight", tform.right);
|
||||
if (skyMat.HasProperty("_MatrixUp")) skyMat.SetVector("_MatrixUp", tform.up);
|
||||
if (skyMat.HasProperty("_MatrixForward")) skyMat.SetVector("_MatrixForward", tform.forward);
|
||||
}
|
||||
|
||||
RenderSettings.skybox = skyMat;
|
||||
EditorUtility.SetDirty(skyMat);
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
12
Assets/Editor/x64/Bakery/scripts/ftSkyLightInspector.cs.meta
Normal file
12
Assets/Editor/x64/Bakery/scripts/ftSkyLightInspector.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 43b464df539471c47880a0cc39cd4861
|
||||
timeCreated: 1525278120
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
54
Assets/Editor/x64/Bakery/scripts/ftTextureProcessor.cs
Normal file
54
Assets/Editor/x64/Bakery/scripts/ftTextureProcessor.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class ftTextureProcessor : AssetPostprocessor
|
||||
{
|
||||
public static Dictionary<string, Vector2> texSettings = new Dictionary<string, Vector2>();
|
||||
|
||||
public const int TEX_LM = 0;
|
||||
public const int TEX_LMDEFAULT = 1;
|
||||
public const int TEX_MASK = 2;
|
||||
public const int TEX_DIR = 3;
|
||||
|
||||
void OnPreprocessTexture()
|
||||
{
|
||||
TextureImporter importer = assetImporter as TextureImporter;
|
||||
Vector2 settings;
|
||||
|
||||
if (!texSettings.TryGetValue(importer.assetPath, out settings)) return;
|
||||
|
||||
importer.maxTextureSize = (int)settings.x;
|
||||
importer.mipmapEnabled = ftAdditionalConfig.mipmapLightmaps;
|
||||
importer.wrapMode = TextureWrapMode.Clamp;
|
||||
|
||||
int texType = (int)settings.y;
|
||||
switch(texType)
|
||||
{
|
||||
case TEX_LM:
|
||||
{
|
||||
importer.textureType = TextureImporterType.Lightmap;
|
||||
break;
|
||||
}
|
||||
case TEX_LMDEFAULT:
|
||||
{
|
||||
importer.textureType = TextureImporterType.Default;
|
||||
break;
|
||||
}
|
||||
case TEX_MASK:
|
||||
{
|
||||
importer.textureType = TextureImporterType.Default;
|
||||
importer.textureCompression = TextureImporterCompression.CompressedHQ;
|
||||
break;
|
||||
}
|
||||
case TEX_DIR:
|
||||
{
|
||||
importer.textureType = TextureImporterType.Default;
|
||||
importer.textureCompression = TextureImporterCompression.CompressedHQ;
|
||||
importer.sRGBTexture = ftAdditionalConfig.preferPNG;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
12
Assets/Editor/x64/Bakery/scripts/ftTextureProcessor.cs.meta
Normal file
12
Assets/Editor/x64/Bakery/scripts/ftTextureProcessor.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 68d2ca0e99ca9604fa09956f75773620
|
||||
timeCreated: 1546597706
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
465
Assets/Editor/x64/Bakery/scripts/ftUVGBufferGen.cs
Normal file
465
Assets/Editor/x64/Bakery/scripts/ftUVGBufferGen.cs
Normal file
@@ -0,0 +1,465 @@
|
||||
#if UNITY_EDITOR
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.IO;
|
||||
|
||||
public class ftUVGBufferGen
|
||||
{
|
||||
static RenderTexture rtAlbedo, rtEmissive, rtNormal;
|
||||
public static Texture2D texAlbedo, texEmissive, texNormal, texBestFit;
|
||||
//static GameObject dummyCamGO;
|
||||
//static Camera dummyCam;
|
||||
static float texelSize;
|
||||
//static Vector4 shaBlack, shaWhite;
|
||||
static Material matFromRGBM;
|
||||
static Material matDilate, matMultiply;
|
||||
static bool emissiveEnabled = false;
|
||||
static bool normalEnabled = false;
|
||||
static Vector4 metaControl, metaControlAlbedo, metaControlEmission, metaControlNormal;
|
||||
static Material fallbackMat, normalMat, blackMat;
|
||||
static int fallbackMatMetaPass;
|
||||
|
||||
static float[] uvOffset =
|
||||
{
|
||||
-2, -2,
|
||||
2, -2,
|
||||
-2, 2,
|
||||
2, 2,
|
||||
|
||||
-1, -2,
|
||||
1, -2,
|
||||
-2, -1,
|
||||
2, -1,
|
||||
-2, 1,
|
||||
2, 1,
|
||||
-1, 2,
|
||||
1, 2,
|
||||
|
||||
-2, 0,
|
||||
2, 0,
|
||||
0, -2,
|
||||
0, 2,
|
||||
|
||||
-1, -1,
|
||||
1, -1,
|
||||
-1, 0,
|
||||
1, 0,
|
||||
-1, 1,
|
||||
1, 1,
|
||||
0, -1,
|
||||
0, 1,
|
||||
|
||||
0, 0
|
||||
};
|
||||
|
||||
static public void UpdateMatrix(Matrix4x4 worldMatrix, float offsetX, float offsetY)//Matrix4x4 worldMatrix)
|
||||
{
|
||||
// Generate a projection matrix similar to LoadOrtho
|
||||
/*var dummyCamGO = new GameObject();
|
||||
dummyCamGO.name = "dummyCam";
|
||||
var dummyCam = dummyCamGO.AddComponent<Camera>();
|
||||
dummyCam.cullingMask = 0;
|
||||
dummyCam.orthographic = true;
|
||||
dummyCam.orthographicSize = 0.5f;
|
||||
dummyCam.nearClipPlane = -10;
|
||||
dummyCam.aspect = 1;
|
||||
var proj = dummyCam.projectionMatrix;
|
||||
var c3 = proj.GetColumn(3);
|
||||
proj.SetColumn(3, new Vector4(-1, -1, c3.z, c3.w));
|
||||
Debug.Log(proj);*/
|
||||
|
||||
var proj = new Matrix4x4();
|
||||
proj.SetRow(0, new Vector4(2.00000f, 0.00000f, 0.00000f, -1.00000f + offsetX));
|
||||
proj.SetRow(1, new Vector4(0.00000f, 2.00000f, 0.00000f, -1.00000f + offsetY));
|
||||
proj.SetRow(2, new Vector4(0.00000f, 0.00000f, -0.00198f, -0.98f));
|
||||
proj.SetRow(3, new Vector4(0.00000f, 0.00000f, 0.00000f, 1.00000f));
|
||||
|
||||
//if (ftBuildGraphics.unityVersionMajor < 2018) // Unity 2018 stopped multiplying vertices by world matrix in meta pass
|
||||
//{
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
#else
|
||||
proj = proj * worldMatrix.inverse;
|
||||
#endif
|
||||
//}
|
||||
|
||||
// If Camera.current is set, multiply our matrix by the inverse of its view matrix
|
||||
if (Camera.current != null)
|
||||
{
|
||||
proj = proj * Camera.current.worldToCameraMatrix.inverse;
|
||||
}
|
||||
|
||||
GL.LoadProjectionMatrix(proj);
|
||||
}
|
||||
|
||||
static public void StartUVGBuffer(int size, bool hasEmissive, bool hasNormal)
|
||||
{
|
||||
emissiveEnabled = hasEmissive;
|
||||
normalEnabled = hasNormal;
|
||||
|
||||
rtAlbedo = new RenderTexture(size, size, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB);
|
||||
texAlbedo = new Texture2D(size, size, TextureFormat.RGBA32, false, false);
|
||||
|
||||
Graphics.SetRenderTarget(rtAlbedo);
|
||||
GL.Clear(true, true, new Color(0,0,0,0));
|
||||
|
||||
if (hasEmissive)
|
||||
{
|
||||
rtEmissive = new RenderTexture(size, size, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
|
||||
texEmissive = new Texture2D(size, size, TextureFormat.RGBAHalf, false, true);
|
||||
Graphics.SetRenderTarget(rtEmissive);
|
||||
GL.Clear(true, true, new Color(0,0,0,0));
|
||||
}
|
||||
|
||||
if (hasNormal)
|
||||
{
|
||||
rtNormal = new RenderTexture(size, size, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
|
||||
texNormal = new Texture2D(size, size, TextureFormat.RGBA32, false, true);
|
||||
Graphics.SetRenderTarget(rtNormal);
|
||||
GL.Clear(true, true, new Color(0,0,0,0));
|
||||
}
|
||||
|
||||
//GL.sRGBWrite = true;//!hasEmissive;
|
||||
GL.invertCulling = false;
|
||||
GL.PushMatrix();
|
||||
//GL.LoadOrtho();
|
||||
//UpdateMatrix();
|
||||
/*float ambR, ambG, ambB;
|
||||
//ambR = ambG = ambB = emissiveOnly ? 0 : 1;
|
||||
Shader.SetGlobalVector("unity_SHBr", Vector4.zero);
|
||||
Shader.SetGlobalVector("unity_SHBg", Vector4.zero);
|
||||
Shader.SetGlobalVector("unity_SHBb", Vector4.zero);
|
||||
Shader.SetGlobalVector("unity_SHC", Vector4.zero);*/
|
||||
texelSize = (1.0f / size) / 5;
|
||||
//shaBlack = new Vector4(0,0,0,0);
|
||||
//shaWhite = new Vector4(0,0,0,1);
|
||||
metaControl = new Vector4(1,0,0,0);
|
||||
metaControlAlbedo = new Vector4(1,0,0,0);
|
||||
metaControlEmission = new Vector4(0,1,0,0);
|
||||
metaControlNormal = new Vector4(0,0,1,0);
|
||||
Shader.SetGlobalVector("unity_MetaVertexControl", metaControl);
|
||||
Shader.SetGlobalFloat("unity_OneOverOutputBoost", 1.0f);
|
||||
Shader.SetGlobalFloat("unity_MaxOutputValue", 10000000.0f);
|
||||
Shader.SetGlobalFloat("unity_UseLinearSpace", PlayerSettings.colorSpace == ColorSpace.Linear ? 1.0f : 0.0f);
|
||||
}
|
||||
|
||||
static public void RenderUVGBuffer(Mesh mesh, Renderer renderer, Vector4 scaleOffset, Matrix4x4 worldMatrix, bool vertexBake,
|
||||
Vector2[] uvOverride, bool terrainNormals = false)
|
||||
{
|
||||
Material[] materials = renderer.sharedMaterials;
|
||||
#if SUPPORT_MBLOCKS
|
||||
var mb = new MaterialPropertyBlock();
|
||||
#endif
|
||||
|
||||
var m = mesh;
|
||||
if (uvOverride != null)
|
||||
{
|
||||
m = Mesh.Instantiate(mesh);
|
||||
//var uvs = m.uv2;
|
||||
//if (uvs.Length == 0) uvs = m.uv;
|
||||
//var pos = new Vector3[uvs.Length];
|
||||
/*for(int i=0; i<uvs.Length; i++)
|
||||
{
|
||||
pos[i] = new Vector3(uvs[i].x * scaleOffset.x + scaleOffset.z, uvs[i].y * scaleOffset.y + scaleOffset.w, 0.0f);
|
||||
}
|
||||
m.vertices = pos;*/
|
||||
|
||||
m.uv2 = uvOverride;
|
||||
|
||||
if (vertexBake)
|
||||
{
|
||||
for(int i=0; i<mesh.subMeshCount; i++)
|
||||
{
|
||||
var indices = m.GetIndices(i);
|
||||
m.SetIndices(indices, MeshTopology.Points, i, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var scaleOffsetFlipped = new Vector4(scaleOffset.x, -scaleOffset.y, scaleOffset.z, 1.0f - scaleOffset.w);
|
||||
|
||||
//UpdateMatrix(worldMatrix);
|
||||
|
||||
for(int pass=0; pass<3; pass++)
|
||||
{
|
||||
if (pass == 1 && !emissiveEnabled) continue;
|
||||
if (pass == 2 && !normalEnabled) continue;
|
||||
|
||||
if (pass == 0)
|
||||
{
|
||||
Graphics.SetRenderTarget(rtAlbedo);
|
||||
}
|
||||
else if (pass == 1)
|
||||
{
|
||||
Graphics.SetRenderTarget(rtEmissive);
|
||||
}
|
||||
else
|
||||
{
|
||||
Graphics.SetRenderTarget(rtNormal);
|
||||
}
|
||||
|
||||
for(int i=0; i<mesh.subMeshCount; i++)
|
||||
{
|
||||
if (materials.Length <= i) break;
|
||||
if (materials[i] == null) continue;
|
||||
if (materials[i].shader == null) continue;
|
||||
|
||||
// Optionally skip emission
|
||||
bool passAsBlack = (pass == 1 && materials[i].globalIlluminationFlags != MaterialGlobalIlluminationFlags.BakedEmissive);
|
||||
|
||||
var rpTag = materials[i].GetTag("RenderPipeline", true, "");
|
||||
bool isHDRP = rpTag == "HDRenderPipeline";
|
||||
if (pass == 2) isHDRP = false;
|
||||
int bakeryPass = -1;
|
||||
|
||||
if (pass < 2)
|
||||
{
|
||||
int metaPass = -1;
|
||||
if (!passAsBlack)
|
||||
{
|
||||
metaPass = materials[i].FindPass("META");
|
||||
if (metaPass < 0)
|
||||
{
|
||||
// Try finding another pass pass with "META" in it
|
||||
for(int mpass=0; mpass<materials[i].passCount; mpass++)
|
||||
{
|
||||
if (materials[i].GetPassName(mpass).IndexOf("META") >= 0)
|
||||
{
|
||||
metaPass = mpass;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Shader.SetGlobalVector("unity_LightmapST", (isHDRP) ? scaleOffsetFlipped : scaleOffset);
|
||||
Shader.SetGlobalVector("unity_MetaFragmentControl", pass == 0 ? metaControlAlbedo : metaControlEmission);
|
||||
|
||||
if (metaPass >= 0)
|
||||
{
|
||||
materials[i].SetPass(metaPass);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (passAsBlack)
|
||||
{
|
||||
if (blackMat == null)
|
||||
{
|
||||
blackMat = new Material(Shader.Find("Hidden/ftBlack"));
|
||||
}
|
||||
Shader.SetGlobalVector("unity_LightmapST", scaleOffset);
|
||||
blackMat.SetPass(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fallbackMat == null)
|
||||
{
|
||||
fallbackMat = new Material(Shader.Find("Standard"));
|
||||
fallbackMat.EnableKeyword("_EMISSION");
|
||||
fallbackMatMetaPass = fallbackMat.FindPass("META");
|
||||
}
|
||||
Debug.LogWarning("Material " + materials[i].name + " doesn't have meta pass - maps are taken by name");
|
||||
if (materials[i].HasProperty("_MainTex")) fallbackMat.mainTexture = materials[i].GetTexture("_MainTex");
|
||||
if (materials[i].HasProperty("_Color")) fallbackMat.SetVector("_Color", materials[i].GetVector("_Color"));
|
||||
if (materials[i].HasProperty("_EmissionMap")) fallbackMat.SetTexture("_EmissionMap", materials[i].GetTexture("_EmissionMap"));
|
||||
if (materials[i].HasProperty("_EmissionColor")) fallbackMat.SetVector("_EmissionColor", materials[i].GetVector("_EmissionColor"));
|
||||
fallbackMat.SetPass(fallbackMatMetaPass);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var metaPass = materials[i].FindPass("META_BAKERY");
|
||||
bakeryPass = metaPass;
|
||||
|
||||
if (normalMat == null && metaPass < 0)
|
||||
{
|
||||
normalMat = new Material(Shader.Find("Hidden/ftUVNormalMap"));
|
||||
}
|
||||
if (texBestFit == null)
|
||||
{
|
||||
texBestFit = new Texture2D(1024, 1024, TextureFormat.RGBA32, false, true);
|
||||
var edPath = ftLightmaps.GetEditorPath();
|
||||
var fbestfit = new BinaryReader(File.Open(edPath + "NormalsFittingTexture_dds", FileMode.Open, FileAccess.Read));
|
||||
fbestfit.BaseStream.Seek(128, SeekOrigin.Begin);
|
||||
var bytes = fbestfit.ReadBytes(1024 * 1024 * 4);
|
||||
fbestfit.Close();
|
||||
texBestFit.LoadRawTextureData(bytes);
|
||||
texBestFit.Apply();
|
||||
}
|
||||
|
||||
if (metaPass < 0)
|
||||
{
|
||||
if (materials[i].HasProperty("_BumpMap"))
|
||||
{
|
||||
normalMat.SetTexture("_BumpMap", materials[i].GetTexture("_BumpMap"));
|
||||
if (materials[i].HasProperty("_MainTex_ST"))
|
||||
{
|
||||
normalMat.SetVector("_BumpMap_scaleOffset", materials[i].GetVector("_MainTex_ST"));
|
||||
//Debug.LogError(materials[i].GetVector("_MainTex_ST"));
|
||||
}
|
||||
else
|
||||
{
|
||||
normalMat.SetVector("_BumpMap_scaleOffset", new Vector4(1,1,0,0));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
normalMat.SetTexture("_BumpMap", null);
|
||||
}
|
||||
normalMat.SetFloat("_IsTerrain", terrainNormals ? 1.0f : 0.0f);
|
||||
normalMat.SetTexture("bestFitNormalMap", texBestFit);
|
||||
normalMat.SetPass(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
materials[i].SetTexture("bestFitNormalMap", texBestFit);
|
||||
materials[i].SetPass(metaPass);
|
||||
}
|
||||
Shader.SetGlobalVector("unity_MetaFragmentControl", metaControlNormal);
|
||||
}
|
||||
|
||||
GL.sRGBWrite = pass == 0;
|
||||
|
||||
if (!vertexBake)
|
||||
{
|
||||
for(int j=0; j<uvOffset.Length/2; j++)
|
||||
{
|
||||
if (pass < 2)
|
||||
{
|
||||
UpdateMatrix(worldMatrix, uvOffset[j*2] * texelSize, uvOffset[j*2+1] * texelSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: use in HDRP as well
|
||||
var srcVec = (isHDRP) ? scaleOffsetFlipped : scaleOffset;
|
||||
var vec = new Vector4(srcVec.x, srcVec.y, srcVec.z + uvOffset[j*2] * texelSize, srcVec.w + uvOffset[j*2+1] * texelSize);
|
||||
Shader.SetGlobalVector("unity_LightmapST", vec);
|
||||
if (bakeryPass >= 0)
|
||||
{
|
||||
materials[i].SetPass(bakeryPass);
|
||||
}
|
||||
else
|
||||
{
|
||||
normalMat.SetPass(0);
|
||||
}
|
||||
}
|
||||
Graphics.DrawMeshNow(m, worldMatrix, i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateMatrix(worldMatrix, 0, 0);
|
||||
#if SUPPORT_MBLOCKS
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
renderer.GetPropertyBlock(mb, i);
|
||||
#else
|
||||
renderer.GetPropertyBlock(mb);
|
||||
#endif
|
||||
Graphics.DrawMesh(m, worldMatrix, materials[i], 0, null, i, mb, false, false, false);
|
||||
#else
|
||||
Graphics.DrawMeshNow(m, worldMatrix, i);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static public void EndUVGBuffer()
|
||||
{
|
||||
GL.PopMatrix();
|
||||
|
||||
Graphics.SetRenderTarget(rtAlbedo);
|
||||
texAlbedo.ReadPixels(new Rect(0,0,rtAlbedo.width,rtAlbedo.height), 0, 0, false);
|
||||
texAlbedo.Apply();
|
||||
|
||||
if (emissiveEnabled)
|
||||
{
|
||||
Graphics.SetRenderTarget(rtEmissive);
|
||||
texEmissive.ReadPixels(new Rect(0,0,rtEmissive.width,rtEmissive.height), 0, 0, false);
|
||||
texEmissive.Apply();
|
||||
}
|
||||
|
||||
if (normalEnabled)
|
||||
{
|
||||
Graphics.SetRenderTarget(rtNormal);
|
||||
texNormal.ReadPixels(new Rect(0,0,rtNormal.width,rtNormal.height), 0, 0, false);
|
||||
texNormal.Apply();
|
||||
}
|
||||
}
|
||||
|
||||
static public Texture2D DecodeFromRGBM(Texture2D emissive)
|
||||
{
|
||||
var rt = new RenderTexture(emissive.width, emissive.height, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
|
||||
var tex = new Texture2D(emissive.width, emissive.height, TextureFormat.RGBAHalf, false, true);
|
||||
|
||||
if (matFromRGBM == null) matFromRGBM = new Material(Shader.Find("Hidden/ftRGBM2Half"));
|
||||
|
||||
Graphics.SetRenderTarget(rt);
|
||||
GL.sRGBWrite = false;
|
||||
|
||||
matFromRGBM.SetTexture("_MainTex", emissive);
|
||||
|
||||
Graphics.Blit(emissive, rt, matFromRGBM);
|
||||
|
||||
tex.ReadPixels(new Rect(0,0,rt.width,rt.height), 0, 0, false);
|
||||
tex.Apply();
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
static public void Dilate(Texture2D albedo)
|
||||
{
|
||||
if (matDilate == null) matDilate = new Material(Shader.Find("Hidden/ftDilate"));
|
||||
|
||||
RenderTexture rt, rt2;
|
||||
if (albedo.format == TextureFormat.RGBA32)
|
||||
{
|
||||
rt = new RenderTexture(albedo.width, albedo.height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB);
|
||||
rt2 = new RenderTexture(albedo.width, albedo.height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt = new RenderTexture(albedo.width, albedo.height, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
|
||||
rt2 = new RenderTexture(albedo.width, albedo.height, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
|
||||
}
|
||||
|
||||
GL.sRGBWrite = albedo.format == TextureFormat.RGBA32;
|
||||
Graphics.Blit(albedo, rt, matDilate);
|
||||
|
||||
for(int i=0; i<8; i++)
|
||||
{
|
||||
Graphics.Blit(rt, rt2, matDilate);
|
||||
Graphics.Blit(rt2, rt, matDilate);
|
||||
}
|
||||
|
||||
Graphics.SetRenderTarget(rt);
|
||||
albedo.ReadPixels(new Rect(0,0,rt.width,rt.height), 0, 0, false);
|
||||
albedo.Apply();
|
||||
}
|
||||
|
||||
static public void Multiply(Texture2D albedo, float val)
|
||||
{
|
||||
if (matMultiply == null) matMultiply = new Material(Shader.Find("Hidden/ftMultiply"));
|
||||
|
||||
RenderTexture rt;
|
||||
if (albedo.format == TextureFormat.RGBA32)
|
||||
{
|
||||
rt = new RenderTexture(albedo.width, albedo.height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt = new RenderTexture(albedo.width, albedo.height, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
|
||||
}
|
||||
|
||||
GL.sRGBWrite = albedo.format == TextureFormat.RGBA32;
|
||||
matMultiply.SetFloat("multiplier", val);
|
||||
Graphics.Blit(albedo, rt, matMultiply);
|
||||
|
||||
Graphics.SetRenderTarget(rt);
|
||||
albedo.ReadPixels(new Rect(0,0,rt.width,rt.height), 0, 0, false);
|
||||
albedo.Apply();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
12
Assets/Editor/x64/Bakery/scripts/ftUVGBufferGen.cs.meta
Normal file
12
Assets/Editor/x64/Bakery/scripts/ftUVGBufferGen.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5d93843fab7110948a9eba95e82ced39
|
||||
timeCreated: 1533369120
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Editor/x64/Bakery/scripts/xatlas.meta
Normal file
9
Assets/Editor/x64/Bakery/scripts/xatlas.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1ce637195762a1b48b43dfc5c77e6d27
|
||||
folderAsset: yes
|
||||
timeCreated: 1606240229
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
23
Assets/Editor/x64/Bakery/scripts/xatlas/xatlas-license.txt
Normal file
23
Assets/Editor/x64/Bakery/scripts/xatlas/xatlas-license.txt
Normal file
@@ -0,0 +1,23 @@
|
||||
xatlas
|
||||
https://github.com/jpcy/xatlas
|
||||
Copyright (c) 2018 Jonathan Young
|
||||
|
||||
thekla_atlas
|
||||
https://github.com/Thekla/thekla_atlas
|
||||
Copyright (c) 2013 Thekla, Inc
|
||||
Copyright NVIDIA Corporation 2006 -- Ignacio Castano <icastano@nvidia.com>
|
||||
|
||||
Fast-BVH
|
||||
https://github.com/brandonpelfrey/Fast-BVH
|
||||
Copyright (c) 2012 Brandon Pelfrey
|
||||
|
||||
px_sched
|
||||
https://github.com/pplux/px
|
||||
Copyright (c) 2017-2018 Jose L. Hidalgo (PpluX)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
<EFBFBD> 2019 GitHub, Inc.
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 157fce07d9e165f4ea73f754793d6c48
|
||||
timeCreated: 1553351391
|
||||
licenseType: Store
|
||||
TextScriptImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
289
Assets/Editor/x64/Bakery/scripts/xatlas/xatlas.cs
Normal file
289
Assets/Editor/x64/Bakery/scripts/xatlas/xatlas.cs
Normal file
@@ -0,0 +1,289 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
public class xatlas
|
||||
{
|
||||
//#define UV_HINT
|
||||
|
||||
public static List<Vector2> newUVBuffer;
|
||||
public static List<int> newXrefBuffer;
|
||||
|
||||
[DllImport ("xatlasLib", CallingConvention=CallingConvention.Cdecl)]
|
||||
public static extern System.IntPtr xatlasCreateAtlas();
|
||||
|
||||
[DllImport ("xatlasLib", CallingConvention=CallingConvention.Cdecl)]
|
||||
public static extern int xatlasAddMesh(System.IntPtr atlas, int vertexCount, System.IntPtr positions, System.IntPtr normals, System.IntPtr uv, int indexCount, int[] indices32);
|
||||
|
||||
[DllImport ("xatlasLib", CallingConvention=CallingConvention.Cdecl)]
|
||||
public static extern int xatlasAddUVMesh(System.IntPtr atlas, int vertexCount, System.IntPtr uv, int indexCount, int[] indices32, bool allowRotate);
|
||||
|
||||
[DllImport ("xatlasLib", CallingConvention=CallingConvention.Cdecl)]
|
||||
public static extern void xatlasParametrize(System.IntPtr atlas);
|
||||
|
||||
[DllImport ("xatlasLib", CallingConvention=CallingConvention.Cdecl)]
|
||||
public static extern void xatlasPack(System.IntPtr atlas, int attempts, float texelsPerUnit, int resolution, int maxChartSize, int padding, bool bruteForce);//, bool allowRotate);
|
||||
|
||||
[DllImport ("xatlasLib", CallingConvention=CallingConvention.Cdecl)]
|
||||
public static extern void xatlasNormalize(System.IntPtr atlas, int[] atlasSizes);
|
||||
|
||||
[DllImport ("xatlasLib", CallingConvention=CallingConvention.Cdecl)]
|
||||
public static extern int xatlasGetAtlasCount(System.IntPtr atlas);
|
||||
|
||||
[DllImport ("xatlasLib", CallingConvention=CallingConvention.Cdecl)]
|
||||
public static extern int xatlasGetAtlasIndex(System.IntPtr atlas, int meshIndex, int chartIndex);
|
||||
|
||||
[DllImport ("xatlasLib", CallingConvention=CallingConvention.Cdecl)]
|
||||
public static extern int xatlasGetVertexCount(System.IntPtr atlas, int meshIndex);
|
||||
|
||||
[DllImport ("xatlasLib", CallingConvention=CallingConvention.Cdecl)]
|
||||
public static extern int xatlasGetIndexCount(System.IntPtr atlas, int meshIndex);
|
||||
|
||||
[DllImport ("xatlasLib", CallingConvention=CallingConvention.Cdecl)]
|
||||
public static extern void xatlasGetData(System.IntPtr atlas, int meshIndex, System.IntPtr outUV, System.IntPtr outRef, System.IntPtr outIndices);
|
||||
|
||||
[DllImport ("xatlasLib", CallingConvention=CallingConvention.Cdecl)]
|
||||
public static extern int xatlasClear(System.IntPtr atlas);
|
||||
|
||||
static T[] FillAtrribute<T>(List<int> xrefArray, T[] origArray)
|
||||
{
|
||||
if (origArray == null || origArray.Length == 0) return origArray;
|
||||
|
||||
var arr = new T[xrefArray.Count];
|
||||
for(int i=0; i<xrefArray.Count; i++)
|
||||
{
|
||||
int xref = xrefArray[i];
|
||||
arr[i] = origArray[xref];
|
||||
}
|
||||
return arr;
|
||||
|
||||
/*
|
||||
var finalAttr = new T[vertCount + xrefCount];
|
||||
for(int i=0; i<vertCount; i++) finalAttr[i] = origArray[i];
|
||||
for(int i=0; i<xrefCount; i++) finalAttr[i + vertCount] = origArray[ xrefArray[i] ];
|
||||
return finalAttr;
|
||||
*/
|
||||
}
|
||||
|
||||
public static double GetTime()
|
||||
{
|
||||
return (System.DateTime.Now.Ticks / System.TimeSpan.TicksPerMillisecond) / 1000.0;
|
||||
}
|
||||
|
||||
public static void Unwrap(Mesh m, UnwrapParam uparams)
|
||||
{
|
||||
//EditorUtility.DisplayDialog("Bakery", "xatlas start", "OK");
|
||||
int padding = (int)(uparams.packMargin*1024);
|
||||
//Debug.Log("xatlas! " + padding);
|
||||
|
||||
newUVBuffer = null;
|
||||
newXrefBuffer = null;
|
||||
|
||||
var t = GetTime();
|
||||
|
||||
var positions = m.vertices;
|
||||
var normals = m.normals;
|
||||
var existingUV = m.uv;
|
||||
var handlePos = GCHandle.Alloc(positions, GCHandleType.Pinned);
|
||||
var handleNorm = GCHandle.Alloc(normals, GCHandleType.Pinned);
|
||||
var handleUV = GCHandle.Alloc(existingUV, GCHandleType.Pinned);
|
||||
int err = 0;
|
||||
|
||||
var atlas = xatlasCreateAtlas();
|
||||
|
||||
//EditorUtility.DisplayDialog("Bakery", "xatlas created", "OK");
|
||||
|
||||
try
|
||||
{
|
||||
var pointerPos = handlePos.AddrOfPinnedObject();
|
||||
var pointerNorm = handleNorm.AddrOfPinnedObject();
|
||||
|
||||
#if UV_HINT
|
||||
var pointerUV = handleUV.AddrOfPinnedObject();
|
||||
#else
|
||||
var pointerUV = (System.IntPtr)0;
|
||||
#endif
|
||||
|
||||
for(int i=0; i<m.subMeshCount; i++)
|
||||
{
|
||||
err = xatlasAddMesh(atlas, m.vertexCount, pointerPos, pointerNorm, pointerUV, (int)m.GetIndexCount(i), m.GetIndices(i));
|
||||
if (err == 1)
|
||||
{
|
||||
Debug.LogError("xatlas::AddMesh: indices are out of range");
|
||||
}
|
||||
else if (err == 2)
|
||||
{
|
||||
Debug.LogError("xatlas::AddMesh: index count is incorrect");
|
||||
}
|
||||
else if (err != 0)
|
||||
{
|
||||
Debug.LogError("xatlas::AddMesh: unknown error");
|
||||
}
|
||||
if (err != 0) break;
|
||||
}
|
||||
//EditorUtility.DisplayDialog("Bakery", "xatlas added", "OK");
|
||||
if (err == 0)
|
||||
{
|
||||
xatlasParametrize(atlas);
|
||||
//EditorUtility.DisplayDialog("Bakery", "xatlas param done", "OK");
|
||||
|
||||
xatlasPack(atlas, 4096, 0, 0, 1024, padding, false);//, true);
|
||||
//EditorUtility.DisplayDialog("Bakery", "xatlas pack done", "OK");
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (handlePos.IsAllocated) handlePos.Free();
|
||||
if (handleNorm.IsAllocated) handleNorm.Free();
|
||||
if (handleUV.IsAllocated) handleUV.Free();
|
||||
}
|
||||
if (err != 0)
|
||||
{
|
||||
//EditorUtility.DisplayDialog("Bakery", "xatlas cancel", "OK");
|
||||
xatlasClear(atlas);
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Log("xatlas time: " + (GetTime() - t));
|
||||
t = GetTime();
|
||||
|
||||
//EditorUtility.DisplayDialog("Bakery", "xatlas unwrap start", "OK");
|
||||
//var uv2 = new Vector2[m.vertexCount];
|
||||
//int vertexOffset = m.vertexCount;
|
||||
//var newUV2 = new List<Vector2>();
|
||||
//var newXref = new List<int>();
|
||||
var indexBuffers = new List<int[]>();
|
||||
|
||||
newUVBuffer = new List<Vector2>();
|
||||
newXrefBuffer = new List<int>();
|
||||
while(newUVBuffer.Count < m.vertexCount)
|
||||
{
|
||||
newUVBuffer.Add(new Vector2(-100, -100));
|
||||
newXrefBuffer.Add(0);
|
||||
}
|
||||
|
||||
xatlasNormalize(atlas, null);
|
||||
|
||||
// Collect UVs/xrefs/indices
|
||||
for(int i=0; i<m.subMeshCount; i++)
|
||||
{
|
||||
// Get data from xatlas
|
||||
int newVertCount = xatlasGetVertexCount(atlas, i);
|
||||
int indexCount = xatlasGetIndexCount(atlas, i); // should be unchanged
|
||||
|
||||
var uvBuffer = new Vector2[newVertCount];
|
||||
var xrefBuffer = new int[newVertCount];
|
||||
var indexBuffer = new int[indexCount];
|
||||
|
||||
var handleT = GCHandle.Alloc(uvBuffer, GCHandleType.Pinned);
|
||||
var handleX = GCHandle.Alloc(xrefBuffer, GCHandleType.Pinned);
|
||||
var handleI = GCHandle.Alloc(indexBuffer, GCHandleType.Pinned);
|
||||
|
||||
try
|
||||
{
|
||||
var pointerT = handleT.AddrOfPinnedObject();
|
||||
var pointerX = handleX.AddrOfPinnedObject();
|
||||
var pointerI = handleI.AddrOfPinnedObject();
|
||||
|
||||
xatlasGetData(atlas, i, pointerT, pointerX, pointerI);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (handleT.IsAllocated) handleT.Free();
|
||||
if (handleX.IsAllocated) handleX.Free();
|
||||
if (handleI.IsAllocated) handleI.Free();
|
||||
}
|
||||
|
||||
// Generate new UV buffer and xatlas->final index mappings
|
||||
var xatlasIndexToNewIndex = new int[newVertCount];
|
||||
for(int j=0; j<newVertCount; j++)
|
||||
{
|
||||
int xref = xrefBuffer[j];
|
||||
Vector2 uv = uvBuffer[j];
|
||||
|
||||
if (newUVBuffer[xref].x < 0)
|
||||
{
|
||||
// first xref encounter gets UV
|
||||
xatlasIndexToNewIndex[j] = xref;
|
||||
newUVBuffer[xref] = uv;
|
||||
newXrefBuffer[xref] = xref;
|
||||
}
|
||||
else if (newUVBuffer[xref].x == uv.x && newUVBuffer[xref].y == uv.y)
|
||||
{
|
||||
// vertex already added
|
||||
xatlasIndexToNewIndex[j] = xref;
|
||||
}
|
||||
else
|
||||
{
|
||||
// duplicate vertex
|
||||
xatlasIndexToNewIndex[j] = newUVBuffer.Count;
|
||||
newUVBuffer.Add(uv);
|
||||
newXrefBuffer.Add(xref);
|
||||
}
|
||||
}
|
||||
|
||||
// Generate final index buffer
|
||||
for(int j=0; j<indexCount; j++)
|
||||
{
|
||||
indexBuffer[j] = xatlasIndexToNewIndex[ indexBuffer[j] ];
|
||||
}
|
||||
indexBuffers.Add(indexBuffer);
|
||||
}
|
||||
|
||||
//EditorUtility.DisplayDialog("Bakery", "xatlas unwrap end", "OK");
|
||||
|
||||
int vertCount = m.vertexCount;
|
||||
|
||||
bool origIs16bit = true;
|
||||
#if UNITY_2017_3_OR_NEWER
|
||||
origIs16bit = m.indexFormat == UnityEngine.Rendering.IndexFormat.UInt16;
|
||||
#endif
|
||||
bool is32bit = newUVBuffer.Count >= 65000;//0xFFFF;
|
||||
if (is32bit && origIs16bit)
|
||||
{
|
||||
Debug.LogError("Unwrap failed: original mesh (" + m.name + ") has 16 bit indices, but unwrapped requires 32 bit.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Duplicate attributes
|
||||
//if (newXrefBuffer.Count > m.vertexCount) // commented because can be also swapped around
|
||||
{
|
||||
m.vertices = FillAtrribute<Vector3>(newXrefBuffer, positions);
|
||||
m.normals = FillAtrribute<Vector3>(newXrefBuffer, normals);
|
||||
m.boneWeights = FillAtrribute<BoneWeight>(newXrefBuffer, m.boneWeights);
|
||||
m.colors32 = FillAtrribute<Color32>(newXrefBuffer, m.colors32);
|
||||
m.tangents = FillAtrribute<Vector4>(newXrefBuffer, m.tangents);
|
||||
m.uv = FillAtrribute<Vector2>(newXrefBuffer, m.uv);
|
||||
m.uv3 = FillAtrribute<Vector2>(newXrefBuffer, m.uv3);
|
||||
m.uv4 = FillAtrribute<Vector2>(newXrefBuffer, m.uv4);
|
||||
#if UNITY_2018_2_OR_NEWER
|
||||
m.uv5 = FillAtrribute<Vector2>(newXrefBuffer, m.uv5);
|
||||
m.uv6 = FillAtrribute<Vector2>(newXrefBuffer, m.uv6);
|
||||
m.uv7 = FillAtrribute<Vector2>(newXrefBuffer, m.uv7);
|
||||
m.uv8 = FillAtrribute<Vector2>(newXrefBuffer, m.uv8);
|
||||
#endif
|
||||
}
|
||||
|
||||
m.uv2 = newUVBuffer.ToArray();
|
||||
|
||||
/*
|
||||
|
||||
// Set new UV2
|
||||
var finalUV2 = new Vector2[vertCount + newUV2.Count];
|
||||
for(int i=0; i<vertCount; i++) finalUV2[i] = uv2[i];
|
||||
for(int i=0; i<newUV2.Count; i++) finalUV2[i + vertCount] = newUV2[i];
|
||||
m.uv2 = finalUV2;
|
||||
*/
|
||||
// Set indices
|
||||
for(int i=0; i<m.subMeshCount; i++)
|
||||
{
|
||||
m.SetTriangles(indexBuffers[i], i);
|
||||
}
|
||||
|
||||
//Debug.Log("post-xatlas mesh building time: " + GetTime() - t));
|
||||
|
||||
xatlasClear(atlas);
|
||||
}
|
||||
}
|
||||
12
Assets/Editor/x64/Bakery/scripts/xatlas/xatlas.cs.meta
Normal file
12
Assets/Editor/x64/Bakery/scripts/xatlas/xatlas.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 144aa3fbdb8360b4aaa4051032c25680
|
||||
timeCreated: 1557759843
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
13
Assets/Editor/x64/Bakery/scripts/xatlas/xatlasEnable.cs
Normal file
13
Assets/Editor/x64/Bakery/scripts/xatlas/xatlasEnable.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public partial class ftModelPostProcessor : ftModelPostProcessorInternal
|
||||
{
|
||||
public override void UnwrapXatlas(Mesh m, UnwrapParam param)
|
||||
{
|
||||
xatlas.Unwrap(m, uparams);
|
||||
}
|
||||
}
|
||||
|
||||
12
Assets/Editor/x64/Bakery/scripts/xatlas/xatlasEnable.cs.meta
Normal file
12
Assets/Editor/x64/Bakery/scripts/xatlas/xatlasEnable.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: deadc446e4efea944b443c59b6aed3f8
|
||||
timeCreated: 1559601034
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Editor/x64/Bakery/scripts/xatlas/xatlasLib.dll
LFS
Normal file
BIN
Assets/Editor/x64/Bakery/scripts/xatlas/xatlasLib.dll
LFS
Normal file
Binary file not shown.
28
Assets/Editor/x64/Bakery/scripts/xatlas/xatlasLib.dll.meta
Normal file
28
Assets/Editor/x64/Bakery/scripts/xatlas/xatlasLib.dll.meta
Normal file
@@ -0,0 +1,28 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b8be677e296fbf94092b02ac72dab402
|
||||
timeCreated: 1582151152
|
||||
licenseType: Store
|
||||
PluginImporter:
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
platformData:
|
||||
data:
|
||||
first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
data:
|
||||
first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86_64
|
||||
DefaultValueInitialized: true
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user