воскресенье, 29 ноября 2009 г.

Не хочется переполнять блог политическим флудом, но т. к. новые вещи пока в стадии активного research-а, и пока не придумал, чего-бы такого написать, вот замечательная статейка:

Россия сближается с Европой за счет Украины

понедельник, 23 ноября 2009 г.

Paper dragon

Вот по прошествии некоторого времени стало неясно: а чего NVIDIA вообще вылезла со своим "бумажным драконом"? Приостановить ажиотаж вокруг ATI? Грязно, товарищи, грязно. Вы же рвётесь на рынок суперкомьютеров и научных вычислений - и уже давно! ECC, double precision и унифицированные указатели - вот последние форпосты, которые мешали использовать NVIDIA GPU в кластерах и научных расчётах (Fermi, к слову, начал разрабатываться сразу после G80, т. е. в 2006 году, и один Бог ведает, что готовится сейчас на смену Fermi). Того и гляди, игровой рынок вообще пойдёт нвидии побоку - они научились делать процессоры лучше, чем Intel'овские - какие уж тут игры. За двумя зайцами не угонишься - или игры, или суперы, и не надо подрывать бизнес конкурента.

Как интересно, сделана тесселяция в новом чипе - дополнительными транзисторами, или всё через CUDA в драйвере? А если аппаратно, то становится интересно - что, чипы так и будут, вместе с тесселятором и останками fixed-function pipe стоять в кластерах? Или NVIDIA запустит несколько веток, где Tesla не будет содержать ничего, кроме CUDA ядер? В общем, интересно, как одна и та же архитектура будет позиционироваться для совершенно разных прикладных задач.

А стоить новые монстры будут по 600$, после торжественного выхода... весной. Зачем бумажный дракон?

вторник, 17 ноября 2009 г.

Ray-Tracing Super Sampling

После поисков в Гугле решил пока оставить процедурное сглаживание и реализовал SSAA. Идея проста: Сначала делается стандартный 1x проход, в дополнительный буфер пишутся ID треугольников. Потом запускается kernel 3x3 и пиксели с различными ID маскируются в стенсель-буфере. Затем запускается "тяжёлый" шейдер, который выпускает несколько лучей в одном пикселе по заданному паттерну смещений. Стенсель тест реджектит выполнение этого шейдера вне маски. Полученный результат усредняется и записывается в буфер кадра. Примеры:

Aliased render:

Edge mask detection:

Ordered grid 4x:

Rotated grid 4x:

Optimal N-rook 8x:

Что интересно, на этом маленьком примере падение скорости не от множества лучей в маске, а от прохода, ищущего эту самую маску.

воскресенье, 15 ноября 2009 г.

Ну очень крутой рендер

Не предел совершенства, конечно, но видна профессиональная рука:



Особенно мне понравился эффект "испорченного сигнала" монитора.

пятница, 13 ноября 2009 г.

О всяком

Реализовал двусторонние преломления с использованием двоичного поиска по буферу глубины, как я и хотел ещё летом. Для референса использовал трансформации в world space и линейный двоичный поиск, затем реализовал non-linear binary search in texture space. Функция получилась весьма эффективной, цикл занимает 14 инструкций, conservative - чуть больше. Последний я пока не использую, т. к. для выпуклых линз он необязателен. Вообще binary search штука замечательная, очень быстро сходится в нужной точке, а с float depth buffer так вообще сказка. С реализацией пришлось повозиться, конечно, зато теперь я уверен, что трёхмерный вариант работает аналогично тестовым двумерным. Полноэкранный шейдер на моей колымаге ковыляет со скоростью ~ 30 fps.

Скрины пока не выкладываю, надо полировать. Теперь думаю поместить внутрь линзы произвольный меш. Стоимость поиска увеличивается, конечно, т. к. теперь надо "перекапывать" два буфера глубины - один линзы, другой - меша.

