⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 engine07.shtml

📁 关于windows游戏编程的一些文章还有相关图形
💻 SHTML
📖 第 1 页 / 共 2 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<html>
<head>
	<title>Dan's Tutorials: 07 - Radiosity lighting</title>
	<LINK REL="stylesheet" HREF="tutorial_styles.css">
</head>

<BODY BGCOLOR="white">
<a name="top"></a>
<BR>
<CENTER>
<!--
<br>
<DIV CLASS="main1">DAN'S</div><div class="main2">Programming Tutorials</DIV>
<br>
<TABLE WIDTH="700" BORDER="0" CELLPADDING="5" CELLSPACING="0">
<TR><TD BGCOLOR="black" ALIGN="center" VALIGN="center"><FONT FACE="arial" COLOR="white"><B>
[</B></FONT>
</TD><TD BGCOLOR="black" ALIGN="center" VALIGN="center" WIDTH="100"><FONT FACE="arial" COLOR="white"><B>
<A HREF="index.shtml">news</A></B></FONT>
</TD><TD BGCOLOR="black" ALIGN="center" VALIGN="center"><FONT FACE="arial" COLOR="white"><B>
|</B></FONT>
</TD><TD BGCOLOR="black" ALIGN="center" VALIGN="center" WIDTH="100"><FONT FACE="arial" COLOR="white"><B>
tutorials</B></FONT>
</TD><TD BGCOLOR="black" ALIGN="center" VALIGN="center"><FONT FACE="arial" COLOR="white"><B>
|</B></FONT>
</TD><TD BGCOLOR="black" ALIGN="center" VALIGN="center" WIDTH="100"><FONT FACE="arial" COLOR="white"><B>
<!--A HREF="Files.shtml"--><!--files</a></B></FONT>
</TD><TD BGCOLOR="black" ALIGN="center" VALIGN="center"><FONT FACE="arial" COLOR="white"><B>
|</B></FONT>
</TD><TD BGCOLOR="black" ALIGN="center" VALIGN="center" WIDTH="100"><FONT FACE="arial" COLOR="white"><B>
<a href="ResourcesWeb.shtml">links</a></B></FONT>
</TD><TD BGCOLOR="black" ALIGN="center" VALIGN="center"><FONT FACE="arial" COLOR="white"><B>
|</B></FONT>
</TD><TD BGCOLOR="black" ALIGN="center" VALIGN="center" WIDTH="100"><FONT FACE="arial" COLOR="white"><B>
<A HREF="Contact.shtml">contact</A></B></FONT>
</TD><TD BGCOLOR="black" ALIGN="center" VALIGN="center"><FONT FACE="arial" COLOR="white"><B>
]</B></FONT>
</TD></TR>
</TABLE>
-->
<BR>

<TABLE WIDTH="700" BORDER="0" CELLSPACING="0" CELLPADDING="0" ALIGN="CENTER" VALIGN="TOP">

<tr>
<td valign="top" align="left" width="200">

<TABLE WIDTH="200" BORDER="1" CELLPADDING="3" CELLSPACING="0">
<TR><TD BGCOLOR="silver" ALIGN="center">
<FONT FACE="arial" COLOR="black"><B>Table of Contents</B></FONT>
</TD></TR>
</TABLE>

<TABLE WIDTH="200" BORDER="0" CELLPADDING="3" CELLSPACING="0"><TR><TD>
<FONT FACE="arial" SIZE="-1">
<BR>
<CENTER><B>3D</B></CENTER>
Creating a cutting-edge engine<BR>
 &nbsp; <A HREF="Engine01.shtml">01 - Design document</A><BR>
 &nbsp; <A HREF="Engine02.shtml">02 - Overall structure</A><BR>
<BR>
 &nbsp; <A HREF="Engine03.shtml">03 - Binary Space Partitioning</A><BR>
 &nbsp; <A HREF="Engine04.shtml">04 - Constrctive Solid Geometry</A><BR>
 &nbsp; <A HREF="Engine05.shtml">05 - Portals</A><BR>
 &nbsp; <A HREF="Engine06.shtml">06 - Possible Visible Set</A><BR>
 &nbsp; <A HREF="Engine07.shtml">07 - Radiosity lighting</A><BR>
 &nbsp; <!--A HREF="Engine08.shtml"-->08 - Mirrors</A><BR>
