champions-of-luneraria/Assets/Luneraria/Editor/Setup/LuneProjectSetup.cs
Martin Stickelbroeck 4883d95a2f U5.4 Figuren: Surface-Materialien, Randlicht, SSAO
Die Figuren (Einheiten, Monster, Völker, Helden) bekommen den Materialweg
der Welt; dazu Umgebungsverdeckung für die ganze Szene.

- Surface-Materialien für alle 146 Figurenmaterialien (142 neu unter
  Materials/Units/, die LN_Boss_* gehörten schon zu den Gebäuden). Farbe,
  Rauigkeit und Emission bleiben die Blender-Werte; Metalle werden
  metallisch (vorher war keines der 414 Figurenmaterialien metallisch),
  ein Randlicht hebt die Silhouetten im Draufblick vom Boden ab.
- Oberflächenstruktur je Materialfamilie im eigenen Raum der Figur, nur
  in den HUD-Porträts. Im Feld (30-60 px hohe Figuren) war sie nicht zu
  sehen und kostete rund 10 % Bildrate.
- Ringborkes 4k-Satz liegt am Schnittholz (RB_Cutwood), wohin er gehört;
  U5.3 hatte ihn an die Rinde gebunden. Verwaistes RB_Bark.mat entfernt.
- SSAO über LuneProjectSetup: nach den opaken Objekten, halbe Auflösung,
  Radius 0,35 m, Ausblendung ab 260 m. Standardmäßig an (Entscheidung des
  Projektinhabers), in den Optionen abschaltbar, -luneSsao 0 für eine
  Sitzung. Die Variante mit Tiefen-Normalen-Vorpass kostete 19-28 %.
- Shader: Steinreliefkarte nur noch für Gelände, Stein, Pflaster, Erde.
- Werkzeug: Übersichtsbilder mit LUNE_DRESS=1 eingekleidet wie im Spiel;
  das Materialset wird nach der leeren Vorschauszene geladen (sie entlädt
  unreferenzierte Assets).
- Tests: EditMode 29/29, PlayMode 14/14, Verify 718/0, Player-Selbsttest
  30/30 (4 neue zur SSAO-Option), Fingerabdrücke unverändert
  (DCE95C96556F3A1A, 7B8E43AEFC0D60C5).
- Leistung (A/B mit U5.3 im selben Lauf): Mid nah 177,7 -> 148,5 fps
  (-16 %), Karte 127,8 -> 111,5 fps (-13 %); ohne SSAO -3,5 / -4,5 %.
- Doku: U5-VISUAL (U5.4), PORT-STATUS, PORT-QA; Bilder screenshots/u5.4/.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 10:07:28 +02:00

