Настройка текстурирования. Прямое MIP-текстурирование

Как видим, билинейная фильтрация выглядит несколько лучше, нежели Point Sampling. И всё же она очень далека от идеала.

Tri-Linear filtering

Tri-Linear filtering – трилинейная фильтрация, представляет собой симбиоз билинейной фильтрации и mip-текстурирования. Прежде чем говорить об алгоритме работы трилинейной фильтрации, давайте выясним, что такое МIP-текстурирование. MIP-текстурирование, или mip-mapping, – это метод уменьшения объёма вычислений, необходимых для точного наложения текстурного изображения на полигон. По сути, мипмеппинг выполняет те же задачи, что и Point Sampling, но делает это на порядок лучше. MIP-текстурирование призвано избавить нас от ухудшений изображений, когда несколько текселей накладываются на один пиксель.

Посмотрим на проблему глобальней и попробуем найти решение всему этому. Для того чтобы правильно вывести пиксель на экран, необходимо скомбинировать значения всех текселей, которые и будут накладываться на этот пиксель. Но пропускная способность памяти не бесконечна, а это огромнейший обьём работы, который неблагоприятно отразится на быстродействии вашей видеокарты. Mip-mapping способствует снижению объёмов этой работы. Метод MIP-текстурирования основан на генерации и хранении множества версий исходного текстурного изображения. Эти версии имеют большое количество разрешений, каждое из которых всё меньше и меньше исходного. Во время текстурирования пикселя вам достаточно выбрать версию текстурного изображения. В вашем распоряжении есть 4 близлежащих текселея из текстурного изображения, больших по размеру, чем пиксель, и столько же текселей, меньших по размеру, чем пиксель. По сути, mip-уровни представляют собой заранее рассчитанные, более маленькие версии исходной текстуры, из-за чего обеспечивается лучшая аппроксимация.

Итак, мы выяснили, что такое mip-mapping, теперь вернёмся к нашей трилинейной фильтрации. Как мы уже говорили, Tri-Linear filtering представляет собой симбиоз билинейной фильтрации и mip-текстурирования. По сути, билинейная фильтрация производится на двух mip-уровнях. А в итоге мы имеем 2 текселя, по одному для каждого mip-уровня. Цвет пикселя определяется при помощи интерполяции по цветам двух mip-текстур.

В итоге имеем несколько лучшее качество фильтрации, нежели у билинейной. Стоит отметить, что качество улучшается незначительно, а требования к ширине полосы пропускания памяти в сравнении с той же Bi-Linear Filtering удваиваются.

Anisotropic filtering

Выше мы уже выяснили, что для получения хороших результатов фильтрации недостаточно определять цвет по нескольким пикселям. Используя всего четыре пикселя для определения цвета, мы получаем искажённую картину, используем недостаточный обьём фильтрации или, выражаясь простым языком, совершаем сверхфильтрацию в одном месте нашего светового пятна и недостаточно фильтруем в другом. Добавьте сюда изменение формы светового пятна и то, что ни один из вышеизложенных алгоритмов фильтрации этого не учитывает.

Вполне очевидно – для того чтобы добиться лучшего качества, необходимо использовать все пиксели светового пятна с усреднённым значением. Существуют техники фильтрации, которые применяют от 16 до 32 текселей для определения цвета пикселя. Мы также должны учитывать тот факт, что форма светового пятна изменяется вместе с изменением положения полигона относительно точки наблюдения. Собственно говоря, этим и предлагает пользоваться анизотропная фильтрация.

Всё это, конечно, хорошо, но использование такого количества пикселей требует огромной пропускной способности памяти, поэтому анизотропная фильтрация более-менее сносно может функционировать лишь на мощных современных видеокартах.

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

В видеорешениях, использующих тайловую (тайл, говоря простым языком, – участок изображения опредёленного размера, как правило, 32х32 пикселя) архитектуру, благодаря применению тайлов, существенно экономятся ресурсы полосы пропускания памяти, что позволяет использовать анизотропную фильтрацию без значимых потерь быстродействия. При помощи анизотропной фильтрации можно получить лучшее качество изображения. Оно достигается за счёт более точного представления текстур и улучшенной глубины детализации.

Уровень анизотропной фильтрации определяется числом текселей, которые обрабатываются при вычислении конечного пикселя. Современные графические решения позволяют выставить уровень фильтрации в драйвере. Самыми распространёнными уровнями фильтрации являются 2x (16 текселей), 4x (32 текселя), 8x (64 текселя) и 16x (128 текселей). Очевидно, что при повышении уровня анизотропной фильтрации нагрузка на полосу пропускания памяти также увеличивается, а это неминуемо сказывается на производительности.

Оптимизации анизотропной и трилинейной фильтраций сегодня

Компании-разработчики графических чипов ATI и NVIDIA всё время стараются выжать дополнительную производительность из своих продуктов. Что, в общем-то, очевидно и оправдано – конкуренцию между двумя гигантами-производителями графических процессоров никто не отменял. Для достижения своих целей вендоры применяют различные оптимизации, которые позволяют увеличить производительность графических решений. Однако зачастую оптимизации повышают производительность, но снижают качество картинки. Увы, но поговорка «сделать быстрей – не значит сделать лучше» очень часто актуальна для ситуации с различными оптимизациями ATI и NVIDIA.

Разработчики пытаются играть на всё тех же особенностях зрения человека и стараются повысить производительность за счёт слабозаметного ухудшения качества изображения. Возьмём, к примеру, брилинейную фильтрацию. Нет-нет, мы не оговорились, именно брилинейная фильтрация. Так сказать, новый вид, который появился благодаря упорным стараниям вендоров. Брилинейная фильтрация представляет собой смешанный режим фильтрации между билинейной и трилинейной – область, в которой граничат соседние mip-уровни, и которая, собственно говоря, подвергается трилинейной фильтрации, была уменьшена. Вследствие этого удалось поднять производительность, что вполне ожидаемо, ведь мы фильтруем гораздо меньше. При этом качество изображения становится хуже, однако ухудшение качества в данном случае явно оправдано, если учесть значительный выигрыш в производительности. Это отчётливо видно, если сравнивать изображения, полученные с помощью полной трилинейной фильтрации. Брилинейную фильтрацию впервые применила NVIDIA на своих видеокартах GeForce FX 5xxx Новые видеокарты GeForce 6xxx также используют брилинейную фильтрацию, однако компания NVIDIA после критики и различных дискуссий в многочисленных конференциях добавила возможность отключения оптимизации.

В недалёком прошлом продукты компании ATI славились более высоким качеством картинки, нежели таковые от NVIDIA. Однако с выходом графического процессора Radeon 9600 всё изменилось – последний, как и более новое решение Radeon X800, также использует брилинейную фильтрацию. Однако, в отличие от NVIDIA, ATI не соизволила не только объяснить процедуру фильтрации, но и не признала сам факт использования оптимизаций.

