21 июля 2011 г.

Flash3D, Molehill. Добавляем блик от источника света на AGAL

В прошлой записи к 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 комментария:

XProger комментирует...

Можно избавиться от neg в вершинном шейдере заменим порядок вычитания в sub. Ну и в фрагментном вместо max можно использовать sat (fc0.w не понадобится)

Иван комментирует...

Спасибо! Над оптимизацией еще не думал, исправлю.

Отправить комментарий