пятница, 30 июля 2010 г.

Сколково

Это Россия, сжатая до наноразмеров :)

четверг, 29 июля 2010 г.

Single point silhouette approximation

По-новой реализовал поиск силуэтов и построение теневого объёма на GPU. На этот раз я решил воспользоваться изюминкой Direct3D 11 и превратил структуру источника света в класс с собственными методами, т. к. гонять структуру по функциям aka C-style скучно.
Даже this поддерживается, хотя в SDK я не нашёл упоминания об этом keyword.


Раз уж я снова решил заняться мягкими тенями, то нужно рассказать об одной проблеме, которую необходимо преодолеть для достижения реалистичности пенумбры. Дело в том, что теневые объёмы (и карты теней тоже), строятся по упрощённой схеме - как они видны из центра источника света. Всё ок, пока нам нужны только примитивные, жёсткие тени или же мягкие тени, полученные каким-нить размазыванием жёстких (а что? пипл хавает). Но если источник света протяжённый, то shadow caster должен рассматриваться с позиций, по крайней мере, нескольких сэмплов на поверхности этого источника. В случае карт теней придётся рендерить кастер в отдельные карты N раз, в случае теневых объёмов - искать силуэт и вытягивать объём в геометрическом шейдере N раз. Это слишком сильно бьёт по производительности, и поэтому даже в случае мягких теней всё равно используют single point approximation.

К сожалению, такое отступление от честного подхода даром не проходит - пенумбра в некоторых случаях выглядит неестественно, как бы overshadowed, что портит впечатление. Особенно это заметно в случае penumbra wedges: авторы алгоритма как-то приводили картинки с искажённой пенумброй и эталоном, точно такие же отклонения были и у меня.


Кроме того, из-за аппроксимации силуэтные рёбра могут меняться неожиданным образом, перескакивая с ребра не ребро, если геометрия объекта грубая (коробка, например), что ведёт к penumbrae jumping.

В случае penumbra wedges выхода два: либо искать и рисовать теневые объёмы по N раз (а также рассчитывать N раз пенумбру в шейдере), либо искать силуэт каким-то особым образом, так, чтобы учесть все сэмплы на поверхности и. с. Учитывая, что теневые объёмы и так крайне прожорливы к филлрейту, первый вариант малореалистичен (хотя и очень прост в реализации). Интересен второй вариант, при котором учитываются все сэмплы, но дубликаты силуэтных рёбер при этом отбрасываются. Таким образом исходный теневой объём и пенумбра лишь немного "прибавят в весе". Неясно, насколько этот подход правилен, результаты сможет показать только тестовый рендер.

Хуже всего, что стандартными средствами Direct3D 11 невозможно отбрасывать рёбра-дубликаты, т. к. геометрический шейдер не имеет доступа к топологии всего меша. Кроме того, если на вход GS можно подавать индексированную геометрию, то на выходе получаем только неиндексированную. Т. е. shared by index вершины размножаются и мы никак не можем сохранить какое-то общее для них свойство (добавлены в силуэт или нет, например). Я продумал разные варианты поиска и отбрасывания дубликатов, и все они говорят одно - придётся подключать тормоз CPU. Но выходом может стать использование DirectCompute. Подключаем к CS буфер вершин и буфер индексов,  находим силуэтные рёбра и кладём их в append buffer. Вполне так неплохо может получиться: одно ребро - один тред, натравить целый мультипроцессор на меш, вот он нам всё быстро и посчитает.

Update

Реализовал на CPU расчёт от нескольких сэмплов и понял свою ошибку. Мы можем постараться и сделать силуэтное ребро уникальным (без дубликатов), но из него всё равно нужно вытягивать N квадов (где N - кол-во сэмплов, для которых ребро является силуэтным), при этом квады будут иметь разные направления! Другими словами, придётся рисовать теневой объём N раз.

Вот тесты для одного и четырёх сэмплов:



