OpenGL - белые края на кубах

12

В игре, похожей на майнкрафт, я получаю белые края на кубах:

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

Это гораздо более заметно в более темных текстурах. Текстуры настраиваются так: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

Любая помощь?

Луис Круз
источник
3
Можете ли вы показать некоторый код о том, как вы визуализируете каждый куб и как вы размещаете кубы?
Joncodo
1
Делает ли обтекание текстур что-то другое? Как выглядит текстура / размер, к которому вы привязываетесь?
Чак Д
Я просто хотел отметить, что я видел, что это также происходит в больших текстурных атласах, которые используют маленькие плитки. Например, скажем, у вас есть 1024 * 1024 набора плиток / атласа, и вы используете плитки 32 * 32. Вы получаете ошибки округления, потому что десятичная точка, которая отображается на упомянутую плитку, очень мала. Это делает точность почти невозможной. Решение? Разбейте плитку атласа на отдельные плитки. Это то, что Майнкрафт делает, или раньше делал. У них был один большой набор плиток, и во время выполнения они разбивали его на отдельные текстуры.
Krythic

Ответы:

19

Есть две возможные причины для этого типа проблемы, в зависимости от того, какая именно это проблема. Я перечислю оба:

1. Вы видите другие цвета от вашей текстуры по краям плитки.

Это выглядит для меня как проблема в данном случае, потому что все краевые пиксели являются одним из трех цветов, которые правдоподобно присутствуют в вашей текстуре: белый, черный и коричневый.

Если вы используете несколько плиточных изображений рядом друг с другом в одной текстуре (текстурном атласе), как я полагаю, вы делаете, это неизбежно. Это происходит потому, что графический процессор не совсем совпадает с интерполяцией по краю треугольника с интерполяцией по текстуре, и вы получаете маленькие кусочки соседней текстуры.

Есть несколько вещей, которые вы можете сделать.

  • Используйте текстуру массива вместо текстурного атласа. Текстура массива состоит из стопки двухмерных изображений одинакового размера, и вы выбираете третью координату, чтобы выбрать одну; он предназначен именно для замены текстурных атласов без проблем с фильтрацией. Однако текстуры массивов - более новая функция, которая может быть недоступна в используемой версии OpenGL.
  • Создайте 1-пиксельную границу в каждой из ваших текстурных плиток, которая повторяет цвет смежного обычного пикселя. (Это, по сути, переопределение GL CLAMP[_TO_EDGE], но таким образом, который учитывает атласы текстур - ваше использование их не имеет никакого эффекта, потому что большинство ваших краев плитки не на краю текстуры.) Это решение, которое я использую в своей собственной записи в жанре кубики . Я не знаю особых недостатков, кроме того, что он использует больше текстурной памяти.
  • Очень немного вставьте ваши текстурные координаты, чтобы они не доходили до края текстурной плитки. Выполнение этого слишком много приведет к заметной тонкости краев текстуры по сравнению с пикселями в середине.
  • Используйте одну текстуру для каждого типа плитки. Это налагает затраты на переключение текстур.

2. Вы видите сквозь промежутки между плитками.

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

Это может произойти, если вы не предоставляете точно такие же координаты для вершин встречных ребер соседних плиток, что обычно возникает из-за ошибки с плавающей точкой. Например, если у вас есть плитки размером 0,6 и вы вычислили правый край плитки в x=100с (100*0.6) + 0.6, а левый край плитки в x=101с (100*0.6), вы не получите тот же самый ответ, и разница может быть видна как маленькие пятнышки пробелы.

Решение состоит в том, чтобы гарантировать, что ваша арифметика последовательна; некоторые способы сделать это:

  • Убедитесь, что вы не (даже косвенно) вычисления index*size + size, а только (index+1)*size.
  • Убедитесь, что ваша арифметика точна; Самый простой способ сделать это - сделать размер плитки ровно 1,0, что даст точную целочисленную арифметику, даже если вы выполняете вычисления с 32-разрядными числами с плавающей запятой (в любом случае, до 16 миллионов блоков от начала координат).
  • Используйте фактические целые числа для вычисления координат вершины; это дает вам еще больший диапазон.
Кевин Рид
источник
Для меня это похоже на пробелы - нет текстурного кровотечения (если только это не довольно высокая текстура с высоким разрешением), учитывая мелкие и острые кусочки.
Марио
Спасибо, вставка текстурных координат немного, кажется, исправляет это.
Луис Круз
@Mario Я предполагаю, что это с ближайшим увеличением - обратите внимание на четкую границу внутри плитки. Так что с этой точки зрения это текстура с бесконечным разрешением.
Кевин Рид
Вы также можете использовать массив текстур, чтобы избежать затрат на переключение.
Данияр