130 lines
6.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace Luneraria.EditorTools
{
/// <summary>
/// Rendering setup of the project (URP asset and renderer, linear colour space, SSAO since
/// U5.4), idempotent.
/// Unity -batchmode -projectPath . -executeMethod Luneraria.EditorTools.LuneProjectSetup.ConfigureRendering
/// </summary>
public static class LuneProjectSetup
{
public const string SettingsFolder = "Assets/Luneraria/Settings/Rendering";
public const string PipelinePath = SettingsFolder + "/Luneraria_URP.asset";
public const string RendererPath = SettingsFolder + "/Luneraria_URP_Renderer.asset";
public static void ConfigureRendering()
{
int code = 0;
try
{
Configure();
}
catch (System.Exception error)
{
Debug.LogError("LUNE_SETUP failed: " + error);
code = 1;
}
EditorApplication.Exit(code);
}
public static UniversalRenderPipelineAsset Configure()
{
Directory.CreateDirectory(SettingsFolder);
AssetDatabase.Refresh();
var asset = AssetDatabase.LoadAssetAtPath<UniversalRenderPipelineAsset>(PipelinePath);
if (asset == null)
{
var renderer = ScriptableObject.CreateInstance<UniversalRendererData>();
AssetDatabase.CreateAsset(renderer, RendererPath);
ResourceReloader.ReloadAllNullIn(renderer, UniversalRenderPipelineAsset.packagePath);
asset = UniversalRenderPipelineAsset.Create(renderer);
AssetDatabase.CreateAsset(asset, PipelinePath);
}
// The Godot sun reaches 190 m with four splits (scripts/luneraria/view/lune_world.gd).
asset.shadowDistance = 190f;
asset.shadowCascadeCount = 4;
asset.supportsHDR = true;
asset.msaaSampleCount = 4;
asset.useSRPBatcher = true;
EditorUtility.SetDirty(asset);
Ssao(AssetDatabase.LoadAssetAtPath<UniversalRendererData>(RendererPath));
GraphicsSettings.defaultRenderPipeline = asset;
int current = QualitySettings.GetQualityLevel();
for (int level = 0; level < QualitySettings.names.Length; level++)
{
QualitySettings.SetQualityLevel(level, false);
QualitySettings.renderPipeline = asset;
}
QualitySettings.SetQualityLevel(current, false);
PlayerSettings.colorSpace = ColorSpace.Linear;
MoveInto("Assets/UniversalRenderPipelineGlobalSettings.asset", SettingsFolder + "/UniversalRenderPipelineGlobalSettings.asset");
MoveInto("Assets/DefaultVolumeProfile.asset", SettingsFolder + "/DefaultVolumeProfile.asset");
AssetDatabase.SaveAssets();
Debug.Log("LUNE_SETUP rendering: " + PipelinePath + ", colour space " + PlayerSettings.colorSpace);
return asset;
}
/// <summary>SSAO intensity, radius (m) and fade distance (m) for the top-down camera (U5.4).</summary>
public const float SsaoIntensity = 1.2f;
public const float SsaoRadius = .35f;
public const float SsaoFalloff = 260f;
/// <summary>
/// Screen-space ambient occlusion (U5.4): contact shadows of figures and buildings on the
/// ground and occlusion in crevices, the depth cue of current renderers. Radius in metres
/// for figures of 1–2 m seen from 20–100 m; it fades only beyond the overview distance.
/// The feature is a sub-asset of the renderer and listed in its feature map; updated in place.
/// </summary>
static void Ssao(UniversalRendererData renderer)
{
if (renderer == null)
return;
var feature = renderer.rendererFeatures.OfType<ScreenSpaceAmbientOcclusion>().FirstOrDefault();
if (feature == null)
{
feature = ScriptableObject.CreateInstance<ScreenSpaceAmbientOcclusion>();
feature.name = "ScreenSpaceAmbientOcclusion";
AssetDatabase.AddObjectToAsset(feature, renderer);
AssetDatabase.TryGetGUIDAndLocalFileIdentifier(feature, out string _, out long localId);
var data = new SerializedObject(renderer);
SerializedProperty list = data.FindProperty("m_RendererFeatures");
list.arraySize++;
list.GetArrayElementAtIndex(list.arraySize - 1).objectReferenceValue = feature;
SerializedProperty map = data.FindProperty("m_RendererFeatureMap");
map.arraySize++;
map.GetArrayElementAtIndex(map.arraySize - 1).longValue = localId;
data.ApplyModifiedPropertiesWithoutUndo();
}
var settings = new SerializedObject(feature);
settings.FindProperty("m_Settings.Intensity").floatValue = SsaoIntensity;
settings.FindProperty("m_Settings.Radius").floatValue = SsaoRadius;
settings.FindProperty("m_Settings.Falloff").floatValue = SsaoFalloff;
settings.FindProperty("m_Settings.DirectLightingStrength").floatValue = .25f;
// Depth source after the opaques: URP copies the depth it already has, so SSAO needs no
// second geometry pass (the depth-normals prepass cost 19–28 % frame rate on the M5).
settings.FindProperty("m_Settings.Source").enumValueIndex = 0;
settings.FindProperty("m_Settings.Downsample").boolValue = true;
settings.FindProperty("m_Settings.AfterOpaque").boolValue = true;
settings.ApplyModifiedPropertiesWithoutUndo();
feature.SetActive(System.Environment.GetEnvironmentVariable("LUNE_SSAO") != "0");
EditorUtility.SetDirty(feature);
EditorUtility.SetDirty(renderer);
}
static void MoveInto(string from, string to)
{
if (File.Exists(from) && !File.Exists(to))
{
string error = AssetDatabase.MoveAsset(from, to);
if (!string.IsNullOrEmpty(error))
Debug.LogWarning("LUNE_SETUP move " + from + ": " + error);
}
}
}
}