✨ Add water shader by Atlas and, flip some faces and experiment with animations
This commit is contained in:
parent
bf6da1e7c9
commit
c50e9258cf
1764 changed files with 303341 additions and 66722 deletions
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:
|
79
Assets/Editor/x64/Bakery/scripts/ftAdditionalConfig.cs
Normal file
79
Assets/Editor/x64/Bakery/scripts/ftAdditionalConfig.cs
Normal file
|
@ -0,0 +1,79 @@
|
|||
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;
|
||||
|
||||
// Coefficients used in "Remove ringing" mode
|
||||
public const float rr_irradianceConvolutionL0 = irradianceConvolutionL0;
|
||||
public const float rr_irradianceConvolutionL1 = irradianceConvolutionL1;
|
||||
public const float rr_irradianceConvolutionL2_4_5_7 = irradianceConvolutionL2_4_5_7 * 0.6F;
|
||||
public const float rr_irradianceConvolutionL2_6 = irradianceConvolutionL2_6 * 0.6f;
|
||||
public const float rr_irradianceConvolutionL2_8 = irradianceConvolutionL2_8 * 0.6f;
|
||||
|
||||
// Used for L1 light probes and volumes
|
||||
public const float convL0 = 1;
|
||||
public const float convL1 = 0.9f; // approx convolution
|
||||
|
||||
// Calculate multiple point lights in one pass. No reason to disable it, unless there is a bug.
|
||||
public static bool batchPointLights = true;
|
||||
|
||||
public static bool batchAreaLights = true;
|
||||
|
||||
#if UNITY_2017_3_OR_NEWER
|
||||
public const int sectorFarSphereResolution = 256;
|
||||
#else
|
||||
// older version can't handle 32 bit meshes
|
||||
public const int sectorFarSphereResolution = 64;
|
||||
#endif
|
||||
|
||||
public const int volumeSceneLODLevel = -1;
|
||||
|
||||
/*
|
||||
Following settings are moved to Project Settings
|
||||
(on >= 2018.3; you can also edit BakeryProjectSettings.asset directly)
|
||||
|
||||
// Use PNG instead of TGA for shadowmasks, directions and L1 maps
|
||||
public const bool preferPNG = false;
|
||||
|
||||
// Padding values for atlas packers
|
||||
public const int texelPaddingForDefaultAtlasPacker = 3;
|
||||
public const int texelPaddingForXatlasAtlasPacker = 1;
|
||||
|
||||
// Scales resolution for alpha Meta Pass maps
|
||||
public const int alphaMetaPassResolutionMultiplier = 2;
|
||||
|
||||
// Render mode for all volumes in the scene. Defaults to Auto, which uses global scene render mode.
|
||||
public const BakeryLightmapGroup.RenderMode volumeRenderMode = BakeryLightmapGroup.RenderMode.Auto;
|
||||
|
||||
// Should previously rendered Bakery lightmaps be deleted before the new bake?
|
||||
// Turned off by default because I'm scared of deleting anything
|
||||
public const bool deletePreviousLightmapsBeforeBake = false;
|
||||
|
||||
// Print information about the bake process to console?
|
||||
public enum LogLevel
|
||||
{
|
||||
Nothing = 0,
|
||||
Info = 1, // print to Debug.Log
|
||||
Warning = 2 // print to Debug.LogWarning
|
||||
}
|
||||
public const LogLevel logLevel = LogLevel.Info | LogLevel.Warning;
|
||||
|
||||
// Make it work more similar to original Unity behaviour
|
||||
public const bool alternativeScaleInLightmap = false;
|
||||
|
||||
// Should we adjust sample positions to prevent incorrect shadowing on very low-poly meshes with smooth normals?
|
||||
public const bool generateSmoothPos = true;
|
||||
*/
|
||||
}
|
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:
|
166
Assets/Editor/x64/Bakery/scripts/ftAtlasPreview.cs
Normal file
166
Assets/Editor/x64/Bakery/scripts/ftAtlasPreview.cs
Normal file
|
@ -0,0 +1,166 @@
|
|||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
public class ftAtlasPreview : EditorWindow
|
||||
{
|
||||
RenderTexture atlasRT;
|
||||
int curAtlas, numAtlases;
|
||||
int firstID, lastID;
|
||||
|
||||
public bool update = true;
|
||||
BakeryLightmapGroup grp = null;
|
||||
|
||||
static Shader shader;
|
||||
static Material mat;
|
||||
|
||||
public static ftAtlasPreview instance;
|
||||
|
||||
public static bool selectionChanged = false;
|
||||
|
||||
public static void SelectionCallback()
|
||||
{
|
||||
if (instance == null) return;
|
||||
instance.update = true;
|
||||
instance.OnGUI();
|
||||
}
|
||||
|
||||
void Awake()
|
||||
{
|
||||
Selection.selectionChanged -= SelectionCallback;
|
||||
Selection.selectionChanged += SelectionCallback;
|
||||
}
|
||||
|
||||
public void OnGUI()
|
||||
{
|
||||
instance = this;
|
||||
if (!ftRenderLightmap.showChecker) Close();
|
||||
|
||||
titleContent.text = "Atlas preview";
|
||||
|
||||
var objs = ftBuildGraphics.atlasOnlyObj;
|
||||
if (objs == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var scaleOffset = ftBuildGraphics.atlasOnlyScaleOffset;
|
||||
var ids = ftBuildGraphics.atlasOnlyID;
|
||||
var groups = ftBuildGraphics.atlasOnlyGroup;
|
||||
|
||||
if (shader == null)
|
||||
{
|
||||
shader = Shader.Find("Hidden/ftAtlas");
|
||||
if (shader == null)
|
||||
{
|
||||
Debug.LogError("Can't load atlas shader");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (mat == null)
|
||||
{
|
||||
mat = new Material(shader);
|
||||
}
|
||||
|
||||
if (atlasRT == null) atlasRT = new RenderTexture(1024, 1024, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB);
|
||||
if (update)
|
||||
{
|
||||
Graphics.SetRenderTarget(atlasRT);
|
||||
GL.Clear(true, true, new Color(0,0,0,0));
|
||||
GL.sRGBWrite = true;
|
||||
|
||||
var worldMatrix = Matrix4x4.identity;
|
||||
//numAtlases = 0;
|
||||
firstID = 99999;
|
||||
lastID = 0;
|
||||
|
||||
for(int i=0; i<objs.Count; i++)
|
||||
{
|
||||
if (ids[i] > lastID) lastID = ids[i];
|
||||
if (ids[i] < firstID) firstID = ids[i];
|
||||
}
|
||||
numAtlases = (lastID - firstID) + 1;
|
||||
if (curAtlas < firstID) curAtlas = firstID;
|
||||
|
||||
grp = null;
|
||||
for(int i=0; i<objs.Count; i++)
|
||||
{
|
||||
if (ids[i] != curAtlas) continue;
|
||||
if (objs[i] == null) continue;
|
||||
var mf = objs[i].GetComponent<MeshFilter>();
|
||||
if (mf == null) continue;
|
||||
var mesh = mf.sharedMesh;
|
||||
if (mesh == null) continue;
|
||||
int numSubs = mesh.subMeshCount;
|
||||
Shader.SetGlobalVector("unity_LightmapST", scaleOffset[i]);
|
||||
mat.SetPass(0);
|
||||
for(int s=0; s<numSubs; s++)
|
||||
{
|
||||
Graphics.DrawMeshNow(mesh, worldMatrix, s);
|
||||
}
|
||||
if (System.Array.IndexOf(Selection.objects, objs[i].gameObject) >= 0)
|
||||
{
|
||||
GL.wireframe = true;
|
||||
Shader.SetGlobalFloat("isSelected", 1.0f);
|
||||
mat.SetPass(0);
|
||||
for(int s=0; s<numSubs; s++)
|
||||
{
|
||||
Graphics.DrawMeshNow(mesh, worldMatrix, s);
|
||||
}
|
||||
GL.wireframe = false;
|
||||
Shader.SetGlobalFloat("isSelected", 0.0f);
|
||||
}
|
||||
grp = groups[i];
|
||||
}
|
||||
Graphics.SetRenderTarget(null);
|
||||
GL.sRGBWrite = false;
|
||||
update = false;
|
||||
Repaint();
|
||||
}
|
||||
|
||||
this.minSize = new Vector2(160, 160);
|
||||
this.maxSize = new Vector2(2048, 2048);
|
||||
|
||||
var pos = this.position;
|
||||
if (pos.height != pos.width+32)
|
||||
{
|
||||
this.position = new Rect(pos.x, pos.y, pos.width, pos.width+32);
|
||||
}
|
||||
|
||||
if (GUI.Button(new Rect(0, 0, 32, 32), "<"))
|
||||
{
|
||||
curAtlas--;
|
||||
if (curAtlas < 0) curAtlas = 0;
|
||||
update = true;
|
||||
}
|
||||
if (GUI.Button(new Rect(32, 0, 32, 32), ">"))
|
||||
{
|
||||
curAtlas++;
|
||||
if (curAtlas > lastID) curAtlas = lastID;
|
||||
update = true;
|
||||
}
|
||||
|
||||
int y = 0;
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
y = -10;
|
||||
#endif
|
||||
|
||||
GUI.Label(new Rect(64, y, 320, 32), "Showing atlas "+((curAtlas-firstID)+1)+" of "+numAtlases);
|
||||
if (grp != null)
|
||||
{
|
||||
GUI.Label(new Rect(64, y+15, 320, 32), grp.name + " (" + grp.resolution + "x" + grp.resolution + ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.Label(new Rect(64, y+15, 320, 32), "(Not shown / per-vertex)");
|
||||
}
|
||||
|
||||
if (atlasRT != null)
|
||||
{
|
||||
EditorGUI.DrawPreviewTexture(new Rect(0, 32, position.width, position.height-32), atlasRT);//, ScaleMode.ScaleToFit, false, 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
12
Assets/Editor/x64/Bakery/scripts/ftAtlasPreview.cs.meta
Normal file
12
Assets/Editor/x64/Bakery/scripts/ftAtlasPreview.cs.meta
Normal file
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 42f4cd34e81c6a1498d3b0574f6124e0
|
||||
timeCreated: 1645128907
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8172
Assets/Editor/x64/Bakery/scripts/ftBuildGraphics.cs
Normal file
8172
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:
|
1230
Assets/Editor/x64/Bakery/scripts/ftBuildLights.cs
Normal file
1230
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:
|
59
Assets/Editor/x64/Bakery/scripts/ftClearCache.cs
Normal file
59
Assets/Editor/x64/Bakery/scripts/ftClearCache.cs
Normal file
|
@ -0,0 +1,59 @@
|
|||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEngine.SceneManagement;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
public class ftClearCache
|
||||
{
|
||||
static void Clear(string[] files)
|
||||
{
|
||||
for(int i=0; i<files.Length; i++) File.Delete(files[i]);
|
||||
}
|
||||
|
||||
[MenuItem("Bakery/Utilities/Clear cache", false, 51)]
|
||||
private static void ClearCache()
|
||||
{
|
||||
var list = new HashSet<string>();
|
||||
|
||||
var defaultPath = System.Environment.GetEnvironmentVariable("TEMP", System.EnvironmentVariableTarget.Process) + "\\frender";
|
||||
|
||||
var gstorage = ftRenderLightmap.FindGlobalStorage();
|
||||
if (gstorage != null && gstorage.renderSettingsTempPath != "") defaultPath = gstorage.renderSettingsTempPath;
|
||||
|
||||
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) continue;
|
||||
|
||||
list.Add(storage.renderSettingsTempPath == "" ? defaultPath : storage.renderSettingsTempPath);
|
||||
}
|
||||
|
||||
foreach(var tempPath in list)
|
||||
{
|
||||
if (Directory.Exists(tempPath) && EditorUtility.DisplayDialog("Bakery", "Clear cache from '" + tempPath + "'?", "OK", "Cancel"))
|
||||
{
|
||||
var files = Directory.GetFiles(tempPath, "*.lz4");
|
||||
Clear(files);
|
||||
|
||||
files = Directory.GetFiles(tempPath, "*.dds");
|
||||
Clear(files);
|
||||
|
||||
files = Directory.GetFiles(tempPath, "*.bin");
|
||||
Clear(files);
|
||||
|
||||
files = Directory.GetFiles(tempPath, "lastscene.txt");
|
||||
Clear(files);
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Log("Done");
|
||||
}
|
||||
}
|
||||
|
12
Assets/Editor/x64/Bakery/scripts/ftClearCache.cs.meta
Normal file
12
Assets/Editor/x64/Bakery/scripts/ftClearCache.cs.meta
Normal file
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8d87362a9a7d1764092176850188e84b
|
||||
timeCreated: 1558111532
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
190
Assets/Editor/x64/Bakery/scripts/ftClearMenu.cs
Normal file
190
Assets/Editor/x64/Bakery/scripts/ftClearMenu.cs
Normal file
|
@ -0,0 +1,190 @@
|
|||
// Disable 'obsolete' warnings
|
||||
#pragma warning disable 0618
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEngine.SceneManagement;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class ftClearMenu : EditorWindow
|
||||
{
|
||||
public enum SceneClearingMode
|
||||
{
|
||||
nothing = 0,
|
||||
lightmapReferences = 1,
|
||||
lightmapReferencesAndBakeSettings = 2
|
||||
}
|
||||
|
||||
static public string[] options = new string[] {"Nothing", "Baked data references", "All (data and bake settings)"};
|
||||
|
||||
public SceneClearingMode sceneClearingMode = SceneClearingMode.lightmapReferences;
|
||||
public bool clearLightmapFiles = false;
|
||||
public bool clearVertexStreams = false;
|
||||
|
||||
[MenuItem("Bakery/Utilities/Clear baked data", false, 44)]
|
||||
private static void ClearBakedDataShow()
|
||||
{
|
||||
var instance = (ftClearMenu)GetWindow(typeof(ftClearMenu));
|
||||
instance.titleContent.text = "Clear Baked Data";
|
||||
instance.minSize = new Vector2(250, 180);
|
||||
instance.maxSize = new Vector2(instance.minSize.x, instance.minSize.y + 1);
|
||||
instance.Show();
|
||||
}
|
||||
|
||||
void OnGUI()
|
||||
{
|
||||
EditorGUILayout.BeginVertical(EditorStyles.inspectorFullWidthMargins);
|
||||
GUILayout.Space(10);
|
||||
EditorGUILayout.LabelField("Clear from scenes:", EditorStyles.boldLabel);
|
||||
GUILayout.Space(EditorGUIUtility.standardVerticalSpacing);
|
||||
sceneClearingMode = (SceneClearingMode)EditorGUILayout.Popup("", (int)sceneClearingMode, options, GUILayout.ExpandWidth(true));
|
||||
GUILayout.Space(10);
|
||||
EditorGUILayout.LabelField("Delete:", EditorStyles.boldLabel);
|
||||
GUILayout.Space(EditorGUIUtility.standardVerticalSpacing);
|
||||
EditorGUI.indentLevel++;
|
||||
clearLightmapFiles = EditorGUILayout.ToggleLeft(" Lightmap Files", clearLightmapFiles);
|
||||
clearVertexStreams = EditorGUILayout.ToggleLeft(" Vertex Lightmap Streams", clearVertexStreams);
|
||||
EditorGUI.indentLevel--;
|
||||
GUILayout.Space(20);
|
||||
|
||||
|
||||
if (GUILayout.Button("Clear", GUILayout.Height(24)))
|
||||
{
|
||||
string txt = "";
|
||||
if (sceneClearingMode == SceneClearingMode.nothing)
|
||||
{
|
||||
if (clearLightmapFiles) { txt += "Delete currently used lightmap files"; }
|
||||
|
||||
if (clearVertexStreams) { txt += " and vertex lightmap stream assets"; }
|
||||
else
|
||||
{
|
||||
EditorGUILayout.EndVertical();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sceneClearingMode == SceneClearingMode.lightmapReferences) { txt = "Clear all Bakery data for currently loaded scenes"; }
|
||||
else { txt = "Clear all Bakery data and settings for currently loaded scenes"; }
|
||||
|
||||
if (clearLightmapFiles && clearVertexStreams) txt += ", currently used lightmap files, and vertex lightmap stream assets";
|
||||
if (clearLightmapFiles && !clearVertexStreams) txt += " and delete currently used lightmap files";
|
||||
if (clearVertexStreams && !clearLightmapFiles) txt += " and vertex lightmap stream assets";
|
||||
}
|
||||
|
||||
if (EditorUtility.DisplayDialog("Bakery", txt + "?", "Yes", "No")) { ClearBakedData(sceneClearingMode, clearLightmapFiles, clearVertexStreams); }
|
||||
}
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
static void RemoveFiles(Texture2D map)
|
||||
{
|
||||
var path = AssetDatabase.GetAssetPath(map);
|
||||
AssetDatabase.DeleteAsset(path);
|
||||
ftRenderLightmap.DebugLogInfo("Deleted " + path);
|
||||
}
|
||||
|
||||
static void RemoveFiles(List<Texture2D> maps)
|
||||
{
|
||||
for(int i=0; i<maps.Count; i++)
|
||||
{
|
||||
RemoveFiles(maps[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void RemoveFiles(Mesh mesh)
|
||||
{
|
||||
var path = AssetDatabase.GetAssetPath(mesh);
|
||||
AssetDatabase.DeleteAsset(path);
|
||||
ftRenderLightmap.DebugLogInfo("Deleted " + path);
|
||||
}
|
||||
|
||||
static void RemoveFiles(List<Mesh> meshes)
|
||||
{
|
||||
for(int i=0; i<meshes.Count; i++)
|
||||
{
|
||||
var mesh = meshes[i];
|
||||
if (mesh == null) continue;
|
||||
RemoveFiles(mesh);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ClearBakedData(SceneClearingMode sceneClearMode, bool removeLightmapFiles, bool removeVertexStreams = false)
|
||||
{
|
||||
if (removeLightmapFiles || removeVertexStreams)
|
||||
{
|
||||
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) continue;
|
||||
|
||||
RemoveFiles(storage.maps);
|
||||
RemoveFiles(storage.masks);
|
||||
RemoveFiles(storage.dirMaps);
|
||||
RemoveFiles(storage.rnmMaps0);
|
||||
RemoveFiles(storage.rnmMaps1);
|
||||
RemoveFiles(storage.rnmMaps2);
|
||||
if (removeVertexStreams) { RemoveFiles(storage.bakedVertexColorMesh); }
|
||||
}
|
||||
}
|
||||
|
||||
if (sceneClearMode == SceneClearingMode.lightmapReferences)
|
||||
{
|
||||
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();
|
||||
newGO.hideFlags = HideFlags.HideInHierarchy;
|
||||
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 (sceneClearMode == SceneClearingMode.lightmapReferencesAndBakeSettings)
|
||||
{
|
||||
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];
|
||||
}
|
||||
|
||||
#if UNITY_2017_3_OR_NEWER
|
||||
var lights = FindObjectsOfType<Light>() as Light[];
|
||||
for(int i=0; i<lights.Length; i++)
|
||||
{
|
||||
var output = lights[i].bakingOutput;
|
||||
output.isBaked = false;
|
||||
lights[i].bakingOutput = output;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
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:
|
561
Assets/Editor/x64/Bakery/scripts/ftClient.cs
Normal file
561
Assets/Editor/x64/Bakery/scripts/ftClient.cs
Normal file
|
@ -0,0 +1,561 @@
|
|||
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_COMBINESH = 4;
|
||||
|
||||
public const byte SERVERTASK_DENOISE5 = 5;
|
||||
public const byte SERVERTASK_DENOISE6 = 6;
|
||||
public const byte SERVERTASK_DENOISE7 = 7;
|
||||
public const byte SERVERTASK_DENOISEOIDN = 8;
|
||||
public const byte SERVERTASK_DENOISEOIDN2 = 9;
|
||||
|
||||
public const byte SERVERTASK_HF2HDR = 10;
|
||||
public const byte SERVERTASK_RGBA2TGA = 11;
|
||||
public const byte SERVERTASK_SEAMFIX = 12;
|
||||
|
||||
public const byte SERVERTASK_LMREBAKE = 13;
|
||||
public const byte SERVERTASK_LMREBAKESIMPLE = 14;
|
||||
public const byte SERVERTASK_LODGEN = 15;
|
||||
public const byte SERVERTASK_LODGENINIT = 16;
|
||||
public const byte SERVERTASK_GIPARAMS = 17;
|
||||
public const byte SERVERTASK_RECEIVEFILE = 18;
|
||||
public const byte SERVERTASK_REPORTSTATUS = 19;
|
||||
public const byte SERVERTASK_SETSCENENAME = 20;
|
||||
public const byte SERVERTASK_GETDATA = 21;
|
||||
public const byte SERVERTASK_GETDATAREADY = 22;
|
||||
|
||||
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},
|
||||
{"combineSH", SERVERTASK_COMBINESH},
|
||||
|
||||
{"denoiserLegacy", SERVERTASK_DENOISE5},
|
||||
{"denoiser", SERVERTASK_DENOISE6},
|
||||
{"denoiser72", SERVERTASK_DENOISE7},
|
||||
{"denoiserOIDN", SERVERTASK_DENOISEOIDN},
|
||||
{"denoiserOIDN2", SERVERTASK_DENOISEOIDN2},
|
||||
|
||||
{"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, serverPort);
|
||||
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);
|
||||
bool connectionInProgress;
|
||||
|
||||
for(int i=0; i<serverFileList.Count; i++)
|
||||
{
|
||||
var fsoc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
connectionInProgress = true;
|
||||
while(connectionInProgress)
|
||||
{
|
||||
try
|
||||
{
|
||||
connectionInProgress = false;
|
||||
fsoc.Connect(remoteEP);
|
||||
}
|
||||
catch(SocketException s)
|
||||
{
|
||||
if (s.ErrorCode == 10035) // WSAEWOULDBLOCK
|
||||
{
|
||||
connectionInProgress = true;
|
||||
}
|
||||
else if (s.ErrorCode == 10061) // WSAECONNREFUSED
|
||||
{
|
||||
connectionInProgress = true;
|
||||
System.Threading.Thread.Sleep(1000); // apparently we're sending more than the server can chew - wait a bit
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Socket error");
|
||||
throw s;
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
||||
connectionInProgress = true;
|
||||
while(connectionInProgress)
|
||||
{
|
||||
try
|
||||
{
|
||||
connectionInProgress = false;
|
||||
fsoc.Send(buff);
|
||||
}
|
||||
catch(SocketException s)
|
||||
{
|
||||
if (s.ErrorCode == 10035) // WSAEWOULDBLOCK
|
||||
{
|
||||
connectionInProgress = true;
|
||||
}
|
||||
else if (s.ErrorCode == 10061) // WSAECONNREFUSED
|
||||
{
|
||||
connectionInProgress = true;
|
||||
System.Threading.Thread.Sleep(1000); // apparently we're sending more than the server can chew - wait a bit
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Socket error (2)");
|
||||
throw s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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:
|
96
Assets/Editor/x64/Bakery/scripts/ftCreateMenu.cs
Normal file
96
Assets/Editor/x64/Bakery/scripts/ftCreateMenu.cs
Normal file
|
@ -0,0 +1,96 @@
|
|||
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;
|
||||
}
|
||||
|
||||
[MenuItem("Bakery/Create/Volume", false, 20)]
|
||||
private static void CreateVolume()
|
||||
{
|
||||
var go = new GameObject();
|
||||
Undo.RegisterCreatedObjectUndo(go, "Create Bakery Volume");
|
||||
go.AddComponent<BakeryVolume>();
|
||||
go.name = "BakeryVolume";
|
||||
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:
|
48
Assets/Editor/x64/Bakery/scripts/ftDefine.cs
Normal file
48
Assets/Editor/x64/Bakery/scripts/ftDefine.cs
Normal file
|
@ -0,0 +1,48 @@
|
|||
#if UNITY_EDITOR
|
||||
|
||||
// Disable 'obsolete' warnings
|
||||
#pragma warning disable 0618
|
||||
|
||||
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";
|
||||
if (!defines.Contains("BAKERY_NOREIMPORT"))
|
||||
{
|
||||
defines += ";BAKERY_NOREIMPORT";
|
||||
}
|
||||
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:
|
283
Assets/Editor/x64/Bakery/scripts/ftDetectSettings.cs
Normal file
283
Assets/Editor/x64/Bakery/scripts/ftDetectSettings.cs
Normal file
|
@ -0,0 +1,283 @@
|
|||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.IO;
|
||||
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, bool onTop);
|
||||
|
||||
[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, runsOIDN2;
|
||||
|
||||
const string progressHeader = "Detecting compatible configuration";
|
||||
|
||||
static void ShowProgress(string msg, float percent)
|
||||
{
|
||||
simpleProgressBarShow(progressHeader, msg, percent, 0, true);
|
||||
}
|
||||
|
||||
static void ValidateFileAttribs(string file)
|
||||
{
|
||||
if (File.Exists(file))
|
||||
{
|
||||
var attribs = File.GetAttributes(file);
|
||||
if ((attribs & FileAttributes.ReadOnly) != 0)
|
||||
{
|
||||
File.SetAttributes(file, attribs & ~FileAttributes.ReadOnly);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[MenuItem("Bakery/Utilities/Detect optimal settings", false, 54)]
|
||||
public static void DetectCompatSettings()
|
||||
{
|
||||
var bakeryPath = ftLightmaps.GetEditorPath();
|
||||
ValidateFileAttribs(bakeryPath+"/hwtestdata/image.lz4");
|
||||
ValidateFileAttribs(bakeryPath+"/hwtestdata/light_HDR.lz4");
|
||||
|
||||
progressFunc = DetectCoroutine();
|
||||
EditorApplication.update += DetectUpdate;
|
||||
}
|
||||
|
||||
static IEnumerator DetectCoroutine()
|
||||
{
|
||||
float stages = 7;
|
||||
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;
|
||||
|
||||
ShowProgress("Testing: OpenImageDenoise2 (CUDA)", progress);
|
||||
crt = ProcessCoroutine("denoiserOIDN2 c hwtestdata/image.lz4 hwtestdata/image.lz4 16 0");
|
||||
while (crt.MoveNext()) yield return null;
|
||||
if (userCanceled) yield break;
|
||||
runsOIDN2 = 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 += "OpenImageDenoise2 (CUDA): " + (runsOIDN2 ? "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 (runsOIDN2)
|
||||
{
|
||||
// OIDN2+CUDA is the best option on modern HW
|
||||
str += "OpenImageDenoise2\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;
|
||||
gstorage.runsOIDN2 = runsOIDN2;
|
||||
}
|
||||
|
||||
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 (runsOIDN2)
|
||||
{
|
||||
gstorage.renderSettingsDenoiserType = (int)ftGlobalStorage.DenoiserType.OpenImageDenoise2;
|
||||
}
|
||||
else 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:
|
663
Assets/Editor/x64/Bakery/scripts/ftDirectLightInspector.cs
Normal file
663
Assets/Editor/x64/Bakery/scripts/ftDirectLightInspector.cs
Normal file
|
@ -0,0 +1,663 @@
|
|||
|
||||
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;
|
||||
SerializedProperty ftraceLightSupersample;
|
||||
|
||||
ftLightmapsStorage storage;
|
||||
|
||||
static bool projectionMode = false;
|
||||
|
||||
bool isHDRP = false;
|
||||
|
||||
public enum BakeWhat
|
||||
{
|
||||
DirectAndIndirect = 0,
|
||||
IndirectOnly = 1,
|
||||
IndirectAndShadowmask = 2,
|
||||
DirectIndirectShadowmask = 3
|
||||
};
|
||||
|
||||
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 public string[] directContributionOptions = new string[] {"Direct And Indirect", "Indirect Only", "Shadowmask and Indirect", "Direct, Indirect, Shadowmask (custom lighting only)"};
|
||||
static public string[] directContributionIndirectOptions = new string[] {"Direct And Indirect", "Indirect Only", "Shadowmask and Indirect (not applicable in Indirect mode)", "Direct, Indirect, Shadowmask (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");
|
||||
ftraceLightSupersample = obj.FindProperty("supersample");
|
||||
|
||||
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.r;
|
||||
lightG = light.color.g;
|
||||
lightB = light.color.b;
|
||||
|
||||
if (GraphicsSettings.lightsUseColorTemperature)
|
||||
{
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
if (light.useColorTemperature)
|
||||
#endif
|
||||
{
|
||||
var temp = Mathf.CorrelatedColorTemperatureToRGB(light.colorTemperature).gamma;
|
||||
lightR *= temp.r;
|
||||
lightG *= temp.g;
|
||||
lightB *= temp.b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnSceneGUI()
|
||||
{
|
||||
if (projectionMode)
|
||||
{
|
||||
var obj = target as BakeryDirectLight;
|
||||
var tform = obj.transform;
|
||||
|
||||
Vector3 normal = tform.forward;
|
||||
Vector3 binormal, tangent;
|
||||
if(Mathf.Abs(normal.x) > Mathf.Abs(normal.z))
|
||||
{
|
||||
binormal = new Vector3(-normal.y, normal.x, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
binormal = new Vector3(0, -normal.z, normal.y);
|
||||
}
|
||||
binormal = binormal.normalized;
|
||||
tangent = Vector3.Cross(binormal, normal);
|
||||
var rot = Quaternion.LookRotation(normal, -binormal);
|
||||
var pos = tangent * -obj.cloudShadowOffsetX/obj.cloudShadowTilingX + binormal * -obj.cloudShadowOffsetY/obj.cloudShadowTilingY;
|
||||
pos += tangent * 0.5f/obj.cloudShadowTilingX;
|
||||
pos += binormal * 0.5f/obj.cloudShadowTilingY;
|
||||
var ntangent = tangent;
|
||||
var nbinormal = binormal;
|
||||
|
||||
var mtx = new Matrix4x4();
|
||||
tangent /= obj.cloudShadowTilingX;
|
||||
binormal /= obj.cloudShadowTilingY;
|
||||
float depth = 1000.0f;
|
||||
normal *= depth;
|
||||
//pos += normal * depth * 0.5f;
|
||||
mtx.SetColumn(0, new Vector4(tangent.x, tangent.y, tangent.z, 0));
|
||||
mtx.SetColumn(1, new Vector4(binormal.x, binormal.y, binormal.z, 0));
|
||||
mtx.SetColumn(2, new Vector4(normal.x, normal.y, normal.z, 0));
|
||||
mtx.SetColumn(3, new Vector4(pos.x, pos.y, pos.z, 1.0f));
|
||||
|
||||
Handles.color = Color.red;
|
||||
Handles.matrix = mtx;// * Matrix4x4.Translate(Vector3.one * 0.5f);
|
||||
Handles.DrawWireCube(Vector3.zero, Vector3.one);
|
||||
Handles.matrix = Matrix4x4.identity;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var newPos = Handles.PositionHandle(pos, rot);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(obj, "Move directional light projection");
|
||||
|
||||
newPos -= ntangent * 0.5f/obj.cloudShadowTilingX;
|
||||
newPos -= nbinormal * 0.5f/obj.cloudShadowTilingY;
|
||||
obj.cloudShadowOffsetX = Vector3.Dot(ntangent, newPos) * -obj.cloudShadowTilingX;
|
||||
obj.cloudShadowOffsetY = Vector3.Dot(nbinormal, newPos) * -obj.cloudShadowTilingY;
|
||||
Shader.SetGlobalVector("_BakeryProjectionTilingOffset", new Vector4(obj.cloudShadowTilingX, obj.cloudShadowTilingY, obj.cloudShadowOffsetX, obj.cloudShadowOffsetY));
|
||||
if (BakeryDirectLight.lightsChanged == 0) BakeryDirectLight.lightsChanged = 1;
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
float size = HandleUtility.GetHandleSize(pos);
|
||||
var newScale = Handles.ScaleHandle(new Vector3(obj.cloudShadowTilingX, obj.cloudShadowTilingY, 0), pos - tform.up * size * 0.25f, rot, -size);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(obj, "Scale directional light projection");
|
||||
obj.cloudShadowTilingX = newScale.x;
|
||||
obj.cloudShadowTilingY = newScale.y;
|
||||
Shader.SetGlobalVector("_BakeryProjectionTilingOffset", new Vector4(obj.cloudShadowTilingX, obj.cloudShadowTilingY, obj.cloudShadowOffsetX, obj.cloudShadowOffsetY));
|
||||
if (BakeryDirectLight.lightsChanged == 0) BakeryDirectLight.lightsChanged = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 (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)
|
||||
{
|
||||
if (ftraceLightBakeToIndirect.boolValue)
|
||||
{
|
||||
contrib = BakeWhat.DirectIndirectShadowmask;
|
||||
}
|
||||
else
|
||||
{
|
||||
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.Popup("Baked contribution", (int)contrib, directContributionOptions);
|
||||
}
|
||||
|
||||
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 if (contrib == BakeWhat.DirectIndirectShadowmask)
|
||||
{
|
||||
ftraceLightShadowmask.boolValue = true;
|
||||
ftraceLightBakeToIndirect.boolValue = true;
|
||||
}
|
||||
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(ftraceLightSupersample, new GUIContent("Anti-alias", "Performs supersampling for the shadows, using 8 sub-samples."));
|
||||
|
||||
EditorGUILayout.PropertyField(ftraceLightTexture, new GUIContent("Texture projection", "Tiled projected texture"));
|
||||
if (ftraceLightTexture.objectReferenceValue != null)
|
||||
{
|
||||
var obj = target as BakeryDirectLight;
|
||||
|
||||
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"));
|
||||
|
||||
if (GUILayout.Button("Tweak projection in Scene View"))
|
||||
{
|
||||
ftSceneView.ToggleProjMode();
|
||||
projectionMode = ftSceneView.enabled;
|
||||
|
||||
UnityEditor.EditorWindow.GetWindow<SceneView>();
|
||||
var lastView = SceneView.lastActiveSceneView;
|
||||
if (lastView == null)
|
||||
{
|
||||
Debug.LogError("Can't get lastActiveSceneView");
|
||||
}
|
||||
else
|
||||
{
|
||||
var cam = lastView.camera;
|
||||
if (cam == null)
|
||||
{
|
||||
Debug.LogError("Can't get sceneView camera");
|
||||
}
|
||||
else
|
||||
{
|
||||
var camTform = cam.transform;
|
||||
var tform = obj.transform;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (projectionMode)
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
if (GUILayout.Button("Render reference frame"))
|
||||
{
|
||||
float far = 1000.0f;
|
||||
int width = 512;
|
||||
int height = 512;
|
||||
|
||||
var g = new GameObject();
|
||||
g.name = "TempCamera";
|
||||
var cam = g.AddComponent<Camera>();
|
||||
cam.aspect = obj.cloudShadowTilingY / obj.cloudShadowTilingX;
|
||||
cam.farClipPlane = far;
|
||||
cam.orthographic = true;
|
||||
cam.orthographicSize = (1.0f/obj.cloudShadowTilingY) * 0.5f;
|
||||
//cam.cullingMask = renderMapLayers;
|
||||
|
||||
var tform = obj.transform;
|
||||
Vector3 normal = tform.forward;
|
||||
Vector3 binormal, tangent;
|
||||
if(Mathf.Abs(normal.x) > Mathf.Abs(normal.z))
|
||||
{
|
||||
binormal = new Vector3(-normal.y, normal.x, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
binormal = new Vector3(0, -normal.z, normal.y);
|
||||
}
|
||||
binormal = binormal.normalized;
|
||||
tangent = Vector3.Cross(binormal, normal);
|
||||
var rot = Quaternion.LookRotation(normal, -binormal);
|
||||
var pos = tangent * -obj.cloudShadowOffsetX/obj.cloudShadowTilingX + binormal * -obj.cloudShadowOffsetY/obj.cloudShadowTilingY;
|
||||
pos += tangent * 0.5f/obj.cloudShadowTilingX;
|
||||
pos += binormal * 0.5f/obj.cloudShadowTilingY;
|
||||
|
||||
cam.transform.position = pos - normal * far*0.5f;
|
||||
cam.transform.rotation = rot;
|
||||
|
||||
var rt = new RenderTexture(width, height, 16, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB);
|
||||
cam.targetTexture = rt;
|
||||
cam.enabled = false;
|
||||
#if UNITY_2017_1_OR_NEWER
|
||||
cam.cameraType = CameraType.Reflection; // trick for SRP
|
||||
#endif
|
||||
cam.Render();
|
||||
|
||||
var tex = new Texture2D(width, height, TextureFormat.RGBA32, false);
|
||||
Graphics.SetRenderTarget(rt);
|
||||
tex.ReadPixels(new Rect(0, 0, width, height), 0, 0, false);
|
||||
tex.Apply();
|
||||
|
||||
int index, indexA, indexB;
|
||||
int minSwapped;
|
||||
Color a, b;
|
||||
var pixels = tex.GetPixels();
|
||||
for(int y=0; y<height; y++)
|
||||
{
|
||||
index = y*width;
|
||||
minSwapped = 16384;
|
||||
for(int x=0; x<width; x++)
|
||||
{
|
||||
indexA = index+x;
|
||||
if (minSwapped == indexA) break;
|
||||
indexB = index+(width-1)-x;
|
||||
a = pixels[indexA];
|
||||
b = pixels[indexB];
|
||||
pixels[indexA] = b;
|
||||
pixels[indexB] = a;
|
||||
minSwapped = indexB;
|
||||
}
|
||||
}
|
||||
tex.SetPixels(pixels);
|
||||
|
||||
RenderTexture.active = null;
|
||||
rt.Release();
|
||||
|
||||
byte[] _bytes = tex.EncodeToPNG();
|
||||
var path = EditorUtility.SaveFilePanelInProject("Save texture", "", "png", "");
|
||||
if (path.Length != 0)
|
||||
{
|
||||
System.IO.File.WriteAllBytes(path, _bytes);
|
||||
}
|
||||
|
||||
DestroyImmediate(g);
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
Shader.SetGlobalTexture("_BakeryProjectionMap", ftraceLightTexture.objectReferenceValue as Texture2D);
|
||||
Shader.SetGlobalVector("_BakeryProjectionDir", obj.gameObject.transform.forward);
|
||||
Shader.SetGlobalVector("_BakeryProjectionTilingOffset", new Vector4(obj.cloudShadowTilingX, obj.cloudShadowTilingY, obj.cloudShadowOffsetX, obj.cloudShadowOffsetY));
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
|
||||
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.r;// * fintensity;
|
||||
fg = clr.g;// * fintensity;
|
||||
fb = clr.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);
|
||||
|
||||
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;
|
||||
|
||||
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.colorTemperature = 6570; // neutral in Unity
|
||||
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:
|
268
Assets/Editor/x64/Bakery/scripts/ftErrorCodes.cs
Normal file
268
Assets/Editor/x64/Bakery/scripts/ftErrorCodes.cs
Normal file
|
@ -0,0 +1,268 @@
|
|||
#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"},
|
||||
{850, "Can't open log file"}
|
||||
};
|
||||
|
||||
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_DENOISEOIDN2, "denoiserOIDN2"},
|
||||
|
||||
{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 == "denoiserOIDN2") 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:
|
135
Assets/Editor/x64/Bakery/scripts/ftExtendLightmapParameters.cs
Normal file
135
Assets/Editor/x64/Bakery/scripts/ftExtendLightmapParameters.cs
Normal file
|
@ -0,0 +1,135 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[CustomEditor(typeof(LightmapParameters), true)]
|
||||
[CanEditMultipleObjects]
|
||||
public class ftExtendLightmapParameters : Editor
|
||||
{
|
||||
Editor defaultEditor;
|
||||
//LightmapParameters lp;
|
||||
SerializedProperty spBakedTag;
|
||||
bool tagOverride = false;
|
||||
int prevTag = -999;
|
||||
int tagDataIndex = -1;
|
||||
|
||||
static bool showBakeryOnly = false;
|
||||
static ftGlobalStorage gstorage;
|
||||
|
||||
void ValidateTagOverride()
|
||||
{
|
||||
tagOverride = false;
|
||||
int curTag = spBakedTag.intValue;
|
||||
if (gstorage == null) gstorage = ftRenderLightmap.FindGlobalStorage();
|
||||
var tagTable = gstorage.tagOverrides;
|
||||
if (tagTable == null) tagTable = gstorage.tagOverrides = new List<ftGlobalStorage.TagData>();
|
||||
for(int i=0; i<tagTable.Count; i++)
|
||||
{
|
||||
var tagData = tagTable[i];
|
||||
if (tagData.tag != curTag) continue;
|
||||
tagOverride = true;
|
||||
tagDataIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void InitSerializedProperties(SerializedObject obj)
|
||||
{
|
||||
spBakedTag = obj.FindProperty("bakedLightmapTag");
|
||||
ValidateTagOverride();
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
defaultEditor = Editor.CreateEditor(targets, Type.GetType("UnityEditor.LightmapParametersEditor, UnityEditor"));
|
||||
//lp = target as LightmapParameters;
|
||||
InitSerializedProperties(serializedObject);
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
MethodInfo disableMethod = defaultEditor.GetType().GetMethod("OnDisable", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
|
||||
if (disableMethod != null) disableMethod.Invoke(defaultEditor,null);
|
||||
DestroyImmediate(defaultEditor);
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
if (!showBakeryOnly) defaultEditor.OnInspectorGUI();
|
||||
serializedObject.Update();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Bakery", EditorStyles.boldLabel);
|
||||
showBakeryOnly = false;//EditorGUILayout.Toggle("Show compatible only", showBakeryOnly);
|
||||
//if (showBakeryOnly)
|
||||
{
|
||||
EditorGUILayout.PropertyField(spBakedTag, new GUIContent("Baked Tag", "Objects with different tag will always use separate atlases."));
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
int curTag = spBakedTag.intValue;
|
||||
if (curTag != prevTag) ValidateTagOverride();
|
||||
prevTag = curTag;
|
||||
|
||||
if (curTag < 0) GUI.enabled = false;
|
||||
bool tagOverridePrev = tagOverride;
|
||||
tagOverride = EditorGUILayout.Toggle("Override settings for this tag", tagOverride);
|
||||
if (tagOverride != tagOverridePrev)
|
||||
{
|
||||
if (tagOverride)
|
||||
{
|
||||
var tagData = gstorage.DefaultTagData();
|
||||
tagData.tag = curTag;
|
||||
tagDataIndex = gstorage.tagOverrides.Count;
|
||||
gstorage.tagOverrides.Add(tagData);
|
||||
EditorUtility.SetDirty(gstorage);
|
||||
}
|
||||
else
|
||||
{
|
||||
var tagTable = gstorage.tagOverrides;
|
||||
for(int i=0; i<tagTable.Count; i++)
|
||||
{
|
||||
var tagData = tagTable[i];
|
||||
if (tagData.tag != curTag) continue;
|
||||
tagTable.RemoveAt(i);
|
||||
EditorUtility.SetDirty(gstorage);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
GUI.enabled = true;
|
||||
|
||||
if (tagOverride)
|
||||
{
|
||||
var tagData = gstorage.tagOverrides[tagDataIndex];
|
||||
|
||||
EditorGUILayout.PrefixLabel("Render mode");
|
||||
tagData.renderMode = (int)(BakeryLightmapGroup.RenderMode)EditorGUILayout.EnumPopup((BakeryLightmapGroup.RenderMode)tagData.renderMode);
|
||||
EditorGUILayout.PrefixLabel("Directional mode");
|
||||
tagData.renderDirMode = (int)(BakeryLightmapGroup.RenderDirMode)EditorGUILayout.EnumPopup((BakeryLightmapGroup.RenderDirMode)tagData.renderDirMode);
|
||||
tagData.bitmask = EditorGUILayout.MaskField(new GUIContent("Bitmask", "Lights only affect renderers with overlapping bits"), tagData.bitmask, ftLMGroupSelectorInspector.selStrings);
|
||||
tagData.transparentSelfShadow = EditorGUILayout.Toggle(new GUIContent("Transparent selfshadow", "Start rays behind the surface so it doesn't cast shadows on self. Might be useful for translucent foliage"), tagData.transparentSelfShadow);
|
||||
tagData.computeSSS = EditorGUILayout.Toggle("Subsurface scattering", tagData.computeSSS);
|
||||
if (tagData.computeSSS)
|
||||
{
|
||||
tagData.sssSamples = EditorGUILayout.IntField("Samples", tagData.sssSamples);
|
||||
tagData.sssDensity = EditorGUILayout.FloatField("Density", tagData.sssDensity);
|
||||
tagData.sssColor = EditorGUILayout.ColorField("Color", tagData.sssColor);
|
||||
}
|
||||
|
||||
gstorage.tagOverrides[tagDataIndex] = tagData;
|
||||
EditorUtility.SetDirty(gstorage);
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 38b33630a03b6c04e9e30f4d89644c03
|
||||
timeCreated: 1645006015
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,32 @@
|
|||
#if UNITY_EDITOR
|
||||
|
||||
// Disable 'obsolete' warnings
|
||||
#pragma warning disable 0618
|
||||
|
||||
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.OnEnable(); // 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:
|
107
Assets/Editor/x64/Bakery/scripts/ftLMGroupInspector.cs
Normal file
107
Assets/Editor/x64/Bakery/scripts/ftLMGroupInspector.cs
Normal file
|
@ -0,0 +1,107 @@
|
|||
|
||||
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 ftraceHoleFilling;
|
||||
SerializedProperty ftraceBitmask;
|
||||
SerializedProperty ftraceThickness;
|
||||
SerializedProperty ftraceSSS;
|
||||
SerializedProperty ftraceSSSSamples;
|
||||
SerializedProperty ftraceSSSDensity;
|
||||
SerializedProperty ftraceSSSColor;
|
||||
SerializedProperty ftraceFakeShadowBias;
|
||||
SerializedProperty ftraceTransparentSelfShadow;
|
||||
SerializedProperty ftraceFlipNormal;
|
||||
SerializedProperty ftraceSSSScale;
|
||||
SerializedProperty ftraceAutoResolution;
|
||||
|
||||
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");
|
||||
ftraceHoleFilling = serializedObject.FindProperty("holeFilling");
|
||||
ftraceBitmask = serializedObject.FindProperty("bitmask");
|
||||
//ftraceThickness = serializedObject.FindProperty("aoIsThickness");
|
||||
ftraceSSS = serializedObject.FindProperty("computeSSS");
|
||||
ftraceSSSSamples = serializedObject.FindProperty("sssSamples");
|
||||
ftraceSSSDensity = serializedObject.FindProperty("sssDensity");
|
||||
ftraceSSSColor = serializedObject.FindProperty("sssColor");
|
||||
ftraceSSSScale = serializedObject.FindProperty("sssScale");
|
||||
ftraceFakeShadowBias = serializedObject.FindProperty("fakeShadowBias");
|
||||
ftraceTransparentSelfShadow = serializedObject.FindProperty("transparentSelfShadow");
|
||||
ftraceFlipNormal = serializedObject.FindProperty("flipNormal");
|
||||
ftraceAutoResolution = serializedObject.FindProperty("autoResolution");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI() {
|
||||
serializedObject.Update();
|
||||
|
||||
EditorGUILayout.LabelField("Bakery lightmap group parameters");
|
||||
EditorGUILayout.Space();
|
||||
|
||||
if (ftraceMode.intValue != 2)
|
||||
{
|
||||
EditorGUILayout.PropertyField(ftraceAutoResolution, new GUIContent("Auto resolution", "Use Texels Per Unit to determine closest power-of-two resolution."));
|
||||
if (!ftraceAutoResolution.boolValue)
|
||||
{
|
||||
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", ""));
|
||||
|
||||
if (ftraceAtlasPacker.intValue != (int)BakeryLightmapGroup.AtlasPacker.Default)
|
||||
{
|
||||
EditorGUILayout.PropertyField(ftraceHoleFilling, new GUIContent("Hole filling", ""));
|
||||
}
|
||||
|
||||
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(ftraceSSSScale, new GUIContent("Scale", ""));
|
||||
}
|
||||
|
||||
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:
|
190
Assets/Editor/x64/Bakery/scripts/ftLMGroupSelectorInspector.cs
Normal file
190
Assets/Editor/x64/Bakery/scripts/ftLMGroupSelectorInspector.cs
Normal file
|
@ -0,0 +1,190 @@
|
|||
|
||||
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 ftraceActive;
|
||||
SerializedProperty ftraceAsset;
|
||||
SerializedProperty ftraceOverride;
|
||||
SerializedProperty ftraceResolution;
|
||||
|
||||
string newName = null;
|
||||
int newRes = 512;
|
||||
int newMask = 1;
|
||||
bool newAutoRes = false;
|
||||
BakeryLightmapGroup.ftLMGroupMode newMode = BakeryLightmapGroup.ftLMGroupMode.PackAtlas;
|
||||
BakeryLightmapGroup.RenderDirMode newDirMode = BakeryLightmapGroup.RenderDirMode.Auto;
|
||||
|
||||
public 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()
|
||||
{
|
||||
ftraceActive = serializedObject.FindProperty("active");
|
||||
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");
|
||||
|
||||
EditorGUILayout.PropertyField(ftraceActive, new GUIContent("Enabled", "Take this group into account when baking. Objects will be auto-atlased as usual, if this option is not set."));
|
||||
|
||||
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";
|
||||
} else if (group.renderDirMode == BakeryLightmapGroup.RenderDirMode.MonoSH) {
|
||||
modeString += "MonoSH";
|
||||
}
|
||||
EditorGUILayout.LabelField(modeString);
|
||||
|
||||
if (group.mode != BakeryLightmapGroup.ftLMGroupMode.Vertex)
|
||||
{
|
||||
if (group.autoResolution)
|
||||
{
|
||||
EditorGUILayout.LabelField("Resolution: " + (ftraceOverride.boolValue ? (ftraceResolution.intValue + " (atlas: auto)") : "auto"));
|
||||
}
|
||||
else
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (!newAutoRes)
|
||||
{
|
||||
newRes = (int)Mathf.ClosestPowerOfTwo(EditorGUILayout.IntSlider("Resolution", newRes, 1, 8192));
|
||||
}
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.PrefixLabel(new GUIContent("Auto resolution", "Use Texels Per Unit to determine closest power-of-two resolution."));
|
||||
GUILayout.FlexibleSpace();
|
||||
newAutoRes = EditorGUILayout.Toggle(" ", newAutoRes);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
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;
|
||||
newGroup.autoResolution = newAutoRes;
|
||||
|
||||
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:
|
715
Assets/Editor/x64/Bakery/scripts/ftLightMeshInspector.cs
Normal file
715
Assets/Editor/x64/Bakery/scripts/ftLightMeshInspector.cs
Normal file
|
@ -0,0 +1,715 @@
|
|||
|
||||
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 ftraceLightSamples2_previous;
|
||||
SerializedProperty ftraceLightBitmask;
|
||||
SerializedProperty ftraceLightSelfShadow;
|
||||
SerializedProperty ftraceLightShadowmask;
|
||||
SerializedProperty ftraceLightBakeToIndirect;
|
||||
SerializedProperty ftraceLightShadowmaskFalloff;
|
||||
|
||||
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");
|
||||
ftraceLightSamples2_previous = obj.FindProperty("samples2_previous");
|
||||
ftraceLightBitmask = obj.FindProperty("bitmask");
|
||||
ftraceLightSelfShadow = obj.FindProperty("selfShadow");
|
||||
ftraceLightShadowmask = obj.FindProperty("shadowmask");
|
||||
ftraceLightBakeToIndirect = obj.FindProperty("bakeToIndirect");
|
||||
ftraceLightShadowmaskFalloff = obj.FindProperty("shadowmaskFalloff");
|
||||
}
|
||||
|
||||
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.r;
|
||||
lightG = light.color.g;
|
||||
lightB = light.color.b;
|
||||
|
||||
if (GraphicsSettings.lightsUseColorTemperature)
|
||||
{
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
if (light.useColorTemperature)
|
||||
#endif
|
||||
{
|
||||
var temp = Mathf.CorrelatedColorTemperatureToRGB(light.colorTemperature).gamma;
|
||||
lightR *= temp.r;
|
||||
lightG *= temp.g;
|
||||
lightB *= temp.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)
|
||||
{
|
||||
if (ftraceLightSamples2_previous.intValue != ftraceLightSamples2.intValue)
|
||||
{
|
||||
ftraceLightSamples2.intValue = ftraceLightSamples2_previous.intValue;
|
||||
}
|
||||
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'."));
|
||||
ftraceLightSamples2_previous.intValue = ftraceLightSamples2.intValue;
|
||||
}
|
||||
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 (ftraceLightShadowmask.boolValue)
|
||||
{
|
||||
if (ftraceLightBakeToIndirect.boolValue)
|
||||
{
|
||||
contrib = ftDirectLightInspector.BakeWhat.DirectIndirectShadowmask;
|
||||
}
|
||||
else
|
||||
{
|
||||
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.Popup("Baked contribution", (int)contrib, ftDirectLightInspector.directContributionOptions);
|
||||
}
|
||||
|
||||
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 if (contrib == ftDirectLightInspector.BakeWhat.DirectIndirectShadowmask)
|
||||
{
|
||||
ftraceLightShadowmask.boolValue = true;
|
||||
ftraceLightBakeToIndirect.boolValue = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ftraceLightShadowmask.boolValue = false;
|
||||
ftraceLightBakeToIndirect.boolValue = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(ftraceLightIndirectIntensity, new GUIContent("Indirect intensity", "Non-physical GI multiplier for this light"));
|
||||
|
||||
EditorGUILayout.PropertyField(ftraceLightShadowmaskFalloff, new GUIContent("Shadowmask with falloff", "Only useful for custom lighting. Bakes complete light attenuation into the shadowmask."));
|
||||
|
||||
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.r;// * fintensity;
|
||||
fg = clr.g;// * fintensity;
|
||||
fb = clr.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)
|
||||
{
|
||||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
ftRenderLightmap.DebugLogInfo("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();
|
||||
ftRenderLightmap.DebugLogInfo("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:
|
121
Assets/Editor/x64/Bakery/scripts/ftLightmappedPrefabInspector.cs
Normal file
121
Assets/Editor/x64/Bakery/scripts/ftLightmappedPrefabInspector.cs
Normal file
|
@ -0,0 +1,121 @@
|
|||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
[CustomEditor(typeof(BakeryLightmappedPrefab))]
|
||||
[CanEditMultipleObjects]
|
||||
public class ftLightmappedPrefabInspector : UnityEditor.Editor
|
||||
{
|
||||
bool allPrefabsGood = true;
|
||||
SerializedProperty isEnabled;
|
||||
SerializedProperty ignoreWarnings;
|
||||
|
||||
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");
|
||||
ignoreWarnings = serializedObject.FindProperty("ignoreWarnings");
|
||||
}
|
||||
|
||||
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."));
|
||||
EditorGUILayout.PropertyField(ignoreWarnings, new GUIContent("Ignore warnings", "Still attempt to bake the prefab, even if it has unapplied properties."));
|
||||
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);
|
||||
EditorUtility.SetDirty(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:
|
418
Assets/Editor/x64/Bakery/scripts/ftModelPostProcessor.cs
Normal file
418
Assets/Editor/x64/Bakery/scripts/ftModelPostProcessor.cs
Normal file
|
@ -0,0 +1,418 @@
|
|||
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;
|
||||
|
||||
ModelImporter importer = (ModelImporter)assetImporter;
|
||||
|
||||
//if (storage == null) return;
|
||||
bool hasGlobalPaddingAdjustment = (storage != null && storage.modifiedAssetPathList.IndexOf(assetPath) >= 0);
|
||||
bool hasGlobalPaddingAdjustment2 = false;
|
||||
#if UNITY_2017_1_OR_NEWER
|
||||
var props = importer.extraUserProperties;
|
||||
for(int p=0; p<props.Length; p++)
|
||||
{
|
||||
if (props[p].Substring(0,7) == "#BAKERY")
|
||||
{
|
||||
hasGlobalPaddingAdjustment2 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
var savedAdjustment = AssetDatabase.LoadAssetAtPath(
|
||||
Path.GetDirectoryName(assetPath) + "/" + Path.GetFileNameWithoutExtension(assetPath) + "_padding.asset", typeof(ftSavedPadding2)) as ftSavedPadding2;
|
||||
|
||||
if (!hasGlobalPaddingAdjustment && !hasGlobalPaddingAdjustment2 && savedAdjustment == null) return;
|
||||
|
||||
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:
|
874
Assets/Editor/x64/Bakery/scripts/ftPointLightInspector.cs
Normal file
874
Assets/Editor/x64/Bakery/scripts/ftPointLightInspector.cs
Normal file
|
@ -0,0 +1,874 @@
|
|||
|
||||
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 ftraceLightLegacySampling;
|
||||
SerializedProperty ftraceLightShadowmask;
|
||||
SerializedProperty ftraceLightShadowmaskFalloff;
|
||||
SerializedProperty ftraceLightIndirectIntensity;
|
||||
SerializedProperty ftraceLightFalloffMinRadius;
|
||||
SerializedProperty ftraceLightInnerAngle;
|
||||
SerializedProperty ftraceShadowmaskGroupID;
|
||||
SerializedProperty ftraceDirectionMode;
|
||||
|
||||
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");
|
||||
ftraceLightLegacySampling = obj.FindProperty("legacySampling");
|
||||
ftraceLightShadowmask = obj.FindProperty("shadowmask");
|
||||
ftraceLightShadowmaskFalloff = obj.FindProperty("shadowmaskFalloff");
|
||||
ftraceLightFalloffMinRadius = obj.FindProperty("falloffMinRadius");
|
||||
ftraceShadowmaskGroupID = obj.FindProperty("shadowmaskGroupID");
|
||||
ftraceDirectionMode = obj.FindProperty("directionMode");
|
||||
|
||||
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.r;
|
||||
lightG = light.color.g;
|
||||
lightB = light.color.b;
|
||||
|
||||
if (GraphicsSettings.lightsUseColorTemperature)
|
||||
{
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
if (light.useColorTemperature)
|
||||
#endif
|
||||
{
|
||||
var temp = Mathf.CorrelatedColorTemperatureToRGB(light.colorTemperature).gamma;
|
||||
lightR *= temp.r;
|
||||
lightG *= temp.g;
|
||||
lightB *= temp.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;
|
||||
}
|
||||
}
|
||||
|
||||
SerializedProperty hdrpLightRadius = so.FindProperty("m_ShapeRadius");
|
||||
if (hdrpLightRadius != null)
|
||||
{
|
||||
if (hdrpLightRadius.floatValue != 0)
|
||||
{
|
||||
why = "light radius is not 0.";
|
||||
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;
|
||||
|
||||
SerializedProperty hdrpLightRadius = so.FindProperty("m_ShapeRadius");
|
||||
if (hdrpLightRadius != null)
|
||||
{
|
||||
hdrpLightRadius.floatValue = 0;
|
||||
}
|
||||
|
||||
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(ftraceLightLegacySampling, new GUIContent("Legacy sampling", "Use Bakery's original more biased shadow sampling strategy. Produces noise-free shadows, but wide penumbras can exhibit banding. If disabled, an unbiased, but noisier technique is used."));
|
||||
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;
|
||||
}
|
||||
}
|
||||
EditorGUILayout.PropertyField(ftraceDirectionMode, new GUIContent("Orientation", "Defines forward axis for the IES light."));
|
||||
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)
|
||||
{
|
||||
if (ftraceLightBakeToIndirect.boolValue)
|
||||
{
|
||||
contrib = ftDirectLightInspector.BakeWhat.DirectIndirectShadowmask;
|
||||
}
|
||||
else
|
||||
{
|
||||
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.Popup("Baked contribution", (int)contrib, ftDirectLightInspector.directContributionOptions);
|
||||
}
|
||||
|
||||
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 if (contrib == ftDirectLightInspector.BakeWhat.DirectIndirectShadowmask)
|
||||
{
|
||||
ftraceLightShadowmask.boolValue = true;
|
||||
ftraceLightBakeToIndirect.boolValue = true;
|
||||
}
|
||||
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."));
|
||||
EditorGUILayout.PropertyField(ftraceLightShadowmaskFalloff, new GUIContent("Shadowmask with falloff", "Only useful for custom lighting. Bakes complete light attenuation (except distance) into the shadowmask."));
|
||||
}
|
||||
|
||||
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.r;// * fintensity;
|
||||
fg = clr.g;// * fintensity;
|
||||
fb = clr.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)
|
||||
{
|
||||
if (!(ftraceLightShadowmask.boolValue && ftraceLightBakeToIndirect.boolValue)) // not applicable to direct/indirect/shadowmask mode
|
||||
{
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
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:
|
11606
Assets/Editor/x64/Bakery/scripts/ftRenderLightmap.cs
Normal file
11606
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:
|
207
Assets/Editor/x64/Bakery/scripts/ftSceneView.cs
Normal file
207
Assets/Editor/x64/Bakery/scripts/ftSceneView.cs
Normal file
|
@ -0,0 +1,207 @@
|
|||
#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, projShader;
|
||||
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>();
|
||||
var usedLMIDs = new HashSet<int>();
|
||||
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)
|
||||
{
|
||||
usedLMIDs.Add(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: " + usedLMIDs.Count);
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
public static void ToggleProjMode()
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
ToggleChecker(); // same code for turning it off
|
||||
return;
|
||||
}
|
||||
|
||||
// Different code for turning it on
|
||||
|
||||
var sceneView = SceneView.lastActiveSceneView;
|
||||
if (sceneView == null)
|
||||
{
|
||||
Debug.LogError("Can't get SceneView");
|
||||
return;
|
||||
}
|
||||
|
||||
//if (projShader == null)
|
||||
{
|
||||
projShader = Shader.Find("Hidden/ftProjection");
|
||||
if (projShader == null)
|
||||
{
|
||||
Debug.LogError("Can't load projection shader");
|
||||
return;
|
||||
}
|
||||
}
|
||||
sceneView.SetSceneViewShaderReplace(projShader, null);
|
||||
enabled = true;
|
||||
|
||||
var gstorage = ftLightmaps.GetGlobalStorage();
|
||||
gstorage.checkerPreviewOn = true;
|
||||
EditorUtility.SetDirty(gstorage);
|
||||
|
||||
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:
|
506
Assets/Editor/x64/Bakery/scripts/ftSectorInspector.cs
Normal file
506
Assets/Editor/x64/Bakery/scripts/ftSectorInspector.cs
Normal file
|
@ -0,0 +1,506 @@
|
|||
// Disable 'obsolete' warnings
|
||||
#pragma warning disable 0618
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine;
|
||||
using System.IO;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
using UnityEditor.SceneManagement;
|
||||
#endif
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[CustomEditor(typeof(BakerySector))]
|
||||
public class BakerySectorInspector : Editor
|
||||
{
|
||||
BoxBoundsHandle boundsHandle = new BoxBoundsHandle(typeof(BakerySectorInspector).GetHashCode());
|
||||
SerializedProperty ftraceCaptureMode, ftraceCaptureAssetName, ftraceCaptureAsset, ftraceAllowUV, ftraceBakeLightProbes;
|
||||
int curSelectedB = -1;
|
||||
int curSelectedC = -1;
|
||||
Tool lastTool = Tool.None;
|
||||
|
||||
static GUIStyle ToggleButtonStyleNormal = null;
|
||||
static GUIStyle ToggleButtonStyleNormalBig = null;
|
||||
static GUIStyle CButtonStyle = null;
|
||||
static GUIStyle XButtonStyle = null;
|
||||
static GUIStyle LabelStyle = null;
|
||||
|
||||
GameObject objToRemove;
|
||||
EditorApplication.CallbackFunction remFunc;
|
||||
|
||||
ftLightmapsStorage storage;
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
ftraceCaptureMode = serializedObject.FindProperty("captureMode");
|
||||
ftraceCaptureAssetName = serializedObject.FindProperty("captureAssetName");
|
||||
ftraceCaptureAsset = serializedObject.FindProperty("captureAsset");
|
||||
ftraceAllowUV = serializedObject.FindProperty("allowUVPaddingAdjustment");
|
||||
ftraceBakeLightProbes = serializedObject.FindProperty("bakeChildLightProbeGroups");
|
||||
}
|
||||
|
||||
void RemoveWithUndo()
|
||||
{
|
||||
EditorApplication.delayCall -= remFunc;
|
||||
if (objToRemove == null) return;
|
||||
Undo.DestroyObjectImmediate(objToRemove);
|
||||
}
|
||||
|
||||
public static void DisablePreview(BakerySector vol)
|
||||
{
|
||||
var outRend = vol.previewDisabledRenderers;
|
||||
if (outRend != null)
|
||||
{
|
||||
for(int i=0; i<outRend.Count; i++)
|
||||
{
|
||||
if (outRend[i] != null) outRend[i].enabled = true;
|
||||
}
|
||||
}
|
||||
vol.previewDisabledRenderers = null;
|
||||
|
||||
ftRenderLightmap.showProgressBar = false;
|
||||
ftBuildGraphics.ProgressBarEnd(true);
|
||||
ftRenderLightmap.showProgressBar = true;
|
||||
|
||||
var temp = vol.previewTempObjects;
|
||||
if (temp != null)
|
||||
{
|
||||
for(int i=0; i<temp.Count; i++)
|
||||
{
|
||||
if (temp[i] != null) DestroyImmediate(temp[i]);
|
||||
}
|
||||
}
|
||||
vol.previewTempObjects = null;
|
||||
|
||||
vol.previewEnabled = false;
|
||||
EditorUtility.SetDirty(vol);
|
||||
|
||||
EditorSceneManager.MarkAllScenesDirty();
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
var vol = target as BakerySector;
|
||||
|
||||
if ( ToggleButtonStyleNormal == null )
|
||||
{
|
||||
ToggleButtonStyleNormal = "Button";
|
||||
}
|
||||
|
||||
if ( ToggleButtonStyleNormalBig == null )
|
||||
{
|
||||
ToggleButtonStyleNormalBig = new GUIStyle("Button");
|
||||
ToggleButtonStyleNormalBig.fixedHeight = 32;
|
||||
}
|
||||
|
||||
if (CButtonStyle == null)
|
||||
{
|
||||
CButtonStyle = new GUIStyle("Button");
|
||||
CButtonStyle.fixedWidth = 48;
|
||||
}
|
||||
|
||||
if (XButtonStyle == null)
|
||||
{
|
||||
XButtonStyle = new GUIStyle("Button");
|
||||
XButtonStyle.fixedWidth = 32;
|
||||
}
|
||||
|
||||
if (LabelStyle == null)
|
||||
{
|
||||
LabelStyle = new GUIStyle("Label");
|
||||
LabelStyle.fontSize = 18;
|
||||
LabelStyle.fontStyle = FontStyle.Bold;
|
||||
}
|
||||
|
||||
if (remFunc == null) remFunc = new EditorApplication.CallbackFunction(RemoveWithUndo);
|
||||
|
||||
EditorGUILayout.PropertyField(ftraceAllowUV, new GUIContent("Allow UV adjustment", "Allow UV padding adjustment when baking this sector? Disable when having multiple sectors affecting instances of the same mesh to prevent one sector from breaking UVs on another sector."));
|
||||
|
||||
EditorGUILayout.PropertyField(ftraceBakeLightProbes, new GUIContent("Bake light probes", "Bakes child LightProbeGroups."));
|
||||
|
||||
if (vol.previewEnabled) GUI.enabled = false;
|
||||
EditorGUILayout.PropertyField(ftraceCaptureMode, new GUIContent("Capture mode", "'Capture In Place' will generate outside geometry approximation every time 'Render' is pressed or RTPreview is open. It is a good option for exterior scenes where all sectors are loaded together and visible in the Editor.\n'Capture To Asset' will save approximated outside geometry into a file which can be used in another scene using 'Load Captured'."));
|
||||
|
||||
if (ftraceCaptureMode.intValue == (int)BakerySector.CaptureMode.CaptureToAsset)
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
var assetName = ftraceCaptureAssetName.stringValue;
|
||||
if (assetName.Length == 0) assetName = "SectorCapture_" + target.name;
|
||||
assetName = EditorGUILayout.TextField("Asset name", assetName);
|
||||
bool guiPrev = GUI.enabled;
|
||||
GUI.enabled = false;
|
||||
EditorGUILayout.PropertyField(ftraceCaptureAsset, new GUIContent("Captured asset", ""));
|
||||
GUI.enabled = guiPrev;
|
||||
EditorGUILayout.Space();
|
||||
if (GUILayout.Button("Capture", GUILayout.Height(32)))
|
||||
{
|
||||
if (storage == null) storage = ftRenderLightmap.FindRenderSettingsStorage();
|
||||
|
||||
var asset = ScriptableObject.CreateInstance<BakerySectorCapture>();
|
||||
asset.write = true;
|
||||
|
||||
ftRenderLightmap.fullSectorRender = true;
|
||||
ftBuildGraphics.modifyLightmapStorage = false;
|
||||
ftBuildGraphics.validateLightmapStorageImmutability = false;
|
||||
var exportSceneFunc = ftBuildGraphics.ExportScene(null, false, true, asset);
|
||||
var prevSector = storage.renderSettingsSector as BakerySector;
|
||||
storage.renderSettingsSector = ftRenderLightmap.curSector = vol;
|
||||
while(exportSceneFunc.MoveNext())
|
||||
{
|
||||
}
|
||||
storage.renderSettingsSector = ftRenderLightmap.curSector = prevSector;
|
||||
|
||||
if (asset.meshes != null && asset.meshes.Count > 0)
|
||||
{
|
||||
string fname;
|
||||
var activeScene = SceneManager.GetActiveScene();
|
||||
if (activeScene.path.Length > 0)
|
||||
{
|
||||
fname = Path.GetDirectoryName(activeScene.path) + "/" + assetName;
|
||||
}
|
||||
else
|
||||
{
|
||||
fname = "Assets/" + assetName;
|
||||
}
|
||||
|
||||
var tform = (target as BakerySector).transform;
|
||||
asset.sectorPos = tform.position;
|
||||
asset.sectorRot = tform.rotation;
|
||||
|
||||
var apath = fname + ".asset";
|
||||
AssetDatabase.CreateAsset(asset, apath);
|
||||
|
||||
for(int i=0; i<asset.meshes.Count; i++)
|
||||
{
|
||||
if (asset.meshes[i] == null)
|
||||
{
|
||||
Debug.LogError("Mesh " + i + " is null");
|
||||
continue;
|
||||
}
|
||||
AssetDatabase.AddObjectToAsset(asset.meshes[i], apath);
|
||||
AssetDatabase.AddObjectToAsset(asset.textures[i], apath);
|
||||
}
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
ftraceCaptureAsset.objectReferenceValue = asset;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("SectorCapture wasn't generated");
|
||||
}
|
||||
ftBuildGraphics.ProgressBarEnd(true);
|
||||
}
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
else if (ftraceCaptureMode.intValue == (int)BakerySector.CaptureMode.LoadCaptured)
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.PropertyField(ftraceCaptureAsset, new GUIContent("Captured asset", ""));
|
||||
}
|
||||
|
||||
if (vol.previewEnabled) GUI.enabled = true;
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
bool loadNothing = (ftraceCaptureMode.intValue == (int)BakerySector.CaptureMode.LoadCaptured && ftraceCaptureAsset.objectReferenceValue == null);
|
||||
if (loadNothing) GUI.enabled = false;
|
||||
|
||||
bool previewEnabled = GUILayout.Toggle(vol.previewEnabled, "Preview", ToggleButtonStyleNormalBig);
|
||||
if (!vol.previewEnabled && previewEnabled)
|
||||
{
|
||||
vol.previewEnabled = true;
|
||||
|
||||
if (storage == null) storage = ftRenderLightmap.FindRenderSettingsStorage();
|
||||
|
||||
BakerySectorCapture asset = null;
|
||||
bool loadedAsset = (ftraceCaptureMode.intValue == (int)BakerySector.CaptureMode.LoadCaptured);
|
||||
|
||||
if (loadedAsset)
|
||||
{
|
||||
asset = vol.captureAsset;
|
||||
asset.write = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
asset = ScriptableObject.CreateInstance<BakerySectorCapture>();
|
||||
asset.write = true;
|
||||
}
|
||||
|
||||
ftRenderLightmap.showProgressBar = false;
|
||||
ftRenderLightmap.fullSectorRender = true;
|
||||
ftBuildGraphics.modifyLightmapStorage = false;
|
||||
ftBuildGraphics.validateLightmapStorageImmutability = false;
|
||||
var exportSceneFunc = ftBuildGraphics.ExportScene(null, false, true, asset);
|
||||
var prevSector = storage.renderSettingsSector as BakerySector;
|
||||
storage.renderSettingsSector = ftRenderLightmap.curSector = vol;
|
||||
while(exportSceneFunc.MoveNext())
|
||||
{
|
||||
}
|
||||
storage.renderSettingsSector = ftRenderLightmap.curSector = prevSector;
|
||||
ftRenderLightmap.showProgressBar = true;
|
||||
|
||||
var outRend = asset.outsideRenderers;
|
||||
vol.previewDisabledRenderers = outRend;
|
||||
if (outRend != null)
|
||||
{
|
||||
for(int i=0; i<outRend.Count; i++)
|
||||
{
|
||||
if (outRend[i] != null) outRend[i].enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
vol.previewTempObjects = ftBuildGraphics.temporaryGameObjects;
|
||||
|
||||
EditorUtility.SetDirty(vol);
|
||||
if (!loadedAsset) DestroyImmediate(asset);
|
||||
|
||||
EditorSceneManager.MarkAllScenesDirty();
|
||||
}
|
||||
else if (vol.previewEnabled && !previewEnabled)
|
||||
{
|
||||
DisablePreview(vol);
|
||||
}
|
||||
if (loadNothing) GUI.enabled = true;
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.BeginVertical("box");
|
||||
|
||||
if (previewEnabled) GUI.enabled = false;
|
||||
|
||||
if (GUILayout.Button(new GUIContent("Add capture point", "Adds a new capture point to this sector. Points will appear as dummy objects parented to this object. When baking the scene (or clicking 'Capture'), each point will generate a simplified scene representation as seen from it. Points can approximate parts of the outside scene geometry and provide shadows/bounces from that geometry without loading the whole world in memory.")))
|
||||
{
|
||||
var g = new GameObject();
|
||||
Undo.RegisterCreatedObjectUndo(g, "Create capture point");
|
||||
g.name = vol.name + "_C_" + vol.tforms.Count;
|
||||
var t = g.transform;
|
||||
t.localPosition = vol.transform.position;
|
||||
t.parent = vol.transform;
|
||||
t.localScale = Vector3.one * 4;
|
||||
vol.cpoints.Add(t);
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
if (vol.cpoints.Count > 0)
|
||||
{
|
||||
GUILayout.Label("Edit capture points:");
|
||||
}
|
||||
|
||||
for(int i=0; i<vol.cpoints.Count; i++)
|
||||
{
|
||||
if (vol.cpoints[i] == null)
|
||||
{
|
||||
vol.cpoints.RemoveAt(i);
|
||||
curSelectedC = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
GUILayout.BeginHorizontal("box");
|
||||
|
||||
bool wasSelected = i == curSelectedC;
|
||||
bool selected = GUILayout.Toggle(i == curSelectedC, new GUIContent("" + i, "Select this capture point. Switch to the Move tool to manipulate it."), ToggleButtonStyleNormal);
|
||||
if (selected)
|
||||
{
|
||||
curSelectedC = i;
|
||||
curSelectedB = -1;
|
||||
}
|
||||
else if (wasSelected != selected)
|
||||
{
|
||||
curSelectedC = -1;
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Clone", CButtonStyle))
|
||||
{
|
||||
var g = new GameObject();
|
||||
Undo.RegisterCreatedObjectUndo(g, "Clone capture point");
|
||||
g.name = vol.name + "_C_" + vol.cpoints.Count;
|
||||
var t = g.transform;
|
||||
t.localPosition = vol.cpoints[i].position;
|
||||
t.parent = vol.transform;
|
||||
t.localScale = Vector3.one * 4;
|
||||
vol.cpoints.Add(t);
|
||||
}
|
||||
|
||||
if (GUILayout.Button(new GUIContent("X", "Delete this capture point"), XButtonStyle))
|
||||
{
|
||||
objToRemove = vol.cpoints[i].gameObject;
|
||||
|
||||
Undo.RecordObject(vol, "Remove capture point");
|
||||
vol.cpoints.RemoveAt(i);
|
||||
curSelectedC = -1;
|
||||
|
||||
EditorApplication.delayCall += remFunc;
|
||||
|
||||
break;
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
if (previewEnabled) GUI.enabled = true;
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
protected virtual void OnSceneGUI()
|
||||
{
|
||||
var vol = (BakerySector)target;
|
||||
|
||||
var origHMatrix = Handles.matrix;
|
||||
boundsHandle.center = Vector3.zero;
|
||||
boundsHandle.size = Vector3.one;
|
||||
|
||||
var solid = new Color(0.3f, 0.6f, 0.95f) * 2;
|
||||
//var semiTransparent = new Color(1, 1, 1, 0.2f);
|
||||
Handles.color = solid;
|
||||
|
||||
bool cull = false;
|
||||
Plane[] frustum = null;
|
||||
var curView = SceneView.currentDrawingSceneView;
|
||||
if (curView != null)
|
||||
{
|
||||
var cam = curView.camera;
|
||||
if (cam != null)
|
||||
{
|
||||
cull = true;
|
||||
frustum = GeometryUtility.CalculateFrustumPlanes(cam);
|
||||
}
|
||||
}
|
||||
|
||||
if (Tools.current != lastTool && Tools.current != Tool.None)
|
||||
{
|
||||
lastTool = Tools.current;
|
||||
}
|
||||
if (curSelectedB >= 0 || curSelectedC >= 0) Tools.current = Tool.None;
|
||||
|
||||
for(int i=0; i<vol.tforms.Count; i++)
|
||||
{
|
||||
if (vol.tforms[i] == null) continue;
|
||||
|
||||
Handles.matrix = origHMatrix;
|
||||
//Handles.color = solid;
|
||||
|
||||
Handles.zTest = UnityEngine.Rendering.CompareFunction.Less;
|
||||
Handles.matrix = Matrix4x4.TRS(vol.tforms[i].position, vol.tforms[i].rotation, Vector3.one);
|
||||
boundsHandle.size = vol.tforms[i].localScale;
|
||||
|
||||
if (!vol.previewEnabled)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
boundsHandle.DrawHandle();
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(vol.tforms[i], "Change Bounds");
|
||||
vol.tforms[i].localScale = boundsHandle.size;
|
||||
vol.tforms[i].position = Handles.matrix.MultiplyPoint(boundsHandle.center);
|
||||
}
|
||||
}
|
||||
|
||||
if (cull)
|
||||
{
|
||||
if(!GeometryUtility.TestPlanesAABB(frustum, new Bounds(vol.tforms[i].position, Vector3.one)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Handles.Label(Vector3.zero, "" + i, LabelStyle);
|
||||
|
||||
|
||||
//Handles.color = semiTransparent;
|
||||
//Handles.DrawWireCube(boundsHandle.center, boundsHandle.size + Vector3.one * vol.nearDistance);
|
||||
}
|
||||
|
||||
if (curSelectedB >= 0)
|
||||
{
|
||||
Handles.matrix = origHMatrix;
|
||||
int i = curSelectedB;
|
||||
Handles.zTest = UnityEngine.Rendering.CompareFunction.Always;
|
||||
var pos = vol.tforms[i].position;
|
||||
var rot = vol.tforms[i].rotation;
|
||||
var scl = vol.tforms[i].localScale;
|
||||
|
||||
if (!vol.previewEnabled)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
if (lastTool == Tool.Move)
|
||||
{
|
||||
pos = Handles.PositionHandle(pos, Quaternion.identity);
|
||||
}
|
||||
else if (lastTool == Tool.Rotate)
|
||||
{
|
||||
rot = Handles.RotationHandle(rot, pos);
|
||||
}
|
||||
else if (lastTool == Tool.Scale)
|
||||
{
|
||||
scl = Handles.ScaleHandle(scl, pos, rot, HandleUtility.GetHandleSize(pos));
|
||||
}
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(vol.tforms[i], "Change Bounds");
|
||||
vol.tforms[i].position = pos;
|
||||
vol.tforms[i].rotation = rot;
|
||||
vol.tforms[i].localScale = scl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Handles.matrix = Matrix4x4.identity;
|
||||
Handles.color = Color.green;
|
||||
|
||||
for(int i=0; i<vol.cpoints.Count; i++)
|
||||
{
|
||||
if (vol.cpoints[i] == null) continue;
|
||||
|
||||
Handles.zTest = UnityEngine.Rendering.CompareFunction.Less;
|
||||
|
||||
if (cull)
|
||||
{
|
||||
if(!GeometryUtility.TestPlanesAABB(frustum, new Bounds(vol.cpoints[i].position, Vector3.one)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Handles.Label(vol.cpoints[i].position, "" + i, LabelStyle);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Unity can throw nullrefs when Handles.Label uses larger font
|
||||
}
|
||||
}
|
||||
|
||||
if (curSelectedC >= 0)
|
||||
{
|
||||
int i = curSelectedC;
|
||||
Handles.zTest = UnityEngine.Rendering.CompareFunction.Always;
|
||||
|
||||
if (vol.cpoints[i] != null)
|
||||
{
|
||||
var pos = vol.cpoints[i].position;
|
||||
|
||||
if (!vol.previewEnabled)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
if (lastTool == Tool.Move)
|
||||
{
|
||||
pos = Handles.PositionHandle(pos, Quaternion.identity);
|
||||
}
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(vol.cpoints[i], "Change capture point");
|
||||
vol.cpoints[i].position = pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
12
Assets/Editor/x64/Bakery/scripts/ftSectorInspector.cs.meta
Normal file
12
Assets/Editor/x64/Bakery/scripts/ftSectorInspector.cs.meta
Normal file
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: adbe9477f3f37ce4b9269e796a502ed0
|
||||
timeCreated: 1619369355
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
90
Assets/Editor/x64/Bakery/scripts/ftSettingsProvider.cs
Normal file
90
Assets/Editor/x64/Bakery/scripts/ftSettingsProvider.cs
Normal file
|
@ -0,0 +1,90 @@
|
|||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
public class ftSettingsProvider
|
||||
{
|
||||
static BakeryProjectSettings pstorage;
|
||||
|
||||
static void GUIHandler(string searchContext)
|
||||
{
|
||||
if (pstorage == null) pstorage = ftLightmaps.GetProjectSettings();
|
||||
if (pstorage == null) return;
|
||||
|
||||
var so = new SerializedObject(pstorage);
|
||||
|
||||
var prev = EditorGUIUtility.labelWidth;
|
||||
EditorGUIUtility.labelWidth = 280;
|
||||
|
||||
var fhdr = so.FindProperty("formatHDR");
|
||||
var f8bit = so.FindProperty("format8bit");
|
||||
|
||||
EditorGUILayout.PropertyField(so.FindProperty("mipmapLightmaps"), new GUIContent("Mipmap Lightmaps", "Enable mipmapping on lightmap assets. Can cause leaks across UV charts as atlases get smaller."));
|
||||
EditorGUILayout.PropertyField(fhdr, new GUIContent("Color file format", ""));
|
||||
EditorGUILayout.PropertyField(f8bit, new GUIContent("Mask/Direction file format", ""));
|
||||
EditorGUILayout.PropertyField(so.FindProperty("lightmapCompression"), new GUIContent("Compress lightmaps", "Apply texture compression to lightmaps?"));
|
||||
EditorGUILayout.PropertyField(so.FindProperty("dirHighQuality"), new GUIContent("High quality direction", "Use high quality compression for directional and SH L1 maps? (on desktop, high = BC7, not high = DXT1)"));
|
||||
if (fhdr.intValue == 1 || f8bit.intValue == 2)
|
||||
{
|
||||
EditorGUILayout.PropertyField(so.FindProperty("maxAssetMip"), new GUIContent("Maximum mipmap count", "Limit mipmap count for Asset files."));
|
||||
}
|
||||
EditorGUILayout.PropertyField(so.FindProperty("texelPaddingForDefaultAtlasPacker"), new GUIContent("Texel padding (Default atlas packer)", "How many empty texels to add between objects' UV layouts in lightmap atlases."), GUILayout.ExpandWidth(true));
|
||||
EditorGUILayout.PropertyField(so.FindProperty("texelPaddingForXatlasAtlasPacker"), new GUIContent("Texel padding (xatlas packer)", "How many empty texels to add between objects' UV layouts in lightmap atlases."));
|
||||
EditorGUILayout.PropertyField(so.FindProperty("alphaMetaPassResolutionMultiplier"), new GUIContent("Alpha Meta Pass resolution multiplier", "Scales resolution for alpha Meta Pass maps."));
|
||||
//EditorGUILayout.PropertyField(so.FindProperty("volumeRenderMode"), new GUIContent("Volume render mode", "Render mode for volumes."));
|
||||
|
||||
var volMode = (BakeryLightmapGroup.RenderMode)so.FindProperty("volumeRenderMode").intValue;
|
||||
var newVolMode = (BakeryLightmapGroup.RenderMode)EditorGUILayout.EnumPopup(new GUIContent("Volume render mode", "Render mode for volumes."), volMode);
|
||||
if (volMode != newVolMode) so.FindProperty("volumeRenderMode").intValue = (int)newVolMode;
|
||||
|
||||
EditorGUILayout.PropertyField(so.FindProperty("deletePreviousLightmapsBeforeBake"), new GUIContent("Delete previous lightmaps before bake", "Should previously rendered Bakery lightmaps be deleted before the new bake?"));
|
||||
EditorGUILayout.PropertyField(so.FindProperty("logLevel"), new GUIContent("Log level", "Print information about the bake process to console? 0 = don't. 1 = info only; 2 = warnings only; 3 = everything."));
|
||||
EditorGUILayout.PropertyField(so.FindProperty("alternativeScaleInLightmap"), new GUIContent("Alternative Scale in Lightmap", "Make 'Scale in Lightmap' renderer property act more similar to built-in Unity behaviour."));
|
||||
EditorGUILayout.PropertyField(so.FindProperty("alignToTextureBlocksWithXatlas"), new GUIContent("Align to texture compression blocks with xatlas", "Make xatlas align charts to 4x4 block boundaries to make texture compression happy."));
|
||||
EditorGUILayout.PropertyField(so.FindProperty("generateSmoothPos"), new GUIContent("Generate smooth positions", "Should we adjust sample positions to prevent incorrect shadowing on very low-poly meshes with smooth normals?"));
|
||||
bool smoothPos = so.FindProperty("generateSmoothPos").boolValue;
|
||||
if (!smoothPos) GUI.enabled = false;
|
||||
EditorGUILayout.PropertyField(so.FindProperty("perTriangleSmoothPos"), new GUIContent("Smooth positions per-triangle", "Should smooth/flat position be decided per-triangle?"));
|
||||
if (!smoothPos) GUI.enabled = true;
|
||||
EditorGUILayout.PropertyField(so.FindProperty("takeReceiveGIIntoAccount"), new GUIContent("Use 'Receive GI' values", "Take 'Receive Global Illumination' values into account on renderers. Originally Bakery ignored it."));
|
||||
EditorGUILayout.PropertyField(so.FindProperty("removeRinging"), new GUIContent("Remove ringing in Legacy light probes", "Use softer light probe convolution in Legacy mode to prevent artifacts in high-contrast areas."));
|
||||
|
||||
EditorGUIUtility.labelWidth = prev;
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.Space();
|
||||
|
||||
if (GUILayout.Button("Revert to defaults"))
|
||||
{
|
||||
if (EditorUtility.DisplayDialog("Bakery", "Revert Bskery project settings to default?", "Yes", "No"))
|
||||
{
|
||||
so.FindProperty("mipmapLightmaps").boolValue = false;
|
||||
so.FindProperty("format8bit").intValue = 0;
|
||||
so.FindProperty("texelPaddingForDefaultAtlasPacker").intValue = 3;
|
||||
so.FindProperty("texelPaddingForXatlasAtlasPacker").intValue = 1;
|
||||
so.FindProperty("alphaMetaPassResolutionMultiplier").intValue = 2;
|
||||
so.FindProperty("volumeRenderMode").intValue = 1000;
|
||||
so.FindProperty("deletePreviousLightmapsBeforeBake").boolValue = false;
|
||||
so.FindProperty("logLevel").intValue = 3;
|
||||
so.FindProperty("alternativeScaleInLightmap").boolValue = false;
|
||||
so.FindProperty("alignToTextureBlocksWithXatlas").boolValue = true;
|
||||
so.FindProperty("generateSmoothPos").boolValue = true;
|
||||
so.FindProperty("perTriangleSmoothPos").boolValue = true;
|
||||
so.FindProperty("takeReceiveGIIntoAccount").boolValue = true;
|
||||
so.FindProperty("removeRinging").boolValue = false;
|
||||
}
|
||||
}
|
||||
|
||||
so.ApplyModifiedPropertiesWithoutUndo();
|
||||
}
|
||||
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
[SettingsProvider]
|
||||
public static SettingsProvider CreateSettingsProvider()
|
||||
{
|
||||
var provider = new SettingsProvider("Project/BakeryGlobalSettings", SettingsScope.Project);
|
||||
provider.label = "Bakery GPU Lightmapper";
|
||||
provider.guiHandler = GUIHandler;
|
||||
return provider;
|
||||
}
|
||||
#endif
|
||||
}
|
12
Assets/Editor/x64/Bakery/scripts/ftSettingsProvider.cs.meta
Normal file
12
Assets/Editor/x64/Bakery/scripts/ftSettingsProvider.cs.meta
Normal file
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a23d6b5064fb9a9408669cb173b201a8
|
||||
timeCreated: 1622052091
|
||||
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:
|
365
Assets/Editor/x64/Bakery/scripts/ftSkyLightInspector.cs
Normal file
365
Assets/Editor/x64/Bakery/scripts/ftSkyLightInspector.cs
Normal file
|
@ -0,0 +1,365 @@
|
|||
|
||||
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"))
|
||||
{
|
||||
if (skyMat != null)
|
||||
{
|
||||
Undo.RecordObject(skyMat, "Change skybox");
|
||||
}
|
||||
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);
|
||||
EditorSceneManager.MarkAllScenesDirty();
|
||||
}
|
||||
|
||||
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:
|
147
Assets/Editor/x64/Bakery/scripts/ftTextureProcessor.cs
Normal file
147
Assets/Editor/x64/Bakery/scripts/ftTextureProcessor.cs
Normal file
|
@ -0,0 +1,147 @@
|
|||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
#if UNITY_2021_2_OR_NEWER
|
||||
using System.IO;
|
||||
using System.IO.MemoryMappedFiles;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
#endif
|
||||
|
||||
public class ftTextureProcessor : AssetPostprocessor
|
||||
{
|
||||
public static Dictionary<string, ftRenderLightmap.Int2> texSettings = new Dictionary<string, ftRenderLightmap.Int2>();
|
||||
static BakeryProjectSettings pstorage;
|
||||
//static ftGlobalStorage gstorage;
|
||||
|
||||
public const int TEX_LM = 0;
|
||||
public const int TEX_LMDEFAULT = 1;
|
||||
public const int TEX_MASK = 2;
|
||||
public const int TEX_DIR = 3;
|
||||
public const int TEX_MASK_NO_ALPHA = 4;
|
||||
public const int TEX_DIR_NO_ALPHA = 5;
|
||||
|
||||
#if (!UNITY_2020_2_OR_NEWER)
|
||||
// Pre-broken Unity
|
||||
void OnPreprocessTexture()
|
||||
#else
|
||||
// Do not use OnPreprocessTexture on >= 2020.2.2 due to it forcing full project reimport!
|
||||
// https://forum.unity.com/threads/unity-made-full-project-reimport-on-every-small-change.1066844/
|
||||
#if (!BAKERY_INCLUDED || BAKERY_NOREIMPORT)
|
||||
// First package import OR the new define is set
|
||||
void OnPreprocessAsset()
|
||||
#else
|
||||
// Existing project - don't change the method, or the preprocessor hash (?) will change and trigger the full reimport again!
|
||||
void OnPreprocessTexture()
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
TextureImporter importer = assetImporter as TextureImporter;
|
||||
if (importer == null) return;
|
||||
|
||||
var settings = new ftRenderLightmap.Int2();
|
||||
|
||||
bool loadFromAsset = false;
|
||||
#if UNITY_2021_2_OR_NEWER
|
||||
// For parallel import
|
||||
if (UnityEditor.EditorSettings.refreshImportMode == AssetDatabase.RefreshImportMode.OutOfProcessPerQueue)
|
||||
{
|
||||
loadFromAsset = true;
|
||||
|
||||
try
|
||||
{
|
||||
using (var mmf = MemoryMappedFile.OpenExisting("FTEXPROC"))
|
||||
{
|
||||
using (var stream = mmf.CreateViewStream(0, ftRenderLightmap.maxTexSettingsSize))
|
||||
{
|
||||
var formatter = new BinaryFormatter();
|
||||
var buffer = new byte[ftRenderLightmap.maxTexSettingsSize];
|
||||
if (!stream.CanRead)
|
||||
{
|
||||
Debug.LogError("Can't read texture settings from memory mapped file");
|
||||
return;
|
||||
}
|
||||
stream.Read(buffer, 0, ftRenderLightmap.maxTexSettingsSize);
|
||||
var texS = formatter.Deserialize(new MemoryStream(buffer)) as Dictionary<string, ftRenderLightmap.Int2>;
|
||||
|
||||
if (!texS.TryGetValue(importer.assetPath, out settings)) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(FileNotFoundException)
|
||||
{
|
||||
return;
|
||||
}
|
||||
catch(System.Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!loadFromAsset)
|
||||
{
|
||||
if (!texSettings.TryGetValue(importer.assetPath, out settings)) return;
|
||||
}
|
||||
|
||||
if (pstorage == null) pstorage = ftLightmaps.GetProjectSettings();
|
||||
|
||||
importer.maxTextureSize = (int)settings.x;
|
||||
importer.mipmapEnabled = pstorage.mipmapLightmaps;
|
||||
importer.wrapMode = TextureWrapMode.Clamp;
|
||||
|
||||
int texType = (int)settings.y;
|
||||
switch(texType)
|
||||
{
|
||||
case TEX_LM:
|
||||
{
|
||||
importer.textureType = TextureImporterType.Lightmap;
|
||||
if (pstorage.lightmapCompression != BakeryProjectSettings.Compression.CompressButAllowOverridingAsset)
|
||||
{
|
||||
importer.textureCompression = pstorage.lightmapCompression == BakeryProjectSettings.Compression.ForceCompress ?
|
||||
TextureImporterCompression.Compressed : TextureImporterCompression.Uncompressed;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TEX_LMDEFAULT:
|
||||
{
|
||||
importer.textureType = TextureImporterType.Default;
|
||||
if (pstorage.lightmapCompression != BakeryProjectSettings.Compression.CompressButAllowOverridingAsset)
|
||||
{
|
||||
importer.textureCompression = pstorage.lightmapCompression == BakeryProjectSettings.Compression.ForceCompress ?
|
||||
TextureImporterCompression.Compressed : TextureImporterCompression.Uncompressed;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TEX_MASK:
|
||||
{
|
||||
importer.textureType = TextureImporterType.Default;
|
||||
importer.textureCompression = pstorage.lightmapCompression != BakeryProjectSettings.Compression.ForceNoCompress ? TextureImporterCompression.CompressedHQ : TextureImporterCompression.Uncompressed;
|
||||
importer.alphaSource = TextureImporterAlphaSource.FromInput;
|
||||
break;
|
||||
}
|
||||
case TEX_MASK_NO_ALPHA:
|
||||
{
|
||||
importer.textureType = TextureImporterType.Default;
|
||||
importer.textureCompression = pstorage.lightmapCompression != BakeryProjectSettings.Compression.ForceNoCompress ? TextureImporterCompression.Compressed : TextureImporterCompression.Uncompressed;
|
||||
importer.alphaSource = TextureImporterAlphaSource.None;
|
||||
break;
|
||||
}
|
||||
case TEX_DIR:
|
||||
{
|
||||
importer.textureType = TextureImporterType.Default;
|
||||
importer.textureCompression = pstorage.lightmapCompression != BakeryProjectSettings.Compression.ForceNoCompress ? (pstorage.dirHighQuality ? TextureImporterCompression.CompressedHQ : TextureImporterCompression.Compressed) : TextureImporterCompression.Uncompressed;
|
||||
importer.sRGBTexture = (pstorage.format8bit == BakeryProjectSettings.FileFormat.PNG);
|
||||
break;
|
||||
}
|
||||
case TEX_DIR_NO_ALPHA:
|
||||
{
|
||||
importer.textureType = TextureImporterType.Default;
|
||||
importer.textureCompression = pstorage.lightmapCompression != BakeryProjectSettings.Compression.ForceNoCompress ? TextureImporterCompression.Compressed : TextureImporterCompression.Uncompressed;
|
||||
importer.alphaSource = TextureImporterAlphaSource.None;
|
||||
importer.sRGBTexture = false;//(pstorage.format8bit == BakeryProjectSettings.FileFormat.PNG);
|
||||
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:
|
598
Assets/Editor/x64/Bakery/scripts/ftUVGBufferGen.cs
Normal file
598
Assets/Editor/x64/Bakery/scripts/ftUVGBufferGen.cs
Normal file
|
@ -0,0 +1,598 @@
|
|||
#if UNITY_EDITOR
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.IO;
|
||||
|
||||
public class ftUVGBufferGen
|
||||
{
|
||||
static RenderTexture rtAlbedo, rtEmissive, rtNormal, rtAlpha;
|
||||
public static Texture2D texAlbedo, texEmissive, texNormal, texBestFit, texAlpha;
|
||||
//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 bool alphaEnabled = false;
|
||||
static Vector4 metaControl, metaControlAlbedo, metaControlEmission, metaControlNormal, metaControlAlpha;
|
||||
static Material fallbackMat, normalMat, blackMat;
|
||||
static int fallbackMatMetaPass;
|
||||
static BakeryProjectSettings pstorage;
|
||||
|
||||
const int PASS_ALBEDO = 0;
|
||||
const int PASS_EMISSIVE = 1;
|
||||
const int PASS_NORMAL = 2;
|
||||
const int PASS_ALPHA = 3;
|
||||
const int PASS_COUNT = 4; // just a marker
|
||||
|
||||
public 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;
|
||||
alphaEnabled = false;
|
||||
|
||||
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);
|
||||
metaControlAlpha = new Vector4(0,0,0,1);
|
||||
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 InitAlphaBuffer(int size)
|
||||
{
|
||||
alphaEnabled = true;
|
||||
rtAlpha = new RenderTexture(size, size, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
|
||||
rtAlpha.name = "BakeryRTAlpha";
|
||||
texAlpha = new Texture2D(size, size, TextureFormat.RGBA32, false, true);
|
||||
texAlpha.name = "BakeryTexAlpha";
|
||||
Graphics.SetRenderTarget(rtAlpha);
|
||||
GL.Clear(true, true, new Color(0,0,0,0));
|
||||
}
|
||||
|
||||
static public void RenderUVGBuffer(Mesh mesh, Renderer renderer, Vector4 scaleOffset, Transform worldTransform, bool vertexBake,
|
||||
Vector2[] uvOverride, bool terrainNormals = false, bool metaAlpha = false)
|
||||
{
|
||||
var worldMatrix = worldTransform.localToWorldMatrix;
|
||||
|
||||
if (pstorage == null) pstorage = ftLightmaps.GetProjectSettings();
|
||||
|
||||
if (metaAlpha && !alphaEnabled)
|
||||
{
|
||||
int res = rtAlbedo.width * pstorage.alphaMetaPassResolutionMultiplier;
|
||||
if (res > 8192) res = 8192;
|
||||
InitAlphaBuffer(res);
|
||||
}
|
||||
|
||||
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<PASS_COUNT; pass++)
|
||||
{
|
||||
if (pass == PASS_EMISSIVE && !emissiveEnabled) continue;
|
||||
if (pass == PASS_NORMAL && !normalEnabled) continue;
|
||||
if (pass == PASS_ALPHA && !alphaEnabled) continue; // per Start-End
|
||||
if (pass == PASS_ALPHA && !metaAlpha) continue; // per this object
|
||||
|
||||
if (pass == PASS_ALBEDO)
|
||||
{
|
||||
Graphics.SetRenderTarget(rtAlbedo);
|
||||
}
|
||||
else if (pass == PASS_EMISSIVE)
|
||||
{
|
||||
Graphics.SetRenderTarget(rtEmissive);
|
||||
}
|
||||
else if (pass == PASS_NORMAL)
|
||||
{
|
||||
Graphics.SetRenderTarget(rtNormal);
|
||||
}
|
||||
else if (pass == PASS_ALPHA)
|
||||
{
|
||||
Graphics.SetRenderTarget(rtAlpha);
|
||||
}
|
||||
|
||||
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 == PASS_EMISSIVE && materials[i].globalIlluminationFlags != MaterialGlobalIlluminationFlags.BakedEmissive);
|
||||
|
||||
var rpTag = materials[i].GetTag("RenderPipeline", true, "");
|
||||
bool isHDRP = rpTag == "HDRenderPipeline";
|
||||
if (pass >= PASS_NORMAL) isHDRP = false; // custom meta shaders are not affected
|
||||
int bakeryPass = -1;
|
||||
|
||||
if (pass < PASS_NORMAL)
|
||||
{
|
||||
int metaPass = -1;
|
||||
if (!materials[i].HasProperty("BAKERY_FORCE_NO_META"))
|
||||
{
|
||||
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", scaleOffset);//(isHDRP) ? scaleOffsetFlipped : scaleOffset);
|
||||
Shader.SetGlobalVector("unity_MetaFragmentControl", pass == PASS_ALBEDO ? 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");
|
||||
}
|
||||
if ((pstorage.logLevel & (int)BakeryProjectSettings.LogLevel.Warning) != 0)
|
||||
{
|
||||
if (materials[i].name != "Hidden/ftFarSphere")
|
||||
{
|
||||
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");
|
||||
}
|
||||
else if (materials[i].HasProperty("_BaseColorMap"))
|
||||
{
|
||||
// HDRP
|
||||
fallbackMat.mainTexture = materials[i].GetTexture("_BaseColorMap");
|
||||
}
|
||||
else if (materials[i].HasProperty("_BaseMap"))
|
||||
{
|
||||
// URP
|
||||
fallbackMat.mainTexture = materials[i].GetTexture("_BaseMap");
|
||||
}
|
||||
if (materials[i].HasProperty("_Color"))
|
||||
{
|
||||
fallbackMat.SetVector("_Color", materials[i].GetVector("_Color"));
|
||||
}
|
||||
else
|
||||
{
|
||||
fallbackMat.SetVector("_Color", Color.white);
|
||||
}
|
||||
if (materials[i].HasProperty("_EmissionMap"))
|
||||
{
|
||||
fallbackMat.SetTexture("_EmissionMap", materials[i].GetTexture("_EmissionMap"));
|
||||
}
|
||||
else
|
||||
{
|
||||
fallbackMat.SetTexture("_EmissionMap", null);
|
||||
}
|
||||
if (materials[i].HasProperty("_EmissionColor"))
|
||||
{
|
||||
fallbackMat.SetVector("_EmissionColor", materials[i].GetVector("_EmissionColor"));
|
||||
}
|
||||
else
|
||||
{
|
||||
fallbackMat.SetVector("_EmissionColor", Color.black);
|
||||
}
|
||||
fallbackMat.SetPass(fallbackMatMetaPass);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (pass == PASS_NORMAL)
|
||||
{
|
||||
bool isURP = rpTag == "UniversalPipeline";
|
||||
|
||||
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 if (materials[i].HasProperty("_NormalMap"))
|
||||
{
|
||||
normalMat.SetTexture("_BumpMap", materials[i].GetTexture("_NormalMap"));
|
||||
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.SetFloat("_IsPerPixel", (isURP||isHDRP) ? 1.0f : 0.0f);
|
||||
normalMat.SetPass(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
materials[i].SetTexture("bestFitNormalMap", texBestFit);
|
||||
materials[i].SetFloat("_IsPerPixel", (isURP||isHDRP) ? 1.0f : 0.0f);
|
||||
materials[i].SetPass(metaPass);
|
||||
}
|
||||
Shader.SetGlobalVector("unity_MetaFragmentControl", metaControlNormal);
|
||||
}
|
||||
else if (pass == PASS_ALPHA)
|
||||
{
|
||||
// Unity does not output alpha in its meta pass, so only custom shaders are supported
|
||||
var metaPass = materials[i].FindPass("META_BAKERY");
|
||||
if (metaPass < 0)
|
||||
{
|
||||
Debug.LogError("BAKERY_META_ALPHA_ENABLE is set, but there is no META_BAKERY pass in " + materials[i].name);
|
||||
continue;
|
||||
}
|
||||
bakeryPass = metaPass;
|
||||
materials[i].SetPass(metaPass);
|
||||
Shader.SetGlobalVector("unity_MetaFragmentControl", metaControlAlpha);
|
||||
}
|
||||
|
||||
GL.sRGBWrite = pass == PASS_ALBEDO;
|
||||
|
||||
if (!vertexBake)
|
||||
{
|
||||
for(int j=0; j<uvOffset.Length/2; j++)
|
||||
{
|
||||
if (pass < PASS_NORMAL)
|
||||
{
|
||||
UpdateMatrix(worldMatrix, uvOffset[j*2] * texelSize, uvOffset[j*2+1] * texelSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: use in HDRP as well
|
||||
var srcVec = scaleOffset;//(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
|
||||
{
|
||||
var s = worldTransform.lossyScale;
|
||||
bool isFlipped = Mathf.Sign(s.x*s.y*s.z) < 0;
|
||||
normalMat.SetFloat("_IsFlipped", isFlipped ? -1.0f : 1.0f);
|
||||
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();
|
||||
Graphics.SetRenderTarget(null);
|
||||
rtAlbedo.Release();
|
||||
|
||||
if (emissiveEnabled)
|
||||
{
|
||||
Graphics.SetRenderTarget(rtEmissive);
|
||||
texEmissive.ReadPixels(new Rect(0,0,rtEmissive.width,rtEmissive.height), 0, 0, false);
|
||||
texEmissive.Apply();
|
||||
Graphics.SetRenderTarget(null);
|
||||
rtEmissive.Release();
|
||||
}
|
||||
|
||||
if (normalEnabled)
|
||||
{
|
||||
Graphics.SetRenderTarget(rtNormal);
|
||||
texNormal.ReadPixels(new Rect(0,0,rtNormal.width,rtNormal.height), 0, 0, false);
|
||||
texNormal.Apply();
|
||||
Graphics.SetRenderTarget(null);
|
||||
rtNormal.Release();
|
||||
}
|
||||
|
||||
if (alphaEnabled)
|
||||
{
|
||||
Graphics.SetRenderTarget(rtAlpha);
|
||||
texAlpha.ReadPixels(new Rect(0,0,rtAlpha.width,rtAlpha.height), 0, 0, false);
|
||||
texAlpha.Apply();
|
||||
Graphics.SetRenderTarget(null);
|
||||
rtAlpha.Release();
|
||||
rtAlpha = null;
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
Graphics.SetRenderTarget(null);
|
||||
rt.Release();
|
||||
Object.DestroyImmediate(emissive);
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
static public void Dilate(Texture2D albedo, int pass = 0)
|
||||
{
|
||||
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, pass);
|
||||
|
||||
for(int i=0; i<8; i++)
|
||||
{
|
||||
Graphics.Blit(rt, rt2, matDilate, pass);
|
||||
Graphics.Blit(rt2, rt, matDilate, pass);
|
||||
}
|
||||
|
||||
Graphics.SetRenderTarget(rt);
|
||||
albedo.ReadPixels(new Rect(0,0,rt.width,rt.height), 0, 0, false);
|
||||
albedo.Apply();
|
||||
|
||||
Graphics.SetRenderTarget(null);
|
||||
rt.Release();
|
||||
rt2.Release();
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
Graphics.SetRenderTarget(null);
|
||||
rt.Release();
|
||||
}
|
||||
}
|
||||
|
||||
#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:
|
395
Assets/Editor/x64/Bakery/scripts/ftUpdater.cs
Normal file
395
Assets/Editor/x64/Bakery/scripts/ftUpdater.cs
Normal file
|
@ -0,0 +1,395 @@
|
|||
// Disable 'obsolete' warnings
|
||||
#pragma warning disable 0618
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Callbacks;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Net;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.Networking;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[InitializeOnLoad]
|
||||
public class ftUpdater : EditorWindow
|
||||
{
|
||||
[DllImport ("frender", CallingConvention=CallingConvention.Cdecl)]
|
||||
public static extern int ExtractZIP([MarshalAs(UnmanagedType.LPWStr)]string zipFilename, int skipInnerFolders, string onlyFolder, [MarshalAs(UnmanagedType.LPWStr)]string outPath);
|
||||
|
||||
IEnumerator progressFunc;
|
||||
float progress = 0.0f;
|
||||
string curItem = "";
|
||||
bool isError = false;
|
||||
|
||||
string inLM = "IN000000000000";
|
||||
string inRT = "IN000000000000";
|
||||
string username = "";
|
||||
string errMsg = "";
|
||||
string lastVer = "";
|
||||
bool init = false;
|
||||
|
||||
bool anythingDownloaded = false;
|
||||
|
||||
[MenuItem ("Bakery/Utilities/Check for patches", false, 1000)]
|
||||
public static void Check()
|
||||
{
|
||||
var instance = (ftUpdater)GetWindow(typeof(ftUpdater));
|
||||
instance.titleContent.text = "Bakery patch";
|
||||
instance.minSize = new Vector2(320, 110);
|
||||
instance.maxSize = new Vector2(instance.minSize.x, instance.minSize.y + 1);
|
||||
instance.Show();
|
||||
}
|
||||
|
||||
void DebugLogError(string str)
|
||||
{
|
||||
Debug.LogError(str);
|
||||
errMsg = str;
|
||||
progressFunc = null;
|
||||
isError = true;
|
||||
Repaint();
|
||||
}
|
||||
|
||||
IEnumerator DownloadItem(string url)
|
||||
{
|
||||
var req = UnityWebRequest.Get(url + curItem);
|
||||
yield return req.Send();
|
||||
while(!req.isDone)
|
||||
{
|
||||
progress = req.downloadProgress;
|
||||
Repaint();
|
||||
yield return null;
|
||||
}
|
||||
|
||||
if (req.isError)
|
||||
{
|
||||
DebugLogError("Download error (" + curItem + ")");
|
||||
yield break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (req.downloadHandler.data.Length < 100)
|
||||
{
|
||||
DebugLogError(req.downloadHandler.text);
|
||||
yield break;
|
||||
}
|
||||
else
|
||||
{
|
||||
File.WriteAllBytes(curItem + ".zip", req.downloadHandler.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator GetLastVer(string url)
|
||||
{
|
||||
lastVer = "";
|
||||
var req = UnityWebRequest.Get(url + curItem + "&getLastVer");
|
||||
yield return req.Send();
|
||||
while(!req.isDone)
|
||||
{
|
||||
progress = req.downloadProgress;
|
||||
Repaint();
|
||||
yield return null;
|
||||
}
|
||||
|
||||
if (req.isError)
|
||||
{
|
||||
DebugLogError("Request error (" + curItem + ")");
|
||||
yield break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (req.downloadHandler.data.Length != 40)
|
||||
{
|
||||
DebugLogError(req.downloadHandler.text);
|
||||
yield break;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastVer = req.downloadHandler.text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator DownloadItemIfNewer(string url)
|
||||
{
|
||||
var dw = GetLastVer(url);
|
||||
while(dw.MoveNext()) yield return null;
|
||||
if (isError) yield break;
|
||||
|
||||
var fname = curItem + "-cver.txt"; // currently installed
|
||||
if (File.Exists(fname))
|
||||
{
|
||||
var curVer = File.ReadAllText(fname);
|
||||
if (lastVer == curVer)
|
||||
{
|
||||
Debug.Log(curItem + ": already latest");
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
|
||||
dw = DownloadItem(url);
|
||||
while(dw.MoveNext()) yield return null;
|
||||
anythingDownloaded = true;
|
||||
|
||||
File.WriteAllText(curItem + "-dver.txt", lastVer); // downloaded
|
||||
}
|
||||
|
||||
IEnumerator CheckProc()
|
||||
{
|
||||
//var runtimePath = ftLightmaps.GetRuntimePath();
|
||||
//var editorPath = ftLightmaps.GetEditorPath();
|
||||
|
||||
isError = false;
|
||||
|
||||
bool downloadLM = inLM.Length > 0 && inLM != "IN000000000000";
|
||||
bool downloadRT = inRT.Length > 0 && inRT != "IN000000000000";
|
||||
|
||||
if (!downloadLM && !downloadRT)
|
||||
{
|
||||
DebugLogError("No invoices set");
|
||||
yield break;
|
||||
}
|
||||
|
||||
anythingDownloaded = false;
|
||||
|
||||
if (downloadLM)
|
||||
{
|
||||
// Download bakery-csharp
|
||||
curItem = "bakery-csharp";
|
||||
var dw = DownloadItemIfNewer("https://geom.io/bakery/github-download.php?name=" + username + "&invoice=" + inLM + "&repo=");
|
||||
while(dw.MoveNext()) yield return null;
|
||||
if (isError) yield break;
|
||||
|
||||
// Download bakery-compiled
|
||||
curItem = "bakery-compiled";
|
||||
dw = DownloadItemIfNewer("https://geom.io/bakery/github-download.php?name=" + username + "&invoice=" + inLM + "&repo=");
|
||||
while(dw.MoveNext()) yield return null;
|
||||
if (isError) yield break;
|
||||
}
|
||||
|
||||
if (downloadRT)
|
||||
{
|
||||
// Download bakery-rtpreview-csharp
|
||||
curItem = "bakery-rtpreview-csharp";
|
||||
var dw = DownloadItemIfNewer("https://geom.io/bakery/github-download.php?name=" + username + "&invoice=" + inRT + "&repo=");
|
||||
while(dw.MoveNext()) yield return null;
|
||||
if (isError) yield break;
|
||||
}
|
||||
|
||||
if (!anythingDownloaded)
|
||||
{
|
||||
if (EditorUtility.DisplayDialog("Bakery", "There are no new patches. Re-apply previous patch?", "Yes", "No"))
|
||||
{
|
||||
anythingDownloaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (anythingDownloaded)
|
||||
{
|
||||
var cachePath = Directory.GetCurrentDirectory() + "/BakeryPatchCache";
|
||||
if (!Directory.Exists(cachePath)) Directory.CreateDirectory(cachePath);
|
||||
|
||||
var runtimePath = cachePath + "/Runtime";
|
||||
if (!Directory.Exists(runtimePath)) Directory.CreateDirectory(runtimePath);
|
||||
|
||||
var editorPath = cachePath + "/Editor";
|
||||
if (!Directory.Exists(editorPath)) Directory.CreateDirectory(editorPath);
|
||||
|
||||
if (downloadLM)
|
||||
{
|
||||
// Extract runtime files
|
||||
int err = ExtractZIP("bakery-csharp.zip", 1, "Bakery", runtimePath);
|
||||
if (err != 0)
|
||||
{
|
||||
DebugLogError("ExtractZIP: " + err);
|
||||
yield break;
|
||||
}
|
||||
|
||||
// Extract editor files
|
||||
err = ExtractZIP("bakery-csharp.zip", 3, "Bakery", editorPath);
|
||||
if (err != 0)
|
||||
{
|
||||
DebugLogError("ExtractZIP: " + err);
|
||||
yield break;
|
||||
}
|
||||
|
||||
Debug.Log("Extracted bakery-csharp");
|
||||
|
||||
// Extract binaries
|
||||
err = ExtractZIP("bakery-compiled.zip", 1, "", editorPath);
|
||||
if (err != 0)
|
||||
{
|
||||
DebugLogError("ExtractZIP: " + err);
|
||||
yield break;
|
||||
}
|
||||
|
||||
Debug.Log("Extracted bakery-compiled");
|
||||
}
|
||||
|
||||
if (downloadRT)
|
||||
{
|
||||
// Extract RTPreview files
|
||||
int err = ExtractZIP("bakery-rtpreview-csharp.zip", 1, "", editorPath);
|
||||
if (err != 0)
|
||||
{
|
||||
DebugLogError("ExtractZIP: " + err);
|
||||
yield break;
|
||||
}
|
||||
|
||||
Debug.Log("Extracted bakery-rtpreview-csharp");
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Log("Done");
|
||||
|
||||
progressFunc = null;
|
||||
Repaint();
|
||||
|
||||
if (anythingDownloaded) EditorUtility.DisplayDialog("Bakery", "Restart Editor to apply the patch", "OK");
|
||||
}
|
||||
|
||||
void CheckUpdate()
|
||||
{
|
||||
if (!progressFunc.MoveNext())
|
||||
{
|
||||
EditorApplication.update -= CheckUpdate;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGUI()
|
||||
{
|
||||
if (!init)
|
||||
{
|
||||
if (PlayerPrefs.HasKey("BakeryInvLM")) inLM = PlayerPrefs.GetString("BakeryInvLM");
|
||||
if (PlayerPrefs.HasKey("BakeryInvRT")) inRT = PlayerPrefs.GetString("BakeryInvRT");
|
||||
if (PlayerPrefs.HasKey("BakeryGHUsername")) username = PlayerPrefs.GetString("BakeryGHUsername");
|
||||
init = true;
|
||||
}
|
||||
|
||||
int y = 10;
|
||||
|
||||
if (progressFunc != null) GUI.enabled = false;
|
||||
|
||||
GUI.Label(new Rect(5, y, 130, 18), "Lightmapper invoice:");
|
||||
var prev = inLM;
|
||||
inLM = EditorGUI.TextField(new Rect(140, y, 170, 18), inLM);
|
||||
if (inLM != prev && (inLM.Length == 14 || inLM.Length == 0 || inLM.Length == 20)) // 14 is invoice, 20 is HB code
|
||||
{
|
||||
PlayerPrefs.SetString("BakeryInvLM", inLM);
|
||||
}
|
||||
y += 18;
|
||||
|
||||
GUI.Label(new Rect(5, y, 120, 18), "RTPreview invoice:");
|
||||
prev = inRT;
|
||||
inRT = EditorGUI.TextField(new Rect(140, y, 170, 18), inRT);
|
||||
if (inRT != prev && (inRT.Length == 14 || inRT.Length == 0))
|
||||
{
|
||||
PlayerPrefs.SetString("BakeryInvRT", inRT);
|
||||
}
|
||||
y += 18;
|
||||
|
||||
GUI.Label(new Rect(5, y, 130, 18), "GitHub username:");
|
||||
prev = username;
|
||||
username = EditorGUI.TextField(new Rect(140, y, 170, 18), username);
|
||||
if (username != prev && username.Length <= 255)
|
||||
{
|
||||
PlayerPrefs.SetString("BakeryGHUsername", username);
|
||||
}
|
||||
y += 18*2;
|
||||
|
||||
if (GUI.Button(new Rect(0, y, 320, 18), "Check"))
|
||||
{
|
||||
SessionState.SetBool("BakeryPatchWaitForRestart", true);
|
||||
progressFunc = CheckProc();
|
||||
EditorApplication.update += CheckUpdate;
|
||||
}
|
||||
y += 20;
|
||||
|
||||
GUI.enabled = true;
|
||||
|
||||
minSize = new Vector2(320, isError ? 160 : (progressFunc == null ? 110 : 160));
|
||||
|
||||
if (progressFunc != null)
|
||||
{
|
||||
GUI.Label(new Rect(0, y, 320, 24), curItem);
|
||||
y += 24;
|
||||
EditorGUI.ProgressBar(new Rect(0, y, 320, 24), progress, progress > 0 ? ("Downloading: " + (int)(progress * 100) + "%") : "Waiting for server...");
|
||||
}
|
||||
else if (isError)
|
||||
{
|
||||
EditorGUI.HelpBox(new Rect(0, y, 320, 40), errMsg, MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private static void Copy(string srcFolder, string destFolder)
|
||||
{
|
||||
var dir = new DirectoryInfo(srcFolder);
|
||||
if (!dir.Exists)
|
||||
{
|
||||
Debug.LogError("Can't find " + srcFolder);
|
||||
return;
|
||||
}
|
||||
|
||||
Directory.CreateDirectory(destFolder);
|
||||
|
||||
var files = dir.GetFiles();
|
||||
foreach (FileInfo file in files)
|
||||
{
|
||||
string tempPath = Path.Combine(destFolder, file.Name);
|
||||
file.CopyTo(tempPath, true);
|
||||
}
|
||||
|
||||
var dirs = dir.GetDirectories();
|
||||
foreach (DirectoryInfo subdir in dirs)
|
||||
{
|
||||
string tempPath = Path.Combine(destFolder, subdir.Name);
|
||||
Copy(subdir.FullName, tempPath);
|
||||
|
||||
Debug.Log("Copying " + tempPath);
|
||||
}
|
||||
}
|
||||
|
||||
static void PatchAsk()
|
||||
{
|
||||
EditorApplication.update -= PatchAsk;
|
||||
|
||||
if (Application.isPlaying) return;
|
||||
|
||||
// Run only once when opening the editor (not when reloading scripts, changing between modes, etc)
|
||||
if (SessionState.GetBool("BakeryPatchWaitForRestart", false)) return;
|
||||
|
||||
var cachePath = Directory.GetCurrentDirectory() + "/BakeryPatchCache";
|
||||
|
||||
if (EditorUtility.DisplayDialog("Bakery", "Bakery patch was downloaded. Apply patch?", "Yes", "No"))
|
||||
{
|
||||
Copy(cachePath + "/Runtime", ftLightmaps.GetRuntimePath());
|
||||
Copy(cachePath + "/Editor", ftLightmaps.GetEditorPath());
|
||||
|
||||
// Downloaded version -> current version
|
||||
if (File.Exists("bakery-csharp-dver.txt")) File.Copy("bakery-csharp-dver.txt", "bakery-csharp-cver.txt", true);
|
||||
if (File.Exists("bakery-compiled-dver.txt")) File.Copy("bakery-compiled-dver.txt", "bakery-compiled-cver.txt", true);
|
||||
if (File.Exists("bakery-rtpreview-csharp-dver.txt")) File.Copy("bakery-rtpreview-csharp-dver.txt", "bakery-rtpreview-csharp-cver.txt", true);
|
||||
}
|
||||
|
||||
Directory.Delete(cachePath, true);
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
static ftUpdater()
|
||||
{
|
||||
// Was the patch downloaded?
|
||||
var cachePath = Directory.GetCurrentDirectory() + "/BakeryPatchCache";
|
||||
if (!Directory.Exists(cachePath)) return;
|
||||
|
||||
// Can't call everything in the constructor, continue there
|
||||
EditorApplication.update += PatchAsk;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
12
Assets/Editor/x64/Bakery/scripts/ftUpdater.cs.meta
Normal file
12
Assets/Editor/x64/Bakery/scripts/ftUpdater.cs.meta
Normal file
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7150afb8f1312c144ab37ad7b22c6e7a
|
||||
timeCreated: 1618931374
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
230
Assets/Editor/x64/Bakery/scripts/ftVolumeInspector.cs
Normal file
230
Assets/Editor/x64/Bakery/scripts/ftVolumeInspector.cs
Normal file
|
@ -0,0 +1,230 @@
|
|||
// Disable 'obsolete' warnings
|
||||
#pragma warning disable 0618
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
#endif
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[CustomEditor(typeof(BakeryVolume))]
|
||||
public class BakeryVolumeInspector : Editor
|
||||
{
|
||||
BoxBoundsHandle boundsHandle = new BoxBoundsHandle(typeof(BakeryVolumeInspector).GetHashCode());
|
||||
|
||||
SerializedProperty ftraceAdaptiveRes, ftraceResX, ftraceResY, ftraceResZ, ftraceVoxelsPerUnit, ftraceAdjustSamples, ftraceEnableBaking, ftraceEncoding, ftraceShadowmaskEncoding, ftraceShadowmaskFirstLightIsAlwaysAlpha, ftraceDenoise, ftraceGlobal, ftraceRotation;
|
||||
|
||||
bool showExperimental = false;
|
||||
|
||||
ftLightmapsStorage storage;
|
||||
|
||||
static BakeryProjectSettings pstorage;
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
ftraceAdaptiveRes = serializedObject.FindProperty("adaptiveRes");
|
||||
ftraceVoxelsPerUnit = serializedObject.FindProperty("voxelsPerUnit");
|
||||
ftraceResX = serializedObject.FindProperty("resolutionX");
|
||||
ftraceResY = serializedObject.FindProperty("resolutionY");
|
||||
ftraceResZ = serializedObject.FindProperty("resolutionZ");
|
||||
ftraceEnableBaking = serializedObject.FindProperty("enableBaking");
|
||||
ftraceEncoding = serializedObject.FindProperty("encoding");
|
||||
ftraceShadowmaskEncoding = serializedObject.FindProperty("shadowmaskEncoding");
|
||||
ftraceShadowmaskFirstLightIsAlwaysAlpha = serializedObject.FindProperty("firstLightIsAlwaysAlpha");
|
||||
ftraceDenoise = serializedObject.FindProperty("denoise");
|
||||
ftraceGlobal = serializedObject.FindProperty("isGlobal");
|
||||
ftraceRotation = serializedObject.FindProperty("supportRotationAfterBake");
|
||||
//ftraceAdjustSamples = serializedObject.FindProperty("adjustSamples");
|
||||
}
|
||||
|
||||
string F(float f)
|
||||
{
|
||||
// Unity keeps using comma for float printing on some systems since ~2018, even if system-wide decimal symbol is "."
|
||||
return (f + "").Replace(",", ".");
|
||||
}
|
||||
|
||||
string FormatSize(int b)
|
||||
{
|
||||
float mb = b / (float)(1024*1024);
|
||||
return mb.ToString("0.0");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
var vol = target as BakeryVolume;
|
||||
|
||||
if (pstorage == null) pstorage = ftLightmaps.GetProjectSettings();
|
||||
|
||||
EditorGUILayout.PropertyField(ftraceEnableBaking, new GUIContent("Enable baking", "Should the volume be (re)computed? Disable to prevent overwriting existing data."));
|
||||
bool wasGlobal = ftraceGlobal.boolValue;
|
||||
EditorGUILayout.PropertyField(ftraceGlobal, new GUIContent("Global", "Automatically assign this volume to all volume-compatible shaders, unless they have overrides."));
|
||||
if (!wasGlobal && ftraceGlobal.boolValue)
|
||||
{
|
||||
(target as BakeryVolume).SetGlobalParams();
|
||||
}
|
||||
EditorGUILayout.PropertyField(ftraceDenoise, new GUIContent("Denoise", "Apply denoising after baking the volume."));
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUILayout.PropertyField(ftraceAdaptiveRes, new GUIContent("Adaptive resolution", "Calculate voxel resolution based on size?"));
|
||||
if (ftraceAdaptiveRes.boolValue)
|
||||
{
|
||||
EditorGUILayout.PropertyField(ftraceVoxelsPerUnit, new GUIContent("Voxels per unit"));
|
||||
|
||||
GUI.enabled = false;
|
||||
var size = vol.bounds.size;
|
||||
ftraceResX.intValue = System.Math.Max((int)(size.x * vol.voxelsPerUnit), 1);
|
||||
ftraceResY.intValue = System.Math.Max((int)(size.y * vol.voxelsPerUnit), 1);
|
||||
ftraceResZ.intValue = System.Math.Max((int)(size.z * vol.voxelsPerUnit), 1);
|
||||
}
|
||||
EditorGUILayout.PropertyField(ftraceResX, new GUIContent("Resolution X"));
|
||||
EditorGUILayout.PropertyField(ftraceResY, new GUIContent("Resolution Y"));
|
||||
EditorGUILayout.PropertyField(ftraceResZ, new GUIContent("Resolution Z"));
|
||||
if (ftraceResX.intValue < 1) ftraceResX.intValue = 1;
|
||||
if (ftraceResY.intValue < 1) ftraceResY.intValue = 1;
|
||||
if (ftraceResZ.intValue < 1) ftraceResZ.intValue = 1;
|
||||
GUI.enabled = true;
|
||||
|
||||
EditorGUILayout.Space();
|
||||
if (storage == null) storage = ftRenderLightmap.FindRenderSettingsStorage();
|
||||
var rmode = storage.renderSettingsUserRenderMode;
|
||||
int sizeX = ftRenderLightmap.VolumeDimension(ftraceResX.intValue);
|
||||
int sizeY = ftRenderLightmap.VolumeDimension(ftraceResY.intValue);
|
||||
int sizeZ = ftRenderLightmap.VolumeDimension(ftraceResZ.intValue);
|
||||
int vSize = 0;
|
||||
if (storage.renderSettingsCompressVolumes)
|
||||
{
|
||||
const int blockDimension = 4;
|
||||
const int blockByteSize = 16; // both BC6H and BC7
|
||||
int numBlocks = (sizeX/blockDimension) * (sizeY/blockDimension);
|
||||
vSize = numBlocks * blockByteSize * sizeZ * 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
vSize = sizeX*sizeY*sizeZ*8*3;
|
||||
}
|
||||
string note = "VRAM: " + FormatSize(vSize) + " MB " + (storage.renderSettingsCompressVolumes ? "(compressed color)" : "(color)");
|
||||
if (rmode == (int)ftRenderLightmap.RenderMode.Shadowmask || pstorage.volumeRenderMode == (int)BakeryLightmapGroup.RenderMode.Shadowmask)
|
||||
{
|
||||
note += ", " + FormatSize(sizeX*sizeY*sizeZ * (ftraceShadowmaskEncoding.intValue == 0 ? 4 : 1)) + " MB (mask)";
|
||||
}
|
||||
EditorGUILayout.LabelField(note);
|
||||
|
||||
//EditorGUILayout.PropertyField(ftraceAdjustSamples, new GUIContent("Adjust sample positions", "Fixes light leaking from inside surfaces"));
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
showExperimental = EditorGUILayout.Foldout(showExperimental, "Experimental", EditorStyles.foldout);
|
||||
if (showExperimental)
|
||||
{
|
||||
EditorGUILayout.PropertyField(ftraceEncoding, new GUIContent("Encoding"));
|
||||
EditorGUILayout.PropertyField(ftraceShadowmaskEncoding, new GUIContent("Shadowmask Encoding"));
|
||||
EditorGUILayout.PropertyField(ftraceShadowmaskFirstLightIsAlwaysAlpha, new GUIContent("First light uses Alpha", "In RGBA8 mode, the first light will always be in the alpha channel. This is useful when unifying RGBA8 and A8 volumes, as the main/first light is always in the same channel."));
|
||||
|
||||
bool wasSet = ftraceRotation.boolValue;
|
||||
EditorGUILayout.PropertyField(ftraceRotation, new GUIContent("Support rotation after bake", "Normally volumes can only be repositioned or rescaled at runtime. With this checkbox volume's rotation matrix will also be sent to shaders. Shaders must have a similar checkbox enabled."));
|
||||
if (wasSet != ftraceRotation.boolValue)
|
||||
{
|
||||
(target as BakeryVolume).SetGlobalParams();
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
if (vol.bakedTexture0 == null)
|
||||
{
|
||||
EditorGUILayout.LabelField("Baked texture: none");
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.LabelField("Baked texture: " + vol.bakedTexture0.name);
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
var wrapObj = EditorGUILayout.ObjectField("Wrap to object", null, typeof(GameObject), true) as GameObject;
|
||||
if (wrapObj != null)
|
||||
{
|
||||
var mrs = wrapObj.GetComponentsInChildren<MeshRenderer>() as MeshRenderer[];
|
||||
if (mrs.Length > 0)
|
||||
{
|
||||
var b = mrs[0].bounds;
|
||||
for(int i=1; i<mrs.Length; i++)
|
||||
{
|
||||
b.Encapsulate(mrs[i].bounds);
|
||||
}
|
||||
Undo.RecordObject(vol, "Change Bounds");
|
||||
Undo.RecordObject(vol.transform, "Change Bounds");
|
||||
vol.transform.position = b.center;
|
||||
vol.bounds = b;
|
||||
Debug.Log("Bounds set");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("No mesh renderers to wrap to");
|
||||
}
|
||||
}
|
||||
|
||||
var boxCol = vol.GetComponent<BoxCollider>();
|
||||
if (boxCol != null)
|
||||
{
|
||||
if (GUILayout.Button("Set from box collider"))
|
||||
{
|
||||
Undo.RecordObject(vol, "Change Bounds");
|
||||
vol.bounds = boxCol.bounds;
|
||||
}
|
||||
if (GUILayout.Button("Set to box collider"))
|
||||
{
|
||||
boxCol.center = Vector3.zero;
|
||||
boxCol.size = vol.bounds.size;
|
||||
}
|
||||
}
|
||||
|
||||
var bmin = vol.bounds.min;
|
||||
var bmax = vol.bounds.max;
|
||||
var bsize = vol.bounds.size;
|
||||
EditorGUILayout.LabelField("Min: " + bmin.x+", "+bmin.y+", "+bmin.z);
|
||||
EditorGUILayout.LabelField("Max: " + bmax.x+", "+bmax.y+", "+bmax.z);
|
||||
|
||||
if (GUILayout.Button("Copy bounds to clipboard"))
|
||||
{
|
||||
GUIUtility.systemCopyBuffer = "float3 bmin = float3(" + F(bmin.x)+", "+F(bmin.y)+", "+F(bmin.z) + "); float3 bmax = float3(" + F(bmax.x)+", "+F(bmax.y)+", "+F(bmax.z) + "); float3 binvsize = float3(" + F(1.0f/bsize.x)+", "+F(1.0f/bsize.y)+", "+F(1.0f/bsize.z) + ");";
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
protected virtual void OnSceneGUI()
|
||||
{
|
||||
var vol = (BakeryVolume)target;
|
||||
|
||||
boundsHandle.center = vol.transform.position;
|
||||
boundsHandle.size = vol.bounds.size;
|
||||
Handles.zTest = UnityEngine.Rendering.CompareFunction.Less;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
boundsHandle.DrawHandle();
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(vol, "Change Bounds");
|
||||
Undo.RecordObject(vol.transform, "Change Bounds");
|
||||
|
||||
Bounds newBounds = new Bounds();
|
||||
newBounds.center = boundsHandle.center;
|
||||
newBounds.size = boundsHandle.size;
|
||||
vol.bounds = newBounds;
|
||||
vol.transform.position = boundsHandle.center;
|
||||
}
|
||||
else if ((vol.bounds.center - boundsHandle.center).sqrMagnitude > 0.0001f)
|
||||
{
|
||||
Bounds newBounds = new Bounds();
|
||||
newBounds.center = boundsHandle.center;
|
||||
newBounds.size = boundsHandle.size;
|
||||
vol.bounds = newBounds;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
12
Assets/Editor/x64/Bakery/scripts/ftVolumeInspector.cs.meta
Normal file
12
Assets/Editor/x64/Bakery/scripts/ftVolumeInspector.cs.meta
Normal file
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 96725c7b01d15304c92894c9b78b76d4
|
||||
timeCreated: 1608652614
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Editor/x64/Bakery/scripts/xatlas.meta
Normal file
8
Assets/Editor/x64/Bakery/scripts/xatlas.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e39dd17a9fe5b0c4ea700f9357627326
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
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.
|
||||
© 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 blockAlign);//, bool allowRotate);
|
||||
|
||||
[DllImport ("xatlasLib", CallingConvention=CallingConvention.Cdecl)]
|
||||
public static extern void xatlasNormalize(System.IntPtr atlas, int[] atlasSizes, bool preferDensity);
|
||||
|
||||
[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);//, 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, false);
|
||||
|
||||
// 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
(Stored with Git LFS)
Normal file
BIN
Assets/Editor/x64/Bakery/scripts/xatlas/xatlasLib.dll
(Stored with Git 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:
|
Loading…
Add table
Add a link
Reference in a new issue