gi stuff, static batching toggle

This commit is contained in:
2022-07-03 22:07:36 +03:00
parent 9cc8e81b33
commit 5805529ba8
8 changed files with 220 additions and 33 deletions

View File

@@ -4,6 +4,9 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using FlaxEditor;
@@ -61,6 +64,7 @@ namespace Game
private float indirectLightMultiplier_ = 1.0f;
private List<MapEntity> lightEnts = new List<MapEntity>();
private Actor worldSpawnActor = null;
private bool staticBatching_ = false;
[Range(0.1f, 4f)]
public float BrightnessMultiplier
@@ -97,6 +101,20 @@ namespace Game
set { indirectLightMultiplier_ = value; resetLights = true; }
}
public bool StaticBatching
{
get => staticBatching_;
set
{
if (staticBatching_ == value)
return;
staticBatching_ = value;
FlaxEngine.Debug.Log("StaticBatching changed, reloading map");
LoadMap(true);
}
}
private static void QuickHull(Float3[] points, out Float3[] outVertices)
{
@@ -345,6 +363,21 @@ namespace Game
}
}
private static bool IsMapDirty(Actor worldSpawnActor, string mapPath)
{
#if FLAX_EDITOR
LevelScript levelScript = worldSpawnActor.GetScript<LevelScript>();
if (levelScript.MapName != mapPath)
return true;
DateTime timestamp = File.GetLastWriteTime(mapPath);
if (timestamp != levelScript.MapTimestamp)
return true;
#endif
return false;
}
private void LoadMap(bool forceLoad)
{
Stopwatch sw = Stopwatch.StartNew();
@@ -354,26 +387,14 @@ namespace Game
//Console.Print("Map parsing time: " + sw.Elapsed.TotalMilliseconds + "ms");
worldSpawnActor = Actor.FindActor("WorldSpawn");
LevelScript levelScript = worldSpawnActor?.GetScript<LevelScript>();
if (worldSpawnActor != null)
{
#if FLAX_EDITOR
DateTime timestamp = File.GetLastWriteTime(mapPath);
if (timestamp != levelScript.MapTimestamp)
{
FlaxEngine.Debug.Log($"Map dirty, reloading. {timestamp.ToString()} != {levelScript.MapTimestamp.ToString()}");
forceLoad = true;
levelScript.MapTimestamp = timestamp;
}
#endif
if (forceLoad)
worldSpawnActor.DestroyChildren();
else
{
//FlaxEngine.Debug.Log("Map already loaded in the scene");
resetLights = false;
if (!forceLoad && !IsMapDirty(worldSpawnActor, mapPath))
return;
}
FlaxEngine.Debug.Log($"Map dirty, reloading.");
worldSpawnActor.DestroyChildren();
resetLights = false;
}
//else
// FlaxEngine.Debug.Log("No WorldSpawn, loading map");
@@ -388,24 +409,25 @@ namespace Game
ConcurrentBag<Model> sdfModels = new ConcurrentBag<Model>();
bool oneMesh = false;
bool useStaticBatching = false;
bool useStaticBatching = StaticBatching;
bool convexMesh = true;
if (worldSpawnActor == null)
{
worldSpawnActor = Actor.AddChild<Actor>();
worldSpawnActor.Name = "WorldSpawn";
levelScript = worldSpawnActor.AddScript<LevelScript>();
#if FLAX_EDITOR
levelScript.MapTimestamp = File.GetLastWriteTime(mapPath);
#endif
worldSpawnActor.HideFlags &= ~HideFlags.DontSave;
//worldSpawnActor.HideFlags |= HideFlags.DontSave;
//worldSpawnActor.HideFlags |= HideFlags.DontSelect;
}
else
levelScript = worldSpawnActor.GetScript<LevelScript>();
LevelScript levelScript =
worldSpawnActor.GetScript<LevelScript>() ?? worldSpawnActor.AddScript<LevelScript>();
#if FLAX_EDITOR
levelScript.MapTimestamp = File.GetLastWriteTime(mapPath);
levelScript.MapName = mapPath;
#endif
if (!oneMesh)
{
@@ -1041,6 +1063,45 @@ namespace Game
//Debug.Log($"generate:{generateSdf}, GI:{Graphics.PostProcessSettings.GlobalIllumination.Mode != GlobalIlluminationMode.None}, {sdfModels.Count}");
if (generateSdf /*&& Graphics.PostProcessSettings.GlobalIllumination.Mode != GlobalIlluminationMode.None*/ && sdfModels.Count > 1)
{
int modelIndex = 0;
// TODO: read sdf data from texture and dump it to file, and reuse it when generating sdf data
using var sha1 = new SHA1Managed();
string mapHash = sha1.ComputeHash(Encoding.UTF8.GetBytes(levelScript.MapName + levelScript.MapTimestamp.Ticks.ToString())).ToString();
foreach (var model in sdfModels.ToList())
{
string sdfDataPath = Path.Combine(AssetManager.CachePath, "MapSdfData",
$"{mapHash}_brush{modelIndex+1}");
/*if (File.Exists(sdfDataPath))
{
sdfModels.TryTake(out var model_);
T RawDeserialize<T>(byte[] rawData, int position)
{
int rawsize = Marshal.SizeOf(typeof(T));
if (rawsize > rawData.Length - position)
throw new ArgumentException("Not enough data to fill struct. Array length from position: " +
(rawData.Length - position) + ", Struct length: " + rawsize);
IntPtr buffer = Marshal.AllocHGlobal(rawsize);
Marshal.Copy(rawData, position, buffer, rawsize);
T retobj = (T)Marshal.PtrToStructure(buffer, typeof(T));
Marshal.FreeHGlobal(buffer);
return retobj;
}
ModelBase.SDFData sdfData = new ModelBase.SDFData();
sdfData.Texture
model.SetSDF(sdfData);
}*/
modelIndex++;
}
var task = Task.Run(() =>
{
Stopwatch sw = Stopwatch.StartNew();
@@ -1048,14 +1109,34 @@ namespace Game
ParallelOptions opts = new ParallelOptions();
FlaxEngine.Debug.Log("processorcount: " + Environment.ProcessorCount);
float backfacesThreshold = 0.15f;
if (useStaticBatching)
opts.MaxDegreeOfParallelism = 2;//Environment.ProcessorCount / 2;
Parallel.ForEach(sdfModels, opts, model =>
{
opts.MaxDegreeOfParallelism = 2; //Environment.ProcessorCount / 2;
//backfacesThreshold = 1f;
}
Parallel.ForEach(sdfModels, opts, (model, _, index) =>
{
if (model.WaitForLoaded())
throw new Exception("model was not loaded");
model.GenerateSDF(0.9f, 6, true, 0.15f);
model.GenerateSDF(0.9f, 6, true, backfacesThreshold);
/*byte[] RawSerialize(object anything)
{
int rawSize = Marshal.SizeOf(anything);
IntPtr buffer = Marshal.AllocHGlobal(rawSize);
Marshal.StructureToPtr(anything, buffer, false);
byte[] rawDatas = new byte[rawSize];
Marshal.Copy(buffer, rawDatas, 0, rawSize);
Marshal.FreeHGlobal(buffer);
return rawDatas;
}
string sdfDataPath = Path.Combine(AssetManager.CachePath, "MapSdfData",
$"{mapHash}_brush{modelIndex+1}");*/
});
FlaxEngine.Debug.Log($"Generated level SDF in {sw.Elapsed.TotalMilliseconds}ms");