Что такое постобработка в играх и зачем она нужна
Что такое постобработка в играх и зачем она нужна
Это вторая часть нашего гайда. Первая, где собраны основные настройки вроде разрешения, качества текстур и теней, вы можете прочитать по ссылке.
Качество освещения (Lightning Quality)
То, насколько правдоподобно симулируется освещение в игре. Если это единственный подобный параметр в игре, то именно в эту настройку заложили уйму других, будь-то и объемный свет, и рассеивание лучей, и отражения, а иногда даже глобальное затенение. Освещение — это, пожалуй, вообще едва ли не самое основное из всего, что влияет на красоту картинки: оно делает ее объемной, натуралистичной, правдоподобной. Но и ресурсов все это дело «кушает» тоже немало. Именно поэтому, например, Nvidia так расхваливает свои новые RTX-видеокарты — они изначально разработаны под Ray Tracing — метод рендеринга, предполагающий правдоподобную симуляцию каждого луча.
Влияние на производительность
Зависит от движка, но почти во всех современных играх — очень сильное. Симулировать свет — это очень непросто, так что врубайте «ультра» только если у вас действительно мощная видеокарта.
Качество эффектов (Effects Quality)
Влияние на производительность
Тоже зависит от игры, чаще всего не особенно высокое. Но чем выше этот параметр, тем сильнее будет нагружаться ваша видеокарта в загруженных сценах, например, при масштабных перестрелках. Так что если игра начинает «подлагивать» в особо динамичные моменты, можно попробовать поиграться с этим ползунком, прежде чем снижать, например.
…Качество шейдеров (Shader Quality)
Шейдеры — это специальные программы для вашей видеокарты, исполняемые ее процессором. Грубо говоря, это такие «инструкции» от игры вашей GPU, по которым та понимает, как именно нужно отрисовывать тот или иной эффект. Чаще всего шейдеры используются для улучшения освещения, затенения, создания эффектов преломления лучей в воде (помните, как взрывала мозг та самая «шейдерная водичка из Half-Life 2: Lost Coast?), отражений, рассеиваний и так далее. Так что да, эта опция работает в тандеме с другими параметрами: качеством освещения и качеством теней. Существует три вида шейдеров: вершинные, геометрические и пиксельные, но игры, где можно отрегулировать качество каждого из них отдельно, встречаются невероятно редко.
Соответственно, чем выше качество шейдеров, тем лучше описанные выше эффекты, красивее тени и свет, реалистичнее геометрия — и тем сильнее нагрузка на видеокарту. Именно на видеокарту — потому что шейдеры считаются только GPU.
Влияние на производительность
Чаще всего — высокое. Например, в GTA V это один из самых «тяжелых» параметров в игре — снизив качество шейдеров с «Ультра» на средниее значение, вы получите прирост больше, чем в 15 FPS. Но бывает и так, что снижение этого параметра почти ничего не дает, как, например, в Mass Effect Anromeda.
Хроматическая аберрация – эффект, который вы наверняка отключаете в настройках игр. Зачем он вообще нужен?
Объясняем тренд.
Одна из самых часто встречающихся графических настроек в современных играх – хроматическая аберрация. По умолчанию эффект обычно включен, хотя многие геймеры отключают его при первой же возможности. Причина проста: без хроматической аберрации картинка выглядит «чище».
Так почему разработчики тратят силы, чтобы добавить в игры «лишнюю» постобработку, и кто ее придумал?
Хроматическая аберрация пришла в игры из кино
Происхождение у аберрации общее с другими неоднозначными эффектами постобработки: lens flare, motion blur, глубиной резкости, виньетированием и так далее. Изначально они появились в кинематографе.
Реальная хроматическая аберрация возникает при использовании фотоаппаратов и видеокамер. Из-за того, что лучи света разных цветов отличаются длиной волн, они преломляются в линзе камеры по-разному. Когда объективу не удается собрать все лучи в одну точку, цвета на полученных фото и видео искажаются. Сильнее всего это заметно по краям объектов: они размываются и расслаиваются на красный, зеленый и синий цветовые каналы.
Долгое время операторам и фотографам приходилось мириться с хроматической аберрацией – ее можно было только минимизировать, используя более дорогостоящие и качественные объективы. Со временем от нежелательного побочного эффекта научились избавляться на этапе постобработки: многие современные камеры компенсируют цветовые искажения с помощью встроенного процессора, также аберрацию можно убрать в графических редакторах при работе с RAW-форматами.
В то же время хроматическая аберрация стала настолько распространенным и привычным явлением, что ее начали относить к ретро-эстетике и оставлять (или даже добавлять) намеренно, добиваясь более «винтажного» вида фотографий или фильмов. Произошло то же, что и с lens flare, только в меньших масштабах: признак непрофессионализма превратился в осознанный стилистический прием.
(Здание на одном и том же кадре без хроматической аберрации и с ее сильным проявлением)
Аберрация в играх – попытка сделать их кинематографичнее
Хотя сами геймеры часто определяют крутость игровой графики, сравнивая ее с реальной жизнью, сами разработчики ориентируются в первую очередь на кинематограф. Логика простая: сделать картинку ближе кинематографичнее проще, чем приблизить ее к «чистой» реальности.
Эффекты вроде хроматической аберрации позволяют замаскировать технические недостатки игры и стилизовать ее простым приемом, который к тому же практически не сказывается на производительности. Нет смысла отключать аберрацию, чтобы игра работала лучше – из этого получится выжать примерно один дополнительный кадр в секунду, да и то не всегда.
(В Resident Evil 7 аберрация заметна, только если присмотреться, например, к раме)
Цель у хроматической аберрации в играх простая: «смягчить» контуры объектов, чтобы они подсознательно больше напоминали фильмы (и показанную в них реальность), а не компьютерную графику.
Понятное дело, в играх физической камеры нет, поэтому хроматическая аберрация симулируется: эффект просто добавляет сине-красные края объектам в кадре. Конкретная реализация, конечно, зависит от игры: где-то эффект бросается в глаза, в других случаях он едва заметен – примерно так же отличаются дешевые и дорогостоящие объективы.
Иногда эффект лучше оставлять включенным
Хроматическая аберрация набрала популярность в прошлом поколении консолей, когда игры повсеместно стали выглядеть (или пытаться выглядеть) «как кино». Аберрацию нельзя назвать объективным улучшением или ухудшением: ей нужно уметь пользоваться, а ее восприятие – исключительно субъективно. Часть игроков совершенно не терпит эффект, поскольку из-за него картинка становится менее четкой, другим дополнительная «киношность» по душе.
Правда, в зависимости от визуального стиля самой игры аберрация чаще может просто загрязнять кадр, чем дополнять его. Например, если игра в целом выглядит не очень хорошо или стилизована под мультяшный стиль – значит, на «киношный фотореализм» она претендовать не может. Тем не менее разработчики все равно добавляют постобработку – в таком случае эффект вызовет раздражение с большей вероятностью.
Куда уместнее использовать хроматическую аберрацию в проектах с реалистичным визуальным стилем: в The Last of Us: Part II, Red Dead Redemption 2 или, скажем, в «Сталкере 2». В них частичная нечеткость краев скорее сойдет за кинематографичность, чем за чужеродный визуальный эффект.
(Ползунок хроматической аберрации все чаще встречается в фоторежимах)
Другой вариант – применять хроматическую аберрацию там, где физическая (не игровая) камера используется по сюжету. Вот первая Life is Strange, например, выглядит слишком стилизованно, чтобы быть фильмом, но главная героиня увлекается фотографией, да и винтажные снимки играют ключевую роль в развитии сюжета. Поэтому здесь аберрация имеет хотя бы нарративный смысл.
Также, конечно, аберрацию стоит отключать в случаях, если из-за нее у вас сильнее устают глаза – такой побочный эффект тоже встречается.
У разработчиков нет объективных причин отказываться от хроматической аберрации в будущем: эффект очень просто реализовать, он не сказывается на оптимизации и зачастую делает игру визуально дороже (по крайней мере в глазах казуальных игроков, не вникающих в технологии). Главное, чтобы ее всегда можно было отключить в настройках – это логичное правило игровые студии обычно соблюдают.
Несколько советов по оптимизации производительности + Детальное описание настроек
Решил перенести тему в отдельный блог, так как предыдущий получился через-чур большим и неудобным для просмотра и редактирования. Тему дополнил скриншотами и забытыми в предыдущий раз пунктами 🙂
Несколько советов для повышения ФПС в игре, а так-же расшифровка настроек изображения:
ПОСТОБРАБОТКА:
— «Хроматическая аберрация» или что-то там. ФПС не меняет, эффект от нее странный. Призвана сделать изображение фотореалистичным или просто хромым. Пример:
— «Четкость изображения«, оно же шарп, искусственно делает изображение более четким. На фпс не влияет. Ставим по вкусу.
— «Световые шахты«(о, эта прекрасная русская локализация, в народе обзываются «лучами бога»), слабое влияние на фпс, не рекомендую отключать:
Основные настройки:
— Отключите вертикальную синхронизацию в игре, на мощных системах на производительность она не влияет, однако на видеокартах уровня 650TI/660/760/750ti и т.д, она отнимет 1-5 кадров, в зависимости от сцены. Вертикальная синхронизация убирает разрывы изображения в динамичных сценах. В Ведьмаке, я их редко замечаю, так что настройкой можно смело жертвовать, если вы не потомственный эстет.
— Включите НИЗКОЕ качество теней, поверьте, разницы вы не заметете, но освободите немного видеопамяти и получите приличный буст ФПС, особенно в городах и экшн сценах. Доказательство — сравнение низкого и ултра качества теней.
— Совет относительно травы от Mr.Nobody. , из комментариев ниже: «Вместо этого советую удалить файл Grass_ps,результат будет одинаковый НО при удаления файла Grass почему фризы исчезают напрочь,а при удаления травы через «GrassDensity» блокнотом фризы в некоторых местах все ровно остаются. Вот такая у поляков интересная оптимизация)))»
ОБЩИЕ СОВЕТЫ:
— Если совсем все плохо, то в настройках интерфейса можете отключить отображение миникарты, в ранних версиях игры (не знаю как сейчас, может так же) на некоторых конфигурациях отключение миникарты добовляло 4-5фпс. Но с тем же успехом можно отключить Геральта, уверен, что это тоже повысит ФПС 🙂
Видео-доказательство:
8 необычных детских игр и экспериментов
Что такое постобработка в играх сравнение картинок
Ambient Occlusion
В игре присутствует раздел эффектов постобработки. Практически все параметры имеют два состояния — эффект включен или выключен. Сюда же вынесены настройки режима глобального затенения. На нем остановимся подробнее.
По умолчанию игра всегда предлагает режим SSAO. По желанию можно переключиться на HBAO+. Есть возможность полного отключения Ambient Occlusion. Как меняется изображение в каждом из режимов, показано ниже.
В первой сцене, на рынке, мы видим, что SSAO делает общую картинку темнее из-за более насыщенных теней в сравнении с HBAO+. Это наиболее заметно по теням на стенах и под навесом торговых лотков. Полное отключение AO приводит к исчезновению полутеней и влияния объектов друг на друга. Во второй сцене ситуация иная. При HBAO+ у травы и кустов есть насыщенные тени, что выделяет их и придает объема всей картинке. С SSAO тени выражены слабее. Обратите еще внимание, как равномерно затенен склон бугра в левой части кадра и полностью отсутствуют тени от камней у его основания. С HBAO+ сам склон светлее, а тени от куста и камней более насыщенные. Без AO вообще нет никаких полутеней и теней от растительности на земле. В итоге трава сливается в одну зеленую массу — привлекательность итоговой картинки сильно страдает.
В итоге мы строго рекомендуем задействовать один из режимов AO. И после сравнения скриншотов видно, что наиболее привлекательная картинка, где растительность обретает максимум объема, обеспечивается с HBAO+. В этом режиме AO влияние объектов друг на друга учитывается наиболее полно. Это отчасти видно и по первой сравнительной сцене, где SSAO вроде бы дает более насыщенные тени. Если вы обратите внимание на лоток в центре кадра, то увидите небольшое затенение под бочкой и легкое затенение на бочке от соседнего ящика. Таких деталей при SSAO нет. Или обратите внимание на телегу слева. С HBAO+ освещенная сторона ярче, а вся нижняя часть колеса при этом темнее. В HBAO+ явно учитывается больше факторов для формирования итоговой картины затенения.
HBAO+ является и самым ресурсоемким режимом. SSAO позволяет выиграть несколько процентов производительности. Без AO производительность еще выше.
Постобработка
Теперь бегло рассмотрим особенности остальных параметров раздела постобработки и в конце взглянем, как они сказываются на производительности.
Параметры «Размытие» и «Размытие в движении» (Blur и Motion Blur) влияют на смазывание картинки при резких движениях. Это придает небольшой кинематографичный эффект и усиливает ощущение скорости.
Игра использует свой метод «сглаживания» при помощи постобработки наподобие FXAA и другим подобным методам.
Сглаживании нейтрализует лесенки и ступеньки на границах объектов, но немного теряется четкость деталей. Компенсировать это позволяет параметр «Повышенная четкость», который за счет обработки особыми фильтрами усиливает или ослабляет резкость изображения (Sharpen).
Влияние очевидно, и повышенная четкость кажется наиболее привлекательной. Но такая резкость может быть чрезмерной. Так что некоторым пользователям может прийтись по душе картинка и без такого эффекта — все будет зависеть от личного восприятия и монитора.
Эффект «Глубины кадра» (Depth of Field) немного размывает дальний план, позволяя достичь более естественного восприятия общей панорамы.
«Хроматическая абберация» (Chromatic Aberration) придает соответствующий фотоэффект. Трудно назвать его полезным, ведь он вносит небольшие искажения — боковые части изображения оказываются слегка не в фокусе. Но поскольку мы привыкли к фото- и видеоматериалам с такими визуальными особенностями, то это придает определенный ассоциативный эффект, позволяя улучшить субъективное восприятие игры. На эффект субъективного восприятие опирается и «Виньетирование» (Vignette), которое затемняет боковые области.
Отследить влияние этих эффектов лучше при постепенном их отключении. Ниже вы можете взглянуть на скриншот со всеми эффектами. Потом скриншот без виньетирования, а потом при отключении хроматической абберации.
В конце мы поговорим о влиянии двух параметров, заметно влияющих на итоговую картинку при определенном освещении. Это «Свечение» (Bloom) и «Световые шахты» (Light Shafts). Второй параметр при своем непонятном названии отвечает за формирование объемных лучей света. «Свечение» усиливает эффект ярких огней и формирует блики на поверхностях.
Лучше всего лучи света проявляются в динамике, когда мы проезжаем через заросли или лес. Но даже, если явных лучей нет, параметр оказывает существенное влияние на общую картинку. Возьмем для примера кадр из прошлого сравнения, когда включены все эффекты, в том числе Bloom и Light Shafts.
Отключение эффекта «Свечение» сразу делает изображение более темным и мрачным, словно солнце скрыто тучами в пасмурный день.
Отключение лучей света дает такой же эффект. Разница лишь в том, что при отключенном Bloom световое пятно от солнца на горизонте еще слабее.
Ну и в конце приведем этот же кадр при отключении обоих эффектов.
Выводы очевидны. Не рекомендуется отключать «Свечение» и «Световые шахты». Это может быть крайней мерой лишь на слабых видеокартах.
Ну а теперь рассмотрим влияние на производительность. За основу берем результаты GeForce GTX 960 при Ultra-качестве и поочередно отключаем один эффект, не трогая остальные.
Наиболее заметен эффект от отключения сглаживания, производительность поднимается на 3–5%. Чуть более процента удается выиграть при отключении одного из вариантов размытия. Пару процентов «съедает» свечение. Влияние остальных эффектов более незначительное. При комплексном отключении разных эффектов итоговый прирост должен быть больше. Что мы сейчас и проверим на практике.
Сравнение производительности в нестандартных режимах
Возьмем три видеокарты среднего класса — GeForce GTX 960, GeForce GTX 770 и Radeon R9 280X. При разрешении 1920×1080 и Ultra-качестве без HairWoks они немного не дотягивают до рубежа в 30 fps.
Попытаемся его достичь при постепенном отключении некоторых эффектов и снижении определенных параметров. Вначале откорректируем конфигурацию эффектов постобработки. Оставим режим затенения SSAO, «Свечение» и «Световые шахты», эффект максимальной резкости. Остальное отключим. Основные параметры пока не будем трогать.
Отключение второстепенных эффектов постобработки подняло производительность у всех участников на 7% и выше.
Теперь добавим к этой конфигурации настроек снижение качества теней с уровня «запредельно» до «высокого».
Получаем еще более существенный рост fps. При этом общая детализация не страдает. Хотя о полном комфорте говорить еще нельзя. Добиться идеального результата на тройке таких видеокарт позволит понижение дальности прорисовки растительности. Стоит отметить, что по мере изменения настроек лучше всех реагирует GeForce GTX 960, позволяя бюджетному новичку уверенно выйти в лидеры при снижении качества теней. Radeon R9 280X на это изменение реагирует наиболее вяло.
Выводы
Для того, чтобы получить максимум удовольствия от Witcher 3: Wild Hunt с максимальным качеством графики нужна мощная видеокарта последнего поколения. В разрешении 1920×1080 при всех параметрах на максимуме обеспечить полный комфорт может GeForce GTX 980. При 2K лучшим вариантом будет GeForce GTX 980 Ti, а для GeForce GTX 980 уже понадобится разгон. Radeon R9 290X уступает GeForce GTX 980, но по итогам сравнения можно предположить, что более новая версия в лице Radeon R9 390X будет почти сопоставима с конкурентом.
Динамическая тесселяция ландшафта
Введение
Описание примеров.1. Рендеринг ландшафта используя displacement mapping.2. Стыковка патчей с разным уровнем тесселяции.3. Использование предварительно сгенерированной текстуры с уровнем тесселяции.4. Увеличение детализации в зависимости от расстояния до камеры.5. Увеличение детализации в зависимости от размера патча на экране.6. Отсечение невидимых патчей.ЗаключениеИсходники
В данной статье рассматриваются статичные и динамические способы расчета уровня тесселяции, способы стыковки патчей с разной детализацией и алгоритм отсечения невидимых патчей. Перед чтением этой статьи рекомендуется ознакомится со статьей про аппаратную тесселяцию и displacement mapping. В каждой главе статьи используются свои шейдеры, для переключения между примерами используются клавиши
F1..F6
, для переключения режимов служат клавиши
1..8
или
(
и
)
— переключают на предыдущий и следующий режим соответственно. В качестве дополнительной возможности можно просматривать нормали и уровень тесселяции, для этого используются клавиши
C
,
N
,
T
,
M
— для вывода текстуры цвета, нормали, уровня тесселяции и смешанный режим: цвет и уровень тесселяции. Клавиша
R
служит для перезагрузки текущих шейдеров,
P
переключает между отображением сетки и полигонов. В примерах, где поддерживается изменение детализации используются следующие клавиши:
—
и
+
изменяет максимальный уровень тесселяции,
изменяет уровень детализации,
[
и
]
изменяет высоту ландшафта. Для перемещения используются клавиши
W
,
S
,
A
,
A
, для движения по вертикали —
Shift
,
Space
. В заголовке окна отображается выбраная часть примера, соответствующая части статьи, количество кадров в секунду, количество выведенных и сгенерированных вершин. Здесь как и в других примерах рисуется сетка размером 128х128 вершин, используются треугольные или квадратные патчи (в зависимости от примера). Квадратные патчи занимают меньше места — для одного патча используется 4 индекса против 6 для треугольного патча. Перед отрисовкой сетки устанавливается размер патча:
glPatchParameteri( GL_PATCH_VERTICES, 4 )
По умолчанию размер патча равен 3. Если не установить правильный размер патча, например поставить 3, когда в шейдере определен как 4, то ошибок не возникнет, но рисоваться будет неправильно. Для избежания подобных ошибок можно получать значение патча из шейдера функцией
glGetProgramiv
с параметром
GL_TESS_CONTROL_OUTPUT_VERTICES
, вернется значение определенное в control шейдере в строке:
layout(vertices = 4) out;
В evaluation шейдере происходит чтение из карты высот и нормалей, позиция смещается на высоту из карты высот, а нормаль передается в фрагментный шейдер, где может быть использованая для расчета освещения. В этом примере используется равномерная тесселяция квадратных патчей, уровень тесселяции фиксирован и равен максимальному значению, что сильно снижает производительность. В следующеих частях будет описана оптимизация рендеринга с сохранением качества. Что бы сохранить качество разбиения поверхности нужно использовать переменную детализацию, но при этом возникает проблема — соседние патчи могут иметь разную детализацию в результате чего между ними получаются разрывы. Поэтому для правильной стыковки патчей с разной детализацией используется параметр gl_TessLevelOuter. В примере для каждой вершины в вершинном шейдере задается случайное значение уровня тесселяции, переключая режимы клавишами
1
и
2
можно включать и отключать правильную стыковку. Результат неправильной стыковки:
На скриншоте видны множественные разрывы между патчами с разной детализацией. В control шейдере устанавливается уровень тесселяции на границе патча, для правильной стыковки нужно чтобы эти уровни совпадали. Это получается за счет одинакового выполнения функции расчета уровня тесселяции во всех шейдерах, в примерах это функция max:
max( Input[1].fLevel, Input[2].fLevel )
Можно использовать любые функции расчета, результаты которых для одинаковых ребер будут совпадать.
Треугольные патчи.
Для треугольных патчей используются только три значения из gl_TessLevelOuter. На нулевой индекс в gl_TessLevelOuter влияют вершины с индексом 1 и 2, на первый — 0 и 2, на второй — 0 и 1. Пример:
gl_TessLevelOuter[0] = max( Input[1].fLevel, Input[2].fLevel ); gl_TessLevelOuter[1] = max( Input[0].fLevel, Input[2].fLevel ); gl_TessLevelOuter[2] = max( Input[0].fLevel, Input[1].fLevel );
Квадратные патчи.
Для квадратных патчей используются все четыре значения из gl_TessLevelOuter. На нулевой индекс в gl_TessLevelOuter вилияют вершины с индексом 0 и 3, на первый — 0 и 1, на второй — 1 и 2, на третий — 2 и 3. Пример:
gl_TessLevelOuter[0] = max( Input[0].fLevel, Input[3].fLevel ); gl_TessLevelOuter[1] = max( Input[0].fLevel, Input[1].fLevel ); gl_TessLevelOuter[2] = max( Input[1].fLevel, Input[2].fLevel ); gl_TessLevelOuter[3] = max( Input[2].fLevel, Input[3].fLevel );
Значение gl_TessLevelInner могут быть любыми — они никак не влияют на правильную стыковку, но для равномерной тесселяции желательно брать максимальное или среднее значение уровней тесселяции ребер (gl_TessLevelOuter), например:
float max_level = max( max( Input[0].fLevel, Input[1].fLevel ), max( Input[2].fLevel, Input[3].fLevel ) ); gl_TessLevelInner[0] = max_level; gl_TessLevelInner[1] = max_level;
Стоит отметить, что при записи нулей в gl_TessLevelInner и gl_TessLevelOuter патч не создается, это свойство можно использовать для отсечения патчей, но так же стоит следить, чтобы отсечение не произошло случайно, поэтому в примере используется функция clamp:
clamp( Rand( inPosition ) * unMaxTessLevel, 1.0, unMaxTessLevel )
unMaxTessLevel — максимальный уровень тесселяции, определяется в приложении. В этом примере используется предварительно сгенерированная текстура с уровнем детализации для каждой вершины. Для хранения уровня детализации вполне хватит текстуры формата R8 разрешением 128х128 (один тексель на вершину). Код фрагментного шейдера gen_normal_and_tesslvl.prg состоит из двух функций:
ReadHeight
— считывает текстуру в матрицу 4х4, для этого используются 4 вызова функции textureGatherOffsets.
GenTessLevel
— функция генерации уровня детализации, расчитываются перепады высот между точками в два прохода: по вертикали и по горизонтали, результат нормализуется и записывается в текстуру. В шейдере тесселяции добавленно чтение уровня детализации в вершинном шейдере.
Как видно на скриншоте там где перепад высот больше уровень тесселяции тоже больше (красный цвет — максимальный уровень детализации), это позволило уменьшить количество полигонов более чем в 2 раза. Дальние полигоны имеют слишком высокий уровень детализации, чтобы исправить эту проблему используется следующий способ. Наибольшая детализация нужна вблизи камеры, а чем дальше от камеры, тем меньше детализация, в этом примере используется линейное изменение детелизации от расстояния до камеры. Уровень детализации для вершины расчитывается в вершинном шейдере, для этого служит функция Level:
unDetailLevel — уровень детализации. dist — расстояние от камеры до вершины, расчитывается оно так:
vec4 pos = unMVPMatrix * vec4( gl_Position.xyz + texture( unHeightMap, Output.vTexcoord1 ).r * Output.vNormal * unHeightScale, 1.0 ); Output.fLevel = Level( length(pos) );
Для правильного расчета расстояния необходимо переместить вершину на значение определенное в карте высот по нормале к поверхности и спроецировать в пространство экрана. После чего расчитывается расстояние до вершины. Так как камера всегда находится в центре координат, то достаточно узнать длинну вектора. Это все изменения, которые были внесены в программу, все достаточно просто и количество полигонов уменьшилось более чем в 10 раз.
В предыдущем примере дальние полигоны могли иметь недостаточную детализацию, особенно это заметно на больших полигонах, техника изменения уровня детализации в зависимости от размера полигона на экране исправляет эту проблему. В вершинный шейдер добавлен перевод позиции вершины в пространство экранна:
vec4 pos = unMVPMatrix * vec4( gl_Position.xyz + texture( unHeightMap, Output.vTexcoord1 ).r * Output.vNormal * unHeightScale, 1.0 ); Output.vScrCoords = pos.xy / pos.w;
В control шейдере расчитывается уровень тесселяции для каждого ребра:
gl_TessLevelOuter[0] = Level( Input[1].vScrCoords, Input[2].vScrCoords ); gl_TessLevelOuter[1] = Level( Input[0].vScrCoords, Input[2].vScrCoords ); gl_TessLevelOuter[2] = Level( Input[0].vScrCoords, Input[1].vScrCoords ); gl_TessLevelInner[0] = max( max( gl_TessLevelOuter[0], gl_TessLevelOuter[1] ), gl_TessLevelOuter[2] );
Функция Level возвращает уровень детализации в зависимости от размера ребра:
float Level(in vec2 p0, in vec2 p1)
unDetailLevel — уровень детализации, определяемый в приложении, как и в прошлом примере. Его значение слишком велико, поэтому используется коэффициент 0.01. У этого подхода есть несколько недостатков: 1. При движении меняется детализация сразу всех патчей — это вызывает мелькание, частично исправляется использованием высокой детализации и другого типа разбиения:
layout(triangles, fractional_even_spacing) in;
2. При вытягивании полигона его ребра могут сильно отличаться в размерах. В результате появляются области с низкой детализацией. Чтобы не вызвать проблемы со стыковкой патчей, нельзя повышать детализацию этих ребер — в соседних патчах не будет информации об этом. Решением данной проблемы может быть объединение с предыдущей техникой.