2D Bump (Эффект неровной поверхности). c Федор Цыплаков Во многих демо используется эффект 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];}} Вот, собственно, и все.