Weitere Grafik Filter hinzugeüfgt

This commit is contained in:
2026-07-21 15:25:17 +02:00
parent b960fb689a
commit ae244e3969
6 changed files with 107 additions and 4 deletions

View File

@@ -30,7 +30,8 @@ public class GraphicsScreen extends MenuScreen {
private static final int ROW_AA = 3;
private static final int ROW_VIEWDIST = 4;
private static final int ROW_SHADOW = 5;
private static final int ROW_COUNT = 6;
private static final int ROW_POSTFX = 6;
private static final int ROW_COUNT = 7;
private final GraphicsSettings live;
private GraphicsSettings edit;
@@ -63,6 +64,7 @@ public class GraphicsScreen extends MenuScreen {
edit.samples = live.samples;
edit.viewDistance = live.viewDistance;
edit.shadowQuality = live.shadowQuality;
edit.postFxQuality = live.postFxQuality;
resIdx = 0;
for (int i = 0; i < resolutions.length; i++) {
@@ -86,7 +88,8 @@ public class GraphicsScreen extends MenuScreen {
"menu.graphics.row.vsync",
"menu.graphics.row.aa",
"menu.graphics.row.viewdist",
"menu.graphics.row.shadow"
"menu.graphics.row.shadow",
"menu.graphics.row.postfx"
};
float lblX = CONT_X + 30f;
@@ -145,6 +148,11 @@ public class GraphicsScreen extends MenuScreen {
case MEDIUM -> t("menu.graphics.val.shadow.medium");
case HIGH -> t("menu.graphics.val.shadow.high");
};
case ROW_POSTFX -> switch (edit.postFxQuality) {
case OFF -> t("menu.graphics.val.off");
case MEDIUM -> t("menu.graphics.val.shadow.medium");
case HIGH -> t("menu.graphics.val.shadow.high");
};
default -> "";
};
BitmapText vt = valTexts[row];
@@ -178,18 +186,24 @@ public class GraphicsScreen extends MenuScreen {
GraphicsSettings.ShadowQuality[] sqs = GraphicsSettings.ShadowQuality.values();
edit.shadowQuality = sqs[(edit.shadowQuality.ordinal() + dir + sqs.length) % sqs.length];
break;
case ROW_POSTFX:
GraphicsSettings.PostFxQuality[] pfqs = GraphicsSettings.PostFxQuality.values();
edit.postFxQuality = pfqs[(edit.postFxQuality.ordinal() + dir + pfqs.length) % pfqs.length];
break;
}
refreshText(row);
}
private void applyAndSave() {
boolean shadowChanged = live.shadowQuality != edit.shadowQuality;
boolean postFxChanged = live.postFxQuality != edit.postFxQuality;
boolean needsRestart = live.width != edit.width
|| live.height != edit.height
|| live.fullscreen != edit.fullscreen
|| live.vsync != edit.vsync
|| live.samples != edit.samples
|| shadowChanged;
|| shadowChanged
|| postFxChanged;
live.width = edit.width;
live.height = edit.height;
@@ -198,6 +212,7 @@ public class GraphicsScreen extends MenuScreen {
live.samples = edit.samples;
live.viewDistance = edit.viewDistance;
live.shadowQuality = edit.shadowQuality;
live.postFxQuality = edit.postFxQuality;
GraphicsStore.save(live);
WeatherState ws = getApplication().getStateManager().getState(WeatherState.class);

View File

@@ -10,6 +10,29 @@ public class GraphicsSettings {
public ShadowQuality shadowQuality = ShadowQuality.MEDIUM;
/** Verstecktes Debug-Flag: erzwingt LOD2 (Impostor) für alle Objekte. Nur per Konsole setzbar. */
public boolean debugLod2 = false;
public PostFxQuality postFxQuality = PostFxQuality.HIGH;
public enum PostFxQuality {
// fxaa toneMap bloomI bloomExp godRays
OFF ( false, false, 0f, 0f, false),
MEDIUM( true, true, 0.4f, 3.0f, false),
HIGH ( true, true, 0.6f, 3.5f, true );
public final boolean fxaa;
public final boolean toneMap;
public final float bloomIntensity;
public final float bloomExposurePower;
public final boolean godRays;
PostFxQuality(boolean fxaa, boolean toneMap,
float bloomIntensity, float bloomExposurePower, boolean godRays) {
this.fxaa = fxaa;
this.toneMap = toneMap;
this.bloomIntensity = bloomIntensity;
this.bloomExposurePower = bloomExposurePower;
this.godRays = godRays;
}
}
/**
* Schattenqualitäts-Stufen.

View File

@@ -23,7 +23,7 @@ public class ThirdPersonCamera {
private static final float BASE_DISTANCE = 5f;
private static final float MIN_DISTANCE = BASE_DISTANCE - 3f;
private static final float MAX_DISTANCE = BASE_DISTANCE + 3f;
private static final float MIN_VERTICAL_ANGLE = 0.08f; // Kamera immer leicht über Schulter
private static final float MIN_VERTICAL_ANGLE = -0.12f; // Kamera kann bis Kniehöhe sinken
private static final float MAX_VERTICAL_ANGLE = FastMath.HALF_PI - 0.1f;
private static final float TARGET_HEIGHT = 1.0f;

View File

@@ -80,6 +80,8 @@ public class WorldScene extends BaseAppState {
private MapData loadedMapData;
private FilterPostProcessor sharedFPP;
private BlightFogFilter fogFilter;
private com.jme3.post.filters.LightScatteringFilter lightScatterFilter;
private com.jme3.post.filters.DepthOfFieldFilter dofFilter;
private TerrainChunkState terrainChunkState;
private Material terrainMaterial;
@@ -435,6 +437,15 @@ public class WorldScene extends BaseAppState {
for (Material mat : characterPbrMaterials) {
mat.setColor("Emissive", new ColorRGBA(ac.r, ac.g, ac.b, 1f));
}
if (lightScatterFilter != null) {
Vector3f sunDir = dayNight.getSunDirection();
// Weltposition der Sonne: von der Kamera aus weit entfernt entgegen der Lichtrichtung
Vector3f sunWorld = app.getCamera().getLocation().add(sunDir.negate().mult(10000f));
lightScatterFilter.setLightPosition(sunWorld);
// Deaktivieren wenn Sonne hinter der Kamera (gleiche Richtung wie Kamera schaut)
lightScatterFilter.setEnabled(sunDir.dot(app.getCamera().getDirection()) < 0.2f);
}
}
}
@@ -492,6 +503,21 @@ public class WorldScene extends BaseAppState {
log.info("[Debug] Nebel {}", nowEnabled ? "AN" : "AUS");
}
/** Tiefenschärfe für Dialogszenen aktivieren. focusDistance in Welt-Einheiten ab Kamera. */
public void focusDof(float focusDistance, float blurScale) {
if (dofFilter == null) return;
dofFilter.setFocusDistance(focusDistance);
dofFilter.setFocusRange(focusDistance * 0.4f);
dofFilter.setBlurScale(blurScale);
dofFilter.setEnabled(true);
}
/** Tiefenschärfe deaktivieren. */
public void clearDof() {
if (dofFilter == null) return;
dofFilter.setEnabled(false);
}
@Override protected void cleanup(Application app) {
}
@Override protected void onDisable() {}
@@ -778,6 +804,43 @@ public class WorldScene extends BaseAppState {
log.warn("[WorldScene] Post-Processing nicht verfügbar: {}", e.getMessage());
}
GraphicsSettings.PostFxQuality pfx = graphicsSettings.postFxQuality;
if (pfx.bloomIntensity > 0f) {
com.jme3.post.filters.BloomFilter bloom =
new com.jme3.post.filters.BloomFilter(com.jme3.post.filters.BloomFilter.GlowMode.Scene);
bloom.setBloomIntensity(pfx.bloomIntensity);
bloom.setExposurePower(pfx.bloomExposurePower);
bloom.setDownSamplingFactor(2f);
fpp.addFilter(bloom);
}
if (pfx.godRays) {
// Initiale Sonnenposition: von Kamera aus weit entfernt entgegen Lichtrichtung
Vector3f initSunPos = app.getCamera().getLocation().add(sunDir.negate().mult(10000f));
lightScatterFilter = new com.jme3.post.filters.LightScatteringFilter(initSunPos);
lightScatterFilter.setLightDensity(0.8f);
lightScatterFilter.setBlurStart(0.3f);
lightScatterFilter.setBlurWidth(0.4f);
lightScatterFilter.setNbSamples(150);
fpp.addFilter(lightScatterFilter);
}
if (pfx.toneMap) {
fpp.addFilter(new com.jme3.post.filters.ToneMapFilter());
}
dofFilter = new com.jme3.post.filters.DepthOfFieldFilter();
dofFilter.setFocusDistance(0f);
dofFilter.setFocusRange(0f);
dofFilter.setBlurScale(1.5f);
dofFilter.setEnabled(false);
fpp.addFilter(dofFilter);
if (pfx.fxaa) {
fpp.addFilter(new com.jme3.post.filters.FXAAFilter());
}
app.getViewPort().addProcessor(fpp);
}