56.htm 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. <!--
  2. demo.design 3D programming FAQ
  3. Idea, texts, screenshots:
  4. Andrew A. Aksyonoff,
  5. shodan@chat.ru
  6. Web-design, illustrations:
  7. Andrey Samoilov,
  8. asy@sense.simbirsk.su
  9. -->
  10. <html>
  11. <head>
  12. <title>demo.design 3D programming FAQ. Освещение. Как совместить текстуру и освещение.</title>
  13. <link rel=stylesheet href="../style.css" type="text/css">
  14. </head>
  15. <script language="javascript">
  16. <!--//
  17. browser = navigator.appName;
  18. version = parseFloat(navigator.appVersion);
  19. if (browser == "Netscape" && version >= 3.0) { jsenabled = 1; } else
  20. if (browser == "Microsoft Internet Explorer" && version >= 3.0) { jsenabled = 1; } else { jsenabled = 0; }
  21. function swap(img,ref) { if (jsenabled) {document.images[img].src = ref;} }
  22. function loadtocache(img,ref) { cache[img] = new Image(); cache[img].src = ref; }
  23. if (jsenabled) {
  24. cache = new Array();
  25. loadtocache(0,"../img/xdl.gif");
  26. loadtocache(1,"../img/xfaq.gif");
  27. loadtocache(2,"../img/xlinks.gif");
  28. loadtocache(3,"../img/xauthor.gif");
  29. loadtocache(4,"../img/xe.gif");
  30. loadtocache(5,"../img/xprev.gif");
  31. loadtocache(6,"../img/xnext.gif");}
  32. //-->
  33. </script>
  34. <body bgcolor=white><center>
  35. <!-- Title -->
  36. <img src="../img/b.gif" width=500 height=1 alt=""><br>
  37. <img src="../img/t.gif" width=500 height=1 alt=""><br>
  38. <img src="../img/b.gif" width=500 height=1 alt=""><br>
  39. <img src="../img/t.gif" width=500 height=2 alt=""><br>
  40. <table width=500 cellpadding=0 cellspacing=0 border=0>
  41. <td><img src="../img/t.gif" width=5 height=1 alt=""><a href="../main.htm" onmouseover="swap('logo','../img/xe.gif');" onmouseout="swap('logo','../img/e.gif');"><img src="../img/e.gif" name=logo width=60 height=50 hspace=10 border=0 alt=" в самое начало "></a></td>
  42. <td><p class=pagetitle><img src="../img/t.gif" width=265 height=1 alt=""><br>demo.design<br>3D programming FAQ</td>
  43. <td align=center><p class=navy><a href="../download.htm" onmouseover="swap('dl','../img/xdl.gif');" onmouseout="swap('dl','../img/dl.gif');"><img src="../img/dl.gif" name=dl width=40 height=40 border=0 hspace=5 alt=" download "></a><br>download</td>
  44. <td align=center><p class=navy><a href="../links.htm" onmouseover="swap('links','../img/xlinks.gif');" onmouseout="swap('links','../img/links.gif');"><img src="../img/links.gif" name=links width=40 height=40 border=0 hspace=5 alt=" коллекция линков "></a><br>links</td>
  45. <td align=center><p class=navy><a href="../author.htm" onmouseover="swap('author','../img/xauthor.gif');" onmouseout="swap('author','../img/author.gif');"><img src="../img/author.gif" name=author width=40 height=40 border=0 hspace=5 alt=" автора! "></a><br>author</td>
  46. </table>
  47. <img src="../img/t.gif" width=500 height=4 alt=""><br><img src="../img/b.gif" width=500 height=1 alt=""><br>
  48. <!-- Head -->
  49. <table width=500 cellpadding=0 cellspacing=10 border=0><td>
  50. <p class=title>
  51. <img src="../img/b5.gif" width=70 height=70 align=left hspace=0 alt="">
  52. <img src="../img/t.gif" width=5 height=70 align=left hspace=0 alt="">
  53. ОСВЕЩЕНИЕ<br>5.6. Как совместить текстуру и освещение
  54. <div align=justify>
  55. <!-- Article -->
  56. <p>Прежде всего, немного теории. Нам понадобится знать то, что конечный цвет
  57. пиксела с составляющими (r,g,b) и освещенного цветом (light_r,light_g,light_b)
  58. считается как
  59. <p class=expression>result_r = r * light_r / max(light_r);<br>
  60. result_g = g * light_g / max(light_g);<br>
  61. result_b = b * light_b / max(light_b);<br>
  62. <p>Здесь max(light_r) - это максимально возможное значение для light_r. Не
  63. максимальное по всем тем градациям освещенности, что мы используем, а вообще
  64. максимальное для всех возможных градаций. Например, если у нас значения для
  65. light_r могут гулять от 0 до 255, а текущий источник света имеет цвет (30,
  66. 40,50), то соответственно градации освещенности будут равны (k*30,k*40,k*50),
  67. где 0 <= k <= 1, то max(light_r) = 255, а не 30. Немного путаное объяснение,
  68. но вообще это известная и понятная почти всем вещь.
  69. <a name="561"></a>
  70. <p class=title><img src="../img/b5.gif" width=70 height=70 align=left hspace=0 alt=""><img src="../img/t.gif" width=5 height=70 align=left hspace=0 alt="">5.6.1. 256-цветные режимы
  71. <p>Метод 1: заранее посчитать таблицу, переводящую пару (цвет, освещенность) в
  72. цвет. Можно не менять палитру, а искать для каждой пары (цвет, освещенность)
  73. наилучшим образом приближающий ее цвет; а можно (как описано в demo.design
  74. FAQ) взять палитру и сгенерировать из нее true color картинку 256x256, в
  75. которой пиксел (x, y) нарисован цветом (уже true color!), соответствующим
  76. цвету x и освещенности y, а потом перевести ее чем-нибудь типа Image Alchemy
  77. в 256 цветов. После чего использовать палитру получившейся картинки, а в
  78. качестве таблицы (colorTable) будет сама получившаяся картинка:
  79. <p class=expression>outputColor = colorTable[intensity][color].<br>
  80. <p>Метод 2: если нас устроит использовать немного цветов и градаций освещения,
  81. то тогда в палитру можно впихнуть все возможные градации всех используемых
  82. цветов. Тогда определение нужного индекса в палитре - это одно умножение,
  83. а лучше - сдвиг, и одно сложение. Пример: пусть у нас есть 8 цветов и 32
  84. градации освещенности. Палитру заполняем так: 32 градации первого цвета,
  85. второго, ..., восьмого. Тогда (для этого примера)
  86. <p class=expression>outputColor = (color << 5) + intensity.<br>
  87. <a name="562"></a>
  88. <p class=title><img src="../img/b5.gif" width=70 height=70 align=left hspace=0 alt=""><img src="../img/t.gif" width=5 height=70 align=left hspace=0 alt="">5.6.2. 24/32-битные режимы
  89. <p>Здесь все делается теми же самыми таблицами. Только таблица переводит не
  90. цвет в цвет, а компоненту цвета в компоненту цвета. То есть, создаем
  91. таблицы redTable[numShades], greenTable[numShades], blueTable[numShades],
  92. а потом для каждой компоненты каждого пиксела и нужной градации освещенности
  93. по этой таблице определяем выходное значение компоненты:
  94. <p class=expression>r = redTable[intensity],<br>
  95. g = greenTable[intensity],<br>
  96. b = blueTable[intensity].<br>
  97. <p>Каждая компонента в этих режимах - это отдельный байт, поэтому никаких
  98. проблем не возникает.
  99. <a name="563"></a>
  100. <p class=title><img src="../img/b5.gif" width=70 height=70 align=left hspace=0 alt=""><img src="../img/t.gif" width=5 height=70 align=left hspace=0 alt="">5.6.3. 15/16-битные режимы
  101. <p>Метод 1: тупой, но действенный. Использовать большую таблицу и занести в нее
  102. все возможные комбинации цвета и градации освещения. Таблица получится совсем
  103. не маленькая, размером 65536*32 = 2 мегабайта. Я написал здесь 32, потому как
  104. в этих режимах на компоненту отводится по 5 бит (за исключением 6-битной
  105. зеленой компоненты в 16-битном режим), и делать больше градаций освещенности,
  106. чем 32, бессмысленно.
  107. <p>Метод 2: делать все так же, как в 24/32-битных режимах. Проблемы возникнут
  108. из-за того, что придется с муками выдирать нужные несколько бит компоненты
  109. из пиксела. Таблицы для компонент лучше заранее сделать со всеми нужными
  110. сдвигами, т.е. значения элементов таблиц должны быть такого вида:
  111. <pre class=formula>
  112. 000bbbbb - синий, 8 бит
  113. 00000gggggg00000 - зеленый, 16 бит
  114. rrrrr000 - красный, 8 бит
  115. </pre>
  116. <p>Тогда конечный цвет считается примерно так:
  117. <pre class=source>
  118. outputColor =
  119. (redTable[(color >> 10) & 0x2F] << 8) +
  120. greenTable[(color >> 5) & 0x1F] +
  121. blueTable[color & 0x1F].
  122. </pre>
  123. <p>На ассемблере это делается, видимо, побыстрее - и покрасивее. Примерно так:
  124. <pre class=source>
  125. ; ...
  126. mov bx,color
  127. shr bx,10
  128. and bx,02Fh
  129. mov ah,redTable[bx]
  130. mov bx,color
  131. and bx,01Fh
  132. mov al,blueTable[bx]
  133. mov bx,color
  134. shr bx,5 ; можно заменить на
  135. and bx,01Fh ; shr bx,4
  136. shl bx,1 ; and bx,02Eh
  137. or ax,greenTable[bx]
  138. mov outputColor,ax
  139. ; ...
  140. </pre>
  141. <p>Метод 3: рисовать все в 24/32-бита, освещение соответсвенно с текстурой
  142. совмещать по пункту <a href="#562">5.6.2</a>, а потом непосредственно при выводе на экран делать
  143. преобразование из 24/32-бит в 15/16. Или использовать PTC и предоставить
  144. делать нужное преобразование именно ему. PTC - это такая графическая система
  145. для C++, взять ее можно на <a href="http://www.gaffer.org/ptc/">http://www.gaffer.org/ptc</a>.
  146. </div>
  147. </td></table>
  148. <!-- Bottom Navigation -->
  149. <img src="../img/b.gif" width=500 height=1 alt=""><br><img src="../img/t.gif" width=500 height=2 alt=""><br>
  150. <table width=500 cellpadding=0 cellspacing=0 border=0>
  151. <td><img src="../img/t.gif" width=5 height=1 alt=""><a href="../main.htm" onmouseover="swap('logo2','../img/xe.gif');" onmouseout="swap('logo2','../img/e.gif');"><img src="../img/e.gif" name=logo2 width=60 height=50 hspace=10 border=0 alt=" в самое начало "></a></td>
  152. <td><p class=pagetitle><img src="../img/t.gif" width=265 height=1 alt=""><br>demo.design<br>3D programming FAQ</td>
  153. <td align=center><p class=navy><a href="55.htm" onmouseover="swap('prev','../img/xprev.gif');" onmouseout="swap('prev','../img/prev.gif');"><img src="../img/prev.gif" name=prev width=40 height=40 border=0 hspace=5 alt=" предыдущая статья "></a><br>previous</td>
  154. <td align=center><p class=navy><a href="../content.htm" onmouseover="swap('faq','../img/xfaq.gif');" onmouseout="swap('faq','../img/faq.gif');"><img src="../img/faq.gif" name=faq width=40 height=40 border=0 hspace=5 alt=" содержание "></a><br>content</td>
  155. <td align=center><p class=navy><a href="61.htm" onmouseover="swap('next','../img/xnext.gif');" onmouseout="swap('next','../img/next.gif');"><img src="../img/next.gif" name=next width=40 height=40 border=0 hspace=5 alt=" следующая статья "></a><br>next</td>
  156. </table>
  157. <img src="../img/t.gif" width=500 height=4 alt=""><br>
  158. <img src="../img/b.gif" width=500 height=1 alt=""><br>
  159. <img src="../img/t.gif" width=500 height=1 alt=""><br>
  160. <img src="../img/b.gif" width=500 height=1 alt=""><br>
  161. </center></body>
  162. </html>