<BR>
<!--A HREF="Dictionary.shtml"-->Dictionary of 3D terms</A><BR>
<BR>
<CENTER><B>OTHER</B></CENTER>
<!--A HREF="GeneticAlgorithm.shtml"-->A Genetic Algorithm</A><BR>
<A HREF="Line01.shtml">Line drawing</a><BR>
<!--A HREF="Line02.shtml"-->Line clipping</a><BR>
<!--A HREF="Line03.shtml"-->Line antialiasing</a><BR>
<!--A HREF="Line04.shtml"-->Line thickening</a><BR>
<!--A HREF="Line05.shtml"-->Line curving</a><BR>
<br>
<A HREF="ResourcesPrint.shtml">Resources in print</A><BR>
<A HREF="ResourcesWeb.shtml">Resources on the web</A><BR>
<!--A HREF="ResourcesFiles.shtml"-->Resources to download</A><BR>
<BR>
</FONT>
</TD></TR></TABLE>

</td>
<td valign="top" align="right" width="500">

<table width="475" border="0" cellpadding="3" cellspacing="0">
<tr><td bgcolor="silver">
<font face="arial"><b>07 - Radiosity lighting</b></font>
</td></tr>
<tr><td><font face="arial" size="-1">
Radiosity lighting is one of those things that makes everybody sit up and say "oh, my."  With a good
 level designer and a good texture artist radiosity can really look cool.  Even if you're doing it all
 by yourself and you have no artistic talent at all, radiosity can still make any level look better.
 Radiosity is to 3D what mayonnaise is to a smoked turkey and roast beef sandwich with lettuce...and
 tomato...excuse me, I'll be right back.<br>
