?? 構建高級粒子系統.htm
字號:
<HTML><HEAD><TITLE>構建高級粒子系統</TITLE></HEAD>
<BODY>
<TABLE align=center bgColor=#000000 border=0 cellPadding=0 cellSpacing=0
height=1 width="99%">
<TBODY>
<TR>
<TD width="100%"></TD></TR></TBODY></TABLE><!-- #EndEditable -->
<TABLE align=center bgColor=#000000 border=0 cellPadding=2 cellSpacing=0
width="99%">
<TBODY>
<TR class=BGGray>
<TD width="100%"> <!-- #BeginEditable "%B6%A8%CE%BB" -->
<!-- #EndEditable --></TD></TR></TBODY></TABLE><BR>
<TABLE align=center border=0 cellPadding=0 cellSpacing=0 width="99%">
<TBODY>
<TR>
<TD class=BGRed width="1%"></TD>
<TD class=BGRed vAlign=top width="17%"><!-- #BeginEditable "%B5%BC%BA%BD" -->
<!-- #EndEditable --></TD>
<TD class=BGGray width="1%"></TD>
<TD width="1%"></TD>
<TD bgColor=#ff9933 width=0%></TD>
<TD colSpan=3 vAlign=top width="84%">
<TABLE border=0 cellPadding=2 cellSpacing=1 width="100%">
<TBODY>
<TR>
<TD class=BGRed width="100%"><B>>> </B><!-- #BeginEditable "%B1%EA%CC%E2" --><A class=YellowLink
href="http://mays.soage.com/develop/effect/200111/AParSystem.htm">構建高級粒子系統</A> 2001-11-22
<A class=BlackLink href="http://www.extremeworkteam.com/"
target=_blank>極限工作組</A> <A class=BlackLink
href="mailto:rick_yin@mail.china.com">Rick Cart </A><!-- #EndEditable -->
<TABLE align=center bgColor=#ff9933 border=0 cellPadding=0
cellSpacing=0 width="100%">
<TBODY>
<TR>
<TD width="100%"><IMG height=1
width=1></TD></TR></TBODY></TABLE></TD></TR>
<TR vAlign=top>
<TD class=BGGrayMain width="100%"><!-- #BeginEditable "%C4%DA%C8%DD" --><BR> <B>目
錄</B><BR> 1 <A class=BlackLink
href="http://mays.soage.com/develop/effect/200111/AParSystem.htm#1.0">性能和需要</A><BR> 2
<A class=BlackLink
href="http://mays.soage.com/develop/effect/200111/AParSystem.htm#2.0">創建數據結構</A><BR> 3
<A class=BlackLink
href="http://mays.soage.com/develop/effect/200111/AParSystem.htm#3.0">函數</A><BR> 4
<A class=BlackLink
href="http://mays.soage.com/develop/effect/200111/AParSystem.htm#4.0">粒子管理器</A><BR> 5
<A class=BlackLink
href="http://mays.soage.com/develop/effect/200111/AParSystem.htm#5.0">小結</A><BR><BR>
<HR align=center noShade SIZE=1 width="95%">
<BR> 請大家想象游戲中的這樣一個場景:一枚火箭拖著尾煙劃過天際,突然火箭爆炸了,碎片四處飛濺。其中,一具生物的尸體向你飛來,它的碎片飛散開來,帶起蓬蓬血霧,然后在鏡頭上留下混亂的血肉痕跡。這個場景中的所有這些元素的共同點是什么呢?<BR> 是的,多數元素都是混亂的。但從技術的角度講,本場景中的大多數效果得益于一個優秀的粒子系統。煙,火花,血這些現代游戲中的效果通常使用粒子系統來創建。<BR> 為了實現這些效果,你需要構件一個粒子系統,而且不僅僅是一個簡單的系統。你所需要的是一個高級粒子系統,一個快速,便捷,可擴展的系統。如果你是初次接觸粒子系統,我推薦你先閱讀Jeff
Lander的文章(<SPAN class=English>The Ocean Spray in Your Face, Graphic
Content, July
1998</SPAN>)。Lander的文章和本文的區別在于,前者描述了粒子系統的基本概念,而這里我著重于如何構建更高級的系統。我將會隨本文提供完整的源代碼,你可以下載以驗證本系統。<BR><A
name=1.0></A><BR><B>1、性能和需要</B><BR> 高級粒子系統可能會需要大量的代碼,所以設計好數據結構是非常重要的。此外必須牢記如果設計欠佳,粒子系統會大幅降低刷新率,并且大多數的性能問題是由粒子系統帶來的內存管理問題引起的。<BR> 設計粒子系統時首先應該明白粒子系統大大增加每幀的可見多邊形數量。每個粒子可能需要四個頂點和兩個三角形。以此計算,一個場景中的2,000個可見的雪花粒子將增加4,000個可見的三角形。又因為大多數粒子是運動的,我們不能預先計算頂點緩沖,所以每一幀,定點緩沖都需要被改變。<BR> 技巧在于只執行盡量少的內存操作(分配和釋放)。這樣,如果一個粒子在一定時間后消亡,不要急著從內存中釋放。相反,用一個標志來記錄它是死亡還是重生(重新初始化)。然后當所有的粒子都被標為死亡時,釋放整個粒子系統。(包括系統中的所有粒子),如果系統是定常的,那么使系統保持存活。如果你想要重建系統或只想假入一個新的粒子,你應該根據粒子所屬的系統使用相應的默認設置/屬性來自動初始化粒子。<BR> 例如,我們在構建一個“煙”系統。當你創建或重建一個粒子時,你可能按表1中的值來設定(當然,血和煙的初始顏色,能量,大小,速度是不同的)。注意各個值亦依賴于系統本身的設定。如果你為煙系統設定風以使煙飄向左方,那么新粒子的速度必然不同于不受風影響的垂直升起的煙系統。如果你有一個定常的煙系統,且煙粒子的能量是零(如此你就看不見它了),你會想重新初始化它的設定以使它滿載能量地又從底部升起。有的粒子系統可能需要粒子以不同的方式被渲染。例如,你或許會想要幾種血系統,例如噴血,濺血,血池和濺在鏡頭上的血痕,等等。每個效果包含特定的粒子。“噴血”將渲染血在空中噴射的景象,當這些血噴在墻壁上,會調用“濺血”系統,營造出血跡在墻和地板濺開的效果。血池系統創建出某人被擊斃后地板上的幾灘血跡。<BR><BR>
<TABLE align=center bgColor=#000000 border=0 cellPadding=2
cellSpacing=1 width="70%">
<TBODY>
<TR class=BGRed>
<TD width="18%"><B><FONT color=#cccccc>數據類型</FONT></B></TD>
<TD width="26%"><B><FONT color=#cccccc>名稱</FONT></B></TD>
<TD width="56%"><B><FONT color=#cccccc>描述</FONT></B></TD></TR>
<TR bgColor=#ffffff>
<TD class=ColorCode vAlign=top width="18%">Vector3</TD>
<TD class=ColorCode vAlign=top width="26%">position</TD>
<TD vAlign=top width="56%">空間中的粒子位置</TD></TR>
<TR bgColor=#ffffff>
<TD class=ColorCode vAlign=top width="18%">Vector3</TD>
<TD class=ColorCode vAlign=top width="26%">oldPos</TD>
<TD vAlign=top width="56%">粒子的先前位置,有時有用</TD></TR>
<TR bgColor=#ffffff>
<TD class=ColorCode vAlign=top width="18%">Vector3</TD>
<TD class=ColorCode vAlign=top width="26%">velocity</TD>
<TD vAlign=top width="56%">粒子速度(position += velocity)</TD></TR>
<TR bgColor=#ffffff>
<TD class=ColorCode vAlign=top width="18%">dword</TD>
<TD class=ColorCode vAlign=top width="26%">color</TD>
<TD vAlign=top width="56%">粒子顏色(頂點顏色)</TD></TR>
<TR bgColor=#ffffff>
<TD class=ColorCode vAlign=top width="18%">int</TD>
<TD class=ColorCode vAlign=top width="26%">energy</TD>
<TD vAlign=top width="56%">粒子的能量</TD></TR>
<TR bgColor=#ffffff>
<TD class=ColorCode vAlign=top width="18%">float</TD>
<TD class=ColorCode vAlign=top width="26%">size</TD>
<TD vAlign=top width="56%">粒子的大小</TD></TR>
<TR bgColor=#ffffff>
<TD class=BGRed colSpan=3 vAlign=top>
<DIV align=center><B><FONT color=#cccccc>表1
粒子屬性</FONT></B></DIV></TD></TR></TBODY></TABLE><BR> 每個粒子系統都以一種獨特的方式工作。濺血和煙霧的渲染方式是有很大區別的。煙霧粒子通常面對活動鏡頭,而濺血則映射到血濺到的平面上。<BR> 當構建粒子系統時,必須考慮到游戲中所有可能的可變參數,并把他們靈活地建入系統。讓我們再次以煙霧系統為例。我們可能會想改變風的方向向量以使當汽車駛過煙霧時,煙粒子受到汽車帶起的風的影響。從這點你會意識到每一個系統對于自己的作用而言都是很特殊的。但如果我們想要以某種方式控制系統中還不被系統規則支持的粒子時,該怎么辦?為了達到這個目的,我們還需要創建一個“手工”粒子系統,以使我們能夠每幀刷新所有的粒子屬性。<BR> 最后我們要考慮的是在引擎層次中連接粒子系統的能力。或許我們想要為一支香煙連接一個煙霧系統或發光系統。如果角色移動,連接到香煙的粒子系統應該得到正確的刷新。這就是高級粒子系統的一些基本要求。在下一節,我將講述如何設計一個性能優良的數據結構以實現上述的所有特性。<BR><A
name=2.0></A><BR><B>2、創建數據結構</B><BR> 現在我們知曉我們需要什么樣的特性。圖1顯示了將要創建的系統的概貌。請注意在圖中有一個粒子管理器(<SPAN
class=English>Particle Manager</SPAN>),稍候我將對此做出解釋。<BR><BR>
<TABLE align=center border=0 cellPadding=2 cellSpacing=0
class=BGRed>
<TBODY>
<TR align=middle>
<TD><IMG height=212 src="AParSystem-1.gif"
width=354></TD></TR>
<TR align=middle>
<TD><FONT color=#cccccc><B>圖1
粒子管理器</B></FONT></TD></TR></TBODY></TABLE><BR> 在此我們采用從下到上的步驟來設計類,首先是粒子類(<SPAN
class=English>Particle
Class</SPAN>)。<BR> 粒子類。如果你曾經建過粒子系統,你會知道粒子必需的屬性。表1列出了其中一些常見的屬性。注意粒子的先前位置也可能有用。例如,你可能會想在一個粒子的先前和當前位置之間畫它。火花就是一個從中受益的好例子。你可以在圖2中看到我創造的火花效果。<BR><BR>
<TABLE align=center border=0 cellPadding=2 cellSpacing=0
class=BGRed>
<TBODY>
<TR align=middle>
<TD><IMG height=160 src="AParSystem-2.jpg"
width=387></TD></TR>
<TR align=middle>
<TD><FONT color=#cccccc><B>圖2
火花效果</B></FONT></TD></TR></TBODY></TABLE><BR> 色彩和能量屬性也能夠用來創建一些有趣的特效。在前一個粒子系統中,我在煙系統中使用色彩,這樣我能夠在場景中動態地為粒子進行光照渲染。能量值也是非常重要的。能量是與粒子的生命周期相關的-你可以利用這一點來判斷一個粒子是否消亡。而且由于某些粒子的色彩和強度隨時間變化(例如火花),你或許會想把它與定點色彩的Alpha通道值聯系起來。<BR> 我強烈推薦把粒子類的構造函數設為空,因為你并不想在構造的時候使用默認值,這是由于對大多數的例子系統來說,這些值總是不同的。<BR> 粒子系統類(<SPAN
class=English>The Particle System
Class</SPAN>)這個類是整個系統的核心。刷新粒子的屬性和設置粒子的形狀都在這個類中進行。我現有的粒子系統類使用我的3D引擎的節點類,其中包含例如位置向量、旋轉四元數和比例值的數據。由于我繼承了這個節點類的所有成員,我能夠在引擎的層次結構中連接我的粒子系統,使得引擎能夠改變粒子系統的位置,就如同上面討論過的香煙系統一樣。但如果你的引擎沒有層次支持,或者如果你在構建一個獨立的粒子系統,這就不需要了。表2列出了在粒子系統基類中你所需要的屬性。<BR><BR>
<TABLE align=center bgColor=#000000 border=0 cellPadding=2
cellSpacing=1 width="95%">
<TBODY>
<TR class=BGRed>
<TD width="18%"><B><FONT color=#cccccc>數據類型</FONT></B></TD>
<TD width="19%"><B><FONT color=#cccccc>名稱</FONT></B></TD>
<TD width="63%"><B><FONT color=#cccccc>描述</FONT></B></TD></TR>
<TR bgColor=#ffffff>
<TD class=ColorCode vAlign=top width="18%">Texture</TD>
<TD class=ColorCode vAlign=top width="19%">*texture</TD>
<TD class=EtoC vAlign=top width="63%">A pointer to a texture,
which all particles will use. For performance reasons, we only
use one texture for each individual particle system; all
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -