champions-of-luneraria/Assets/Luneraria/Editor/World/LuneZones.cs
Martin Stickelbroeck 7fa038a147 U5.2 Stufen: Zielqualität entlang der Lanes, einfachere Randzonen
Entscheidung des Projektinhabers vom 2. Oktober 2026: Weg 2 (Stufen)
statt Gleichziehen oder Drosseln. Der Lankorridor trägt die vollen
PBR-Sätze; Berge, Kluft und ferner Hintergrund behalten Farbe und
Steinschicht.

- LuneZones: Korridor von 22 m um eine Lane-Mittellinie, ein Gebäude
  oder die Grotte. NearLane entscheidet die Stufe eines Weltknotens.
- Surface-Shader _Quality: 1 bindet Albedo, Normal und ORM triplanar;
  0 lässt die neun Map-Samples weg und behält Farbe, Vertex-Tönung,
  Steinschicht und Emission — das U2-Aussehen der Berge.
- LuneMaterialFactory: Spec.Quality, TerrainEdge.mat für die umgebenden
  Berge; Randmaterialien binden keine PBR-Sätze.
- LuneWorldBuilder.ApplyTier: jeder Weltknoten jenseits des Korridors
  bekommt _Quality 0 über einen MaterialPropertyBlock. Gebäude,
  Einheiten, Wege, Wasser und der innere Boden bleiben Lane-Stufe.
- Nachweis: screenshots/u5/edge-mountains.png (Randstufe) und
  lane-and-edge.png (Übergang Lane → Rand in einem Bild).
- Leistung (macOS-Player, 116 Einheiten): 133 fps Übersicht, 180 fps
  Mid nah — auf dem Niveau des Slices, weil die Messfenster den
  Korridor sehen. Die Ersparnis liegt in Weitwinkeln und am Rand.
- Tests: EditMode 29/29, PlayMode 13/13, Kerntests 457/457. Keine
  Regeländerung.
- Dokumentation: U5-VISUAL (Entscheidung und Umsetzung), PORT-QA,
  PORT-STATUS, KNOWN-BEHAVIOR-DIFFERENCES.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 17:45:51 +02:00

61 lines
2.4 KiB
C#

using System;
using Luneraria.Core;
using Luneraria.View;
namespace Luneraria.EditorTools
{
/// <summary>
/// Weg 2 (Stufen) of the U5 map decision (docs/port/U5-VISUAL.md): target quality along the
/// lanes, simpler materials in the edge zones. A point counts as lane tier while it is within
/// LaneCorridor metres of a lane centreline, a building or the grotto — the corridor the
/// players actually look at. Everything beyond (mountains, rim cliffs, far vegetation) gets
/// the edge tier: colour and stone relief, no PBR maps (Surface _Quality 0).
/// </summary>
public static class LuneZones
{
/// <summary>Metres from a lane centreline (or a building) that still count as lane tier.</summary>
public const float LaneCorridor = 22f;
/// <summary>Distance from at to the nearest lane centreline sample.</summary>
public static double DistanceToLanes(LuneMap map, Vec2 at)
{
double best = double.MaxValue;
foreach (string lane in LuneMap.Lanes)
{
LanePath path = map.LanePaths[lane];
for (int i = 0; i < path.Points.Length; i++)
{
float distance = path.Points[i].DistanceTo(at);
if (distance < best)
best = distance;
}
}
return best;
}
/// <summary>True while at is in the target-quality corridor of the slice.</summary>
public static bool NearLane(LuneMap map, Vec2 at)
{
if (DistanceToLanes(map, at) <= LaneCorridor)
return true;
foreach (BuildingDef building in map.Buildings)
{
if (building.Position.DistanceTo(at) <= LaneCorridor)
return true;
}
return map.GrottoCenter().DistanceTo(at) <= LaneCorridor * 1.5;
}
/// <summary>Quality for the Surface shader: 1 lane tier (full PBR), 0 edge tier.</summary>
public static float QualityOf(LuneMap map, Vec2 at)
{
return NearLane(map, at) ? 1f : 0f;
}
/// <summary>Quality of a world-space point (Unity coordinates; x is mirrored).</summary>
public static float QualityOfWorld(LuneMap map, UnityEngine.Vector3 world)
{
return QualityOf(map, LuneSpace.Map(world));
}
}
}