Am Lightning rumgeschraubt (Nicht mc queen)
This commit is contained in:
@@ -219,8 +219,11 @@ public class WorldScene extends BaseAppState {
|
|||||||
animLib = new AnimationLibrary();
|
animLib = new AnimationLibrary();
|
||||||
app.getStateManager().attach(animLib);
|
app.getStateManager().attach(animLib);
|
||||||
|
|
||||||
// Früh starten damit DayNightState bis onEnable() bereits initialisiert ist
|
// Früh starten damit DayNightState bis onEnable() bereits initialisiert ist.
|
||||||
|
// withShadows=false: Shadow-Filter wird in buildLighting() extern übergeben.
|
||||||
|
// setGameMode(true): Spiel-Beleuchtungswerte statt Editor-Werte verwenden.
|
||||||
dayNight = new DayNightState(false);
|
dayNight = new DayNightState(false);
|
||||||
|
dayNight.setGameMode(true);
|
||||||
app.getStateManager().attach(dayNight);
|
app.getStateManager().attach(dayNight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ public class DayNightState extends BaseAppState implements TimeListener {
|
|||||||
private ColorRGBA sunBaseColor = new ColorRGBA(1, 1, 1, 1);
|
private ColorRGBA sunBaseColor = new ColorRGBA(1, 1, 1, 1);
|
||||||
private float shadowBaseIntensity = 0f;
|
private float shadowBaseIntensity = 0f;
|
||||||
private ColorRGBA customAmbient = new ColorRGBA();
|
private ColorRGBA customAmbient = new ColorRGBA();
|
||||||
|
/** true = Spiel-Beleuchtungswerte, false = Editor-Werte. Standardmäßig = withShadows. */
|
||||||
|
private boolean gameMode;
|
||||||
|
|
||||||
private static final float CAVE_RAY_HEIGHT = 12f;
|
private static final float CAVE_RAY_HEIGHT = 12f;
|
||||||
private static final float CAVE_CHECK_INTERVAL = 0.2f;
|
private static final float CAVE_CHECK_INTERVAL = 0.2f;
|
||||||
@@ -69,7 +71,7 @@ public class DayNightState extends BaseAppState implements TimeListener {
|
|||||||
this(new DayTime(), true);
|
this(new DayTime(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @param withShadows false für Editor (kein Shadow-Renderer) */
|
/** @param withShadows false für Editor (kein Shadow-Renderer, Editor-Beleuchtungswerte) */
|
||||||
public DayNightState(boolean withShadows) {
|
public DayNightState(boolean withShadows) {
|
||||||
this(new DayTime(), withShadows);
|
this(new DayTime(), withShadows);
|
||||||
}
|
}
|
||||||
@@ -77,6 +79,15 @@ public class DayNightState extends BaseAppState implements TimeListener {
|
|||||||
public DayNightState(DayTime dayTime, boolean withShadows) {
|
public DayNightState(DayTime dayTime, boolean withShadows) {
|
||||||
this.dayTime = dayTime;
|
this.dayTime = dayTime;
|
||||||
this.withShadows = withShadows;
|
this.withShadows = withShadows;
|
||||||
|
this.gameMode = withShadows;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schaltet auf Spiel-Beleuchtungswerte um, unabhängig vom withShadows-Flag.
|
||||||
|
* Nützlich wenn der Shadow-Filter von außen gesetzt wird (z.B. WorldScene).
|
||||||
|
*/
|
||||||
|
public void setGameMode(boolean gameMode) {
|
||||||
|
this.gameMode = gameMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DayTime getDayTime() { return dayTime; }
|
public DayTime getDayTime() { return dayTime; }
|
||||||
@@ -234,24 +245,28 @@ public class DayNightState extends BaseAppState implements TimeListener {
|
|||||||
float elevC = FastMath.clamp(elevation, 0f, 1f);
|
float elevC = FastMath.clamp(elevation, 0f, 1f);
|
||||||
|
|
||||||
// Spiel vs. Editor: unterschiedliche Helligkeitswerte aus LightingConfig
|
// Spiel vs. Editor: unterschiedliche Helligkeitswerte aus LightingConfig
|
||||||
ColorRGBA ambDay = withShadows ? LightingConfig.AMB_DAY : LightingConfig.EDITOR_AMB_DAY;
|
ColorRGBA ambDay = gameMode ? LightingConfig.AMB_DAY : LightingConfig.EDITOR_AMB_DAY;
|
||||||
ColorRGBA ambNight = withShadows ? LightingConfig.AMB_NIGHT : LightingConfig.EDITOR_AMB_NIGHT;
|
ColorRGBA ambNight = gameMode ? LightingConfig.AMB_NIGHT : LightingConfig.EDITOR_AMB_NIGHT;
|
||||||
ColorRGBA custDay = withShadows ? LightingConfig.CUSTOM_AMB_DAY : LightingConfig.EDITOR_CUSTOM_AMB_DAY;
|
ColorRGBA custDay = gameMode ? LightingConfig.CUSTOM_AMB_DAY : LightingConfig.EDITOR_CUSTOM_AMB_DAY;
|
||||||
ColorRGBA custNight = withShadows ? LightingConfig.CUSTOM_AMB_NIGHT : LightingConfig.EDITOR_CUSTOM_AMB_NIGHT;
|
ColorRGBA custNight = gameMode ? LightingConfig.CUSTOM_AMB_NIGHT : LightingConfig.EDITOR_CUSTOM_AMB_NIGHT;
|
||||||
float sunIntensity = withShadows ? LightingConfig.SUN_INTENSITY : LightingConfig.EDITOR_SUN_INTENSITY;
|
float sunIntensity = gameMode ? LightingConfig.SUN_INTENSITY : LightingConfig.EDITOR_SUN_INTENSITY;
|
||||||
|
|
||||||
// ── Sonnenfarbe: Dämmerung (orange) → Tag (warm-weiß) — jedes Frame ──
|
// ── Sonnenfarbe: Dämmerung (orange) → Tag (warm-weiß) — jedes Frame ──
|
||||||
float dawnFactor = 1f - FastMath.clamp(elevation * LightingConfig.SUN_DAWN_SLOPE, 0f, 1f);
|
float dawnFactor = 1f - FastMath.clamp(elevation * LightingConfig.SUN_DAWN_SLOPE, 0f, 1f);
|
||||||
ColorRGBA sunColor = LightingConfig.SUN_COLOR_DAWN.clone()
|
ColorRGBA sunTint = LightingConfig.SUN_COLOR_DAWN.clone()
|
||||||
.interpolateLocal(LightingConfig.SUN_COLOR_DAY, 1f - dawnFactor);
|
.interpolateLocal(LightingConfig.SUN_COLOR_DAY, 1f - dawnFactor);
|
||||||
sunBaseColor = sunColor.mult(elevC * sunIntensity);
|
sunBaseColor = sunTint.mult(elevC * sunIntensity);
|
||||||
sun.setColor(sunBaseColor.mult(1f - caveFactor));
|
sun.setColor(sunBaseColor.mult(1f - caveFactor));
|
||||||
|
|
||||||
// ── Ambient: Nacht → Tag — jedes Frame ─────────────────────────────
|
// ── Ambient: Nacht (blau) → Tag (Sonnenfarbe-tinted) — jedes Frame ──
|
||||||
|
// Tages-Ambient bekommt den Farbton der Sonne: orange bei Dämmerung,
|
||||||
|
// warm-gelb tagsüber. Nachts bleibt das fixe Blau von AMB_NIGHT.
|
||||||
|
ColorRGBA ambDayTinted = ambDay.mult(sunTint);
|
||||||
|
ColorRGBA custDayTinted = custDay.mult(sunTint);
|
||||||
float ambFactor = FastMath.clamp(
|
float ambFactor = FastMath.clamp(
|
||||||
(elevation - LightingConfig.AMB_ELEV_LOW) / LightingConfig.AMB_ELEV_RANGE, 0f, 1f);
|
(elevation - LightingConfig.AMB_ELEV_LOW) / LightingConfig.AMB_ELEV_RANGE, 0f, 1f);
|
||||||
ambient.setColor(ambNight.clone().interpolateLocal(ambDay, ambFactor));
|
ambient.setColor(ambNight.clone().interpolateLocal(ambDayTinted, ambFactor));
|
||||||
customAmbient.set(custNight.clone().interpolateLocal(custDay, ambFactor));
|
customAmbient.set(custNight.clone().interpolateLocal(custDayTinted, ambFactor));
|
||||||
|
|
||||||
shadowBaseIntensity = FastMath.clamp(
|
shadowBaseIntensity = FastMath.clamp(
|
||||||
elevation * LightingConfig.SHADOW_SLOPE, 0f, LightingConfig.SHADOW_MAX);
|
elevation * LightingConfig.SHADOW_SLOPE, 0f, LightingConfig.SHADOW_MAX);
|
||||||
|
|||||||
@@ -77,16 +77,17 @@ public final class LightingConfig {
|
|||||||
/**
|
/**
|
||||||
* AmbientLight-Farbe am Mittag.
|
* AmbientLight-Farbe am Mittag.
|
||||||
* Skaliert den LightProbe-IBL: envLight = probeIBL × AMB_DAY.
|
* Skaliert den LightProbe-IBL: envLight = probeIBL × AMB_DAY.
|
||||||
* Hoch halten (≥ 0.7) damit PBR-Reflexionen sichtbar bleiben.
|
* Nicht zu hoch – LightProbe bäckt bereits Mittags-Beleuchtung ein;
|
||||||
|
* bei AMB_DAY=0.90 wäre probeIBL + direkte Sonne (0.68) zu hell für weiße Flächen.
|
||||||
* Hat keinen Effekt solange kein LightProbe in der Szene ist.
|
* Hat keinen Effekt solange kein LightProbe in der Szene ist.
|
||||||
*/
|
*/
|
||||||
public static final ColorRGBA AMB_DAY = new ColorRGBA(0.90f, 0.90f, 0.90f, 1f);
|
public static final ColorRGBA AMB_DAY = new ColorRGBA(0.28f, 0.28f, 0.28f, 1f);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AmbientLight-Farbe in der Nacht (LightProbe-Multiplikator).
|
* AmbientLight-Farbe in der Nacht (LightProbe-Multiplikator).
|
||||||
* Leichter Blaustich simuliert Mondlicht-Reflexionen auf PBR-Flächen.
|
* Leichter Blaustich simuliert Mondlicht-Reflexionen auf PBR-Flächen.
|
||||||
*/
|
*/
|
||||||
public static final ColorRGBA AMB_NIGHT = new ColorRGBA(0.10f, 0.10f, 0.25f, 1f);
|
public static final ColorRGBA AMB_NIGHT = new ColorRGBA(0.05f, 0.05f, 0.125f, 1f);
|
||||||
|
|
||||||
|
|
||||||
// ╔══════════════════════════════════════════════════════════════════════════╗
|
// ╔══════════════════════════════════════════════════════════════════════════╗
|
||||||
@@ -103,7 +104,7 @@ public final class LightingConfig {
|
|||||||
* ↓ senken: mehr Kontrast, tiefere Schatten (wirkt moodiger/dramatischer).
|
* ↓ senken: mehr Kontrast, tiefere Schatten (wirkt moodiger/dramatischer).
|
||||||
* Empfehlung: 0.03–0.10 pro Kanal.
|
* Empfehlung: 0.03–0.10 pro Kanal.
|
||||||
*/
|
*/
|
||||||
public static final ColorRGBA CUSTOM_AMB_DAY = new ColorRGBA(0.04f, 0.05f, 0.08f, 1f);
|
public static final ColorRGBA CUSTOM_AMB_DAY = new ColorRGBA(0.03f, 0.04f, 0.06f, 1f);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ambient-Farbe in der Nacht.
|
* Ambient-Farbe in der Nacht.
|
||||||
@@ -111,7 +112,7 @@ public final class LightingConfig {
|
|||||||
* Zu hoch → Nacht wirkt grau statt dunkel.
|
* Zu hoch → Nacht wirkt grau statt dunkel.
|
||||||
* Empfehlung: 0.01–0.04 pro Kanal, Blau-Kanal darf höher sein.
|
* Empfehlung: 0.01–0.04 pro Kanal, Blau-Kanal darf höher sein.
|
||||||
*/
|
*/
|
||||||
public static final ColorRGBA CUSTOM_AMB_NIGHT = new ColorRGBA(0.025f, 0.025f, 0.06f, 1f);
|
public static final ColorRGBA CUSTOM_AMB_NIGHT = new ColorRGBA(0.012f, 0.012f, 0.03f, 1f);
|
||||||
|
|
||||||
|
|
||||||
// ╔══════════════════════════════════════════════════════════════════════════╗
|
// ╔══════════════════════════════════════════════════════════════════════════╗
|
||||||
|
|||||||
@@ -291,6 +291,7 @@ public class WorldObjectsState extends BaseAppState {
|
|||||||
|
|
||||||
geo.setMaterial(pbrMat);
|
geo.setMaterial(pbrMat);
|
||||||
} else if (spatial instanceof Node node) {
|
} else if (spatial instanceof Node node) {
|
||||||
|
if ("lod2".equals(node.getName())) return;
|
||||||
for (Spatial child : new ArrayList<>(node.getChildren())) {
|
for (Spatial child : new ArrayList<>(node.getChildren())) {
|
||||||
convertUnshadedToPbr(child);
|
convertUnshadedToPbr(child);
|
||||||
}
|
}
|
||||||
@@ -303,10 +304,11 @@ public class WorldObjectsState extends BaseAppState {
|
|||||||
if (mat == null) return;
|
if (mat == null) return;
|
||||||
String name = mat.getMaterialDef().getName();
|
String name = mat.getMaterialDef().getName();
|
||||||
if ("Tree".equals(name) || "TreeLeaf".equals(name)) {
|
if ("Tree".equals(name) || "TreeLeaf".equals(name)) {
|
||||||
// j3o-Loading setzt keine j3md-Defaults → Uniforms explizit setzen
|
// j3o-Loading setzt keine j3md-Defaults → Uniforms explizit setzen.
|
||||||
// (Werte für Mittag; werden sofort in update() durch DayNightState überschrieben)
|
// SunColor = SUN_COLOR_DAY × SUN_INTENSITY (wie in update() bei Mittag),
|
||||||
mat.setVector3("SunColor", new Vector3f(1.00f, 0.95f, 0.88f));
|
// sonst leuchten Bäume weiß bis DayNightState das erste Mal überschreibt.
|
||||||
mat.setVector3("AmbientColor", new Vector3f(0.08f, 0.10f, 0.16f));
|
mat.setVector3("SunColor", new Vector3f(0.68f, 0.65f, 0.60f));
|
||||||
|
mat.setVector3("AmbientColor", new Vector3f(0.04f, 0.05f, 0.08f));
|
||||||
mat.setVector3("LightDir", new Vector3f(0f, -1f, 0f));
|
mat.setVector3("LightDir", new Vector3f(0f, -1f, 0f));
|
||||||
sceneLitMaterials.add(mat);
|
sceneLitMaterials.add(mat);
|
||||||
} else if ("Fern".equals(name)) {
|
} else if ("Fern".equals(name)) {
|
||||||
@@ -325,6 +327,7 @@ public class WorldObjectsState extends BaseAppState {
|
|||||||
log.info("[WorldObjects] Material-Def '{}' an '{}' – unbekannt, übersprungen.", name, geo.getName());
|
log.info("[WorldObjects] Material-Def '{}' an '{}' – unbekannt, übersprungen.", name, geo.getName());
|
||||||
}
|
}
|
||||||
} else if (spatial instanceof Node node) {
|
} else if (spatial instanceof Node node) {
|
||||||
|
if ("lod2".equals(node.getName())) return;
|
||||||
for (Spatial child : node.getChildren()) {
|
for (Spatial child : node.getChildren()) {
|
||||||
collectSceneLitMaterials(child);
|
collectSceneLitMaterials(child);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user