これは、数日間私を悩ませ、やる気をなくさせてきたバグです。おそらく誰かが何らかの洞察力を持っています。
プログラムでテレイン メッシュを構築し、PNG ファイルから作成された繰り返しテクスチャを持つテクスチャ属性を持つマテリアルを使用して、レンダリング可能なものをセットアップします。これらはすべて、カメラが x 軸または z 軸に沿ってしばらく移動するまで正常に動作しているように見えます。カメラが十分に離れている場合、テクスチャは最初は黒にちらつき、最終的には黒のままになります。 .
画面を青でクリアします。メッシュはまだレンダリングされていますが、テクスチャはありません。つまり、真っ黒です。これは、カメラの配置に関して同じ場所で発生します。カメラが十分に離れた後も、カメラがワールドの原点から離れ続けると、問題は解決しません。
この問題はデスクトップでは発生せず、Android でのみ発生します。テストには HTC EVO 4G を使用しています。このスマートフォンの初期の Adreno GPU には深刻な 3D 問題があることは認識していますが、大きなテクスチャ付きのランドスケープを使用したゲーム、または少なくともデモは問題なく動作することは確かです。私のメッシュには約 5000 個の三角形があり、通常は約 30 ~ 40 fps でレンダリングされます。
私が実験したいくつかのこと:
- GIMP エクスポート オプションで PNG 圧縮を 0 に変更します
- PNG の代わりに JPG を使用
- ミップマッピングを明示的に指定しない
- フィルタリングモードの変更
- さまざまなサイズと解像度の PNG ファイル
- glGetError を確認する
関連するコードは次のとおりです。
private void createMesh(){
mesh = new Mesh(true, vertices.length, indices.length,
new VertexAttribute(Usage.Position, 3, "a_position"),
new VertexAttribute(Usage.Normal, 3, "a_normal"),
new VertexAttribute(Usage.TextureCoordinates, 2, "a_texCoord0"));
float vertexData[] = new float[vertices.length * 8];
for (int x = 0; x < vertices.length; x++) {
vertexData[x*8] = vertices[x].position.x;
vertexData[x*8+1] = vertices[x].position.y;
vertexData[x*8+2] = vertices[x].position.z;
vertexData[x*8+3] = vertices[x].normal.x;
vertexData[x*8+4] = vertices[x].normal.y;
vertexData[x*8+5] = vertices[x].normal.z;
vertexData[x*8+6] = vertices[x].texCoord.x;
vertexData[x*8+7] = vertices[x].texCoord.y;
}
mesh.setVertices(vertexData);
mesh.setIndices(indices);
}
テクスチャは地形全体で繰り返されますが、以前に setWrap 行をコメントアウトしたため、問題は解決しません。
private void createRenderable(Lights lights){
texture.setWrap(TextureWrap.Repeat, TextureWrap.Repeat);
TextureAttribute textureAttribute1 = new TextureAttribute(TextureAttribute.Diffuse, texture);
terrain = new Renderable();
terrain.mesh = mesh;
terrain.worldTransform.trn(-xTerrainSize/2, (float) -heightRange, -zTerrainSize/2);
terrain.meshPartOffset = 0;
terrain.meshPartSize = mesh.getNumIndices();
terrain.primitiveType = GL10.GL_TRIANGLE_STRIP; // or GL_TRIANGLE_STRIP etc.
terrain.material = new Material(textureAttribute1);
terrain.lights = lights;
}
ファー クリッピング プレーンを小さくしても違いはないことに注意してください。
...
lights = new Lights();
lights.ambientLight.set(0.2f, 0.2f, 0.2f, 1f);
lights.add(new DirectionalLight().set(0.8f, 0.8f, 0.8f, -1f, -0.8f, -0.2f));
cam = new PerspectiveCamera(90, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
cam.position.set(0, 0, 0);
cam.lookAt(0,0,-1);
cam.near = 0.1f;
cam.far = 1000f;
cam.update();
...
@Override
public void render () {
...
Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
Gdx.graphics.getGL10().glClearColor( 0, 0, 1, 1 );
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
modelBatch.begin(cam);
modelBatch.render(terrain);
modelBatch.end();
...
}
この問題に対する洞察は非常に高く評価されます。残念ながら、EVO 4G でスクリーン キャプチャを行うのは困難です。