[an error occurred while processing this directive]
2D Bump (Эффект неровной поверхности).
© Федор Цыплаков
Во многих демо используется
эффект 2D bump (2D рельефа), когда источник света (чаще всего окружность)
двигается по "рельефному" экрану.
Вот как это делается:
- Освещенность точки зависит от угла между нормалью каждого пиксела, и
источником света.
- Так как вектор нормали имеет три координаты (x,y,z), и мы знаем
координаты x и y, то z вычисляется по формуле z=1-sqrt(x*x+y*y). Если
непонятно, откуда взялась эта формула -- вам пора вспомнить геометрию ;)
- Так как в реальном времени это будет очень медленно, то создают
заранее таблицу предвыборки, где для каждого X и Y вычисляется значение
вектора Z. Эта таблица называется enviroment map (карта окружения).
Подобные карты используются и при текстурировании "зеркальных" объектов
(что намного проще, чем прямая трассировка :) Обычно хватает карты
размером 256х256. Генерить ее можно и с помощью 1-sqrt(x^2+y^2), и с
помощью синусов. В общем случае можно использовать любую модель
освещения - все зависит от того, что вы хотите получить :) .
Вот
пример построения простейшей карты:
int i,j;float x,y;
int density=128; //размер пятна
int bright; //количество оттенков
for (i=0;i<256;i++){
for (j=0;j<256;j++){
x=j/density-1;// (делается для того, чтобы прирвести координаты
y=i/density-1;// к значениям от -1 до 1)
z=1-sqrt(x*x+y*y);
z=z<0?z:0;
envmap[i][j]=z*bright;}}
Точка на экране для вышеприведенного случая рассчитывается по
формуле result=envmap[X нормали+density][Y нормали+density] (так как
точка наибольшей освещенности лежит посредине карты окружения)
Нормали X и Y рассчитываем так: xnorm=screen[x,y]-screen[x+n,y],
ynorm=screen[x,y]-screen[x,y+n].
Где n - число от (-5 до 5,n!=0)
Большие числа приводят к сильному ухудшению картинки. (А может вам и не
надо "правильное" отображение ? Тогда можно применять и большие числа)
Параметр n влияет на "высоту рельефа". Не забудьте, что при
отрицательных значениях n рельеф будет "вдавленным", при n>0 -
выпуклым.)
Это все касается неподвижного источника с
координатами (0,0,-бесконечность) Для того, чтобы пятно света двигалось,
нужно всего лишь из получившейся нормали вычесть разность координат
пиксела (освещенность которого рассчитывается) и координат источника
света. Окончательная освещенность точки получается такая:
result=envmap[(xnorm-(lx-x))][(ynorm-(lx-y))]
Получившееся значение сравнивается с границами допустимого
диапазона яркости, и , если нужно, исправляется в соответствии с этой
границей.
Пример.
lx,ly - координаты источника света. x,y - координаты точки
на экране и на бамп-текстуре. b_low,b_max - минимальный и
максимальный доустимый порог освещенности точки.
for (int y=0;y<200;y++){
for (int x=0;x<320;x++){
int xn=(bmap[x][y]-bmap[x+1][y])-(lx-x)+density;
int yn=(bmap[x][y]-bmap[x][y+1])-(ly-y)+density;
if (xnb_max) xn=b_low;
if (ynb_max) yn=b_max;
screen[x][y]=envmap[xn][yn];}}
Вот, собственно, и все.
Пояснительный
пример Оригинальная версия
документа(RAR-архив)
[an error occurred while processing this directive]
|