На этом простом примере, даже в wireframe ясно, насколько сильно разнится результат в случае протяжённого источника света, если мухлевать и считать честно. Неудивительно, что вроде бы "честный" метод penumbra wedges даёт нереалистичную пенумбру.

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

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

понедельник, 26 июля 2010 г.

Баг в геометрическом шейдере

Вот уже почти два часа ночи, и я нашёл, в чём причина бага.

Разница в том, что если использовать .fx формат D3DX, то с глобальными константами всё ок. Если же использовать простые шейдеры, то глобальные константы, например вида

const float4 g_plane = float4(1., 0., 0., 1.);

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

Зараза, хоть бы warning выдавал!

воскресенье, 25 июля 2010 г.

О слугах народа

«Утром мажу бутерброд – 
Сразу мысль: а как народ?
И икра не лезет в горло,
И компот не льется в рот...»

iPhone

Я так понимаю, что если Яблочники имеют наглось продавать свой ойФон по бешенным ценам, а миллионы его всё-таки покупают, то крызис уже закончился?

суббота, 24 июля 2010 г.

Inception

Посмотрел этот опус. Я разочарован. Ну почему, почему решительно все режиссёры после отличных картин (Нолан после "Тёмного рыцаря", Снайдер после "300") начинают снимать всякую охинею? Все эти небылицы со снами, которые понапридумывал тов. Нолан (претензия на "Матрицу"?), вызывают откровенную скуку и мысли о зря потраченных кровных. Постоянные стрелялки во снах с какими-то охранниками в костюмах заставляют искать в кинозале Кнопку Быстрой Перемотки, т. к. всё это "не по-настоящему", а значит полная туфта. Всё, заканчиваю рецензию, фильм не заслуживает более длинной. Ну вы короче всё поняли :)

P.S. Я, кажется, догадываюсь, кто сыграет камео Джокера в следующем "Бэтмене"!

пятница, 23 июля 2010 г.

Оптимизация

Сегодня по работе оптимизировал одну функцию в движке, длиной строк в 20. Всякие if-ы, array compaction, вызов glUniform*()... Беда в том, что эта функция вызывается много тысяч раз (> 50k), и это создаёт нагрузку на CPU и драйвер.

Надо было оптимизировать. Пораскинув мозгами, я вдруг понял, что можно применить принцип "лучше день потерять, зато потом за пять минут долететь". Осознав, что конкретно для этой функции можно сделать precompute данных, что можно реплицировать входные константы в несколько массивов и таким образом избежать "неизбежного" array compaction, что можно не делать switch по типу, а хранить адрес нужной функции, то переписав код функции и сделав рефакторинг уложился в одну строчку - тот самый вызов glUniform*() по адресу с предрассчитанными аргументами.

Ещё одним "открытием" стало то, что program object кэширует свои юниформы, так что данные в них выживают после смены программ. Благодаря этому оказалось возможным сделать проверку на предмет изменения данных и не телипать лишний раз API/драйвер если данные не изменились. Замер показал, что кол-во необходимых вызовов снижается до 5-6k, что при 400 DIP-ах является вполне приемлемым.

воскресенье, 18 июля 2010 г.

Глянец

Зарплата теперь позволяет мне приобретать такие штучки, на которые раньше я только пускал слюни. Вот и приобрёл для своего рабочего места монитор Samsung XL2370 с "ЭЛ-И-ДИ" подсветкой матрицы, т. к. пялиться в дешёвенькую девятнашку от Dell-a уже нет мочи: старый, маленький, VGA-DVI переходник мылит шрифты, ублюдский макосёвый интерфейс на этом мониторе еле помещается...



