1

次のコードを使用して、いくつかのメッシュをマージしています。

import java.util.ArrayList;
import java.util.Arrays;

import org.obsgolem.crystalia.gfx.Renderer;

import com.badlogic.gdx.graphics.Mesh;
import com.badlogic.gdx.graphics.VertexAttribute;
import com.badlogic.gdx.graphics.VertexAttributes.Usage;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Array;
import java.util.*;

public class MeshBatch
{

    private final static VertexAttribute[] attributeConfig = new VertexAttribute[]{
        new VertexAttribute(Usage.Position, 3, "a_position"),
        new VertexAttribute(Usage.ColorPacked, 4, "a_color"),
        new VertexAttribute(Usage.Normal, 3, "a_normal")};
    private final static int VERTEX_SIZE = 3 + 1 + 3;

    private Mesh m;
    private List<Float> vertices = new ArrayList<Float>();
    private List<Short> indices = new ArrayList<Short>();

    public void addMesh(float[] vert, short[] ind)
    {
        int offset = (vertices.size() / VERTEX_SIZE);

        //You have to throw an exception when you get over the limit of short indices
        if (offset + vert.length / VERTEX_SIZE > Short.MAX_VALUE) {
            throw new RuntimeException("blablabla");
        }

        for (short i : addOffset(ind, offset)) {
            indices.add(i);
        }

        for (float v : vert) {
            vertices.add(v);
        }
    }

    public short[] addOffset(short[] ind, int offset)
    {
        short[] indarr = new short[ind.length];
        for (int i = 0; i < ind.length; ++i) {
            //Do you really need this check? You are the only one using this code
            //so make sure that you never provide a null value. If you really want to have a chekc throw an exception instead
            short value = ind[i];//ind[i] == null ? 0 : ind[i];
            indarr[i] = (short) (value + offset);
        }
        return indarr;
    }


    public void end()
    {
        m = new Mesh(false, vertices.size(), indices.size(), attributeConfig);
        m.setVertices(Renderer.makeFloatArray(vertices));
        m.setIndices(Renderer.makeShortArray(indices));
    }

    public void render()
    {
        Renderer.getInstance().render(m);
    }
}

ただし、このクラスを使用して描画すると、照明で奇妙な効果が得られます。このメッシュを使用すると、他のすべてのオブジェクトのライトが明るくなりますが、レンダリングされたオブジェクトのライトはフラットに見えます。通常の方法(オブジェクトごとに個別のメッシュ)を使用すると、スムーズな照明が得られます。これが私が撮った2つのスクリーンショットです:

メッシュをマージした場合:
マージされたメッシュ照明

メッシュをマージしない場合:
メッシュをマージせずにピクセル単位照明をスムーズ

この問題の原因は何ですか?また、別のメッシュのライティングにどのように影響しますか?私の頂点は適切な形式で送信されます(頂点用に3つのフロート、カラー用に1つ、法線用に3つ)。私のインデックスも機能しています。この問題は、メッシュが実際にレンダリングされたときにのみ発生します。それがなければ、照明は完璧に機能します。問題は法線と関係があると思いますが、その問題が何であるかはわかりません。

編集:私は問題を修正したと思います。タイルを個別のメッシュの使用からメッシュバッチに切り替えたとき、照明はそれ自体を修正しました。これはどのように起こりますか?

4

1 に答える 1