В прошлой записи к 3-мерной сцене было добавлено рассеянное (диффузное) освещение. Но можно сделать освещение объектов чуть более естественным, добавив к нему блик от источника света. Сделать это не сложно. Следует лишь дополнительно учитывать положение наблюдателя в пространстве. Зная положение наблюдателя и положение источника света можно найти биссектрису между этими направлениями. Скалярное же произведение нормали и биссектрисы, возведенное в степень выбранного числа даст нам составляющую зеркального блика.
Вот измененный код вершинного шейдера:
m44 vt0, va0, vc0 mov op, vt0 mov v0, va1 m44 vt0, va0, vc4 m44 vt1, va2, vc4 nrm vt1.xyz, vt1.xyz mov v1, vt1 sub vt1, vt0.xyz, vc9.xyz sub vt2, vt0.xyz, vc8.xyz nrm vt1.xyz, vt1.xyz nrm vt2.xyz, vt2.xyz mov v2, vt1 mov v3, vt2
а вот фрагментного:
dp3 ft0.xyzw, v2.xyz, v1.xyz sat ft0, ft0 add ft2.xyz, v2.xyz, v3.xyz nrm ft2.xyz, ft2.xyz dp3 ft2.xyzw, v1.xyz, ft2.xyz sat ft2, ft2 pow ft2.xyzw, ft2.x, fc0.x tex ft1, v0, fs1 <2d,clamp,linear> mul ft0, ft1, ft0 add ft0, ft0, ft2 mov oc, ft0
Надо сказать, что данный алгоритм для блика не лучший. Это можно заметить, например, приблизив объект, чтобы пятно было крошечным. Но способы решения данной проблемы безусловно существуют.
Отсюда можно загрузить исходный код примера (*.rar, 4Mb). Помните, что пример создавался для Flash Player 11 Incubator.
2 комментария:
Можно избавиться от neg в вершинном шейдере заменим порядок вычитания в sub. Ну и в фрагментном вместо max можно использовать sat (fc0.w не понадобится)
Спасибо! Над оптимизацией еще не думал, исправлю.
Отправить комментарий