Об трехмерную графику
У меня хобби - компьютерная обработка изображений. Когда-то давно, когда W98 еще считалась передовой операционкой по сравнению с W95, я прочитал хорошую книжку про трехмерную графику в Win, про пакет DirectX. И даже написал несколько программок, которые показывали всякие вращающиеся друг вокруг друга красивые планеты, с натянутыми на них разнообразными текстурами…
С тех пор дважды, а то и трижды, поменялись винды, сменилась версия компилятора С++, и программки эти приказали долго жить. :) Сам DirectX, конечно, никуда не делся. И коды-то программ остались, но на уровне вызовов процедур API DitectX-а это было настолько запредельно сложно (все равно как на голом С писать оконные приложения для Вин), что запала продолжать это как-то не хватило…
И вот как-то раз нам, аккурат перед Новым годом, попала в руки программка, реализующая алгоритм трассировки лучей методом Монте-Карло, содержащая всего 99 строк на С++! Мы ее, конечно, разобрали, адаптировали каждый под свой любимый компилятор, и начали по всякому гонять. Вот какие картинки она дает - пример вверху поста. Здесь мы видим некую комнату, образованную пересечением поверхностей пяти огромных сфер - программа может обсчитывать только шары. Сферы эти настолько большие, что видимые их поверхности кажутся плоскими. Одна из этих сфер - верхняя - пересечена сферой, тоже огромной, но чуть меньше. Ее кусочек виден на потолке в виде светящегося круга. Так зделано потому, что свет в программе может получаться только от светящихся объектов, а объектами такими, как я уже сказал, могут быть только сферы… Довольно остроумно… На полу комнаты лежит сфера прозрачная, внутри нее еще одна прозрачная, поменьше. Все это демонстрирует заинтересованному наблюдателю, как моделируется прохождение, преломление и отражение света в методе Монте-Карло.
Есть у этой программы и другой недостаток, кроме наличия одних только сфер… Она очень медленно работает. На картинке сверху показан результат расчета, когда на каждую точку экрана - картинки - было протрассировано 3600 лучей. Сколько она считала (на четырех распараллеленных процессах - используя одновременно 4 процессора), я уж сейчас не помню, несколько часов…
Вот результат расчетов с 300 лучами из каждой точки, продвинутый вариант, где делалась попытка вкрутить в программу еще и треугольники (основной элемент построения изображений).
Не то качество, не правда ли? А 4 процессора молотили порядка 300 секунд…
Поэтому я вспомнил старую добрую книжку про Direct3D, и начал программу эту модифицировать. Первым делом выкинул Монте-Карло. Пришлось добавлять свой свет, как это делается в D3D, там есть свет из бесконечности, рассеянный свет и свет произвольных точечных, но невидимых, источников. Потом вставил треугольники. Результаты все могли видеть в постах про иллюстрации к «Робинзону». (
http://victor-chapaev.livejournal.com/101921.html и
http://victor-chapaev.livejournal.com/102358.html )
Там много чего не хватает, в частности, теней. А ведь рассчитать тень очень просто, надо всего лишь из точки пересечения с объектом, на которой трассировка заканчивалась обычно, провести луч к источнику света. И если его что-то загораживает (пересеклись еще с чем-то, кроме источника) освещение от этого источника не учитывать. Долго я над этим бился, пока не обнаружил, что в программе две строчки местами переставил :) Но заработало.
Здесь тоже комната, но стены уже реально плоские (каждая из двух треугольников), есть два точечных источника света (их видно под потолком) и бесконечно удаленный источник, светящий в комнату со стороны наблюдателя. Ну и два шара, как без них.
Потом, раз уж я взялся трассировать лучи и после первого пересечения, я понял, что сделать зеркальную поверхность не представляет никаких трудностей.
Кстати, на скриншотах видно время, затрачиваемое четырьмя процессорами на расчет этой картинки - 1.6 секунды.
Нормальная программа трехмерной графики должна уметь натягивать на трехмерные объекты текстуры. Я решил, что мне достаточно будет наложить текстуру на треугольник.
Вот как с текстурами получается. Ничего, вроде…
Ну и напоследок - я понял, что текстура может иметь «прозрачные» цвета - через точки, окрашенные в этот цвет лучи будут проходить беспрепятственно. Попробовать, что ли?
Бенц! На картинке два зеркальных шарика смотрят друг на друга через дырку в стенке, поставленную между ними! А вокруг колосится золотая рожь, и гуляют девушки! И всего-то за 6.2 секунды
Право слово, с гораздо меньшими возможностями в девяностых создавались шедевры компьютерной графики.