<br>
Moo can cobe a fimple *gulp* You can code a simple radiosity calculator in a very short period of time.
 The only drawback is that the complexity of your calculator is inversely proportional to the speed at
 which it runs.  I think that's one of Murphy's laws.  The first step to setting up a radiosity
 calculator is to have an engine that can render light maps.  "Ah, but if you don't have light maps, how
 can you tell if it's rendering them?"  Use a hex editor and make some really simple grey scale light maps
 by hand to test.  There is one major decision to make at this point and it is: how detailed will your
 light maps be?  Quake had a maximum resolution of (I think) 32x32 which worked great until you had sharp
 contrasts on a big wall, it looked like a set of 'z's running down the wall.  You can opt for larger
 light maps or (if you're feeling up to it) you can make different sized light maps for different polygons.
 Who knows, two or three different sizes might actually save you some memory.<br>
<br>
<center><img src="0706.jpg" width="428" height="128" border="0" alt="texturemaps and lightmaps"></center>
<br>
Once you've got light maps working you've got a foundation to test on, so you can start writing the
 calculator.  I'm going to break each of the major concepts into separate groups, take your time to eat
 a sandwich or something between them 'cause it's heavy stuff.<br>
<br>
<hr>
 &nbsp; <b>The Radiosity Equation</b><br>
<br>
The concept of radiosity is pretty easy.  The reason more people haven't implemented it is because almost
 know one who understands it wants to talk about it, probably because they've all got high pay, high stress
 jobs that keep them far too busy.  Sounds to me like someone's bought their silence, probably some of
 those same guys who claim the whole Roswell thing was to keep Stalin scared the US had UFOs technology.
 Oh yeah, it's all so clear to me now...<br>
<br>
...My point being that once you get past all the integrals and the differential areas and a whole bunch of
 other fancy lingo it breaks down to this:  For every point on every surface everywhere in the world find
 the total amount of light incident at that point.  By incident I mean find all the light that is
 <i>absorbed</i>, <i>reflected</i> or <i>emitted</i> at that point.<br>
<br>
Think about that for a minute: if you're going to find every point on every surface blah blah blah, how
 big are your points?  I mean if they're infinitely small points then it would take forever to solve the
 equation.  Uh oh.  The solution is to break each surface into finite, bite size pieces called
 <i>patches</i> and average the light incident in each patch.  Once all the calculations are done the the
 patches can be converted back to light maps and voila!<br>
<br>
Before I show you how to figure out how much light travels from patch i to patch j there's one more very
 important point to touch on.  As I said, radiosity works by finding the amount of light incident at
 every point everywhere in the world <b>BUT</b> it is supposed to find these values <i>simultaneously</i>.
 Stay calm, it's not as bad as you might think.  When radiosity calculations were first invented there was
 a brute force solution - given that you had n patches you could build an n<sup>2</sup> matrix and (slowly)
 solve it until your first row or column had the light values at every point.  In today's world of highly
 complex geometries and the ever greater push to wow people with high polygon counts, a matrix just isn't a
 practical solution.<br>
<br>
Thus <i>Progressive Refinement</i> came to be.  The idea works like this:  Find the patch giving off the
 most light and send it's light to all the other patches.  Repeat until the brightest patch is giving off
 less than some really small value.  This means we have to keep track of both the radiosity (light incident)
 and the delta radiosity (amount of light being reflected) of each patch.<br>
<br>
 But is there anything else we need to keep track of?  Take a look at the wall for a second.  What is it
 you're seeing?  The light hitting the wall or the light being reflected?  If you said reflected, give
 yourself a back on the back.  Careful, you don't break the arm!  If we denote a patch n's radiosity as
 <b>B<sub>n</sub></b> then our equation so far is<br>
<br>
<center><img src="0701.jpg" width="125" height="100" border="0" alt="Beginnings of the radiosity eqn'"></center>
<br>
Where Pj is the amount of reflected light, some value in the range (0...1).  No sweat, right?  Well, this
 equation would only work if every patch was exactly the same size, shape and distance apart.  First of all,
 we can (for the most part) ignore a difference in shape but size is crucial. If you shine a light the size
 of a pin near a wall you'd see almost no change on the wall.  However the opposite is also true, if you held
 a pin sized dot near a well lit wall, you'd see the dot very clearly.  If we denote the area of a patch n as
 <b>A<sub>n</sub></b> then we've now got<br>
<br>
<center><img src="0702.jpg" width="225" height="100" border="0" alt="Radiosity eqn' continued..."></center>
<br>
Much better, but it still needs work.  What we're missing is the <i>Form Factor</i>, the most powerful part of
 the process.  If we weren't using patches, the form factor equation would look like this:<br>
<br>
<center><img src="0703.jpg" width="375" height="110" border="0" alt="Form factor eqn'"></center>
<br>
Yikes!  Thankfully we're using patches so we can take out all the integrals and simplify to<br>
<br>
<center><img src="0704.jpg" width="275" height="75" border="0" alt="Simpler form factor eqn'"></center>
<br>
Where
<ul>
<li><b>cos( theta i ) * cos( theta j )</b> is the angle between the normals of the planes of each patch.  This
 will make sure that a patch in front of a light source gets more light than one that's way off to a side.  It
 will also make sure that a patch that faces directly into the light will get more light than a patch that's
 turned away.
<li><b>pi * r<sup>2</sup></b> accounts for the distance between the two patches.  The further away, the dimmer
 the light.
<li><b>H( i, j )</b> is the visibility between patches i and j.  If there is no line of sight between i and j then
 H( i, j ) would be 0.  If there was full visibility between the two then H( i, j ) would be 1.  Naturally, H( i, j )
 can be some fraction in the range [0...1] if the line of sight is partially occluded (blocked)
<li><b>dAj</b> is the area of patch j.
</ul>
So our final patch to patch radiosity equation is<br>
<br>
<center><img src="0705.jpg" width="260" height="100" border="0" alt="Radiosity eqn' continued..."></center>
<br>
I know that seems weird multiply by dAj in the form factor and then dividing by dAj back in the main part of the
 radiosity equation but that's the way it goes.  Personally, I'd just simplify and remove both references.  Note that
 no one I spoke to would give me a straight, concise answer on what dAj was supposed to be in the form factor so it
 could be that I've totally screwed this up but if that were true my code wouldn't be working, would it? (:<br>
</font>
<pre>
<font color="green">/* Pseudocode for a simple radiosity calculator loop.
 * I highly reccomend using doubles everywhere, you
 * will need the extra precision.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -