📄 isodynlight.htm
字号:
<!--Header-->
<HTML>
<HEAD>
<TITLE>GPMega - Beginners Section - Isometric Dynamic Lighting Algorithm</TITLE>
</HEAD>
<BODY BGCOLOR=#000000 TEXT=#FFFFFF LINK=#00FF00 VLINK=#00FF00 ALINK=#0000FF>
<!--End Header-->
<!--Advertiser-->
<CENTER>
<TABLE>
<TR>
<TD>
<A HREF="http://www.ugo.com/">
<IMG SRC="/GPMega/ugologo120.gif" BORDER=0 WIDTH=120 HEIGHT=60></A>
</TD>
<TD>
<IMG SRC="/GPMega/sponsored.gif" WIDTH=468 HEIGHT=10><br><br>
<SCRIPT LANGUAGE= "JavaScript">
<!--
var now = new Date();
var random_num = now.getSeconds();
document.write("<A HREF='http://www.ugo.net/RealMedia/ads/click_nx.cgi/www.perplexed.com/GPMega/beginners/isodynlight.htm/" + random_num + "/@Top'>");
document.write("<IMG SRC='http://www.ugo.net/RealMedia/ads/adstream_nx.cgi/www.perplexed.com/GPMega/beginners/isodynlight.htm/" + random_num + "/@Top' BORDER='0' WIDTH='468' HEIGHT='60'></A>");
//-->
</SCRIPT>
</TD>
</TR>
</TABLE>
</CENTER>
<!--End Advertiser-->
<!--Splitter-->
<BR>
<!--End Splitter-->
<!--Body-->
<FONT SIZE=2 FACE=Helvetica>
<STRONG>
<!--Top Navigation-->
<A NAME="top"></A>
<CENTER>
<TABLE WIDTH=75%>
<TR VALIGN=MIDDLE>
<TD ALIGN=LEFT>
<IMG SRC="gradsplit2.jpg" WIDTH=100% HEIGHT=1><BR><BR>
<A HREF="http://www.perplexed.com/GPMega/"><IMG SRC="logo.jpg" BORDER=0 ALT="Home" WIDTH=80 HEIGHT=47 ALIGN=CENTER></A>
<FONT COLOR=#666666 FACE=HELVETICA SIZE=-1><I>
This Article Is Taken From <A HREF="http://www.perplexed.com/GPMega/">The Game Programming MegaSite</A>, A Definitive Resource For Game Developers!
</I></FONT><BR>
<IMG SRC="gradsplit2.jpg" WIDTH=100% HEIGHT=1>
</TD>
</TR>
</TABLE>
</CENTER>
<BR><!--End Top Navigation-->
<!--Title-->
<H3 ALIGN=CENTER><font color="#FFF800">I</font><font color="#FFF100">s</font><font color="#FFEA00">o</font><font color="#FFE300">m</font><font color="#FFDC00">e</font><font color="#FFD500">t</font><font color="#FFCE00">r</font><font color="#FFC700">i</font><font color="#FFC000">c</font><font color="#FFB900"> </font><font color="#FFB200">D</font><font color="#FFAB00">y</font><font color="#FFA400">n</font><font color="#FF9D00">a</font><font color="#FF9600">m</font><font color="#FF8F00">i</font><font color="#FF8800">c</font><font color="#FF8100"> </font><font color="#FF7A00">L</font><font color="#FF7300">i</font><font color="#FF6C00">g</font><font color="#FF6500">h</font><font color="#FF5E00">t</font><font color="#FF5700">i</font><font color="#FF5000">n</font><font color="#FF4900">g</font><font color="#FF4200"> </font><font color="#FF3B00">A</font><font color="#FF3400">l</font><font color="#FF2D00">g</font><font color="#FF2600">o</font><font color="#FF1F00">r</font><font color="#FF1800">i</font><font color="#FF1100">t</font><font color="#FF0A00">h</font><font color="#FF0300">m</font><BR><FONT SIZE=-2>By: Travis "Razorblade" Bemann</FONT></H3>
<!--End Title-->
<p>Isometric engines use 2D tiles masquerading as if they were in 3D, minus perspective. A problem with most isometric engines today is that they cannot have dynamic lighting with point light sources. This article does not explain isometric engines, but explains how to implement and use dynamic lighting in isometric engines.
<P>In most isometric engines, the light source is directional and is permanently fixed when the tiles are created. At the time of writing, there is only one isometric game that I know of that has point light sources, which is Command & Conquer 2: Tiberian Sun, but it has not come out yet as of writing this.
<P>The approach shown here uses specially made tiles in which each pixel has two values. The first value is a value which is the RGB color of the pixel, and the second value is a 8-bit value which designates the direction the pixel faces. The 8-bit value is actually a two 4 bit values, one which is the rotation of the normal of the pixel around the y axis in a right handed system, and the other being the elevation of the normal of the pixel.
<UL>
<LI>The rotation is from 0-15 with 0 designating 0 degrees, and 15 designating 360 degrees.
<LI>The elevation is from 0-15 with 0 designation straight down and 15 straight up.
</UL>
<P>Before each tile is drawn while rendering, a table of lighting values (monochromatic or
RGB) is calculated using the locations and distances of each light source. The
rotation/elevation combination for each direction acts as an index in this table. Here is
pseudocode for calculating this table in with simple monochromatic dynamic lighting as
well as ambient lighting:
<BLOCKQUOTE>
<PRE><FONT SIZE=2 COLOR=RED>
calculate tile lighting table
zero out table
from i = 0 to i = 15
from j = 0 to j = 15
table[i][j] = 0
calculate point lighting
from i = 0 to i = number of light sources
distance = sqrt((tile.x - light[i].x)^2 + (tile.y - light[i].y)^2 + (tile.z - light[i].z)^2)
if distance^2 < light[i].intensity
received_light = light[i].intensity - distance^2
if abs( light[i].x - tile.x ) = 0
if light[i].x - tile.x < 0
rotation_angle = 0
else
rotation_angle = pi
else
rotation_angle = atan(light[i].z - tile.z / light[i].x - tile.x)
if abs(light[i].z - tile.z) = 0
if light[i].z - tile.z < 0
elevation_angle = 0
else
elevation_angle = pi
else
elevation_angle = atan(light[i].y - tile.y / light[i].z - tile.z)
if elevation_angle > pi
elevation_angle = elevation_angle - pi
from r = 0 to r = 15
row_light = cos(rotation_angle - (2pi / 16) * r) * received_light
from e = 0 to e = 15
table[r][e] = table[r][e] + cos(elevation_angle - (pi / 16) * e) * row_light
calculate ambient lighting
from r = 0 to r = 15
from e = 0 to e = 15
table[r][e] = table[r][e] + ambient.intensity
</FONT></PRE>
</BLOCKQUOTE>
<p>In the pseudocode, table[i][j] is the table of
monochromatic lighting values, with the first index being the rotation of the normal
around the y axis and the second index being the elevation of the normal. tile.x, tile.y,
and tile.z indicate the location of the isometric tile the table is being generated for in
3D space. light[i].x, light[i].y, and light[i].z indicate the coordinates of each point
light. light[i].intensity is the power of each point light. ambient.intensity is the power
of the ambient light.
<P>The direction value with each pixel is used as an index in the lighting table as if the
lighting table had only one index, not two indexes. The lighting value is then extracted
from the selected location in the table and is used in draw the selected pixel in the
tile, but I will not discuss methods of doing this here because they are very dependent on
whether the isometric uses indexed or RGB colors, monochromatic or RGB lighting, and other
factors, such as quality vs. speed. All tiles must be assigned a location in 3D space in
this engine, even if they are assumed to be on the ground do to the details of this
engine. Unfortunately, tiles do not cast shadows with this engine.</p>
<!--Bottom Navigation-->
<!--End Bottom Navigation-->
</STRONG>
</FONT>
<!--End Body-->
<!--Bottom-->
<BR>
<IMG SRC="gradbar.jpg">
<BR>
<FONT SIZE=2 COLOR=#8B8B8B FACE=Helvetica>
<I><font color="#FBFBFB">T</font><font color="#F7F7F7">h</font><font color="#F3F3F3">e</font><font color="#EFEFEF"> </font><font color="#EBEBEB">G</font><font color="#E7E7E7">a</font><font color="#E3E3E3">m</font><font color="#DFDFDF">e</font><font color="#DBDBDB"> </font><font color="#D7D7D7">P</font><font color="#D3D3D3">r</font><font color="#CFCFCF">o</font><font color="#CBCBCB">g</font><font color="#C7C7C7">r</font><font color="#C3C3C3">a</font><font color="#BFBFBF">m</font><font color="#BBBBBB">m</font><font color="#B7B7B7">i</font><font color="#B3B3B3">n</font><font color="#AFAFAF">g</font><font color="#ABABAB"> </font><font color="#A7A7A7">M</font><font color="#A3A3A3">e</font><font color="#9F9F9F">g</font><font color="#9B9B9B">a</font><font color="#979797">S</font><font color="#939393">i</font><font color="#8F8F8F">t</font><font color="#8B8B8B">e</font> -
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -