Показать сообщение отдельно
Старый 25.04.2008, 16:05
mikleb вне форума Посмотреть профиль Отправить личное сообщение для mikleb Найти все сообщения от mikleb
  № 29  
Ответить с цитированием
mikleb

Регистрация: Feb 2008
Сообщений: 111
Бамп мэппинг:
(n, v) - скалярное произведение вектора n на v
Есть поверхность, и надо узнать степень освещенности каждой ее точки.

Степень освещенности точки поверхности = (n,v)
n - нормаль к поверхности в этой точке
v - анти-направляющий (т.е. направлен в противоположную сторону) вектор света который падает в эту точку.

Так как |n| =1 и |v|=1 и угол между n и v острый то 0 < (n,v)<=1 т.е степень освещенности это число от 0 до 1.

Теперь как хранить нормали:
Удобно хранить их в виде картинки, где цвет каждого пикселя будет кодировать нормаль к поверхности в данном пикселе (точке).
Каждая компонента вектора нормали это вещественное число от -1 до 1,
а каждая компонента вектора цвета (R,G,B) это целое число от 0 до 255.
Т.е нужно отрезок [-1,1] перевести в отрезок [0,255], это проще всего сделать линейным преобразованием. Поэтому если в данном пикселе нормаль к поверхности (x,y,z), то в карте нормалей цвет данного пикселя будет R=x*128+128, G=y*128+128, B=z*128+128. И обратно x=R/128-1, y=G/128-1, z=B/128-1.

Теперь нужно научится получать степень освещенности (обозначим ее S) произвольного пикселя по цвету данного пикселя в карте нормалей (обозначим его (R,G,B), а нормаль в этом пикселе (x,y,z)), и анти-направляющему вектору света в этом пикселе ( обозначим его (vx,vy,vz). S по определению = (n,v) = x*vx+y*vy+z*vz = (R/128-1)*vx+(G/128-1)*vy+(B/128-1)*vz = R*(vx/128)+G*(vy/128)+B*(vz/128)-(vx+vy+vz)

Карта освещенности это чернобелая картинка где цвет каждого пикселя = (R=S*256, G=S*256, B=S*256) (для каждого пикселя своё S)

Видно что вектор (S*256,S*256,S*256) ЛИНЕЙНО выражается через вектор цвета карты нормалей (R,G,B) , а именно:
(S*256,S*256,S*256) = ((2*vx) * R + (2*vy) * G + (2*vz) * B - 256*(vx+vy+vz), то же самое, то же самое)
Запишем матрицу этого линейного преобразования в массив a, только надо учти что alpha не меняется. Эта матрица будет одинаковой для каждого пикселя потому что у нас - параллельное освещение и (vx,vy,vz) постоянный для каждого пикселя. И применим к карте нормалей фильтр ColorMatrixFilter с этой матрицей который как раз и делает линейные преобразования над цветом каждого пикселя картинки.