1

libgdx 3d シャドウに問題があります。私のゲームでは、実験的な DirectionalShadowLight を実装しました。デスクトップではすべてがうまく機能しますが、Androidで実行すると、地面に多くのアーティファクトが発生します。

写真 (左がアンドロイド、右がデスクトップ):

レンダリング コードは、libgdx の github リポジトリのテストからほぼ直接取得しました。

    Gdx.gl.glClearColor(ExtendedEnvironment.FarBackgroundColor.r,ExtendedEnvironment.FarBackgroundColor.g,ExtendedEnvironment.FarBackgroundColor.b,1);
    Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);

    terrain.prepareForShadows();

    environment.shadowLight.begin(new Vector3(cam.position.x+10,0,0), cam.direction);
    shadowBatch.begin(environment.shadowLight.getCamera());

    ball.draw(shadowBatch, null);
    terrain.draw(shadowBatch, null);

    shadowBatch.end();
    environment.shadowLight.end();

    terrain.recoverFromShadows(ball.getPosition().x);

それほど多くはありません。また、デスクトップで動作することを考えると、シャドウの実装自体に問題があると思います。これを修正するためにできることはありますか? 人生で一度もシェーダーに触れたことがないことを考えると。多分いくつかの単純なハック?そうでない場合、誰かが libgdx の他の作業シャドウ実装を推奨できますか?

ありがとうございました。

編集: 追加コード:

BlendingAttribute  blendAttribute = new BlendingAttribute(1f)
IntAttribute intAttribute = IntAttribute.createCullFace(GL20.GL_FRONT);


 public void prepareForShadows(){

    batchedCubesInstance.materials.first().remove(blendAttribute.type);
    batchedCubesInstance.materials.first().remove(intAttribute.type);


}

public void recoverFromShadows(float posX){

    batchedCubesInstance.materials.first().set(blendAttribute);
    batchedCubesInstance.materials.first().set(intAttribute);

}

    //creating the batchedMesh:

    ModelBuilder builder = new ModelBuilder();
    builder.begin();
    MeshPartBuilder mpb = builder.part("cubes", GL20.GL_TRIANGLES, (Usage.Position | Usage.Normal | Usage.Color), new Material(
            IntAttribute.createCullFace(GL20.GL_FRONT),//For some reason, libgdx ModelBuilder makes boxes with faces wound in reverse, so cull FRONT
            blendAttribute = new BlendingAttribute(1f), //opaque since multiplied by vertex color
            new DepthTestAttribute(true), //don't want depth mask or rear cubes might not show through
            ColorAttribute.createDiffuse(Color.WHITE) //white since multiplied by vertex color
            ));

    for (int i=0; i < NUMCUBES; i++){

        mpb.box(1, 1, 1); 

    }
    batchedCubes = builder.end();
    batchedCubesInstance = new ModelInstance(batchedCubes);

ここに画像の説明を入力

4

1 に答える 1

7

あなたが経験している問題は、(浮動小数点の)精度エラーが原因である(ピーターパンとは対照的に)シャドウアクネと呼ばれます。これらはデスクトップよりもモバイルでより顕著です。これは、デスクトップでの精度が最も一般的に優れているためです。影ニキビを避ける方法はいくつかあります。その 1 つは、カメラのニア プレーンとファー プレーンをできるだけ近づけることです。cam.nearそのため、非常に小さい値や非常に高い値を使用しないでくださいcam.far。(DepthShader深度バッファーの作成に使用される) は、背面のみに影を落とすことで、影にきびを回避しようとします。このために、前面カリングを使用します。

ただし、通常のレンダリングでは正面のカリングも行っています (モデルの裏側のみをレンダリングしています)。これにより、可視面と深度バッファの生成に使用される面が同じになります。したがって、影のにきび。

これは、シャドウ マップの生成時に背面カリングを使用することで解決できます。ただし、これによりコードが過度に複雑になり、他の (将来の) 問題も発生する可能性があります。代わりに、前面を可視面のままにして、 を削除する必要がありIntAttribute.createCullFace(GL20.GL_FRONT)ます。デフォルトでは背面はカリングされるため、指定する必要はありません。

カリング フェース アトリビュートを削除すると、通常のレンダリングで他の問題が発生する可能性があります (そうしないと、最初からそこに含まれていません)。これは、モデルの頂点ワインディングが正しくないことが原因である可能性が最も高いです。あなたはこれらを使用して作成すると言います:

for (int i=0; i < NUMCUBES; i++){
    mpb.box(1, 1, 1); 
}

これが実際にイメージ内のモデルを作成するために使用しているコードである可能性はほとんどありません (これは、同じ場所に同じサイズの未定義の数のボックスを作成するだけです)。シーンの作成に使用した方法に応じて、水平座標または垂直座標のいずれかを交換することで頂点の曲がりを簡単に修正できますが、そのうちの 1 つだけです。

何らかの理由で頂点ワインディングを修正したくない場合は、 を呼び出しGdx.gl.glFrontFace​(GL20.GL_CW);て、使用する頂点ワインディングを反時計回りから時計回りに交換できます。ただし、これにより他の (将来) 問題が発生する可能性があることに注意してください。これは、最も一般的にはデフォルト (反時計回り) が想定されているためです。

于 2014-08-10T18:03:13.847 に答える