Java 三维对象相交处的不均匀边和小故障

Java 三维对象相交处的不均匀边和小故障,java,android,opengl-es,3d,libgdx,Java,Android,Opengl Es,3d,Libgdx,我正潜入我的第一个3D游戏,尝试将基于瓷砖的游戏转换为3D游戏。我正在使用libGDX的新3D类来实现这一点 平铺贴图中的每个块都将转换为3D对象。在本例中,我将每个平铺渲染为长方体。它工作得相当好,但我得到的图形错误框共享一个边或角 这在桌面项目上似乎效果更好(似乎有时会发生,但不太严重): 但不是在android设备上: 该毛刺根据块在屏幕上的绘制位置而变化。这种情况发生在几种不同的android设备上,但在屏幕分辨率较高的设备上更为明显 以下是我用于在主libGDX项目中呈现它的代码:

我正潜入我的第一个3D游戏,尝试将基于瓷砖的游戏转换为3D游戏。我正在使用libGDX的新3D类来实现这一点

平铺贴图中的每个块都将转换为3D对象。在本例中,我将每个平铺渲染为长方体。它工作得相当好,但我得到的图形错误框共享一个边或角

这在桌面项目上似乎效果更好(似乎有时会发生,但不太严重):

但不是在android设备上:

该毛刺根据块在屏幕上的绘制位置而变化。这种情况发生在几种不同的android设备上,但在屏幕分辨率较高的设备上更为明显

以下是我用于在主libGDX项目中呈现它的代码:

    @Override
public void create() {      
    modelBatch = new ModelBatch();
    instances = new ArrayList<ModelInstance>();

    //Setup camera
    cam = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    cam.position.set(0, 0, 150f);
    cam.lookAt(0, 0,0);
    cam.near = 0.1f;
    cam.far = 500f;
    cam.update();

    //Setup Lighting
    environment = new Environment();
    environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.4f, 0.4f, 0.4f, 1f));
    environment.add(new DirectionalLight().set(0.8f, 0.8f, 0.8f, -1f, -0.8f, -0.2f));

    // Add boxes
    addBox(new Vector3(-50,0,0));
    addBox(new Vector3(-50,16,0));
    addBox(new Vector3(-50,32,0));
    addBox(new Vector3(-50,48,0));

    addBox(new Vector3(50,48,0));
    addBox(new Vector3(66,48,0));
    addBox(new Vector3(82,48,0));
    addBox(new Vector3(98,48,0));

}

private void addBox(Vector3 position){
    ModelBuilder modelBuilder = new ModelBuilder();
    Model model = modelBuilder.createBox(16f, 16f, 16f, 
            new Material(ColorAttribute.createDiffuse(Color.GREEN)),
            Usage.Position | Usage.Normal);
    ModelInstance mis = new ModelInstance(model);
    mis.transform.setTranslation(position);
    instances.add(mis);
}


@Override
public void render() {      
    Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

//          The next two lines seem to improve the problem. Problem is almost totally gone
//          I tweaked the values in glPolygonOffset to make it work better
            Gdx.gl20.glEnable(Gdx.gl20.GL_POLYGON_OFFSET_FILL);
            Gdx.gl20.glPolygonOffset(0.1f,0.1f);

//          These make it worse!
//              Gdx.gl.glEnable(Gdx.gl20.GL_DEPTH_TEST);
//              Gdx.gl20.glDepthFunc(Gdx.gl20.GL_LEQUAL); // GL_LESS is default


    modelBatch.begin(cam);

    for(ModelInstance mi : instances)
        modelBatch.render(mi,environment);

    modelBatch.end();
}
@覆盖
public void create(){
modelBatch=新modelBatch();
实例=新的ArrayList();
//设置摄像机
cam=新透视照相机(67,Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
凸轮位置设置(0,0,150f);
凸轮注视(0,0,0);
cam.near=0.1f;
凸轮远=500f;
cam.update();
//设置照明
环境=新环境();
set(新的ColorAttribute(ColorAttribute.AmbientLight,0.4f,0.4f,0.4f,1f));
添加(新的DirectionalLight().set(0.8f,0.8f,0.8f,-1f,-0.8f,-0.2f));
//添加框
addBox(新向量3(-50,0,0));
addBox(新向量3(-50,16,0));
addBox(新向量3(-50,32,0));
addBox(新向量3(-50,48,0));
addBox(新向量3(50,48,0));
addBox(新向量3(66,48,0));
addBox(新向量3(82,48,0));
addBox(新向量3(98,48,0));
}
专用无效添加框(矢量3位置){
ModelBuilder ModelBuilder=新的ModelBuilder();
Model Model=modelBuilder.createBox(16f,16f,16f,
新材质(ColorAttribute.createDiffuse(Color.GREEN)),
用法.位置|用法.正常);
ModelInstance mis=新的ModelInstance(模型);
mis.transform.setTranslation(位置);
实例。添加(mis);
}
@凌驾
public void render(){
glViewport(0,0,Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
Gdx.gl.glClear(GL10.gl_颜色_缓冲_位| GL10.gl_深度_缓冲_位);
//接下来的两行似乎改善了问题。问题几乎完全消失了
//我调整了glPolygonOffset中的值,使其工作得更好
Gdx.gl20.glEnable(Gdx.gl20.GL_多边形_偏移_填充);
gl20.glPolygonOffset(0.1f,0.1f);
//这些让事情变得更糟!
//Gdx.gl.glEnable(Gdx.gl20.gl_深度_测试);
//Gdx.gl20.glDepthFunc(Gdx.gl20.GL_LEQUAL);//默认为GL_LESS
modelBatch.begin(cam);
例如(ModelInstance mi:实例)
modelBatch.render(mi,环境);
modelBatch.end();
}
有什么想法吗

编辑:

更改Render()方法后在手机上进行渲染(放大,减少坏边):

当两个对象在完全相同的深度重叠时出现的问题称为“缝合”

你可以用一个简单的方法来避免它。它基本上为绘制的多边形增加了一些额外的深度。对于要渲染的每个对象,可能必须使用不同的值,这可能会重叠

Gdx.gl.glEnable(Gdx.gl10.GL_POLYGON_OFFSET_FILL);
Gdx.gl10.glPolygonOffset(1.0f, 1.0f);
有时调整深度函数也会有所帮助。我们希望调整它,使其在深度等于之前已渲染的深度时也渲染多边形

Gdx.gl.glEnable(Gdx.gl10.GL_DEPTH_TEST);
Gdx.gl10.glDepthFunc(GL10.GL_LEQUAL); // GL_LESS is default

问题的出现是因为这些块靠得太近了。如果看到这些标记闪烁,渲染器会认为块有一点重叠,因此不确定要绘制哪个三角形(因此会在两个相等的可能性之间来回切换)。如果标记不闪烁,渲染器会认为相邻块需要投射一个小阴影。其他人可能会建议如何着手解决Java方面的问题:如果您使用的是Java 7,可能会有一些渲染提示可以帮助您。看起来像光栅化器的亚像素精度问题。GL和GL ES实现具有不同的亚像素精度最小值。通过数学运算以更高的精度生成变换矩阵有助于避免这些问题。GL在转换期间仍将对矩阵使用单一精度,但您可能会在矩阵的初始计算期间避免一些不精确。