Fehler im LOD System behoben

This commit is contained in:
2026-07-21 07:10:49 +02:00
parent 1b3d9bf0af
commit 40be463ced
2 changed files with 7 additions and 29 deletions

View File

@@ -334,23 +334,17 @@ public class WorldObjectsState extends BaseAppState {
private boolean isImpostorNode(Node n) {
if (n.getControl(BillboardControl.class) != null) {
log.info("[Impostor] '{}' erkannt via BillboardControl", n.getName());
return true;
}
if (n.getChildren().isEmpty()) {
log.info("[Impostor] '{}' hat keine Kinder → kein Impostor", n.getName());
return false;
}
Spatial first = n.getChild(0);
log.info("[Impostor] '{}' erstes Kind: {} ({})", n.getName(), first.getName(), first.getClass().getSimpleName());
if (!(first instanceof Geometry g)) {
log.info("[Impostor] '{}' erstes Kind ist kein Geometry → kein Impostor", n.getName());
return false;
}
Material mat = g.getMaterial();
String matName = mat != null ? mat.getMaterialDef().getName() : "null";
log.info("[Impostor] '{}' Material: '{}'", n.getName(), matName);
return mat != null && "Unshaded".equals(matName);
return mat != null && "Unshaded".equals(mat.getMaterialDef().getName());
}
private void initImpostor(Node lod2Node) {
@@ -365,7 +359,6 @@ public class WorldObjectsState extends BaseAppState {
lod2Node.setQueueBucket(com.jme3.renderer.queue.RenderQueue.Bucket.Opaque);
java.util.Set<Material> seen = new java.util.HashSet<>();
boolean firstMat = true;
for (Spatial child : lod2Node.getChildren()) {
if (!(child instanceof com.jme3.scene.Geometry geo)) continue;
Material mat = geo.getMaterial();
@@ -373,32 +366,15 @@ public class WorldObjectsState extends BaseAppState {
mat.setFloat("AlphaDiscardThreshold", 0.5f);
mat.getAdditionalRenderState().setBlendMode(com.jme3.material.RenderState.BlendMode.Off);
// FaceCullMode.Off: Billboard dreht sich immer zur Kamera → beide Seiten rendern
// ist sicherer als Back, da Winding-Order nach Billboard-Rotation nicht deterministisch ist.
// Billboard dreht sich per BillboardControl zur Kamera → FaceCullMode.Off,
// da Winding-Order nach Billboard-Rotation nicht feststeht.
mat.getAdditionalRenderState().setFaceCullMode(com.jme3.material.RenderState.FaceCullMode.Off);
geo.setQueueBucket(com.jme3.renderer.queue.RenderQueue.Bucket.Opaque);
// Helligkeit-Fix: Atlas wurde ohne Gamma-Korrektur gerendert (kein FPP im Editor).
com.jme3.material.MatParam colorMap = mat.getParam("ColorMap");
if (colorMap != null && colorMap.getValue() instanceof com.jme3.texture.Texture t) {
t.getImage().setColorSpace(com.jme3.texture.image.ColorSpace.sRGB);
log.info("[Impostor] Tex '{}': {}×{} fmt={}",
t.getName(), t.getImage().getWidth(), t.getImage().getHeight(), t.getImage().getFormat());
// Diagnose: Alpha-Wert im Zentrum von Strip 0 prüfen (Pixel 256,256)
if (firstMat) {
firstMat = false;
java.nio.ByteBuffer imgData = t.getImage().getData(0);
if (imgData != null && imgData.capacity() >= (256 * 4096 + 256) * 4 + 4) {
int off = (256 * 4096 + 256) * 4;
int r = imgData.get(off) & 0xFF;
int g = imgData.get(off + 1) & 0xFF;
int b = imgData.get(off + 2) & 0xFF;
int a = imgData.get(off + 3) & 0xFF;
log.info("[Impostor] Atlas Pixel(256,256) Strip0: R={} G={} B={} A={}", r, g, b, a);
} else {
log.warn("[Impostor] Atlas-Daten nicht lesbar (capacity={})",
imgData != null ? imgData.capacity() : -1);
}
}
} else {
log.warn("[Impostor] Quad '{}' hat KEINE ColorMap!", geo.getName());
}