Компания ATI пошла на хитрость: драйверы переключаются на полную трилинейную фильтрацию при использовании цветных mip-текстур. Именно последние применяются в стандартных тестах качества, которые используют обозреватели и тестировщики.

Однако находчивые ребята с сайта Computerbase обнаружили, что в компьютерной игре «Call Of Duty» X800 даёт меньшую частоту кадров при использовании цветных mip-текстур. После чего обозреватели Computerbase провели сравнение качества изображения. Как оказалось, при применении обычных текстур Radeon X800 использует брилинейную фильтрацию. При употреблении цветных текстур в «Call Of Duty» (1600х1200) общий показатель FPS Radeon Х800 падает на 11-13 fps.

Самое интересное, что ATI заявляет об использовании полноценной трилинейной фильтрации и рекомендует тестировщикам отключать оптимизации у конкурентов для обеспечения честного сравнения.

В интервью популярному сайту Toms Hardware Guide компания ATI всячески уходила от конкретного ответа, утверждая, что X800 использует полноценную трилинейную фильтрацию. На этом оптимизации от компании ATI не заканчиваются. Так, продукты канадской фирмы ATI используют ещё один вид оптимизации, который называется «stage optimization» – оптимизацией ступени. Метод оптимизации основан на применении «трилинейной» (брилинейной) фильтрации только к первой ступени текстуры (0). Остальные ступени 1-7 фильтруются простым билинейным методом.

Стоит отметить, что во многих играх это не критично, поскольку верхние ступени текстур являются либо картами неровностей, либо картами освещения, для которых полноценная фильтрация не критична, поэтому ухудшения изображения вы попросту не заметите. Однако есть и исключения. Популярная компьютерная игра «Unreal Tournament» использует карты деталей с высоким разрешением на ступенях 1-7, поэтому потери в качестве неизбежны.

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

Компания NVIDIA также стала использовать эту оптимизацию, которая появилась в драйверах версии 51.xx для карт GeForce 5xxx.

Адаптивная анизотропная фильтрация – ещё одна вариация на тему оптимизаций. Её уже давно используют продукты компании ATI. NVIDIA также не отстаёт – в GeForce 6800 эта оптимизация частично реализована.

Алгоритм адаптивной анизотропной фильтрации заключается в том, что поверхности 3D-изображения получают различный уровень анизотропной фильтрации в точке наблюдения. Такой подход позволяет существенно экономить вычислительные ресурсы и тем самым значительно повышать общий fps.

Использование такого метода фильтрации оправданно. Представьте себе сцену из какой-нибудь компьютерной игры: скажем, ваш герой стоит лицом к стене. Фильтровать стену с уровнем анизотропной фильтрации 16х не имеет смысла, то есть картинка будет такой же, как и с 2х. Идея адаптивной анизотропной фильтрации очевидна: «сэкономь вычислительную мощность там, где это можно, дабы последняя не расходовалась впустую».

Вы вряд ли заметите существенное ухудшение качества от использования адаптивной анизотропной фильтрации, однако в некоторых сценах этот алгоритм немного грешит, то есть можно заметить определённую потерю качества.

Напоследок хотелось бы отметить, что вендорам было бы неплохо реализовать возможность отключения адаптивной анизотропной фильтрации.

В разделе на вопрос ЧТО ТАКОЕ MIP-MAPPING! заданный автором лучший ответ это MIP MAPPING - это незаменимая в каждой игре вещь. Напрмер вы играете в игру - GTA. В далеке виднеются дома. Их текстуры размыты. Как только вы подойдёте ближе текстурки станут чётче. Это сделонно чтобы не нагружать процессор. Зачем делать тектуры домов чёткими, от которых вы далеко, если вы их всё равно не увидите!? !
Существует и другая вещь. Называется она LOD. Она работает также, как и m-mapping, только заменяет модели, а не текстуры. Заменяет на моделии где полигонов меньше, опятьже тем самым снижая нагрузку ЦП. Яркий тому пример игра: TES 4 Oblivion. Благодаря великолепной системе LOD и M-MAPPINGA эта игра илёт даже на слабых машинах - со слабыми процессормами, (только video карта нужна FX5200 или R9200). Также модели деревьемв заменяются на спрайты (плоские картиннки) .
А вот создатели Gothic 3 что-то поленились оптимизировать игру и она тормозит на всех, даже мощных машинах, хотя графика в этой игре не очень.

Включает/отключает текстуру окружения карты (т.н. «скайбокс » или попросту небо).
очень малое или нет.

Включает/выключает режим использования текстур с разным разрешением в зависимости от дальности, что позволяет увеличить производительность и избавиться от шума на текстурах объектов, находящихся далеко от игрока.
Влияние на производительность: малое.

Подробнее о технологии мип-маппинга

MIP mapping (от лат. multum in parvo - «много в малом») - метод текстурирования, использующий несколько копий одной текстуры с разной детализацией. Это страшное слово на самом деле означает изменение детализации текстур в зависимости от расстояния от камеры. Методика позволяет избавиться от шума на удалённых объектах и существенно повышает производительность отрисовки.

Другими словами, мип-маппинг - это метод улучшения качества текстурных изображений при помощи использования текстур с разным разрешением для различных объектов одного и того же изображения, в зависимости от их размера и глубины. Таким образом, в памяти хранятся несколько копий текстурированного изображения в различных разрешениях. В результате этого изображение остается качественным при приближении к объекту и при удалении от него.

При использовании этого метода вы увидите изображение в высоком разрешении, находясь близко от объекта, и изображение в низком разрешении при удалении от объекта. MIP-mapping снижает мерцание и «зашумлённость» изображения, возникающие при texture mapping.

Мип-маппинг использует некоторые умные методы для упаковки данных о текстурах изображения в памяти. Чтобы использовать MIP mapping, необходимо, взяв все размеры текстур и умножив это число на два, построить одну карту наибольшего размера. Все карты меньшего размера обычно фильтруются и становятся усреднёнными и уменьшенными версиями самой большой карты.

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

Чтобы получить доступ к ручной настройке графических эффектов, приведённых ниже, снимите галочку с опции «Автоматическая настройка качества графики» в настройках. Если у вас нет этой опции, ознакомьтесь со статьёй «Отсутствие настроек графики » .

Включает/отключает тени, отбрасываемые объектами на карте, включая танки и дроп .
Влияние на производительность: высокое.

Включает/отключает затенение малоосвещённых участков карты, что позволяет получить более объёмное изображение.
Влияние на производительность: очень высокое.

Включает/отключает дымку над картой.
Влияние на производительность: очень малое или нет.

Рисунок 1. Шахматная доска без применения MIP-mapping

