gi stuff, static batching toggle
This commit is contained in:
@@ -107,6 +107,7 @@
|
||||
"ID": "56eddcef4698702bd3cb0b8a1fb3396f",
|
||||
"TypeName": "FlaxEngine.EmptyActor",
|
||||
"ParentID": "a50f3639419a8306036ecfab7115e772",
|
||||
"IsActive": false,
|
||||
"Name": "ViewModelHolder",
|
||||
"Transform": {
|
||||
"Translation": {
|
||||
@@ -215,6 +216,7 @@
|
||||
"ID": "12cd95b64f5145dcae7b28b7404ef512",
|
||||
"TypeName": "FlaxEngine.StaticModel",
|
||||
"ParentID": "a50f3639419a8306036ecfab7115e772",
|
||||
"IsActive": false,
|
||||
"Name": "PlayerModel",
|
||||
"Transform": {
|
||||
"Scale": {
|
||||
@@ -225,6 +227,7 @@
|
||||
},
|
||||
"StaticFlags": 0,
|
||||
"Model": "b43f0f8f4aaba3f3156896a5a22ba493",
|
||||
"DrawModes": 31,
|
||||
"Buffer": {
|
||||
"Entries": [
|
||||
{
|
||||
|
||||
Binary file not shown.
@@ -6,7 +6,7 @@
|
||||
"UseVSync": false,
|
||||
"AAQuality": 3,
|
||||
"SSRQuality": 3,
|
||||
"SSAOQuality": 3,
|
||||
"SSAOQuality": 0,
|
||||
"VolumetricFogQuality": 3,
|
||||
"ShadowsQuality": 3,
|
||||
"ShadowMapsQuality": 3,
|
||||
@@ -15,6 +15,7 @@
|
||||
"GlobalSDFQuality": 2,
|
||||
"GenerateSDFOnModelImport": true,
|
||||
"GIQuality": 2,
|
||||
"GIProbesSpacing": 300.0,
|
||||
"GlobalSurfaceAtlasResolution": 2048,
|
||||
"PostProcessSettings": {
|
||||
"AO": {
|
||||
@@ -27,11 +28,12 @@
|
||||
"FadeDistance": 500.0
|
||||
},
|
||||
"GI": {
|
||||
"OverrideFlags": 27,
|
||||
"OverrideFlags": 63,
|
||||
"Mode": 1,
|
||||
"Intensity": 1.0,
|
||||
"TemporalResponse": 0.9,
|
||||
"Distance": 7000.0,
|
||||
"BounceIntensity": 2.0,
|
||||
"TemporalResponse": 1.0,
|
||||
"Distance": 20000.0,
|
||||
"FallbackIrradiance": {
|
||||
"R": 1.0,
|
||||
"G": 0.0,
|
||||
|
||||
@@ -282,6 +282,96 @@ namespace Game
|
||||
}
|
||||
}
|
||||
|
||||
[ConsoleVariable("r_gi_bounce")]
|
||||
public static string GlobalIlluminationBounce
|
||||
{
|
||||
get
|
||||
{
|
||||
return Graphics.PostProcessSettings.GlobalIllumination.BounceIntensity.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
if (float.TryParse(value, out float valueFloat))
|
||||
{
|
||||
valueFloat = Mathf.Clamp(valueFloat, 0.0f, 999.0f);
|
||||
|
||||
PostProcessSettings postProcessSettings = Graphics.PostProcessSettings;
|
||||
|
||||
GlobalIlluminationSettings giSettings = postProcessSettings.GlobalIllumination;
|
||||
giSettings.BounceIntensity = valueFloat;
|
||||
postProcessSettings.GlobalIllumination = giSettings;
|
||||
|
||||
Graphics.PostProcessSettings = postProcessSettings;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ConsoleVariable("r_gi_spacing")]
|
||||
public static string GlobalIlluminationProbeSpacing
|
||||
{
|
||||
get
|
||||
{
|
||||
return Graphics.GIProbesSpacing.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
if (float.TryParse(value, out float valueFloat))
|
||||
{
|
||||
valueFloat = Mathf.Clamp(valueFloat, 0.0f, 999.0f);
|
||||
|
||||
Graphics.GIProbesSpacing = valueFloat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ConsoleVariable("r_gi_time")]
|
||||
public static string GlobalIlluminationTime
|
||||
{
|
||||
get
|
||||
{
|
||||
return Graphics.PostProcessSettings.GlobalIllumination.TemporalResponse.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
if (float.TryParse(value, out float valueFloat))
|
||||
{
|
||||
valueFloat = Mathf.Clamp(valueFloat, 0.0f, 10.0f);
|
||||
|
||||
PostProcessSettings postProcessSettings = Graphics.PostProcessSettings;
|
||||
|
||||
GlobalIlluminationSettings giSettings = postProcessSettings.GlobalIllumination;
|
||||
giSettings.TemporalResponse = valueFloat;
|
||||
postProcessSettings.GlobalIllumination = giSettings;
|
||||
|
||||
Graphics.PostProcessSettings = postProcessSettings;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ConsoleVariable("r_gi_distance")]
|
||||
public static string GlobalIlluminationDistance
|
||||
{
|
||||
get
|
||||
{
|
||||
return Graphics.PostProcessSettings.GlobalIllumination.Distance.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
if (float.TryParse(value, out float valueFloat))
|
||||
{
|
||||
valueFloat = Mathf.Clamp(valueFloat, 0.0f, 10000000.0f);
|
||||
|
||||
PostProcessSettings postProcessSettings = Graphics.PostProcessSettings;
|
||||
|
||||
GlobalIlluminationSettings giSettings = postProcessSettings.GlobalIllumination;
|
||||
giSettings.Distance = valueFloat;
|
||||
postProcessSettings.GlobalIllumination = giSettings;
|
||||
|
||||
Graphics.PostProcessSettings = postProcessSettings;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ConsoleVariable("r_shadows")]
|
||||
public static string SceneShadows
|
||||
{
|
||||
|
||||
@@ -7,6 +7,13 @@ namespace Game
|
||||
[ExecuteInEditMode]
|
||||
public class LevelScript : Script
|
||||
{
|
||||
public string MapName;
|
||||
public DateTime MapTimestamp;
|
||||
}
|
||||
|
||||
public class LevelScript2 : Script
|
||||
{
|
||||
public string MapName;
|
||||
public DateTime MapTimestamp;
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
@@ -63,7 +63,8 @@ namespace Game
|
||||
if (playerId == NetworkManager.LocalPlayerClientId)
|
||||
{
|
||||
FindActor("CameraHolder").IsActive = true;
|
||||
FindActor("ViewModelHolder").IsActive = true;
|
||||
//FindActor("ViewModelHolder").IsActive = true;
|
||||
FindActor("PlayerModel").IsActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,9 @@ namespace Game
|
||||
public static string DemoPath { get; private set; } =
|
||||
Path.Combine(Directory.GetCurrentDirectory(), "Demos");
|
||||
|
||||
public static string CachePath { get; private set; } =
|
||||
Path.Combine(Directory.GetCurrentDirectory(), "Cache");
|
||||
|
||||
public static GameplayGlobals Globals { get; private set; }
|
||||
public static Config Config { get; private set; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user