Артефакты, похожие на перекрывающиеся грани полигонов

#opengl #libgdx

#opengl #libgdx

Вопрос:

У меня есть несколько кубов в сцене. Все эти кубы всегда имеют 6 сторон. Некоторые кубы находятся рядом друг с другом. Проблема проявляется, как показано на рисунке ниже. Возникают странные артефакты, когда кажется, что есть перекрывающиеся треугольники. Я пытался изменить обратную отбраковку, но безрезультатно. Однако, как видно на рисунке, в нижнем кубе нет верхнего куба, но все равно отображаются артефакты сверху.

введите описание изображения здесь

Если я масштабирую положение вершин, проблема в значительной степени исчезает.

 State.glClearDepthf(1);
Gdx.graphics.getGL20().glEnable(GL_DEPTH_TEST);
Gdx.graphics.getGL20().glDisable(GL_BLEND);
State.glDepthMask(true);
Gdx.graphics.getGL20().glColorMask(true, true, true, true);
Gdx.graphics.getGL20().glClearColor(0, 1, 0, 0);
Gdx.graphics.getGL20().glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

Gdx.graphics.getGL20().glColorMask(true, true, true, true);
Gdx.graphics.getGL20().glDepthFunc(GL_LEQUAL);
Gdx.graphics.getGL20().glEnable(GL_CULL_FACE);
Gdx.graphics.getGL20().glCullFace(GL_BACK);
blockShader.begin();
terrain.getTexture().bind(0);
blockShader.setUniformMatrix("worldTrans", transform);
blockShader.setUniformf("cameraPos", camera.position);
blockShader.setUniformMatrix("projTrans", camera.combined);
terrain.render(blockShader);
blockShader.end();
  

Я использую следующие вершины для своих кубов. Я добавляю позицию x, y, z (которая является целым числом) к каждой из вершин с плавающей точкой соответствующим образом. Я сам проверил, что все эти вершины выровнены по CW.

 static float[] CUBE = {
        0f,0f,0f, // triangle 1 : begin
        0f,0f, 1f,
        0f, 1f, 1f, // triangle 1 : end

        1f, 1f,0f, // triangle 2 : begin
        0f,0f,0f,
        0f, 1f,0f, // triangle 2 : end

        1f,0f, 1f,
        0f,0f,0f,
        1f,0f,0f,

        1f, 1f,0f,
        1f,0f,0f,
        0f,0f,0f,

        0f,0f,0f,
        0f, 1f, 1f,
        0f, 1f,0f,

        1f,0f, 1f,
        0f,0f, 1f,
        0f,0f,0f,

        0f, 1f, 1f,
        0f, 0f, 1f,
        1f,0f, 1f,

        1f, 1f, 1f,
        1f,0f,0f,
        1f, 1f,0f,

        1f,0f,0f,
        1f, 1f, 1f,
        1f,0f, 1f,

        1f, 1f, 1f,
        1f, 1f,0f,
        0f, 1f,0f,

        1f, 1f, 1f,
        0f, 1f,0f,
        0f, 1f, 1f,

        1f, 1f, 1f,
        0f, 1f, 1f,
        1f,0f, 1f
};
  

Я использую LibGDX. Любая помощь будет оценена.

Редактировать:

Следующее я использую для создания нескольких кубов:

     float[] spawn = new float[CUBE.length];

    System.arraycopy( CUBE, 0, spawn, 0, CUBE.length );

    for (int i = 0; i < spawn.length; i =3) {
        spawn[i]  = x * 1.01f;
        spawn[i 1]  = y * 1.01f;
        spawn[i 2]  = z * 1.01f;
    }

    vertices.put(spawn);
  

Обратите внимание на 1.01f.Если я добавлю это, проблема в основном исчезнет.
введите описание изображения здесь

Если я удалю 1.01f, первое изображение будет применено там, где проблема четко видна. Похоже, это дублированные вершины, но я не могу их найти. Также заслуживает внимания; если я изменю массив КУБОВ 1.f на 0,9f, я бы предположил, что проблема в значительной степени исчезнет, но это не так.

Редактировать:

Мой ближний — 1f, а дальний — 100f. Так что проблема тоже не в этом.

Редактировать:

Я допустил критическую ошибку, которая должна была быть. Это произошло в шейдере.

 vec3 color = mod(v_vertex, 1.0) * 16.0;
  

использовался для вычисления цвета, поскольку у меня не было нормалей, uv или цветов. Однако многие из моих вершин расположены на уровне 1.0 (или кратно). Иногда, по-видимому, модификация приведет к значению чуть меньше 1, в других случаях это будет 0.

Это было одно из моих исправлений:

 vec3 color = mod(v_vertex   0.01, 1.0) * 16.0;
  

Теперь вершина будет 1.01, а мод обратно до 0.01, что уже лучше. Однако я бы хотел, чтобы цвет был 0.0 — 1.0, а не обтекался. Если кто-то может ответить на это, у меня есть свой окончательный ответ.

Комментарии:

1. Почему вы рендерите несколько кубов друг внутри друга?

2. Они не должны находиться друг внутри друга, я надеюсь, что это не так. Тем не менее, мне всегда нужно отображать 6 шести сторон для каждого куба, также когда они находятся рядом друг с другом (позже будет прозрачность и так далее).

3. Чтобы правильно решить эту проблему, было бы полезно, если бы вы включили свою матрицу проекции и разрядность вашего буфера глубины.

Ответ №1:

Как насчет:

 vec4 mod = mod(v_vertex,1.0);
gl_FragColor = mod   0.999*(1-step(0.001, mod));
  

Для этого требуется все, что округлено до чуть больше единицы (так что mod уменьшает его почти до нуля), и добавляет достаточно, чтобы вернуть его к единице.

Комментарии:

1. Хотя этот код может ответить на вопрос, вам следует добавить некоторое объяснение, почему он это делает.

Ответ №2:

В итоге я сделал кубы в диапазоне от 0,0001f до 0,999f вместо 0f и 1f, что решает все проблемы.