Fortsetzung des angefangenen U5.3-Stands vom 2. Oktober.
- Fünf neue Sätze aus bake_pbr.py (metal, cloth, hide, bone, wood) für
Türme, Ancients, Grotte und die Schlundkrone. Ringborkes Rinde (RB_Bark)
auf ihren eigenen UVs mit dem 4k-Satz (Rauigkeit zu ORM gepackt),
Normalen im Tangentenraum des Meshes. Aufnahmen aller drei Lanes.
- Befund: Seit U5 war die Welt halb so hell und ohne Grün (Mid-Lane
Helligkeit 0,27, Grün 0 %). Ursachen und Korrekturen:
- Die PBR-Albedos wurden über die Godot-Farben multipliziert (Rasen
etwa x0,05). Jetzt teilt der Shader jede Karte durch ihren Mittel-
wert; die Godot-Farbe bleibt der Durchschnitt, die Karte liefert
Struktur. Ebenso die Rauigkeit, wo das Material eine eigene hat.
- Normal- und ORM-Karten waren als sRGB-Farbe importiert. Jetzt
Normalkarte bzw. linear.
- bake_pbr.py verzerrte alle Muster 10:1 (Regenstreifen). Stein, Erde,
Laub, Wasser und die neuen Sätze ohne Maserung neu gebacken.
- Der Treffer-Flash ersetzte die Grundfarbe aller Materialplätze; im
Nahkampf waren die Armeen weiß und der Boss gelb. Jetzt Tönung der
eigenen Farbe je Platz, wenig Emission, 16 Stufen.
- Nebel 0,0085 verschleierte die Kartenansicht zu 35-50 %; jetzt 0,0045.
Ergebnis Mid-Lane: Helligkeit 0,41-0,44, Grün 31-39 % (U3: 0,45 / 27 %).
- Tests: EditMode 29/29, PlayMode 13/13, Verify 718/0, Kerntests .NET
457/457, Fingerabdrücke unverändert (DCE95C96556F3A1A, 7B8E43AEFC0D60C5).
- Leistung: A/B mit einem U5.2-Player unter gleicher Last, kein messbarer
Unterschied (91,4 gegen 93,8 fps Karte, 124,9 gegen 125,3 fps Mid).
- Messwerkzeug tools/port/png_stats.py; Doku U5-VISUAL (U5.3),
PORT-STATUS, PORT-QA; Bilder screenshots/u5.3/ als JPEG.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
152 lines
8.4 KiB
C#
152 lines
8.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using Luneraria.Core;
|
|
using Luneraria.View;
|
|
using UnityEditor;
|
|
using UnityEditor.SceneManagement;
|
|
using UnityEngine;
|
|
|
|
namespace Luneraria.EditorTools
|
|
{
|
|
/// <summary>
|
|
/// Screenshots of the G1 map scene with the camera settings of the Godot G2 captures
|
|
/// (../saumwacht-godot/tools/luneraria/g2_views.gd), so both can be compared side by side:
|
|
/// 15 overview, 01 Blau Ancient, 05 Grenzwacht, 06 Bastion, 07 base towers, 10 grotto.
|
|
/// Unity -batchmode -projectPath . -executeMethod Luneraria.EditorTools.LuneWorldCapture.CaptureAll
|
|
/// </summary>
|
|
public static class LuneWorldCapture
|
|
{
|
|
public const int Width = 1920;
|
|
public const int Height = 1080;
|
|
|
|
struct View
|
|
{
|
|
public string Label;
|
|
public Vec2 At;
|
|
public float Zoom;
|
|
public int YawSteps;
|
|
}
|
|
|
|
public static void CaptureAll()
|
|
{
|
|
int code = 0;
|
|
try
|
|
{
|
|
EditorSceneManager.OpenScene(LuneWorldBuilder.ScenePath, OpenSceneMode.Single);
|
|
var ground = AssetDatabase.LoadAssetAtPath<LuneGround>(LuneWorldBuilder.GroundPath);
|
|
var map = new LuneMap(new LuneBalance());
|
|
Vec2 blue = map.CorePosition(0);
|
|
Vec2 red = map.CorePosition(1);
|
|
Vec2 outer = map.BuildingDef("rot_mid_outer").Position;
|
|
Vec2 inner = map.BuildingDef("rot_mid_inner").Position;
|
|
Vec2 baseA = map.BuildingDef("rot_base_1").Position;
|
|
Vec2 baseB = map.BuildingDef("rot_base_2").Position;
|
|
var views = new List<View>
|
|
{
|
|
new View { Label = "15-gesamtkarte", At = new Vec2(0, 0), Zoom = LuneCameraMath.OverviewZoom },
|
|
new View { Label = "01-ancient-100", At = blue + new Vec2(1.0, -1.0), Zoom = 28f, YawSteps = -1 },
|
|
new View { Label = "05-tower1-grenzwacht", At = outer + new Vec2(0, -2.4), Zoom = 14f },
|
|
new View { Label = "06-tower2-bastion", At = inner + new Vec2(0, -2.8), Zoom = 14f },
|
|
new View { Label = "07-basistuerme", At = (baseA + baseB) * .5 * .5 + red * .5, Zoom = 24f, YawSteps = -1 },
|
|
new View { Label = "10-grotte", At = map.GrottoCenter(), Zoom = 20f },
|
|
};
|
|
string folder = Path.Combine(Path.GetDirectoryName(Application.dataPath), "docs/port/screenshots/u2b");
|
|
Directory.CreateDirectory(folder);
|
|
Camera camera = Camera.main;
|
|
foreach (View view in views)
|
|
{
|
|
// Godot: look_at_point clamps the focus and puts it on the ground under it.
|
|
var focus = new Vec2(Mathf.Clamp((float)view.At.X, -LuneCameraMath.FocusLimit, LuneCameraMath.FocusLimit), Mathf.Clamp((float)view.At.Y, -LuneCameraMath.FocusLimit, LuneCameraMath.FocusLimit));
|
|
Vector3 point = LuneSpace.World(focus, ground.StandHeight(focus));
|
|
LuneCameraMath.Pose(point, view.Zoom, view.YawSteps * Mathf.PI * .25f, out Vector3 position, out Quaternion rotation);
|
|
camera.transform.SetPositionAndRotation(position, rotation);
|
|
Render(camera, Path.Combine(folder, view.Label + ".png"));
|
|
}
|
|
}
|
|
catch (Exception error)
|
|
{
|
|
Debug.LogError("LUNE_CAPTURE failed: " + error);
|
|
code = 1;
|
|
}
|
|
EditorApplication.Exit(code);
|
|
}
|
|
|
|
public static void Render(Camera camera, string file)
|
|
{
|
|
var target = new RenderTexture(Width, Height, 24, RenderTextureFormat.ARGB32) { antiAliasing = 4 };
|
|
camera.aspect = (float)Width / Height;
|
|
camera.targetTexture = target;
|
|
camera.Render();
|
|
RenderTexture.active = target;
|
|
var image = new Texture2D(Width, Height, TextureFormat.RGB24, false);
|
|
image.ReadPixels(new Rect(0, 0, Width, Height), 0, 0);
|
|
image.Apply();
|
|
File.WriteAllBytes(file, image.EncodeToPNG());
|
|
RenderTexture.active = null;
|
|
camera.targetTexture = null;
|
|
UnityEngine.Object.DestroyImmediate(target);
|
|
UnityEngine.Object.DestroyImmediate(image);
|
|
Debug.Log("LUNE_CAPTURE wrote " + file);
|
|
}
|
|
|
|
/// <summary>
|
|
/// U5 vertical slice: the Mid-Lane of the target-quality zone (docs/port/U5-VISUAL.md).
|
|
/// Godot G3 comparison shots live in ../saumwacht-godot/docs/luneraria/screenshots/g3/.
|
|
/// Unity -batchmode -projectPath . -executeMethod Luneraria.EditorTools.LuneWorldCapture.CaptureMidLane
|
|
/// </summary>
|
|
public static void CaptureMidLane()
|
|
{
|
|
int code = 0;
|
|
try
|
|
{
|
|
EditorSceneManager.OpenScene(LuneWorldBuilder.ScenePath, OpenSceneMode.Single);
|
|
var ground = AssetDatabase.LoadAssetAtPath<LuneGround>(LuneWorldBuilder.GroundPath);
|
|
var map = new LuneMap(new LuneBalance());
|
|
Vec2 blue = map.CorePosition(0);
|
|
Vec2 red = map.CorePosition(1);
|
|
Vec2 outer = map.BuildingDef("rot_mid_outer").Position;
|
|
Vec2 inner = map.BuildingDef("rot_mid_inner").Position;
|
|
Vec2 topOuter = map.BuildingDef("rot_top_outer").Position;
|
|
Vec2 topInner = map.BuildingDef("rot_top_inner").Position;
|
|
Vec2 botOuter = map.BuildingDef("rot_bot_outer").Position;
|
|
Vec2 botInner = map.BuildingDef("rot_bot_inner").Position;
|
|
var views = new List<View>
|
|
{
|
|
new View { Label = "mid-lane-overview", At = (outer + inner) * .5, Zoom = 30f },
|
|
new View { Label = "mid-lane-towers", At = outer + new Vec2(0, -2.5), Zoom = 16f },
|
|
new View { Label = "mid-lane-ancient", At = blue + new Vec2(1.5, -2.5), Zoom = 24f, YawSteps = -1 },
|
|
new View { Label = "mid-lane-grotto", At = map.GrottoCenter(), Zoom = 22f },
|
|
new View { Label = "mid-lane-wide", At = (blue + red) * .5, Zoom = 48f, YawSteps = -1 },
|
|
// U5.3: the other two lanes of the corridor, same target quality.
|
|
new View { Label = "top-lane-overview", At = (topOuter + topInner) * .5, Zoom = 30f },
|
|
new View { Label = "top-lane-towers", At = topOuter + new Vec2(0, -2.5), Zoom = 16f },
|
|
new View { Label = "bot-lane-overview", At = (botOuter + botInner) * .5, Zoom = 30f },
|
|
new View { Label = "bot-lane-towers", At = botOuter + new Vec2(0, -2.5), Zoom = 16f },
|
|
// Weg 2 edge tier: the mountains beyond the lane corridor keep colour and stone relief.
|
|
new View { Label = "edge-mountains", At = new Vec2(-55, 55), Zoom = 36f, YawSteps = -1 },
|
|
new View { Label = "lane-and-edge", At = new Vec2(-28, 28), Zoom = 56f },
|
|
};
|
|
// LUNE_EVIDENCE names the folder (as for the PlayMode evidence), so a later stage keeps the U5 records.
|
|
string evidence = Environment.GetEnvironmentVariable("LUNE_EVIDENCE");
|
|
string folder = Path.Combine(Path.GetDirectoryName(Application.dataPath), "docs/port/screenshots", string.IsNullOrEmpty(evidence) ? "u5" : evidence);
|
|
Directory.CreateDirectory(folder);
|
|
Camera camera = Camera.main;
|
|
foreach (View view in views)
|
|
{
|
|
var focus = new Vec2(Mathf.Clamp((float)view.At.X, -LuneCameraMath.FocusLimit, LuneCameraMath.FocusLimit), Mathf.Clamp((float)view.At.Y, -LuneCameraMath.FocusLimit, LuneCameraMath.FocusLimit));
|
|
Vector3 point = LuneSpace.World(focus, ground.StandHeight(focus));
|
|
LuneCameraMath.Pose(point, view.Zoom, view.YawSteps * Mathf.PI * .25f, out Vector3 position, out Quaternion rotation);
|
|
camera.transform.SetPositionAndRotation(position, rotation);
|
|
Render(camera, Path.Combine(folder, view.Label + ".png"));
|
|
}
|
|
}
|
|
catch (Exception error)
|
|
{
|
|
Debug.LogError("LUNE_CAPTURE mid failed: " + error);
|
|
code = 1;
|
|
}
|
|
EditorApplication.Exit(code);
|
|
}
|
|
}
|
|
}
|