Fehler im LOD System behoben
This commit is contained in:
@@ -186,7 +186,9 @@ public final class ImpostorUtil {
|
|||||||
// WaterFilter und andere Post-Effects sehen die korrekte Tiefe des Impostors.
|
// WaterFilter und andere Post-Effects sehen die korrekte Tiefe des Impostors.
|
||||||
mat.setFloat("AlphaDiscardThreshold", 0.5f);
|
mat.setFloat("AlphaDiscardThreshold", 0.5f);
|
||||||
mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Off);
|
mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Off);
|
||||||
mat.getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Back);
|
// Billboard dreht sich per BillboardControl zur Kamera → FaceCullMode.Off ist korrekt,
|
||||||
|
// da die Winding-Order nach der Rotation nicht feststeht.
|
||||||
|
mat.getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Off);
|
||||||
|
|
||||||
Node n = new Node("lod2");
|
Node n = new Node("lod2");
|
||||||
for (int d = 0; d < DIRS; d++) {
|
for (int d = 0; d < DIRS; d++) {
|
||||||
|
|||||||
@@ -334,23 +334,17 @@ public class WorldObjectsState extends BaseAppState {
|
|||||||
|
|
||||||
private boolean isImpostorNode(Node n) {
|
private boolean isImpostorNode(Node n) {
|
||||||
if (n.getControl(BillboardControl.class) != null) {
|
if (n.getControl(BillboardControl.class) != null) {
|
||||||
log.info("[Impostor] '{}' erkannt via BillboardControl", n.getName());
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (n.getChildren().isEmpty()) {
|
if (n.getChildren().isEmpty()) {
|
||||||
log.info("[Impostor] '{}' hat keine Kinder → kein Impostor", n.getName());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Spatial first = n.getChild(0);
|
Spatial first = n.getChild(0);
|
||||||
log.info("[Impostor] '{}' erstes Kind: {} ({})", n.getName(), first.getName(), first.getClass().getSimpleName());
|
|
||||||
if (!(first instanceof Geometry g)) {
|
if (!(first instanceof Geometry g)) {
|
||||||
log.info("[Impostor] '{}' erstes Kind ist kein Geometry → kein Impostor", n.getName());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Material mat = g.getMaterial();
|
Material mat = g.getMaterial();
|
||||||
String matName = mat != null ? mat.getMaterialDef().getName() : "null";
|
return mat != null && "Unshaded".equals(mat.getMaterialDef().getName());
|
||||||
log.info("[Impostor] '{}' Material: '{}'", n.getName(), matName);
|
|
||||||
return mat != null && "Unshaded".equals(matName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initImpostor(Node lod2Node) {
|
private void initImpostor(Node lod2Node) {
|
||||||
@@ -365,7 +359,6 @@ public class WorldObjectsState extends BaseAppState {
|
|||||||
lod2Node.setQueueBucket(com.jme3.renderer.queue.RenderQueue.Bucket.Opaque);
|
lod2Node.setQueueBucket(com.jme3.renderer.queue.RenderQueue.Bucket.Opaque);
|
||||||
|
|
||||||
java.util.Set<Material> seen = new java.util.HashSet<>();
|
java.util.Set<Material> seen = new java.util.HashSet<>();
|
||||||
boolean firstMat = true;
|
|
||||||
for (Spatial child : lod2Node.getChildren()) {
|
for (Spatial child : lod2Node.getChildren()) {
|
||||||
if (!(child instanceof com.jme3.scene.Geometry geo)) continue;
|
if (!(child instanceof com.jme3.scene.Geometry geo)) continue;
|
||||||
Material mat = geo.getMaterial();
|
Material mat = geo.getMaterial();
|
||||||
@@ -373,32 +366,15 @@ public class WorldObjectsState extends BaseAppState {
|
|||||||
|
|
||||||
mat.setFloat("AlphaDiscardThreshold", 0.5f);
|
mat.setFloat("AlphaDiscardThreshold", 0.5f);
|
||||||
mat.getAdditionalRenderState().setBlendMode(com.jme3.material.RenderState.BlendMode.Off);
|
mat.getAdditionalRenderState().setBlendMode(com.jme3.material.RenderState.BlendMode.Off);
|
||||||
// FaceCullMode.Off: Billboard dreht sich immer zur Kamera → beide Seiten rendern
|
// Billboard dreht sich per BillboardControl zur Kamera → FaceCullMode.Off,
|
||||||
// ist sicherer als Back, da Winding-Order nach Billboard-Rotation nicht deterministisch ist.
|
// da Winding-Order nach Billboard-Rotation nicht feststeht.
|
||||||
mat.getAdditionalRenderState().setFaceCullMode(com.jme3.material.RenderState.FaceCullMode.Off);
|
mat.getAdditionalRenderState().setFaceCullMode(com.jme3.material.RenderState.FaceCullMode.Off);
|
||||||
geo.setQueueBucket(com.jme3.renderer.queue.RenderQueue.Bucket.Opaque);
|
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");
|
com.jme3.material.MatParam colorMap = mat.getParam("ColorMap");
|
||||||
if (colorMap != null && colorMap.getValue() instanceof com.jme3.texture.Texture t) {
|
if (colorMap != null && colorMap.getValue() instanceof com.jme3.texture.Texture t) {
|
||||||
t.getImage().setColorSpace(com.jme3.texture.image.ColorSpace.sRGB);
|
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 {
|
} else {
|
||||||
log.warn("[Impostor] Quad '{}' hat KEINE ColorMap!", geo.getName());
|
log.warn("[Impostor] Quad '{}' hat KEINE ColorMap!", geo.getName());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user