Вчера пришла идея, как реализовать антиалиазинг при рэйтрейсинге (зачем мне этот антиалиазинг? - ну не могу я смотреть на эти лесенки!). Рендер в более высокое разрешение с последующим резолвом не годится - скорость. Но можно попробовать использовать тот факт, что наши рёбра - процедурные. Ведь сглаживают же процедурные текстуры (зебра, chekerboard) с помощью производных. Есть идея попробовать использовать барицентрические координаты для определения coverage пикселя. Рассмотрим процедуру рисования. Берём центр пикселя (или любое другое положение в пикселе, неважно, главное, чтобы оно было одинаковым для всех пикселей), это начало нашего луча. Ребро нашего треугольника - идеальный отрезок, алиазинг же происходит из-за двоичной природы теста на пересечение - луч попал/не попал. Очень часто может быть так, что треугольник покрывает часть пикселя, но центр пикселя не попадает в треугольник - не закрашиваем. А надо бы. Идея проста - смотрим, насколько далеко центр пикселя от ребра треугольника, и каким-то образом рассчитываем на основе этого coverage. А дальше, на основе coverage, смешиваем цвет на границе треугольника с цветом в буфере. Мне почему-то кажется, что это сработает. Я ещё покопаю сабж по процедурному сглаживанию и для пробы создам простую CPU реализацию.

Посмотрел "Письма с Иводзимы" Клинта Иствуда. Мораль такова: "Ты должен умереть за императора, и ниипёт".

среда, 11 ноября 2009 г.

Raycaster and MIP-filtering

На днях реализовал MIP-фильтрацию при рэйкастинге.

Вообще, я полагал что tex.Sample() правильно рассчитывает LOD текстуры только при содействии растеризатора. На самом деле это неправда! Оказалось, что LOD рассчитывается по производным правильно и в том случае, если рассчитанные при рэйкасте текстурные координаты приблизительно совпадают с интерполированными координатами из вершинного шейдера. При интерполяции через барицентрические координаты это именно так. Единственное, что не работает - выборка на рёбрах треугольника, т. к. производные от текстурных координат там неправильные. Представьте, что ребро треугольника проходит по центру квада 2x2. В одном пикселе мы получили пересечение и посчитали текстурные координаты, в другом пикселе - пересечения нет и текстурные координаты, скажем, равны 0. Тогда уже не получается правильно посчитать производные от текстурных координат к площади экрана, а значит, и степень наклона поверхности к экрану, и выбрать правильный LOD тоже нельзя. Получаются некрасивые "зазубрины" на рёбрах треугольников:



Не знаю, как эту ситуацию обрабатывает растеризатор, возможно, берётся LOD соседнего пикселя, или каким-то образом производные "достраиваются" в граничном кваде. Я заборол это следующим образом: считаю ddx() и ddy() от текстурных координат вне условия и проверяю abs значения. Если оно выше чем заданный эпсилон - производные неверные, мы на ребре треугольника. Тогда я просто делаю tex.SampleLevel() из нулевого MIP'а, иначе обычную выборку с анизотропной фильтрацией. Такой хак практически не виден даже при больших углах обзора:



[update]
Перечитал про производные и нашёл способ, гарантированно находящий неправильные производные на открытых рёбрах треугольников. Надо будет как-нить написать отдельный пост про это.

PS. И всё же, как растеризатор считает LOD на открытых рёбрах?

воскресенье, 8 ноября 2009 г.

NVidia OptiX

I'm waiting for Pacman and Space Invaders raytraced (this Pohl guy from Intel should port _them_ on LRB)

:)

70 и Бог

Решил утром прогуляться.

Взбираюсь на горку, тут меня останавливают мужчина с женщина средних лет. Первая реакция - хотят что-то втюхать, или может агитация за выборы... Нет, Свидетели. А вы верите в Бога, молодой человек? Нет, не верю - отвечаю я. Почему? А откуда, вы думаете, появился человек? И пошло-поехало. Первая реакция - надо валить но решил всё-таки задержаться. Рассказал вкратце им про материализм и научный метод. Затем понесло меня на геронтологиию, умпомянул про M-Prize и исследования в области старения клеток. Сказал, что если учёные со временем добьются успеха в этой области, Бог нам уже не понадобится. На сим категорично прервал беседу и пошёл дальше. Пускай подумают над этим, "свидетели" никем не виденного Бога. Впрочем и я, гуляя, тоже немало над этим поразмышлял...