Технология MIP-mapping (MIP текстурирование) сглаживает отрицательные визуальные проявления данной проблемы и делает искажения менее заметными. Акроним MIP происходит от латинского "multum in parvo ", означающего "множество в малом" или "много вещей на одном пятачке". Для общего образования отметим, что по информации из OpenGL RedBook термин "mipmap" был предложен для использования Ланцем Вильямсом (Lance Williams) в 1983 году, когда на SIGGRAPH"83 он рассказал идею этой новой техники в своем докладе "Pyramidal Parametrics". Правда, Lance Williams использовал несколько инуюрасшифровку термина, а именно: "multim im parvo ", так что не удивляйтесь, если встретите и такую транскрипцию. По другой версии исследователи из Нью-йоркского технологического института впервые применили данный термин в 1979 году, для того, что бы описать технологию преобразования и сжатия множества пикселей в одну малую, специальным образом сформированную текстуру или карту, известную как MIP-map.

Для того, что бы увидеть насколько улучшается визуальная чистота изображения, достаточно поглядеть на Рисунок 2 , который показывает эффект от применения MIP-mapping c билинейной фильтрацией (bilinear filtering ).


Рисунок 2. Шахматная доска с MIP-mapping and bilinear filtering

Для того, что бы понять, что же вызвало проблемы, показанные на
Рис.1 , вы должны заглянуть внутрь процесса наложения текстуры на объекты и понять каким образом процесс дискретизации текстур влияет на конечное изображение, выводимое на экран монитора. Посмотрите на Рисунок 3а , на котором синусоида дискретизируется внешним сигналом со значительно большей частотой. Видно, что мы можем получить достаточно точную копию исходной синусоиды, если восстановить значения амплитуды каждого из сэмплов при частоте внешнего сигнала. Однако, если частота внешнего сигнала (частота дискретизации) будет равна удвоенной частоте синусоиды (Рис. 3b ), то возможны моменты (при равенстве фаз, например), когда моменты дискретизации будут совпадать с моментами прохождения исходной синусоиды через нуль, в результате чего данный сэмпл будет неинформативен. Применение частоты дискретизации меньше удвоенной частоты исходного сигнала (Рис. 3с ) приведет к тому, что сигнал, восстановленный из значений полученных сэмплов, будет синусоидой с частотой меньшей, чем у исходного сигнала. Исходя из изложенного, мы можем предположить, что частота дискретизации должна быть, по крайней мере, в два раза больше частоты дискретизируемого сигнала. Данное соотношение известно под названием предел Найквиста (В России, данное соотношение носит название теоремы Котельникова. Прим. переводчика).


Рисунок 3. Дискретизация синусоиды

И все же, откуда происходит это, кажущееся магическим число, равное значению удвоенной частоты сигнала необходимого для дискретизации? Для того, что бы получить ответ, мы должны заглянуть чуть глубже и рассмотреть ряд Фурье.

Знакомство с рядом Фурье

Полное изложение вопросов теории Фурье, может запросто занять несколько отдельных книг, поэтому для тех из вас, читатели, кто не особо утруждался на лекциях по ТЭРЦ (теории электро-радио цепей) в институте, я могу предложить почитать книгу Брейсуэлла, ссылка на которую дана в конце статьи. Что же касается самой статьи, то в ней будет изложено очень сжатое введение в теорию преобразований Фурье, но этого должно быть достаточно для того, что бы понять из чего вытекает значение предела Найквиста (Котельникова).


Рисунок 4а. Графическое представление дискретизации Фурье

Рисунок 4а показывает вид функции h(t)=sinc 2 x и ее представление рядом Фурье H(f). Для удобства будем считать, что H(f) это ряд Фурье (или частотный ряд), а h(t) временной ряд. (Если вас интересует, почему я выбрал в качестве функции именно sinc 2 x, просто потому, что она имеет наиболее простое графическое представление в частотном ряду). Для того, что бы перейти от временного ряда к частотному в теории Фурье применяется следующее преобразование:

В этой формуле, представляющей собой преобразование Фурье, f определяет частоты гармоник (обычных синусоидальных сигналов) составляющих исходный сигнал h(t), а говорит нам о том, что степень является комплексным членом, т. е. имеет вещественные и мнимые части. Оператор Й часто используется для обозначения преобразования по Фурье, т.е. выше приведенную формулу мы можем записать как h(t) Й H(f). Рисунок 4b показывает последовательность импульсов и их предстваление рядом Фурье. Импульс, который мы обозначим d(t) это теоретический сигнал бесконечно малой длительности и бесконечно большой амплитуды приведенной к единице. Интересной особенностью последовательности импульсов с периодом T s , является то, что ряд Фурье этой последовательности будет иметь вид другой последовательности импульсов, но с периодом 1/T s .


Рисунок 4b


Рисунок 4с

Результат преобразования h(t) последовательности импульсов представленных функцией s(t) показан на Рисунке 4с . Во временном ряду преобразования напоминают перемножение h(t) и s(t), тогда как в частотном ряду (ряду Фурье) результатом является конволюция H(f) и S(f).

Конволюция двух любых функций f(x) и g(x) представляется формулой:


Формула 4

Если попытки подстановки в формулу 4 результатов функций h(t) и s(t) преобразованных по Фурье вызывают у вас головную боль и желание пропустить эту "мыльную" статью (стр.72 Ноябрьского выпуска Game Developer ), то все же задержитесь на секунду - все не так сложно, как кажется. Конволюция единичного импульса в момент времени t=t 0 измененного по h(t) это ничто иное, как значение h(t) смещенное на позицию времени t=t 0 .


Формула 5

Применим Формулу 5 для нахождения конволюции H(f) и S(f).


Рисунок 4d

Основы MIP-mapping (MIP текстурирования)

Давайте посмотрим, как MIP-mapping позволяет уменьшить искажения вызываемые дискретизацией изображения (aliasing artifacts ) на примере изображения. Помните, наложение текстур на объекты в сцене применяется исключительно для придания большей реалистичности создаваемым объектам. Однако, все мелкие детали изображения в текстуре это всегда наиболее высокочастотные компоненты, и они же и являются источником aliasing problems . Так, как реально мы не можем изменить частоту дискретизации (1/DU и 1/DV в визуализирующей части нашего игрового движка), то мы вынуждены будем отфильтровать (filtering ) наши текстуры таким образом, чтобы убрать высокочастотные составляющие нашего изображения.

* Примечание переводчика : при использовании двумерных текстур в трехмерном пространстве, возникает необходимость использования двумерной координатной системы текстуры внутри существующей трехмерной координатной системы X, Y, Z. Для того, что бы разделить между собой эти координаты, разработчики ввели дополнительные обозначения двумерных координат U и V для текстур. Также был введен параметр W для того, чтобы расширить пространство Евклида (X, Y, Z) до неевклидова гомогенного (X, Y, Z, W). При эжтом, если W>0, то (X, Y, Z, W) совпадает с (X/W, Y/W, Z/W). Так что, если вам необходимо произвести манипуляции над текстурой уже размещенной в вашей 3D сцене, то вы должны будете использовать каординаты U, V.

