📄 3dbfcull.htm
字号:
<!--Header-->
<HTML>
<HEAD>
<TITLE>GPMega - Advanced Section - 3D Backface Culling</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/advanced/3dbfcull.htm/" + random_num + "/@Top'>");
document.write("<IMG SRC='http://www.ugo.net/RealMedia/ads/adstream_nx.cgi/www.perplexed.com/GPMega/advanced/3dbfcull.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="#FFF200">3</font><font color="#FFE500">D</font><font color="#FFD800"> </font><font color="#FFCB00">B</font><font color="#FFBE00">a</font><font color="#FFB100">c</font><font color="#FFA400">k</font><font color="#FF9700">f</font><font color="#FF8A00">a</font><font color="#FF7D00">c</font><font color="#FF7000">e</font><font color="#FF6300"> </font><font color="#FF5600">C</font><font color="#FF4900">u</font><font color="#FF3C00">l</font><font color="#FF2F00">l</font><font color="#FF2200">i</font><font color="#FF1500">n</font><font color="#FF0800">g</font><BR><FONT SIZE=-2>By: Jeff Weeks</FONT></H3>
<!--End Title-->
<P>In my previous chapter I introduced vectors and described some of their uses.
One of these uses was backface culling. I will now further expand upon this
and introduce this system which is used to reject non-visable polygons.
<P>As I said in my vector tutorial, the dot product can be used to find the measure
of the angle between two vectors. It's sign is also important because it alone
can tell a rough estimate of the angle. In backface culling the sign of the
dot product is enough to tell us which polygons are visable, and which are
not.
<P>There is a catch though. When defining polygons for an object, they must be
defined in counter-clockwise (or clockwise) order. Which ever you choose will
reflect wether you cull objects with a dot product greater than 0 or less than
(more on this later). This is a very simple requirement for such a powerful
device. On average, it can be said that half of the polygons in a polyhedron
are facing backwards, so, with this simple technique, you can remove 50% of
the work load from the rest of your routines!
<P>Okay, now that I've hopefully persuaded your of the importance of backface
culling, let's look at how it works. First you must calculate the normal
of the polygon you wish to test. This is done as shown in my vector
tutorial. It is reccomended that you precalculate polygon normals, ofcourse,
because it can save you calculating it each frame. While normalizing the
normal is not needed in backface culling, it will be in shading, etc. so
you might as well normalize the normal only once, rather than every frame.
<P>Next we have to calculate the view vector. This vector is defined by the
camera location (stationary at (0,0,0) for now) and any point on the polygon.
Simply subtract the two vertices to get this vector. Now you have a view
vector and a polygon vector (the normal). By finding the dot product
between these two you will get the angle between them. By examining the
meaning of the sign of the dot product, it should be obvious that if the
dot product is positive (or negative, if your polygon was described as
clockwise) then the polygon is visable, otherwise it is not visable.
<P><IMG SRC="culling.gif">
<P>So, to recap, the steps to determine if a polygon is visable or not are as
follows; First, calculate the polygon normal. Next, calculate the view
vector. Now find the dot product between these two vectors. At this
stage you only draw polygons that have a positive dot product (or negative
if the polygon was described as clockwise). Simple as that. For
completeness, I'll also include some code on how this might look:</P>
<BLOCKQUOTE>
<PRE><FONT SIZE=2 COLOR=RED>
int i;
Vector normal, // the polygon normal
camera(0,0,0), // the camera at 0,0,0
cv; // the camera vector (or view vector)
// Loop through all the polygons
for(i = 0; i < faces; i++)
{
// Transform our normal to view space...
// This example assumes you've already precalculated the normal and
// so all you must do is rotate it into world space by your matrix.
// See my vector tutorial on how to calculate a polygon normal.
normal = *face[i].normal;
normal = normal * to_world_space;
// Now calculate a vector from the camera to any point on the polygon
cv.set(camera, world_space[ face[i].vertex[0] ] );
// Now calculate the dot product of the normal and the camera vector
if((cv.dot(&normal) > 0))
{
// draw the polygon here, it's visible
}
}
</FONT></PRE>
</BLOCKQUOTE>
<!--Bottom Navigation-->
<A NAME="bottom"></A>
<!--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 + -