From 91df324cf1b52472228325caf2959ef12db97d79 Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Tue, 28 Jun 2022 19:45:39 +0300 Subject: [PATCH] parse spotlights in map files, fix reset lights and sdf generation --- Source/Game/Level/Q3MapImporter.cs | 132 +++++++++++++++++++++++------ 1 file changed, 104 insertions(+), 28 deletions(-) diff --git a/Source/Game/Level/Q3MapImporter.cs b/Source/Game/Level/Q3MapImporter.cs index fc381e6..a87e092 100644 --- a/Source/Game/Level/Q3MapImporter.cs +++ b/Source/Game/Level/Q3MapImporter.cs @@ -9,7 +9,9 @@ using System.Threading.Tasks; using FlaxEditor; using FlaxEngine; using FlaxEngine.Assertions; +using FlaxEngine.GUI; using Console = Game.Console; +using Debug = FlaxEngine.Debug; namespace Game { @@ -284,6 +286,7 @@ namespace Game LoadMap(false); } + private List brushGeometries; private bool lastSceneLighting = false; private bool lastSceneShadows = false; public override void OnUpdate() @@ -303,8 +306,12 @@ namespace Game if (resetLights) { + Debug.Log("reset lights"); if (worldSpawnActor == null || !worldSpawnActor || root == null) + { + Debug.Log("worldspawn or root is null"); return; + } foreach (var light in worldSpawnActor.GetChildren()) Destroy(light); @@ -340,6 +347,12 @@ namespace Game private void LoadMap(bool forceLoad) { + Stopwatch sw = Stopwatch.StartNew(); + byte[] mapChars = File.ReadAllBytes(mapPath); + root = MapParser.Parse(mapChars); + sw.Stop(); + //Console.Print("Map parsing time: " + sw.Elapsed.TotalMilliseconds + "ms"); + worldSpawnActor = Actor.FindActor("WorldSpawn"); LevelScript levelScript = worldSpawnActor?.GetScript(); if (worldSpawnActor != null) @@ -357,16 +370,15 @@ namespace Game worldSpawnActor.DestroyChildren(); else { - FlaxEngine.Debug.Log("Map already loaded in the scene"); + //FlaxEngine.Debug.Log("Map already loaded in the scene"); resetLights = false; return; } } - else - FlaxEngine.Debug.Log("No WorldSpawn, loading map"); + //else + // FlaxEngine.Debug.Log("No WorldSpawn, loading map"); FlaxEngine.Debug.Log("Loading map"); - { string matBasePath = Path.Combine(AssetManager.ContentPath, "Materials"); string assetPath = Path.Combine(matBasePath, "missing.flax"); @@ -375,15 +387,8 @@ namespace Game ConcurrentBag sdfModels = new ConcurrentBag(); - Stopwatch sw = Stopwatch.StartNew(); - byte[] mapChars = File.ReadAllBytes(mapPath); - root = MapParser.Parse(mapChars); - sw.Stop(); - - //Console.Print("Map parsing time: " + sw.Elapsed.TotalMilliseconds + "ms"); - bool oneMesh = false; - bool useStaticBatching = true; + bool useStaticBatching = false; bool convexMesh = true; if (worldSpawnActor == null) @@ -413,7 +418,7 @@ namespace Game materials.Add(m.name, m.asset); } - var brushGeometries = new List(root.entities[0].brushes.Count); + brushGeometries = new List(root.entities[0].brushes.Count); // pass 1: triangulation sw.Restart(); @@ -1033,7 +1038,8 @@ namespace Game - if (generateSdf && Graphics.EnableGlobalSDF && sdfModels.Count > 1) + //Debug.Log($"generate:{generateSdf}, GI:{Graphics.PostProcessSettings.GlobalIllumination.Mode != GlobalIlluminationMode.None}, {sdfModels.Count}"); + if (generateSdf /*&& Graphics.PostProcessSettings.GlobalIllumination.Mode != GlobalIlluminationMode.None*/ && sdfModels.Count > 1) { var task = Task.Run(() => { @@ -1059,13 +1065,40 @@ namespace Game private void ParseLight(MapEntity entity, ref int lightIndex) { + LightWithShadow light; + Float3? lightTargetPosition = null; + int preset = 3; + if (entity.properties.TryGetValue("target", out string targetName)) + { + var target = root.entities.FirstOrDefault(x => + x.properties.ContainsKey("targetname") && x.properties["targetname"] == targetName); + + if (target != null) + lightTargetPosition = ParseOrigin(target.properties["origin"]); + } + + if (!lightTargetPosition.HasValue) + light = worldSpawnActor.AddChild(); + else + light = worldSpawnActor.AddChild(); + //Console.Print("light"); - PointLight light = worldSpawnActor.AddChild(); - light.Name = "Light_" + lightIndex; + //PointLight light = worldSpawnActor.AddChild(); + //LightWithShadow light = new PointLight(); + var pointLight = light as PointLight; + var spotLight = light as SpotLight; + + if (spotLight != null) + light.Name = "SpotLight_" + lightIndex; + else + light.Name = "Light_" + lightIndex; light.LocalPosition = ParseOrigin(entity.properties["origin"]); + if (lightTargetPosition.HasValue) + light.Orientation = Quaternion.LookAt(light.LocalPosition, lightTargetPosition.Value); + if (entity.properties.TryGetValue("_color", out string colorStr)) light.Color = ParseColor(colorStr); @@ -1077,23 +1110,44 @@ namespace Game if (entity.properties.TryGetValue("radius", out string radStr)) radamm = float.Parse(radStr); + bool castShadows = true; + if (entity.properties.TryGetValue("castshadows", out string castShadowsStr)) + castShadows = int.Parse(castShadowsStr) != 0; light.Layer = 1; - light.UseInverseSquaredFalloff = false; - light.FallOffExponent = 8; + if (pointLight != null) + { + pointLight.UseInverseSquaredFalloff = false; + pointLight.FallOffExponent = 8; + pointLight.ShadowsStrength = castShadows ? 1.0f : 0.0f; + } + if (spotLight != null) + { + spotLight.UseInverseSquaredFalloff = false; + spotLight.FallOffExponent = 8; + spotLight.ShadowsStrength = castShadows ? 1.0f : 0.0f; + spotLight.InnerConeAngle = 65f; + spotLight.OuterConeAngle = 80f; + } + light.ShadowsDistance = 500f; light.ShadowsDepthBias = 0.027f;//0.005f; if (preset == 0) // most accurate?, huge radius and low performance { light.Brightness = lightamm / 93f; - light.Radius = radamm * 12.5f; - light.FallOffExponent = 3.33f; + light.ShadowsDepthBias = 0.0565f; light.Brightness *= 0.7837f; - light.Radius *= 0.83375f; + + if (pointLight != null) + { + pointLight.Radius = radamm * 12.5f; + pointLight.FallOffExponent = 3.33f; + pointLight.Radius *= 0.83375f; + } var hsv = light.Color.ToHSV(); hsv.Y *= 0.8f; @@ -1101,20 +1155,37 @@ namespace Game } else if (preset == 1) // { - light.Radius = 250f; - light.FallOffExponent = 2f; + if (pointLight != null) + { + pointLight.Radius = 250f; + pointLight.FallOffExponent = 2f; + } + light.Brightness = (lightamm / 128f) * 1.25f; } else if (preset == 2) { - light.Radius = 200f; - light.FallOffExponent = 2f; + if (pointLight != null) + { + pointLight.Radius = 200f; + pointLight.FallOffExponent = 2f; + } + light.Brightness = (lightamm / 128f) * 1.6f; } else //if (preset == 3) { - light.Radius = radamm * LightRadiusMultiplier; - light.FallOffExponent = FallOffExponent; + if (pointLight != null) + { + pointLight.Radius = radamm * LightRadiusMultiplier; + pointLight.FallOffExponent = FallOffExponent; + } + if (spotLight != null) + { + spotLight.Radius = radamm * LightRadiusMultiplier; + spotLight.FallOffExponent = FallOffExponent; + } + light.Brightness = (lightamm / 128f) * BrightnessMultiplier; light.ShadowsNormalOffsetScale = 10f; @@ -1130,8 +1201,13 @@ namespace Game light.ShadowsDepthBias = 0.0565f; // if low quality shadows - light.ShadowsDepthBias = 0.2492f; + //light.ShadowsDepthBias = 0.2492f; + if (spotLight != null) + { + // huge aliasing with spot lights for some reason? + light.ShadowsDepthBias = 0.7f; + } } lightIndex++;