Величины DU и DV, упоминаемые выше по тексту, это минимальные единичные приращения текстуры, которые мы можем использовать для вычислений. Обычно эти величины определяются размерностью пикселя, именно он является минимальной дискретизирующей величиной. Отсюда 1/DU и 1/DV будут величинами, определяющими частоту дискретизации изображения текстуры.


Рисунок 5. Пирамидальность MIP-map

Хотя и считается возможным отфильтровать каждый индивидуальный тексель непосредственно в процессе исполнения программы, но этот способ не применяется ввиду сложности его реализации. Более оптимальным считается вариант использования MIP текстур (MIP-map), которые состоят из серии заранее отфильтрованных и отмасштабированных текстур. Фильтрация текстур может быть произведена непосредственно в период начального запуска программы или произведена самим программистом еще в период разработки программы. Другой способ реализации MIP-mapping, это применение графических акселераторов, например, NVIDIA RIVA 128, которые произведут генерацию необходимых MIP-текстур для вашей сцены в момент, когда исходные текстуры загружаются в видео память. Рис. 5 иллюстрирует пирамидальную структуру MIP карты (текстуры), сформированную в результате MIP-mapping для исходной текстуры размерностью в 64х64 пикселя. Как можно видеть, уровень детализации (LOD) уменьшается по мере увеличения MIP уровня (MIP level). Как только текстура была преобразована в
MIP-map, все, что вам необходимо сделать в период выполнения программы для достижения базового per-polygon MIP-mapping - это выбрать корректный MIP уровень для конкретной текстуры и передать его для визуализации в акселератор или модуль программы отвечающей за визуализацию в случае software rendering.

Генерация MIP текстур

Существует несколько способов генерации MIP текстур. Один из них - просто подготовить их заранее, используя графические пакеты типа Adobe PhotoShop. Другой способ - генерация MIP текстур на "лету", т.е. в процессе выполнения программы. Заранее подготовленные MIP текстуры означают дополнительные 30% дискового пространства для текстур в базовой поставке инсталляции игры, но позволяют применять более гибкие методы управления их созданием и позволяют добавлять различные эффекты и дополнительные детали различным MIP уровням. Независимо от того, какой из способов реализации MIP-mapping вы выбрали, MIP текстуры потребуют дополнительные 30% RAM для своего размещения, что значительно увеличивает минимальные требования к количеству оперативной и/или видеопамяти на компьютере.

Давайте начнем с создания MIP карты для 8-битной текстуры.

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

