2010-02-10

Gouraud shading без канваса

Начну я, пожалуй, с картинки для привлечения внимания.
Смотреть, конечно же, лучше всего — в хроме. Fx, IE7 и IE8 ведут себя удовлетворительно, но всё же медленнее хрома (поэтому «квадратичность» эффекта увеличена); в опере ощутимо подтормаживает; ну а про IE6 и говорить не приходится — странные артефакты в течении секунд 10-15 и тормоза.

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

Отрисовка полигона происходит с помощью технологии scanlines: цикл проходит от самого верха до самого низа полигона, рассчитывая горизонтальные координаты отрезка и интерполируя значение освещённости на его концах. Таким методом можно рисовать только выпуклые полигоны, однако я бы посмотрел на того, кто будет использовать не выпуклые полигоны для 3D графики :)

Так как без канваса теряется возможность рисовать линии по точкам, то и возможность использовать z-buffer тоже отсутствует.

Заведомо невидимые полигоны отсекаются используя нормаль (если нормаль смотрит от камеры, то полигон заведомо не виден). Есть, правда, один тонкий момент — так как используется перспективная проекция, то возможны случаи, когда нормаль у полигона в порядке, но его будет перекрывать другой полигон.

В этом случае, поможет алгоритм художника — достаточно рисовать полигоны с самого дальнего, а те что ближе, перекроют его в случае необходимости. В общем случае, алгоритм художника даёт весьма посредственные результаты, но для вращающегося кубика его хватает за глаза.
Javascript & no canvas

Осталось только научить браузер рисовать линии с градиентом.
Была у меня, честно говоря, крамольная мысль использовать для этого SVG и VML, но я её отверг — слишком просто. А потому я модифицировал метод применённый в Wolf 3D — картинка внутри дива.


Используются 2 картинки — одна с красным градиентом, вторая с синим. Градиент идёт сначала от чёрного к максимуму цвета, затем наоборот — это для случая, когда освещённость на левом конце отрезка выше, чем на правом.

Технические моменты

Код находится в обычном для него месте: http://nocanvas.zame-dev.org/0002/main.js

Чтобы правильно выводить почти одноцветные отрезки (освещённость левого и правого края отрезка различается мало либо равна), максимальная ширина картинки увеличена до 35000 пикселей (в Wolf 3D — 2048).

Изначально для каждого кадра генерировался html код и вставлялся во вьюпорт через innerHTML, однако браузеры каждые секунд 5-10 подтормаживали — видимо происходила сборка мусора; и метод пришлось изменить.

При старте заполняются два списка элементов — с красными градиентами и с синими. В процессе отрисовки линии, элементу просто присваиваются новые стили (памятуя статью на хабре про работу браузеров с DOM деревом, обновление стилей выполняется пачкой через cssText, а не классическим способом).

В конце фрейма лишние элементы прячутся (display:none).

Жизненные моменты

Я теперь больше не пользуюсь Windows 7 дома, и окончательно превратился в красноглазика — на прошлой неделе, придя вечером домой, и желая начать писать новый пост, я включил компьютер, и пошёл делать еду; в принципе, я мог бы и не включать плиту, так как готовить я мог прямо на радиаторе чипсета :)

Ноутбук с gentoo пришёлся весьма кстати, но фотошопа не хватает (это мой open source ноут, где всё ПО open source или на худой конец freeware).

Гимп он всё же написан программистами для программистов — в нём есть почти всё что есть в фотошопе (ну, наверное, кроме векторных масок), только этим всем жутко неудобно пользоваться.

4 comments:

  1. Да ну - удобно gimp-ом пользоваться. Как и vi - програмерам удобно :) Но не сразу понятно...
    Если прочитать про последовательности нажатий модификаторов и кнопок мыши - так совсем класс.

    ReplyDelete
  2. Если мышкой протянуть по кубу, то можно выделить отдельный div и проследить за его эволюцией ;)
    На фольфе когда-то слуайно так вышло - очень удивился как же на самом деле он реализован оказался :)
    ps. интересно, но врятли буду использовать

    ReplyDelete
  3. Lesha: вот я про то и говорю, что gimp он как и vi, для программистов :)

    ReplyDelete
  4. зря ты так, gimp вполне себе хорош

    ReplyDelete