You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LibGDX加载Blender导出的Subaru Impreza模型显示异常求助

LibGDX加载Subaru Impreza 3D模型显示异常问题求助

首次接触LibGDX 3D开发,尝试加载Subaru Impreza汽车3D模型,模型正常效果可查看Sketchfab对应资源,但实际加载后显示异常。以下是实现代码:

package io.github.rally3d;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Cubemap;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.PerspectiveCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g3d.utils.FirstPersonCameraController;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector3;

import net.mgsx.gltf.loaders.gltf.GLTFLoader;
import net.mgsx.gltf.scene3d.attributes.PBRCubemapAttribute;
import net.mgsx.gltf.scene3d.attributes.PBRTextureAttribute;
import net.mgsx.gltf.scene3d.lights.DirectionalLightEx;
import net.mgsx.gltf.scene3d.scene.Scene;
import net.mgsx.gltf.scene3d.scene.SceneAsset;
import net.mgsx.gltf.scene3d.scene.SceneManager;
import net.mgsx.gltf.scene3d.scene.SceneSkybox;
import net.mgsx.gltf.scene3d.utils.IBLBuilder;

public class Main extends ApplicationAdapter
{
    private SceneManager sceneManager;
    private SceneAsset sceneAsset;
    private Scene scene;
    private PerspectiveCamera camera;
    private Cubemap diffuseCubemap;
    private Cubemap environmentCubemap;
    private Cubemap specularCubemap;
    private Texture brdfLUT;
    private float time;
    private SceneSkybox skybox;
    private DirectionalLightEx light;
    private FirstPersonCameraController cameraController;
    
    @Override
    public void create() {
                
        // create scene
        sceneAsset = new GLTFLoader().load(Gdx.files.internal("untitled.gltf"));
        scene = new Scene(sceneAsset.scene);
        sceneManager = new SceneManager();
        sceneManager.addScene(scene);
        
        // setup camera (The BoomBox model is very small so you may need to adapt camera settings for your scene)
        camera = new PerspectiveCamera(60f, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
        float d = .02f;
        camera.near = d / 1000f;
        camera.far = 2000;
        sceneManager.setCamera(camera);
        
        cameraController = new FirstPersonCameraController(camera);
        Gdx.input.setInputProcessor(cameraController);
        
        // setup light
        light = new DirectionalLightEx();
        light.direction.set(1, -3, 1).nor();
        light.color.set(Color.WHITE);
        sceneManager.environment.add(light);
        
        // setup quick IBL (image based lighting)
//      IBLBuilder iblBuilder = IBLBuilder.createOutdoor(light);
//      environmentCubemap = iblBuilder.buildEnvMap(1024);
//      diffuseCubemap = iblBuilder.buildIrradianceMap(256);
//      specularCubemap = iblBuilder.buildRadianceMap(10);
//      iblBuilder.dispose();
        
        // This texture is provided by the library, no need to have it in your assets.
        brdfLUT = new Texture(Gdx.files.classpath("net/mgsx/gltf/shaders/brdfLUT.png"));
        
        sceneManager.setAmbientLight(0f);
//      sceneManager.environment.set(new PBRTextureAttribute(PBRTextureAttribute.BRDFLUTTexture, brdfLUT));
//      sceneManager.environment.set(PBRCubemapAttribute.createSpecularEnv(specularCubemap));
//      sceneManager.environment.set(PBRCubemapAttribute.createDiffuseEnv(diffuseCubemap));
        
        // setup skybox
//      skybox = new SceneSkybox(environmentCubemap);
//      sceneManager.setSkyBox(skybox);
    }
    
    @Override
    public void resize(int width, int height) {
        sceneManager.updateViewport(width, height);
    }
    
    @Override
    public void render() {
        float deltaTime = Gdx.graphics.getDeltaTime();
        time += deltaTime;
        
        cameraController.update();
        scene.modelInstance.transform.rotate(Vector3.Y, 10 * deltaTime);     
        // render
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
        sceneManager.update(deltaTime);
        sceneManager.render();
    }
    
    @Override
    public void dispose() {
        sceneManager.dispose();
        sceneAsset.dispose();
        environmentCubemap.dispose();
        diffuseCubemap.dispose();
        specularCubemap.dispose();
        brdfLUT.dispose();
        skybox.dispose();
    }
}

解决方案建议

  • 初始化相机位置与朝向:当前代码未设置相机位置和看向方向,导致可能无法正确观测模型。在create方法中添加:
    camera.position.set(0, 2, 5); // 根据模型尺寸调整合适位置
    camera.lookAt(0, 0, 0); // 看向模型中心
    camera.update();
    
  • 修复深度缓冲精度问题:相机near平面设置过小(0.00002f),易引发深度冲突。调整为合理值:
    camera.near = 0.1f;
    camera.far = 2000f;
    
  • 启用IBL光照:PBR模型依赖基于图像的光照(IBL)才能正确渲染材质表现,取消代码中IBL相关注释:
    IBLBuilder iblBuilder = IBLBuilder.createOutdoor(light);
    environmentCubemap = iblBuilder.buildEnvMap(1024);
    diffuseCubemap = iblBuilder.buildIrradianceMap(256);
    specularCubemap = iblBuilder.buildRadianceMap(10);
    iblBuilder.dispose();
    
    sceneManager.environment.set(new PBRTextureAttribute(PBRTextureAttribute.BRDFLUTTexture, brdfLUT));
    sceneManager.environment.set(PBRCubemapAttribute.createSpecularEnv(specularCubemap));
    sceneManager.environment.set(PBRCubemapAttribute.createDiffuseEnv(diffuseCubemap));
    
    skybox = new SceneSkybox(environmentCubemap);
    sceneManager.setSkyBox(skybox);
    
    同时调整环境光强度,避免画面过暗:
    sceneManager.setAmbientLight(0.2f);
    
  • 检查模型资源完整性:确保untitled.gltf关联的纹理、二进制文件都正确放置在assets目录下,路径无误。
  • 调整模型缩放:若模型尺寸与相机视角不匹配,可添加缩放调整:
    scene.modelInstance.transform.setToScaling(0.1f, 0.1f, 0.1f); // 根据实际模型大小修改比例
    

内容的提问来源于stack exchange,提问作者Jesús Fernández

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 04:09:57