Связь и интернет Архив Программирование
   
Сделать стартовойСделать закладку            
   ПОИСК  
   
Главная / Алгоритмы / Графика / demodesign 3D programming FAQ /
8  Perl
8  PHP
8  JavaScript
8  HTML
8  DHTML
8  XML
8  CSS
8  C / C++
8  Pascal и Delphi
8  Турбо Ассемблер
8  MySQL
8  CASE-технологии
8  Алгоритмы
8  Python
8  Обратная связь
8  Гостевая книга
Новости о мире


Освещение - Программирование от RIN.RU
Освещение



Как совместить текстуру и освещение


Прежде всего, немного теории. Нам понадобится знать то, что конечный цвет пиксела с составляющими (r,g,b) и освещенного цветом (light_r,light_g,light_b) считается как


result_r = r * light_r / max(light_r);
result_g = g * light_g / max(light_g);
result_b = b * light_b / max(light_b);




Здесь max(light_r) - это максимально возможное значение для light_r. Не максимальное по всем тем градациям освещенности, что мы используем, а вообще максимальное для всех возможных градаций. Например, если у нас значения для light_r могут гулять от 0 до 255, а текущий источник света имеет цвет (30, 40,50), то соответственно градации освещенности будут равны (k*30,k*40,k*50), где 0 <= k <= 1, то max(light_r) = 255, а не 30. Немного путаное объяснение, но вообще это известная и понятная почти всем вещь.


256-цветные режимы


Метод 1: заранее посчитать таблицу, переводящую пару (цвет, освещенность) в цвет. Можно не менять палитру, а искать для каждой пары (цвет, освещенность) наилучшим образом приближающий ее цвет; а можно (как описано в demo.design FAQ) взять палитру и сгенерировать из нее true color картинку 256x256, в которой пиксел (x, y) нарисован цветом (уже true color!), соответствующим цвету x и освещенности y, а потом перевести ее чем-нибудь типа Image Alchemy в 256 цветов. После чего использовать палитру получившейся картинки, а в качестве таблицы (colorTable) будет сама получившаяся картинка:


outputColor = colorTable[intensity][color].


Метод 2: если нас устроит использовать немного цветов и градаций освещения, то тогда в палитру можно впихнуть все возможные градации всех используемых цветов. Тогда определение нужного индекса в палитре - это одно умножение, а лучше - сдвиг, и одно сложение. Пример: пусть у нас есть 8 цветов и 32 градации освещенности. Палитру заполняем так: 32 градации первого цвета, второго, ..., восьмого. Тогда (для этого примера)


outputColor = (color << 5) + intensity.


24/32-битные режимы


Здесь все делается теми же самыми таблицами. Только таблица переводит не цвет в цвет, а компоненту цвета в компоненту цвета. То есть, создаем таблицы redTable[numShades], greenTable[numShades], blueTable[numShades], а потом для каждой компоненты каждого пиксела и нужной градации освещенности по этой таблице определяем выходное значение компоненты:


r = redTable[intensity],
g = greenTable[intensity],
b = blueTable[intensity].




Каждая компонента в этих режимах - это отдельный байт, поэтому никаких проблем не возникает.


15/16-битные режимы


Метод 1: тупой, но действенный. Использовать большую таблицу и занести в нее все возможные комбинации цвета и градации освещения. Таблица получится совсем не маленькая, размером 65536*32 = 2 мегабайта. Я написал здесь 32, потому как в этих режимах на компоненту отводится по 5 бит (за исключением 6-битной зеленой компоненты в 16-битном режим), и делать больше градаций освещенности, чем 32, бессмысленно.


Метод 2: делать все так же, как в 24/32-битных режимах. Проблемы возникнут из-за того, что придется с муками выдирать нужные несколько бит компоненты из пиксела. Таблицы для компонент лучше заранее сделать со всеми нужными сдвигами, т.е. значения элементов таблиц должны быть такого вида:


000bbbbb - синий, 8 бит
00000gggggg00000 - зеленый, 16 бит
rrrrr000 - красный, 8 бит


Тогда конечный цвет считается примерно так:



outputColor =
(redTable[(color >> 10) & 0x2F] << 8) +
greenTable[(color >> 5) & 0x1F] +
blueTable[color & 0x1F].




На ассемблере это делается, видимо, побыстрее - и покрасивее. Примерно так:


; ...
mov bx,color
shr bx,10
and bx,02Fh
mov ah,redTable[bx]
mov bx,color
and bx,01Fh
mov al,blueTable[bx]
mov bx,color
shr bx,5 ; можно заменить на
and bx,01Fh ; shr bx,4
shl bx,1 ; and bx,02Eh
or ax,greenTable[bx]
mov outputColor,ax
; ...


Метод 3: рисовать все в 24/32-бита, освещение соответсвенно с текстурой совмещать по пункту 5.6.2, а потом непосредственно при выводе на экран делать преобразование из 24/32-бит в 15/16. Или использовать PTC и предоставить делать нужное преобразование именно ему. PTC - это такая графическая система для C++, взять ее можно на www.gaffer.org/ptc.

<<<  Назад
 1  2  3  4 


 8  Комментарии к статье  8 8  Обсудить в чате

 
  
  
    Copyright ©  RIN 2003 - 2004      * Обратная связь