Что подобное фильтрация текстур в играх

    1486445230179982061.png

    С явлением 3D-игр стали появляться проблемы, которых в 2D-играх не было: а теперь нужно на плоский монитор вывести трехмерную картинку. Когда объект находится параллельно плоскости экрана вблизи его — проблем нет: один-одинешенек пикселю соответствует один тексель (тексель – это пиксель двухмерного воссоздания, наложенного на 3D-поверхность). А вот что делать, если объект наклонен или находится вклинили? Ведь тогда на один пиксель приходится несколько текселей, и потому что монитор имеет ограниченное количество пикселей, то цвет каждого доводится рассчитывать из нескольких текселей путем определенного процесса — фильтрации. 

    fig7.png

    Для упрощения постижения представим, что каждый пиксель — это квадратная «дырочка» в мониторе, из буркала мы пускаем «лучи света», а тексели расположены на квадратной решетке за монитором. Когда мы расположим решетку параллельно монитору сразу за ним, то свет от одного пиксель прикроет только один тексель. Теперь мы начнем отодвигать решетку — что мы выходим? То, что наше пятно света от пикселя накроет уже больше, чем один тексель. Нынче повернем решетку — получим тоже самое: пятно от одного пикселя прикроет множество текселей. Но ведь пиксель-то может иметь один краска, и если в него попадает много текселей, то нужен алгоритм, с поддержкою которого мы будем определять его цвет — он называется фильтрацией текстур.

    Point Sampling



    Это наиболее простой алгоритм фильтрации: он основан на том, что за цвет пикселя мы берем масть текселя, который находится ближе всего к центру светового пятнышка от пикселя. Плюс этого метода очевиден — он меньше всего грузит видеокарту. Минусов тоже полно — цвет одного основного текселя, может существенно отличаться от цвета десятков и простонар сотен других текселей, которые попадают в пятно от пикселя. К этому же сама форма пятна может серьезно меняться, а его центр при текущем может остаться на том же месте, и в итоге цвет пикселя не изменится. Ну и наиболее главный минус — проблема «блочности»: когда на один пиксель доводится мало текселей (то есть объект рядом с игроком), то мы получаем, что при подобном способе фильтрации достаточно большая часть изображения заливается в одиночестве цветом, что приводит к явно видным «блокам» одного цвета на экране. Окончательное качество картинки получается… просто ужасным:

    pic06.jpg

    Так что не удивительно, что пока такая фильтрация больше не используется.

    Билинейная фильтрация

    С развитием видеокарт начала расти их мощность, так что разработчики игр пошли дальше: если брать за краска пикселя один тексель, то получается плохо. Окей — а давайте поймем средний цвет от 4 текселей и назовем это билинейной фильтрацией? С одной страны, все станет лучше — блочность исчезнет. Зато придет враг штука два — расплывчатость картинки вблизи игрока: это получается из-за того, что для интерполяции надлежит больше текселей, чем четыре. 

    Но главная проблема не в этом: билинеарная фильтрация хорошо работает тогда, когда объект параллелен экрану: в то время всегда можно выбрать 4 текселя и получить «средний» цвет. Но вот 99% структур наклонены по отношению к игроку, и получается, что мы аппроксимируем 4 прямоугольных параллелепипеда (или трапеции) как 4 квадрата, что ненормально. И чем сильнее наклонена текстура, чем ниже точность цвета и сильнее размывание:

    b5240779d6cac6904a175a2424cf8317_i-45.jpg

    Трилинейная фильтрация



    Окей, сказали разработчики игр — раз 4 текселей мало, поймем два раза по четыре, и для более точного попадания в цвет будем употреблять технологию MIP-текстурирования. Как я уже писал выше — чем дальше от игрока текстура, чем более текселей будет в пикселе, и тем труднее видеокарте обработать картинку. MIP-текстурирование же предполагает хранение одной и той же текстур в разных разрешениях: к примеру, если отправной размер текстуры 256х256, то в памяти хранятся ее копии в 128х128, 64х64 и так впоследствии, вплоть до 1х1:

    1.jpg

    И теперь для фильтрации берется не только сама микротекстура, но и мипмап: в зависимости от того, дальше или ближе текстура от игрока ухватывается или меньший, или больший мипмап текстуры, и уже на нем берется 4 текселя, кратчайшие к центру пикселя, и проводится билинейная фильтрация. Далее берется 4 текселя, близких к пикселю, уже исходной текстуры, и опять получается «средний» цвет. Потом чего берется «средний» цвет уже от средних цветов мипмапа и начальной текстуры, и присваивается пикселю — так и работает алгоритм трилинейной фильтрации. В результате видеокарту он нагружает несколько больше, чем билинейная фильтрация (нужно отпахать еще и мипмап), но и качество картинки оказывается лучше:

    pic07.jpg

    Анизотропная фильтрация



    Как следовательно, трилинейная фильтрация серьезно лучше билинейной и уж тем более точечной, но все еще картина на дальних дистанциях «мылится». И нечеткой картинка получается из-за такого, что мы не учитываем то, что текстура может быть наклонена относительно игрока — и только эту проблему и решает анизотропная фильтрация. Вкратце принцип работы анизотропной фильтрации подобной: берется MIP-текстура, установленная поперёк направления обзора, за чего происходит усреднение значений ее цветов с цветом некого численности текселей вдоль направления обзора. Количество текселей варьируется от 16 (для х2 фильтрации) до 128 (для х16). Разговаривая проще — вместо квадратного фильтра (как в билинейной фильтрации) употребляется вытянутый, что позволяет более качественно выбрать нужный цвет для экранного пикселя. Так как точек на экране может быть миллион и даже больше, а и тот и другой тексель весит не менее 32 бит (32-битный масть), анизотропная фильтрация требует огромной пропускной способности видеопамяти — 10-ки гигабайт в секунду. Столь большие требования к памяти уменьшают за результат сжатия текстур и кэширования, но все еще на видеокартах с DDR-памятью или 64-битной покрышкой разница между трилинейной и х16 анизотропной фильтрацией может достигать 10-15% fps, но и картина после такой фильтрации оказывается наилучшей:

    600px-Anisotropic_filtering_en.png