Рассмотрим процесс генерации MIP текстур на "лету". Первый MIP
уровень представляет собой неизмененную исходную текстуру, скопированную в структуру MIP карты. Смотри Listing 1 (С целью экономии печатного пространства все кодовые листинги доступны для загрузки в виде одного архива: nov98.zip (584 Кб).

Создание остальных MIP уровней текстуры это шаг за шагом повторяющийся процесс. Каждый последующий (более высокий) уровень создается на базе предыдущего уровня, имеющего больший масштаб. Каждый созданный уровень располагается в памяти последовательно с предыдущим. Так же в структуре MIP карты хранится стартовый указатель (pointer) на нужный MIP уровень, так что игровой движок с легкостью может извлечь для использования уровень с соответствующим LOD.

Первым шагом в определении цвета нового пикселя будет вычисление усредненой цветности прямоугольника из четырех близлещащих пикселей на предыдущем MIP уровне. См. Listing 2 . Так как, в нашем случае мы работаем с текстурой содержащей палитру цветов, то после того как мы определили значение нового пикселя, нам необходимо найти наиболее соответствующий ему цвет из палитры. Этот процесс показан в Listing 3 . Процесс поиска нужного цвета из палитры прост, но может потребовать значительных временных затрат, так как нам необходимо обработать таким образом все пиксели в каждом из MIP уровней. К счастью, данная процедура требуется только один раз, на этапе инициализации MIP текстуры, значит, это не будет критичным. Однако, если вы пожелаете использовать другие эффекты в процессе рендеринга (визуализации), например билинейная и трилинейная фильтрация, то процесс поиска нужного цвета может стать очень медленным.

В этом случае, нам необходимо отказаться от применения текстур содержащих палитру в заголовке, и перейти к использованию 16 или 24-битных текстур. Ввиду того, что большинство применяемых графических карт поддерживают 16 битные текстуры, то мы рассмотрим в данном разделе именно 16 битную текстуру. Технология создания MIP текстуры для 16 битного изображения, очень близка к той, которую мы применяли для 8 бит, см. Listing 4 . Так как 16 битные текстуры не содержат палитру, усредненные значения цветности для нового пикселя берутся непосредственно из предыдущего MIP уровня. Одна из проблем, которая возникает в результате неоднократно усреднения цветовых величин для каждого из LOD, это то, что каждая последующая текстура будет темнее предыдущей, находящейся на один MIP уровень ниже. Можно компенсировать это некоторым увеличением значений цветовых составляющих пикселя на каждом из новых MIP уровней. Хотя это компенсация обычно не столь необходима ввиду того, что потеря в интенсивности чаще всего не столь значительна, что бы она бросалась в глаза.

Наложение MIP текстур в процессе выполнения приложения

Рисунок 6 (ниже) показывает некоторые из проблем, с которыми вы можете столкнуться, выбирая корректный LOD (уровень детализации) в процессе выполнения программы. На рисунке, прямоугольная текстура, наложенная на треугольник в плоскости самой текстуры, преобразуется в четырехсторонний многоугольник, находящийся в плоскости экрана. Перспективная проекция текстуры вызывает соответствующие преобразования прямоугольных индивидуальных текселей в многоугольники различных размеров. В нашем случае, когда полигон развернут в плоскости экрана, определение корректного LOD, который необходимо применить на полигон, является первостепенной задачей, т.к. именно от него будет зависеть хорошее конечное качество изображения. Если выбранный уровень детализации (LOD) слишком велик (размерность текстуры велика), искажения дискретизации (aliasing) будут видны в "полной своей красе". Если LOD будет недостаточным, то конечное изображение будет слишком размытым. Например, уровень детализации, выбранный для текстуры использованной на Рис. 7 (ниже) слишком мал, поэтому мы можем наблюдать большие грубые тексели в увеличенном окне вынесенном влево. Существует множество различных методов для выбора корректного LOD, каждый из которых имеет свои плюсы и минусы. Существуют два наиболее известных метода, которые мы рассмотрим ниже. Первый, основан на выборе уровня детализации в зависимости от местоположения текстуры в плоскости экрана (Area based); второй, использует для выбора LOD проекции u и v векторов.


Рисунок 6. Искажение текстуры после проекции в плоскости экрана


Рисунок 7. Наложенная текстура имеет неправильный LOD

Следует обратить внимание еще на один момент, дело в том, что вам, возможно, потребуется различное количество текселей для того, что бы прорисовать разные пиксели на экране. Как результат, вам необходимо будет просчитать LOD для каждого из пикселей. Эти вычисления могут быть очень медленными, и именно поэтому большинство программных методов визуализации (software renderers) и некоторые из устаревших видеоакселераторов, производят вычисления LOD основываясь на технологии per-polygon и/или per-triangle. Однако, несомненным плюсом per-polygon технологии в MIP-mapping, особенно при программной визуализации, является то, что для полигонов расположенных на удалении (более мелких) вы применяете более мелкие версии текстур из MIP карты, что значительно снижает требования к количеству кэш-памяти процессора в период интенсивных операций с текстурами. В то же время, по-пиксельный вариант выбора LOD позволяет вам реализовать целый ряд дополнительных преобразований в процессе MIP-mapping, включая такие как: точечная дискретизация; билинейная фильтрация на одном уровне детализации; трилинейная фильтрация между двумя ближайшими LOD.

Per-polygon MIP-mapping

Выбор корректного LOD в per-polygon MIP-mapping считается наиболее выгодным с точки зрения количества вычислений необходимых для его реализации, так как выборка производится однократно для целого полигона. Здесь, однако, есть два недостатка:

Первый - два соприкасающихся полигона могут быть отвизуализированы с применением разных уровней детализации. Визуально это проявляется в виде потери неразрывности восприятия нанесенной на объект текстуры (такие искажения носят название MIP banding). Рис.8 демонстрирует проявление незначительного MIP banding явившегося результатом per-triangle MIP-mapping.

Второй - визуальный недостаток проявляется в резких и неожиданных сменах качества прорисовки на объектах, в те моменты времени, когда происходит замена LOD на текстуре при перемещении точки наблюдения или перемещении полигона, относительно точки наблюдения.


Рисунок 8. Дорога рендеренная с применением per-polygon MIP-mapping

Выбор LOD в зависимости от местоположения текстуры на экране (Area-based LOD selection)

Area based LOD selection реализует по-полигонную технику MIP-mapping. Используя этот метод, вы регулируете LOD путем изменения степени сжатия, которая будет применена к текстуре нужной текстуре. Для того, чтобы определить необходимую степень сжатия, вам нужно определить местоположение полигона в плоскости экрана, а так же определить ту часть текстуры (в проекции текстуры) которая будет покрывать выбранный полигон. Используя пример из Listing 5 , вы можете определить соотношение текселей к пикселю и далее выбрать соответствующий уровень детализации для применения. (С целью экономии печатного пространства все кодовые листинги доступны для загрузки в виде одного архива: nov98.zip (584 Кб).

По-пиксельное MIP текстурирование позволяет реализовать более утонченное управление уровнем применяемой детализации, чем по-полигонное, оно так же допускает применение дополнительных преобразований над текстурами, хотя все это за дополнительную "плату". Все по-пиксельные методы требуют хранения полной MIP текстуры в RAM, а дополнение внутренних циклов в процедурах программы отвечающих за наложение текстур, может привести к значительному падению производительности игрового движка. К счастью, большинство из сущестующих в настоящее время 3D акселераторов аппаратно поддерживают MIP-mapping c билинейной фильтрацией (а некоторые чипы без ущерба могут осуществлять и трилинейную), поэтому мы рассмотрим, что же собственно необходимо для того, что бы реализовать по-пиксельное MIP текстурирование. Хотя и здесь, при выборе уровня детализации, мы можем применить Area based метод, мы все же пойдем по более аккуратному и сложному пути и просчитаем LOD для каждого из пикселей, в отличие от однократного просчитывания LOD на весь полигон.

Выбор LOD на основе краевого сжатия (Edge compression-based LOD selection)

В 1983 году, Поль Хекберт, перед тем как обнаружить, что метод основанный на определении сжатия краев пикселя при обратном проецировании на текстуру, является наиболее эффективной техникой вычисления LOD, он вероятно уже исследовал больше методов вычисления LOD, чем сам мог запомнить. Рис. 9 показывает единичный прямоугольный пиксель в плоскости экрана и соответствующий ему многоугольник в плоскости текстуры. Что бы избежать искажений типа aliasing , мы попробуем определить необходимый LOD основываясь на максимальном сжатии которую претерпевают края пикселя в плоскости текстуры. Она соответствует максимальной длине стороны в плоскости текстуры, и определяется Выражением 7 .


Выражение 7

Значения u x , u y , v x ,v y определяются четырьмя частными производными. См. Рис.9 . Т.к. мы уже знаем, как вычислять значения u и v для любого пикселя на экране, мы можем применить наши знания для вычисления частных производных. Зная текущие градиенты u/z, v/z и 1/z в системе × и y, а так же зная начальные значения u/z, v/z, 1/z в плоскости экрана, мы можем определить значения u и v по формулам 8 и 9. Нотацию, принятую в формулах 8 - 19 вы можете определить из серии статей Криса Хекера (Chris Hecker) по проекционному текстурированию, которые могут быть найдены на его WEB сайте. (См. раздел "Особые благодарности" в конце статьи).


Формула 8


Формула 9

Используя полученные выше результаты, мы можем определить частные производные в соответствии с формулами 10 - 13.

Формула 10

Формула 11

Формула 12

Формула 13

Где, значения a, b, c, d, e, f определяются формулами 14 - 19.

Формула 14

Формула 15

Формула 16

Формула 17

Формула 18

Формула 19

Очень важно заметить, что числители в частных производных u x и v x - функции y, а числители в частных производных u y и v y - функции x. Значения a, b, c, d, e, f вычисляются для всего полигона однократно, точно так же, как и в случае с обычными градиентами текстур. См. Listing 6 . Ну и, наконец, формула для нахождения максимального краевого сжатия дана ниже:


Формула 20

На первый взгляд кажется, что нам необходимо вычислять корень для каждого пикселя. Однако, если внимательнее рассмотреть формулу, то окажется, что значение y l - нам необходимо вычислять только раз на каждое значение × текущего полигона.
Более того, значение x l - достаточно вычислить всего раз для одного прохода луча ЭЛТ монитора (scan line). Listing 7 наглядно показывает как мы производим вычисление значения y l для диапазона × полигона в период нормальной подготовки к нанесению текстуры. Вы также заметите, что x l - вычисляется только раз на проход. И еще, нам не нужно беспокоиться о вычислении значения знаменателя, так как он уже будет вычислен ранее, в процессе стартовой выборки текстуры. Таким образом, вся дополнительная нагрузка к внутренним циклам процедур программы, будет представлять собой две операции умножения и одну операцию сравнения. Теперь, после того, как мы узнали каким образом вычислить краевое сжатие, давайте попробуем произвести выбор необходимого уровня детализации при текстурировании, используя точечную выборку, билинейную и трилинейную фильтрации.

Метод точечной выборки (Point-sampled per-pixel MIP-mapping)

Точечная выборка - самый простой способ реализации по-пиксельного MIP текстурирования и если вы заглянете в Listing 8 вы заметите, что нет значительной разницы между циклами простого наложения текстур и циклами в которых реализуется точечная выборка (point sampling). Как только мы нашли значение краевого сжатия для текущего пикселя, мы можем определить корректный уровень детализации текстуры для визуализации данного пикселя. Предварительные значения краевого сжатия, полученные нами при использовании формул приведенных выше, могут варьироваться в диапазоне значений от 0 до 1. Поэтому нам надо привести эти значения к размерности используемой текстуры, что бы получить значимую высоту в пирамиде примененной MIP текстуры. Как только мы получили значение этой высоты, мы сможем выбрать корректный LOD перемещаясь на уровень выше каждый раз, когда значение высоты будет превышать определенную степень двойки от 1 (например: высота 1 будет означать применение уровня детализации 0; 2 или 3 соответсвует уровню 1; 4 - уровень 2; 8 - уровень 3; 16 - уровень 4 и т.д.). Далее мы используем таблицу соответствий LOD, для получения значения указателя (pointer) внутри нашей MIP текстуры для извлечения соответсвующего текселя. На Рис. 10 показан тот же самый объект, что и на Рис. 8 , только отвизуализированный с применением точечной выборки (point-sampled MIP-mapping). Как можно заметить, при использовании данного метода, по прежнему присутствует проблема MIP banding в тех точках, где происходит смена LOD. Это объясняется тем, что соседние пиксели могут иметь различные уровни детализации, и ощущение неразрывности объекта теряется.


Рисунок 10. Дорога отвизуализированная с применением технологии точечной выборки

По-пиксельное MIP текстурирование с билинейной фильтрацией (Bilinear filtered per-pixel MIP-mapping)

Билинейная фильтрация призвана обеспечить дальнейшее уменьшение искажений типа aliasing на экране, путем усреднения значений четырех соприкасающихся пикселей текстуры, U и V координаты которых наиболее соответствуют реальному пикселю на экране. Рассмотрев Рис.11 и Listing 9 , мы можем заметить, что билинейная интерполяция (аппроксимация) реализуется тремя линейными интерполяциями. Вычисление корректного LOD и извлечение необходимого указателя (pointer) для нашей текстуры производится аналогично тому, что мы делали в случае точечной выборки. Однако, мы извлекаем значения для четырех пикселей текстуры и применяем билинейную интерполяцию для каждого цветового компонента, с целью получения усредненного значения цветности нового пикселя. Рис. 12 показывает, то, как выглядит наша дорога после применения билинейной фильтрации. Хотя заметен значительный прогресс в визуальном представлении по сравнению с Рис. 10 , мы все же можем заметить присутствие MIP banding.


Рисунок 11. Механизм интерполяций при билинейной фильтрации


Рисунок 12. Билинейная фильтрация

По-пиксельное MIP текстурирование с трилинейной фильтрацией (Trilinear filtered per-pixel MIP-mapping)

Способоность аппаратно поддерживать трилинейную фильтрацию при MIP-mapping, является неотемлемой чертой акслелераторов последнего поколения. Трилинейная фильтрация позволяет исключить проявления MIP banding путем сглаживания переходов между различными уровнями детализации. В Listing 10 , вы снова можете заметить, что вычисление корректного LOD производится путем, полностью аналогичным примененному при точечной выборке с той лишь разницей, что мы извлекаем указатели (pointers) для двух LOD: текущего и следущего выше по пирамиде, с меньшей детализацией. Трилинейная фильтрация выполняется путем восьми последовательных линейных интреполяций (апроксимаций). Мы выполняем билинейные интерполяции отдельно для каждого из двух выбранных LOD, а затем производим окончательные интерполяции между самими LOD. Как можно видеть на Рис. 13 , трилинейная фильтрация обеспечивает очень плавный переход между уровнями детализации (хотя это выливается в некоторую размытость линий). К сожалению, "плата" за подобное качество - велика. Непосредственная реализация алгоритмов трилинейной фильтрации требует восьмикратного обращения к текстуре на каждый просчитываемый пиксель, что вызвает производство огромного количества вычислений. Несмотря на то, что мы можем снизить количество обращений к текстуре, путем сохранения значений текселя в промежутках между итерациями цикла, производство самих интерполяций по прежнему будет выполнятся в каждом цикле, отсюда следует, что достижение приемлемых frame rates при использовании трилинейной фильтрации в неакселерированном режиме игрового движка - является очень и очень не простой задачей.


Рисунок 13. Трилинейная фильтрация

Заключение

В данной статье мы осветили довольно большой диапазон вопросов,
связанных с MIP текстурированием, и хотя применение трилинейной фильтрации делает конечное изображение гораздо более привлекательным, по сравнению с методами простого наложения текстур, все же идеального результата мы не получаем. Самой значительной проблемой в наших преобразованиях, является проблема анизотропности алгоритмов сжатия текстур (См. упоминание об этом выше в статье). Мы выбираем необходимый/корректный LOD исходя из максимальной степени краевого сжатия пикселя по одной из его сторон, но что будет если существует заметная разница в компрессии по различным координатным осям. В этом случае, выбранный уровень детализации будет недостаточен для стороны текстуры с меньшей компрессией и наша сцена будет казаться размытой. Посмотрите на Рис. 14 , это скриншот из CHAOSVR demo , который был получен с использованием акселератора на базе 3dfx Voodoo 2 , мы отчетливо видим, что размытие происходит только в направлении одной из осей координат. Данная проблема будет присутствовать при использовании любого 3D акслелератора, который использует алгоритмы вычисления LOD аналогичные разработанным здесь, а не только на Voodoo 2 используемом мной. Определенно, что следующим шагом на пути улучшения качества визуализации будет разработка и принятие алгоритмов анизотропной фильтрации. Уверен, что данная технология не заставит себя долго ждать, и появится на акселераторах следующего поколения.


Рисунок 14. Скриншот из CHAOSVR с использованием трилинейной фильтрации на базе Voodoo 2

Особые благодарности

Огромное спасибо Крису Хекеру (Chris Hecker ), который любезно разрешил мне вставить мои наработки в области MIP-mapping в алгоритмы наложения текстур, разработанные им. Это сэкномило массу времени. Посмотрите материалы на его домашней страничке для получения дополнительной информации по технике наложения текстур и более ранним статьям из Game Developer.

Хочу выразить признательность Полу Хекберту (Paul Heckbert ), за направление в мой адрес материалов публикаций, и наверное единственных, в которых обсуждается MIP текстурирование.

Наконец, я хочу поблагодарить Питера Лофенберга (Peter Laufenberg ) за разрешение использовать скриншот из CHAOSVR demo компнании Virtually Unlimited .

Для дальнейшего изучения:

  • Bracewell, R. N., The Fourier Transform and its applications, McGraw-Hill Book Co., New York, 1986.
  • Williams, L., "Pyramidal Parametrics", Computer Graphics, vol. 17, no. 3, (Proc. SIGGRAPH 1983).
  • Heckbert, P., "Texture Mapping Polygons in Perspective", NYIT Tech. Memo No. 13, 1983

Автор статьи Андрю Флавел (Andrew Flavell ) - еще один безработный Доктор Философии, пытающийся решить для себя, почему он провел все свои предыдущие годы изучая теорию графов и цепей Маркова.

multum in parvo - «много в малом».

Назначение

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

В компьютерных играх главной целью MIP-текстурирования является не улучшение качества, а повышение скорости отрисовки объектов. Технология заключается в том, что удаленные объекты обтягиваются уменьшенными текстурами, и соответственно, уменьшается время отрисовки каждого полигона. В отдельных случаях прирост в скорости текстурирования может увеличиваться в тысячи, а скорость вывода всей сцены на экран - в десятки раз.

Многие современные компьютерные игры позволяют пользователю вручную установить качество текстурирования, в настройках, сделав выбор между производительностью и качеством. В случае установки "низкого" качества текстур, вместо оригинальных текстур игра будет использовать их мипмэпы (уменьшенные копии).

Принцип действия

Создаётся так называемая MIP-пирамида - последовательность текстур с разрешением от максимального до 1×1. Например: 1×1, 2×2, 4×4, 8×8, 16×16, 32×32, 64×64, 128×128, 256×256, 512×512 и 1024×1024. Каждая из этих текстур называется MIP-уровнем (англ. MIP level ) или уровнем детализации (англ. level of detail ).

На всех этих текстурах находится одно и то же изображение. Таким образом, MIP-текстурирование увеличивает расход видеопамяти на треть:

\sum_{i=0}^\infty \left(\frac 1 4 \right)^i = 1 \frac 1 3.

При наложении текстур вычисляется расстояние до объекта и номер текстуры находится по формуле:

{miplevel} = \log_2 \left(\frac Шаблон:Dist {{texelsize} \cdot {resolution}} \right) + {mipbias},

где resolution - разрешение виртуальной камеры (количество пикселей, которое будет в объекте размером в 1 ед., расположенном в 1 ед. от камеры), texelsize - размер текселя в единицах трёхмерного мира, dist - расстояние до объекта в тех же единицах, mip bias - число, позволяющее выбирать более или менее детальную текстуру, чем даёт формула.

Эта цифра округляется до целого, и текстура с соответствующим номером (нулевая - самая детальная, первая - вдвое меньшая и т. д.) накладывается на объект.

Недостатки, способы решения

MIP-текстурирование не решает проблему текстур, находящихся под острым углом к зрителю (например, дорога в автосимуляторе). У таких текстур разрешение по одной оси сильно отличается от разрешения по другой - и, например, по оси X изображение явно размыто, в то время как по оси Y видны мерцания, свойственные завышенному разрешению текстуры. Есть сразу несколько способов решения этого (начиная с наименее качественного):

  1. Установить в видеодрайвере наиболее комфортное значение mip bias - числа́, которое отвечает за выбор номера текстуры в пирамиде. Если оно отрицательное, видеоплата берёт более детальные текстуры, если положительное - менее детальные.
  2. Многие игры сами устанавливают подходящий mip bias для разных типов объектов. Например, в Live for Speed mip bias устанавливается пользователем отдельно для автомобилей, препятствий и дороги.
  3. Воспользоваться анизотропной фильтрацией - методом текстурирования, который направлен именно на решение этой проблемы.

Наконец, видна чёткая граница между MIP-уровнями. Это решается трилинейной фильтрацией .

Альтернативы

В рендерерах высокого качества может применяться таблица частичных сумм . Это даёт высшее качество изображения (за четыре обращения к таблице можно усреднить цвет по любому прямоугольнику), но для хранения сумм нужны более широкие типы. Соответственно, таблица частичных сумм больше не на треть, а как минимум вдвое. Проблем с кэш-промахами таблица частичных сумм не решает.

Напишите отзыв о статье "MIP-текстурирование"

Ссылки

  • Михаил Хабров. . GameDev.ru (29 мая 2002 года). Проверено 12 июля 2009. .
  • (1983) (англ.)

Отрывок, характеризующий MIP-текстурирование

И она, как всегда говоря о Пьере, стала рассказывать анекдоты о его рассеянности, анекдоты, которые даже выдумывали на него.
– Вы знаете, я поверил ему нашу тайну, – сказал князь Андрей. – Я знаю его с детства. Это золотое сердце. Я вас прошу, Натали, – сказал он вдруг серьезно; – я уеду, Бог знает, что может случиться. Вы можете разлю… Ну, знаю, что я не должен говорить об этом. Одно, – чтобы ни случилось с вами, когда меня не будет…
– Что ж случится?…
– Какое бы горе ни было, – продолжал князь Андрей, – я вас прошу, m lle Sophie, что бы ни случилось, обратитесь к нему одному за советом и помощью. Это самый рассеянный и смешной человек, но самое золотое сердце.
Ни отец и мать, ни Соня, ни сам князь Андрей не могли предвидеть того, как подействует на Наташу расставанье с ее женихом. Красная и взволнованная, с сухими глазами, она ходила этот день по дому, занимаясь самыми ничтожными делами, как будто не понимая того, что ожидает ее. Она не плакала и в ту минуту, как он, прощаясь, последний раз поцеловал ее руку. – Не уезжайте! – только проговорила она ему таким голосом, который заставил его задуматься о том, не нужно ли ему действительно остаться и который он долго помнил после этого. Когда он уехал, она тоже не плакала; но несколько дней она не плача сидела в своей комнате, не интересовалась ничем и только говорила иногда: – Ах, зачем он уехал!
Но через две недели после его отъезда, она так же неожиданно для окружающих ее, очнулась от своей нравственной болезни, стала такая же как прежде, но только с измененной нравственной физиогномией, как дети с другим лицом встают с постели после продолжительной болезни.

Здоровье и характер князя Николая Андреича Болконского, в этот последний год после отъезда сына, очень ослабели. Он сделался еще более раздражителен, чем прежде, и все вспышки его беспричинного гнева большей частью обрушивались на княжне Марье. Он как будто старательно изыскивал все больные места ее, чтобы как можно жесточе нравственно мучить ее. У княжны Марьи были две страсти и потому две радости: племянник Николушка и религия, и обе были любимыми темами нападений и насмешек князя. О чем бы ни заговорили, он сводил разговор на суеверия старых девок или на баловство и порчу детей. – «Тебе хочется его (Николеньку) сделать такой же старой девкой, как ты сама; напрасно: князю Андрею нужно сына, а не девку», говорил он. Или, обращаясь к mademoiselle Bourime, он спрашивал ее при княжне Марье, как ей нравятся наши попы и образа, и шутил…
Он беспрестанно больно оскорблял княжну Марью, но дочь даже не делала усилий над собой, чтобы прощать его. Разве мог он быть виноват перед нею, и разве мог отец ее, который, она всё таки знала это, любил ее, быть несправедливым? Да и что такое справедливость? Княжна никогда не думала об этом гордом слове: «справедливость». Все сложные законы человечества сосредоточивались для нее в одном простом и ясном законе – в законе любви и самоотвержения, преподанном нам Тем, Который с любовью страдал за человечество, когда сам он – Бог. Что ей было за дело до справедливости или несправедливости других людей? Ей надо было самой страдать и любить, и это она делала.
Зимой в Лысые Горы приезжал князь Андрей, был весел, кроток и нежен, каким его давно не видала княжна Марья. Она предчувствовала, что с ним что то случилось, но он не сказал ничего княжне Марье о своей любви. Перед отъездом князь Андрей долго беседовал о чем то с отцом и княжна Марья заметила, что перед отъездом оба были недовольны друг другом.
Вскоре после отъезда князя Андрея, княжна Марья писала из Лысых Гор в Петербург своему другу Жюли Карагиной, которую княжна Марья мечтала, как мечтают всегда девушки, выдать за своего брата, и которая в это время была в трауре по случаю смерти своего брата, убитого в Турции.
«Горести, видно, общий удел наш, милый и нежный друг Julieie».
«Ваша потеря так ужасна, что я иначе не могу себе объяснить ее, как особенную милость Бога, Который хочет испытать – любя вас – вас и вашу превосходную мать. Ах, мой друг, религия, и только одна религия, может нас, уже не говорю утешить, но избавить от отчаяния; одна религия может объяснить нам то, чего без ее помощи не может понять человек: для чего, зачем существа добрые, возвышенные, умеющие находить счастие в жизни, никому не только не вредящие, но необходимые для счастия других – призываются к Богу, а остаются жить злые, бесполезные, вредные, или такие, которые в тягость себе и другим. Первая смерть, которую я видела и которую никогда не забуду – смерть моей милой невестки, произвела на меня такое впечатление. Точно так же как вы спрашиваете судьбу, для чего было умирать вашему прекрасному брату, точно так же спрашивала я, для чего было умирать этому ангелу Лизе, которая не только не сделала какого нибудь зла человеку, но никогда кроме добрых мыслей не имела в своей душе. И что ж, мой друг, вот прошло с тех пор пять лет, и я, с своим ничтожным умом, уже начинаю ясно понимать, для чего ей нужно было умереть, и каким образом эта смерть была только выражением бесконечной благости Творца, все действия Которого, хотя мы их большею частью не понимаем, суть только проявления Его бесконечной любви к Своему творению. Может быть, я часто думаю, она была слишком ангельски невинна для того, чтобы иметь силу перенести все обязанности матери. Она была безупречна, как молодая жена; может быть, она не могла бы быть такою матерью. Теперь, мало того, что она оставила нам, и в особенности князю Андрею, самое чистое сожаление и воспоминание, она там вероятно получит то место, которого я не смею надеяться для себя. Но, не говоря уже о ней одной, эта ранняя и страшная смерть имела самое благотворное влияние, несмотря на всю печаль, на меня и на брата. Тогда, в минуту потери, эти мысли не могли притти мне; тогда я с ужасом отогнала бы их, но теперь это так ясно и несомненно. Пишу всё это вам, мой друг, только для того, чтобы убедить вас в евангельской истине, сделавшейся для меня жизненным правилом: ни один волос с головы не упадет без Его воли. А воля Его руководствуется только одною беспредельною любовью к нам, и потому всё, что ни случается с нами, всё для нашего блага. Вы спрашиваете, проведем ли мы следующую зиму в Москве? Несмотря на всё желание вас видеть, не думаю и не желаю этого. И вы удивитесь, что причиною тому Буонапарте. И вот почему: здоровье отца моего заметно слабеет: он не может переносить противоречий и делается раздражителен. Раздражительность эта, как вы знаете, обращена преимущественно на политические дела. Он не может перенести мысли о том, что Буонапарте ведет дело как с равными, со всеми государями Европы и в особенности с нашим, внуком Великой Екатерины! Как вы знаете, я совершенно равнодушна к политическим делам, но из слов моего отца и разговоров его с Михаилом Ивановичем, я знаю всё, что делается в мире, и в особенности все почести, воздаваемые Буонапарте, которого, как кажется, еще только в Лысых Горах на всем земном шаре не признают ни великим человеком, ни еще менее французским императором. И мой отец не может переносить этого. Мне кажется, что мой отец, преимущественно вследствие своего взгляда на политические дела и предвидя столкновения, которые у него будут, вследствие его манеры, не стесняясь ни с кем, высказывать свои мнения, неохотно говорит о поездке в Москву. Всё, что он выиграет от лечения, он потеряет вследствие споров о Буонапарте, которые неминуемы. Во всяком случае это решится очень скоро. Семейная жизнь наша идет по старому, за исключением присутствия брата Андрея. Он, как я уже писала вам, очень изменился последнее время. После его горя, он теперь только, в нынешнем году, совершенно нравственно ожил. Он стал таким, каким я его знала ребенком: добрым, нежным, с тем золотым сердцем, которому я не знаю равного. Он понял, как мне кажется, что жизнь для него не кончена. Но вместе с этой нравственной переменой, он физически очень ослабел. Он стал худее чем прежде, нервнее. Я боюсь за него и рада, что он предпринял эту поездку за границу, которую доктора уже давно предписывали ему. Я надеюсь, что это поправит его. Вы мне пишете, что в Петербурге о нем говорят, как об одном из самых деятельных, образованных и умных молодых людей. Простите за самолюбие родства – я никогда в этом не сомневалась. Нельзя счесть добро, которое он здесь сделал всем, начиная с своих мужиков и до дворян. Приехав в Петербург, он взял только то, что ему следовало. Удивляюсь, каким образом вообще доходят слухи из Петербурга в Москву и особенно такие неверные, как тот, о котором вы мне пишете, – слух о мнимой женитьбе брата на маленькой Ростовой. Я не думаю, чтобы Андрей когда нибудь женился на ком бы то ни было и в особенности на ней. И вот почему: во первых я знаю, что хотя он и редко говорит о покойной жене, но печаль этой потери слишком глубоко вкоренилась в его сердце, чтобы когда нибудь он решился дать ей преемницу и мачеху нашему маленькому ангелу. Во вторых потому, что, сколько я знаю, эта девушка не из того разряда женщин, которые могут нравиться князю Андрею. Не думаю, чтобы князь Андрей выбрал ее своею женою, и откровенно скажу: я не желаю этого. Но я заболталась, кончаю свой второй листок. Прощайте, мой милый друг; да сохранит вас Бог под Своим святым и могучим покровом. Моя милая подруга, mademoiselle Bourienne, целует вас.