Я конечно, понимаю Ubisoft, да и любая другая компания в такой ситуации сэкономит - типа видно что-то, да и ладно! А т. к. крайним в такой ситуации остался именно я (начальству пох - у него бюджет), и пялиться в это "чудо" мне по 8 часов в день пять дней в неделю (четверть жизненного времени), то не долго размышляя, полазил по розетке и выбрал приглянувшийся девайс. Ну какой, какой смысл давить жабу, если крайним остался я сам? Всё равно он будет мой (хоть и на работе), смогу в любое время забрать, если что. Монитор, конечно, вышел дороговатым (барыги накрутили почти до 400$), зато покупаются такие девайсы с прицелом на 3-4 года эксплуатации (да и на глазах, как известно, не экономят). К тому же я хочу приходить на работу с радостью, зная, что там меня ждёт не дождётся кравивая и милая глазам вещь. Да, я таков! :)

Всё, довольно на сегодня.
P. S. Завтра ещё может быть выложу фотки монитора "вживую" и опишу его достоинства и недостатки.

Update
Кое-как нашёл время сфоткать обновку. На экране - заставка по мотивам Матрицы.

четверг, 15 июля 2010 г.

Ну глючит шейдер, чёрт бы его побрал!
:)

понедельник, 5 июля 2010 г.

No Doubt - Running

Нашёл у No Doubt прекрасную композицию - Running. Очень мило, и можно увидеть редкие кадры - историю No Doubt "в картинках".

Конец истории

Ну вот наконец и я добрался до IMAX-a и посмотрел Toy Story 3.
Что тут сказать - пожалуй, один из самых удачных мультфильмов Pixar, (наравне с великолепными Ratatouille и WALLE), завершивший трилогию Историй Игрушек.

Срежессирован и нарисован мастерски. Не думаю, что большинству зрителей интересны такие тонкости, но замечу, что игрушки Энди в 2010 выглядят точно так же, как и в 1995, что не может не радовать. Зато все усовершенствования RenderMan-а, внедрённые за эти годы, создатели применили в рендеринге окружения - объёмный свет, яркое солнце, сочная зелёная трава, DoF (не очень, кстати, уместный в стерео), и т. п. Больше деталей в людях, больше анимации в действиях, одним словом - мир Toy Story 3 ближе к настоящему, чем таковым был пластиковый мир первой серии, но вот сами игрушки, по задумке кудесников из Pixar, остались неподвластны времени.

Сюжет получился, на мой взгляд, удачным - без провалов и нелепиц, действия плавно перетекают одно в другое, постепенно подводя зрителя к финалу трилогии. Честно говоря, у меня в конце глаза становились влажными, т. к. я понимал, что Pixar показывают - здесь они навсегда прощаются со своими (может быть, самыми любимыми), творениями. Иногда хотелось крикнуть им: "Стойте, нет! Что же вы делаете, так нельзя!!!" Для тех, кто уже посмотрел мультфильм, в комментарии написан спойлер, для остальных же скажу, что всё закончилось в итоге благополучно (а как же иначе, мультик ведь детский).

Для граждан незалежной Украины: украинское озвучивание получилось на редкость хорошим и слух не резало - я даже не замечал, на каком языке ведутся диалоги. Одним словом, к озвучиванию подошли добросовестно. А ставший традиционным короткометражный мультфильм (на этот раз - Day & Night) озвучил... Арсений Яценюк, что лично мне было очень приятно. Уж не знаю, чья это была идея, и кто кому заплатил, но PR вашел удачным :)

Ну вот и всё, конец Истории Игрушек. Вердикт: успех. Если кто-то в детстве увлекался этим мультиком - идти однозначно.

P.S. Пару слов об IMAX. Ходил на этот формат впервые (Blockbuster в Киеве), стерео хорошее, без "призраков", хотя я ожидал немного большего. Сперва есть ощущение плоскости некоторых сцен, но через полчаса сознание приспосабливается и начинает охотнее верить в трёхмерность картинки. Экран как бы "нависает" над сидящими ниже зрителями, иногда кажется, что до него можно дотронуться рукой. Яркость из-за очков падает прилично.