Чтобы понять природу анизотропной фильтрации, необходимо четко понимать, что в действительности означает наложение текстуры.
Термин «наложение текстуры» означает назначение позиций на объекте местоположениям в текстуре. Это позволяет растеризатору / шейдеру для каждой позиции на объекте извлекать соответствующие данные из текстуры. Традиционный метод для этого - назначить каждой вершине объекта текстурную координату, которая напрямую отображает эту позицию в местоположение в текстуре. Растеризатор будет интерполировать эту текстурную координату по граням различных треугольников, чтобы получить текстурную координату, используемую для извлечения цвета из текстуры.
Теперь давайте подумаем о процессе растеризации. Как это работает? Он берет треугольник и разбивает его на блоки размером с пиксель, которые мы будем называть «фрагментами». Теперь эти блоки размером в пиксель имеют размер в пикселях относительно экрана.
Но эти фрагменты имеют размер не в пикселях относительно текстуры. Представьте, что наш растеризатор сгенерировал координату текстуры для каждого угла фрагмента. Теперь представьте, что рисуете эти 4 угла не в пространстве экрана, а в пространстве текстур . Какая это будет форма?
Ну, это зависит от координат текстуры. То есть это зависит от того, как текстура сопоставлена с полигоном. Для любого конкретного фрагмента это может быть выровненный по оси квадрат. Это может быть не выровненный по оси квадрат. Это может быть прямоугольник. Это может быть трапеция. Это может быть почти любая четырехсторонняя фигура (или, по крайней мере, выпуклая фигура ).
Если вы правильно выполняли доступ к текстуре, способ получить цвет текстуры для фрагмента - выяснить, что это за прямоугольник. Затем извлеките каждый тексель из текстуры внутри этого прямоугольника (используя покрытие для масштабирования цветов, находящихся на границе). Затем усредните их все вместе. Это было бы идеальное наложение текстуры.
Это также будет очень медленно .
В интересах производительности, мы вместо этого пытаемся приблизить реальный ответ. Мы основываем вещи на одной текстурной координате, а не на 4, которые покрывают всю область фрагмента в пространстве текселей.
Фильтрация на основе MipMap использует изображения с более низким разрешением. Эти изображения в основном являются ярлыком для идеального метода, предварительно вычисляя, как будут выглядеть большие блоки цветов при смешивании. Поэтому, когда он выбирает более низкую карту, он использует предварительно вычисленные значения, где каждый тексель представляет область текстуры.
Анизотропная фильтрация работает путем аппроксимации идеального метода (который может и должен сочетаться с mipmapping) путем отбора фиксированного числа дополнительных образцов. Но как он вычисляет область в пространстве текселей для выборки, поскольку ей все еще дается только одна координата текстуры?
В основном это обманывает. Поскольку фрагментные шейдеры выполняются в соседних блоках 2x2, можно вычислить производную любого значения в фрагментном шейдере в экранном пространстве X и Y. Затем он использует эти производные в сочетании с фактической координатой текстуры, чтобы вычислить приближение какой будет фактический след текстуры фрагмента. И затем он выполняет ряд образцов в этой области.
Вот диаграмма, чтобы помочь объяснить это:
Черно-белые квадраты представляют нашу текстуру. Это просто шахматная доска из 2х2 белого и черного текселей.
Оранжевая точка - это координата текстуры для рассматриваемого фрагмента. Красный контур - это фрагмент фрагмента, который центрирован по координате текстуры.
Зеленые прямоугольники представляют тексели, к которым может обращаться реализация анизотропной фильтрации (детали алгоритмов анизотропной фильтрации зависят от платформы, поэтому я могу объяснить только общую идею).
Эта конкретная диаграмма предполагает, что реализация может получить доступ к 4 текселям. О, да, зеленые ящики покрывают 7 из них, но зеленая коробка в центре может быть получена из меньшего mipmap, таким образом, выбирая эквивалент 4 текселей за один выбор. Реализация, конечно, будет взвешивать среднее значение для этой выборки на 4 по сравнению с единичными текселями.
Если предел анизотропной фильтрации был 2, а не 4 (или выше), то реализация выбрала бы 2 из этих выборок, чтобы представить отпечаток фрагмента.
Несколько моментов, которые вы, вероятно, уже знаете, но я просто хочу высказать это другим. Фильтрация в этом случае относится к фильтрации нижних частот, как вы могли бы получить от размытия по Гауссу или размытия в рамке. Мы должны сделать это, потому что мы берем некоторые носители, которые имеют высокие частоты, и рендерим их в меньшем пространстве. Если бы мы не фильтровали его, мы получили бы артефакты с псевдонимами, которые выглядели бы плохо. Таким образом, мы отфильтровываем частоты, которые слишком высоки для точного воспроизведения в масштабированной версии. (И мы пропускаем низкие частоты, поэтому мы используем фильтр низких частот как размытие.)
Итак, давайте сначала подумаем об этом с точки зрения размытия. Размытие это тип свертки. Мы берем ядро свертки и умножаем его на все пиксели в области, а затем складываем их вместе и делим на вес. Это дает нам вывод одного пикселя. Затем мы перемещаем его и делаем снова для следующего пикселя, и снова, и т. Д.
Это действительно дорого, поэтому есть способ обмануть. Некоторые ядра свертки (в частности, ядро размытия по Гауссу и ядро размытия коробки) можно разделить на горизонтальный и вертикальный проход. Вы можете сначала отфильтровать все с помощью только горизонтального ядра, затем взять результат и отфильтровать его только с вертикальным ядром, и результат будет идентичен выполнению более дорогого вычисления в каждой точке. Вот пример:
Оригинал:
Горизонтальное размытие:
Горизонтальное, за которым следует вертикальное размытие:
Таким образом, мы можем разделить фильтрацию на вертикальный и горизонтальный проход. И что? Что ж, получается, что мы можем сделать то же самое для пространственных преобразований. Если вы думаете о повороте перспективы, вот так:
Это можно разбить на шкалу Х:
сопровождаемый масштабом каждого столбца немного другим количеством:
Итак, теперь у вас есть 2 операции масштабирования. Чтобы получить правильную фильтрацию, вы захотите фильтровать более интенсивно в X, чем в Y, и вы захотите фильтровать по разному количеству для каждого столбца. Первый столбец не фильтруется, потому что он того же размера, что и оригинал. Второй столбец становится немного меньше, потому что он немного меньше первого и т. Д. Последний столбец получает наибольшую фильтрацию из всех столбцов.
Слово «анизотропия» происходит от греческого «an» означает «не», «isos» означает «равный» и «tropos» означает «направление». Так что это означает «не равны во всех направлениях». И это именно то, что мы видим - масштабирование и фильтрация выполняются в разном количестве в каждом направлении.
источник