锘??xml version="1.0" encoding="utf-8" standalone="yes"?>
D3DXPlaneFromPointNormal( &plane, &vPoint, &vNormal ); //鐢熸垚榪欎釜騫抽潰
D3DXMatrixReflect( &matReflect, &plane ); //鍙栧緱璇ュ鉤闈㈢殑鍙嶅皠鐭╅樀
//璁劇疆鍓垏騫抽潰錛屼嬌鍙嶅皠闈笂鐨勫唴瀹硅娓叉煋錛岄潰涓嬬殑琚涪寮?
m_pd3dDevice->SetClipPlane( 0, plane );
m_pd3dDevice->SetRenderState( D3DRS_CLIPPLANEENABLE, 0x01 );
DX10涓嬫ā鎷燂細
User Clip PlanesUser Clip Planes are emulated by specifying a clip distance output from the Vertex Shader with the SV_ClipDistance[n] flag, where n is either 0 or 1. Each component can hold up to 4 clip distances in x, y, z, and w giving a total of 8 clip distances.
鐢ㄦ埛瑁佸噺騫抽潰閫氳繃鍦╒S閲岃瀹氫竴涓猄V_ClipDistance[n]鏍囪錛屽畾涔変竴涓鍑忚窛紱昏緭鍑哄緱鍒?n涓?鎴?銆傝繖閲屼竴鍏辮兘瀛樻斁8涓狢lip Plane璺濈錛屽垎鍒嬌鐢ㄦ暟緇勪袱涓厓绱犵殑x,y,z,w閫氶亾銆?/p>
In this scenario, each clip planes is defined by a plane equation of the form:
鍦ㄨ繖涓満鏅噷錛屾瘡涓猚lip plane琚竴涓鉤闈㈡柟紼嬪畾涔夛細
Ax + By + Cz + D =0;
Where <A,B,C> is the normal of the plane, and D is the distance of the plane from the origin. Plugging in any point <x,y,z> into this equation gives its distance from the plane. Therefore, all points <x,y,z> that satisfy the equation Ax + By + Cz + D = 0 are on the plane. All points that satisfy Ax + By + Cz + D < 0 are below the plane. All points that satisfy Ax + By + Cz + D > 0 are above the plane.
<A,B,C>鏄鉤闈㈡硶鍚戯紝D鏄鉤闈㈠埌鍘熺偣鐨勮窛紱匯傛妸浠繪剰鐐?lt;x,y,z>浠e叆鏂圭▼鑳藉緱鍒板畠鍒板鉤闈㈢殑璺濈銆傛墍鏈夋弧瓚蟲柟紼嬶紳0鐨勭偣鍦ㄥ鉤闈笂錛?lt;0鐨勭偣鍦ㄥ鉤闈笅鑰?>0鐨勭偣鍦ㄥ鉤闈笂銆?/p>
In the Vertex Shader, each vertex is tested against each plane equation to produce a distance to the clip plane. Each of the three clip distances are stored in the first three components of the output component with the semantic SV_ClipDistance0. These clip distances get interpolated over the triangle during rasterization and clipped if the value every goes below 0.
鍦╒S涓紝姣忎釜欏剁偣浼氬甫鍏ュ鉤闈㈡柟紼嬪仛嫻嬭瘯銆傛瘡涓笁瑙掑艦鐨凜lip璺濈瀛樺湪SV_ClipDistance0璇箟杈撳嚭鐨勫墠涓変釜閫氶亾涓傝繖涓窛紱誨湪鍏夋爡鍖栦腑琚嚎鎬ф彃鍊鹼紝鎵鏈夊皬浜?鐨勫儚绱犺鍓旈櫎銆?/p>
At the top level, the rendering steps look like the following:
//
// Calculates fog factor based upon distance
//
// E is defined as the base of the natural logarithm (2.71828)
float CalcFogFactor( float d )
{
float fogCoeff = 1.0;
if( FOGMODE_LINEAR == g_fogMode )
{
fogCoeff = (g_fogEnd - d)/(g_fogEnd - g_fogStart);
}
else if( FOGMODE_EXP == g_fogMode )
{
fogCoeff = 1.0 / pow( E, d*g_fogDensity );
}
else if( FOGMODE_EXP2 == g_fogMode )
{
fogCoeff = 1.0 / pow( E, d*d*g_fogDensity*g_fogDensity );
}
return clamp( fogCoeff, 0, 1 );
}
Finally, the pixel shader uses the fog factor to determine how much of the original color and how much of the fog color to output to the pixel.
鏈鍚庯紝PS浣跨敤闆懼寲鍙傛暟紜畾闆鵑鑹插拰綰圭悊棰滆壊鐨勬販鍚堢▼搴︺?br>return fog * normalColor + (1.0 - fog)*g_fogColor;
float Dsp = length(pointLightDir);
float3 L = pointLightDir/Dsp;
float thetas = acos(dot(N, L));
float lightIntensity = g_PointLightIntensity * 100;
//spotlight
float angleToSpotLight = dot(-L, g_SpotLightDir);
if(g_useSpotLight)
{ if(angleToSpotLight > g_cosSpotlightAngle)
lightIntensity *= abs((angleToSpotLight - g_cosSpotlightAngle)/(1-g_cosSpotlightAngle));
else
lightIntensity = 0;
}
//diffuse contribution
float t1 = exp(-g_beta.x*Dsp)*max(cos(thetas),0)/Dsp;
float4 t2 = g_beta.x*Gtable.SampleLevel(samLinearClamp, float2((g_beta.x*Dsp-g_diffXOffset)*g_diffXScale, (thetas-g_diffYOffset)*g_diffYScale),0)/(2*PI);
float rCol = (t1+t2.x)*exp(-g_beta.x*Dvp)*Kd*lightIntensity/Dsp;
float diffusePointLight = float3(rCol,rCol,rCol);
return diffusePointLight.xxx;
}
璁$畻楂樺厜錛?br>float3 Specular(float lightIntensity, float Ks, float Dsp, float Dvp, float specPow, float3 L, float3 VReflect)
{
lightIntensity = lightIntensity * 100;
float LDotVReflect = dot(L,VReflect);
float thetas = acos(LDotVReflect);
float t1 = exp(-g_beta*Dsp)*pow(max(LDotVReflect,0),specPow)/Dsp;
float4 t2 = g_beta.x*G_20table.SampleLevel(samLinearClamp, float2((g_beta.x*Dsp-g_20XOffset)*g_20XScale, (thetas-g_20YOffset)*g_20YScale),0)/(2*PI);
float specular = (t1+t2.x)*exp(-g_beta.x*Dvp)*Ks*lightIntensity/Dsp;
return specular.xxx;
}
涓嬩竴姝ワ紝鑰冭檻濡備綍涓嶉氳繃DX9鎺ュ彛錛岀洿鎺ュ鍏鏂囦歡銆?/p>
vector3 V = a_Ray.GetDirection();
vector3 R = L - 2.0f * DOT( L, N ) * N;
float dot = DOT( V, R );
if (dot > 0)
{
float spec = powf( dot, 20 ) * prim->GetMaterial()->GetSpecular() * shade;
// add specular component to ray color
a_Acc += spec * light->GetMaterial()->GetColor();
}
璁$畻闃村獎
// handle point light source
float shade = 1.0f;
if (light->GetType() == Primitive::SPHERE)
{
vector3 L = ((Sphere*)light)->GetCentre() - pi;
float tdist = LENGTH( L );
L *= (1.0f / tdist);
Ray r = Ray( pi + L * EPSILON, L );
for ( int s = 0; s < m_Scene->GetNrPrimitives(); s++ )
{
Primitive* pr = m_Scene->GetPrimitive( s );
if ((pr != light) && (pr->Intersect( r, tdist )))
{
shade = 0;
break;
}
}
}
eXtreme3D
緲昏瘧鑷竴綃囪佸鐨勬枃绔?lt;Binary Space Partioning Trees and Polygon Removal in Real Time 3D Rendering>,鏈鍚庝竴鐐規病鏈夌炕璇戝畬,鍛靛懙,涓嶅お濂芥剰鎬?!!!!
BSP鎶鏈綔涓哄鍐呭紩鎿庢覆鏌撶殑涓繪祦鎶鏈櫧鐒跺凡緇忓瓨鍦ㄥ騫?浣嗘槸鐢熷懡鍔涗粛鐒墮潪甯擱〗寮?鏈鏂扮殑DOOM3,HL2浠嶇劧灝嗗畠浣滀負娓叉煋鐨勪富嫻佹妧鏈?浣嗘槸鍦ㄧ綉涓婂瀹冧粙緇嶆枃绔犺櫧鐒跺鍗撮潪甯告祬鏄?澶у鏄嬌鐢≦3鐨凚SP鏂囦歡榪涜娓叉煋,鑰孊SP鏂囦歡濡備綍浜х敓鍒欎粙緇嶉潪甯稿皯,鐩栧洜涓鴻繖涓閮ㄥ垎鏄満鏅紪杈戝櫒鐨勫伐浣?鑰屽畬鎴愪竴涓繖鏍風殑BSP緙栬緫鍣ㄦ槸闈炲父鍥伴毦鐨?闇瑕佹帉鎻$殑鐭ヨ瘑闈炲父澶?涓嬮潰鎴戝皢瀵笲SP緙栬緫鍣ㄨ繖涓閮ㄥ垎闇瑕佺敤鍒扮殑BSP鐭ヨ瘑榪涜涓涓嬩粙緇?榪欏彧鏄竴浜涘緢鍒濇鐨勭煡璇?濡傚笇鏈涗簡瑙f洿澶氱殑鍐呭,Q2寮婧愪唬鐮佷腑鏈変竴涓狟SP緙栬緫鍣ㄧ殑浠g爜鏄綘鐮旂┒鐨勯噸鐐?榪樻湁灝辨槸HL2娉勯湶浠g爜涓殑緙栬緫鍣ㄤ唬鐮?(涓涓棝鑻︾殑鐮旂┒榪囩▼,鍙兘瑕佽姳璐逛綘鍑犱釜鏈堢敋鑷充竴騫寸殑鏃墮棿,涓嶈繃榪欐槸鍊煎緱鐨?濡傛灉浣犳兂瀹屾垚涓涓富嫻佺殑灝勫嚮娓告垙寮曟搸鐨勮瘽,娌℃湁BSP緙栬緫鍣ㄦ槸涓嶅彲鎯寵薄鐨?.
絎竴鑺?BSP Trees
BSP Trees鑻辨枃鍏ㄧО涓築inary Space Partioning trees錛屼簩緇寸┖闂村垎鍓叉爲錛岀畝縐頒負浜屽弶鏍戙傚畠浜?969騫磋Shumacker鍦ㄦ枃绔犮奡tudy for Applying Computer-Generated Images to Visual Simulation銆嬮嬈℃彁鍑猴紝騫惰ID鍏徃絎竴嬈′嬌鐢ㄥ埌FPS娓告垙Doom涓紝Doom鐨勬帹鍑鴻幏寰椾簡絀哄墠鐨勬垚鍔燂紝涓嶄粎濂犲畾浜咺D鍏徃鍦‵PS娓告垙寮鍙戠殑瀹楀笀鍦頒綅錛屼篃浣緽SP鎶鏈垚涓哄鍐呮覆鏌撶殑宸ヤ笟鏍囧噯錛屼粠BSP浜х敓鍒扮幇鍦ㄥ凡緇忔湁30澶氬勾浜嗭紝鍏墮棿铏界劧浜х敓浜嗗ぇ閲忕殑瀹ゅ唴娓叉煋鐨勭畻娉曪紝浣嗗嵈鏃犱漢鑳芥捈鍔ㄥ畠鐨勫湴浣嶏紝瀵逛簬浠ユ懇灝斿畾寰嬪彂灞曠殑璁$畻鏈轟笟鏉ヨ榪欎笉鑳戒笉鏄竴涓榪廣?br>涓轟粈涔堜嬌鐢˙SP Trees
涓涓狟SP Trees濡傚悓瀹冪殑鍚嶅瓧涓鏍鋒槸涓涓眰嬈℃爲鐨勭粨鏋勶紝榪欎釜鏍戠殑鍙惰妭鐐逛繚瀛樹簡鍒嗗壊瀹ゅ唴絀洪棿鎵寰楀埌鐨勫浘鍏冮泦鍚堛傜幇鍦ㄩ殢鐫紜歡鍔犻焃緙撳啿鐨勫嚭鐜幫紝鎴戜滑鍙渶瑕佺敤寰堝皬鐨勪唬浠峰氨鍙互瀵圭┖闂翠腑鐨勫浘鍏冭繘琛屾帓搴忥紝浣嗘槸鍦?0騫翠唬鍒濈敱浜庣‖浠剁殑闄愬埗錛屼嬌鐢˙SP鐨勪富瑕佸師鍥犳槸鍥犱負瀹冨彲浠ュ絀洪棿涓殑鍥懼厓榪涜鎺掑簭鏉ヤ繚璇佹覆鏌撳浘鍏冪殑欏哄簭鏄寜鐓х敱鍚庤嚦鍓嶈繘琛岀殑錛屾崲鍙ヨ瘽璇達紝Z鍊兼渶灝忕殑鐗╀綋鎬繪槸鏈鍚庤娓叉煋銆傚綋鐒惰繕鏈夊叾浠栫殑綆楁硶鍙互瀹屾垚榪欎釜鍔熻兘錛屼緥濡傝憲鍚嶇殑鐢誨綆楁硶錛屼絾鏄畠涓嶣SP姣旇緝璧鋒潵閫熷害澶參浜嗭紝榪欐槸鍥犱負BSP閫氬父瀵瑰浘鍏冩帓搴忔槸棰勫厛璁$畻濂界殑鑰屼笉鏄湪榪愯鏃惰繘琛岃綆椼備粠鏌愮鎰忎箟涓婅BSP鎶鏈疄闄呬笂鏄敾瀹剁畻娉曠殑鎵╁睍錛屾濡傚悓BSP鎶鏈殑鍘熷璁捐涓鏍鳳紝鐢誨綆楁硶涔熸槸浣跨敤鐢卞悗鑷沖墠鐨勯『搴忓鍦烘櫙涓殑鐗╀綋榪涜娓叉煋銆備絾鏄敾瀹剁畻娉曟湁浠ヤ笅鐨勭己鐐癸細
l 濡傛灉涓涓墿浣撲粠鍙︿竴涓墿浣撲腑絀胯繃鏃跺畠涓嶈兘琚紜殑娓叉煋錛?br>l 鍦ㄦ瘡涓甯у琚覆鏌撶殑鐗╀綋榪涜鎺掑簭鏄潪甯稿洶闅劇殑錛屽悓鏃惰繍綆楃殑浠d環闈炲父澶э紱
l 瀹冩棤娉曠鐞嗗驚鐜鐩栫殑鎯呭喌錛屽鍥炬墍紺?
鍥?.1
BSP鍘熺悊
寤虹珛BSP Trees鐨勬渶鍒濇兂娉曟槸鑾峰緱涓涓浘鍏冪殑闆嗗悎錛岃繖涓泦鍚堟槸鍦烘櫙鐨勪竴閮ㄥ垎錛岀劧鍚庡垎鍓茶繖涓浘鍏冮泦鍚堜負鏇村皬鐨勫瓙闆嗗悎錛岃繖閲屽繀欏繪敞鎰忓瓙闆嗗悎蹇呴』涓?#8220;鍑稿杈瑰艦”銆傝繖鎰忓懗鐫瀛愰泦鍚堜腑浠諱竴涓杈瑰艦閮戒綅浜庣浉鍚岄泦鍚堜腑鍏跺畠澶氳竟褰㈢殑“鍓嶉潰”銆傛槸涓嶆槸鏈夌偣闅句互鐞嗚В鍛紝涓句竴涓緥瀛愶紝濡傛灉澶氳竟褰鐨勬瘡涓涓《鐐歸兘浣嶄簬鐢卞杈瑰艦B鎵緇勬垚鐨勪竴涓潰鐨勬闈紝閭d箞鍙互璇村杈瑰艦A浣嶄簬澶氳竟褰鐨?#8220;鍓嶉潰”錛屽弬鑰冨乏鍥俱傛垜浠彲浠ユ兂璞′竴涓嬶紝涓涓洅瀛愭槸鐢?涓潰緇勬垚鐨勶紝濡傛灉鎵鏈夌殑闈㈤兘鏈濆悜鐩掑瓙鐨勫唴閮紝閭d箞鎴戜滑鍙互璇寸洅瀛愭槸涓涓?#8220;鍑稿杈瑰艦”錛屽鏋滀笉鏄兘鏈濆悜鐩掑瓙鐨勫唴閮紝閭d箞鐩掑瓙灝變笉鏄?#8220;鍑稿杈瑰艦”銆?nbsp;
鍥?.2
涓嬮潰璁╂垜浠湅涓涓嬪浣曠‘瀹氫竴涓浘鍏冮泦鍚堟槸鍚︽槸涓涓?#8220;鍑稿杈瑰艦”錛屼吉綆楁硶濡備笅錛?br>l 鍑芥暟CLASSIFY-POINT
l 鍙傛暟:
l Polygon – 紜畾涓涓?D絀洪棿涓偣鐩稿浣嶇疆鐨勫弬鑰冨杈瑰艦銆?br>l Point – 寰呯‘瀹氱殑3D絀洪棿涓殑鐐廣?br>l 榪斿洖鍊?
l 鐐逛綅浜庡杈瑰艦鐨勫摢涓杈廣?br>l 鍔熻兘:
l 紜畾涓涓偣浣嶄簬琚杈瑰艦瀹氫箟鐨勯潰鐨勫摢涓杈廣?br>CLASSIFY-POINT (Polygon, Point)
1 Sidevalue = Polygon.Normal * Point
2 if (Sidevalue == Polygon.Distance)
3 then return COINCIDING
4 else if (Sidevalue < Polygon.Distance)
5 then return BEHIND
6 else return INFRONT
l 鍑芥暟 POLYGON-INFRONT
l 鍙傛暟:
l Polygon1 – 鐢ㄦ潵紜畾鍏跺畠澶氳竟褰㈡槸鍚﹀湪鍏?#8220;鍓嶉潰”鐨勫杈瑰艦銆?br>l Polygon2 – 媯嫻嬫槸鍚﹀湪絎竴涓杈瑰艦“鍓嶉潰”鐨勫杈瑰艦銆?br>l 榪斿洖鍊?
l 絎簩涓杈瑰艦鏄惁鍦ㄧ涓涓杈瑰艦鐨?#8220;鍓嶉潰”銆?br>l 鍔熻兘:
l 媯嫻嬬浜屼釜澶氳竟褰㈢殑姣忎竴涓《鐐規槸鍚﹀湪絎竴涓杈瑰艦鐨?#8220;鍓嶉潰”銆?br>POLYGON-INFRONT (Polygon1, Polygon2)
1 for each point p in Polygon2
2 if (CLASSIFY-POINT (Polygon1, p) <> INFRONT)
3 then return false
4 return true
l 鍑芥暟 IS-CONVEX-SET
l 鍙傛暟:
l PolygonSet – 鐢ㄦ潵媯嫻嬫槸鍚︿負“鍑稿杈瑰艦”鐨勫浘鍏冮泦鍚堛?br>l 榪斿洖鍊?
l 闆嗗悎鏄惁涓?#8220;鍑稿杈瑰艦”銆?br>l 鍔熻兘:
l 鐩稿浜庨泦鍚堜腑鐨勫叾瀹冨杈瑰艦媯鏌ユ瘡涓涓杈瑰艦錛岀湅鏄惁浣嶄簬鍏跺畠澶氳竟褰㈢殑“鍓嶉潰”錛屽鏋滄湁浠繪剰涓や釜澶氳竟褰笉婊¤凍榪欎釜瑙勫垯錛岄偅涔堣繖涓泦鍚堜笉涓?#8220;鍑稿杈瑰艦”銆?br>IS-CONVEX-SET (PolygonSet)
1 for i = 0 to PolygonSet.Length ()
2 for j = 0 to PolygonSet.Length ()
3 if(i != j && not POLYGON-INFRONT(PolygonSet, PolygonSet[j]))
4 then return false
5 return true
鍦ㄥ嚱鏁癙OLYGON-INFRONT涓茍娌℃湁榪涜瀵圭О鐨勬瘮杈冿紝榪欐剰鍛崇潃濡傛灉澶氳竟褰浣嶄簬澶氳竟褰鐨?#8220;鍓嶉潰”浣犲茍涓嶈兘鎯沖綋鐒剁殑璁や負澶氳竟褰涓瀹氫綅浜庡杈瑰艦B鐨?#8220;鍓嶉潰”銆備笅闈㈢殑渚嬪瓙綆鍗曠殑鏄劇ず浜嗚繖涓鐐廣?br>
鍥?.3
鍦ㄥ浘1.3涓垜浠彲浠ョ湅鍒板杈瑰艦1浣嶄簬澶氳竟褰?鐨?#8220;鍓嶉潰”錛岃繖鏄洜涓洪《鐐筽3銆乸4浣嶄簬澶氳竟褰?鐨?#8220;鍓嶉潰”錛岃屽杈瑰艦2鍗存病鏈変綅浜庡杈瑰艦1鐨?#8220;鍓嶉潰”錛屽洜涓洪《鐐筽2浣嶄簬澶氳竟褰?鐨?#8220;鍚庨潰”銆?br>瀵逛簬涓涓狟SP灞傛鏍戞潵璇村彲浠ョ敤涓嬮潰緇撴瀯鏉ュ畾涔夛細
class BSPTree
{
BSPTreeNode RootNode // 鏍戠殑鏍硅妭鐐?br>}
class BSPTreeNode
{
BSPTree Tree // 鎺ョ偣鎵灞炵殑灞傛鏍?br>BSPTreePolygon Divider // 浣嶄簬涓や釜瀛愭爲涔嬮棿鐨勫杈瑰艦
BSPTreeNode *RightChild // 鑺傜偣鐨勫彸瀛愭爲
BSPTreeNode *LeftChild // 鑺傜偣鐨勫乏瀛愭爲
BSPTreePolygon PolygonSet[] // 鑺傜偣涓殑澶氳竟褰㈤泦鍚?br>}
class BSPTreePolygon
{
3DVector Point1 // 澶氳竟褰㈢殑欏剁偣1
3DVector Point3 // 澶氳竟褰㈢殑欏剁偣2
3DVector Point3 // 澶氳竟褰㈢殑欏剁偣3
}
鐜板湪浣犲彲浠ョ湅瑙佹瘡涓涓杈瑰艦鐢?涓《鐐規潵瀹氫箟錛岃繖鏄洜涓虹‖浠跺姞閫熷崱浣跨敤涓夎褰㈡潵瀵瑰杈瑰艦榪涜娓叉煋銆傚皢澶氳竟褰㈤泦鍚堝垎鍓蹭負鏇村皬鐨勫瓙闆嗗悎鏈夊緢澶氭柟娉曪紝渚嬪浣犲彲浠ヤ換鎰忛夋嫨絀洪棿涓殑涓涓潰鐒跺悗鐢ㄥ畠鏉ュ絀洪棿涓殑澶氳竟褰㈣繘琛屽垎鍓詫紝鎶婁綅浜庡垎鍓查潰姝i潰鐨勫杈瑰艦淇濆瓨鍒板彸瀛愭爲涓屼綅浜庡弽闈㈢殑澶氳竟褰繚瀛樺埌宸﹀瓙鏍戜腑銆備嬌鐢ㄨ繖涓柟娉曠殑緙虹偣闈炲父鏄庢樉錛岄偅灝辨槸濡傛灉鎯抽夋嫨涓涓皢絀洪棿涓殑澶氳竟褰㈠垎鍓蹭負涓や釜鐩哥瓑鐨勫瓙闆嗗悎鐨勯潰闈炲父鍥伴毦錛岃繖鏄洜涓哄湪鍦烘櫙涓湁鏃犳暟涓彲閫夋嫨鐨勯潰銆傚浣曞湪闆嗗悎涓夋嫨涓涓渶浣崇殑鍒嗗壊闈㈠憿錛熶笅闈㈡垜灝嗗榪欎釜闂緇欏嚭涓涓瘮杈冮傚綋鐨勮В鍐蟲柟妗堛?br>鎴戜滑鐜板湪宸茬粡鏈変簡涓涓嚱鏁癙OLYGON-INFRONT錛屽畠鐨勫姛鑳芥槸紜畾涓涓杈瑰艦鏄惁浣嶄簬鍏跺畠澶氳竟褰㈢殑姝i潰銆傜幇鍦ㄦ垜浠鍋氱殑鏄慨鏀硅繖涓嚱鏁幫紝浣垮畠涔熻兘澶熺‘瀹氫竴涓杈瑰艦鏄惁妯法榪囧叾瀹冨杈瑰艦瀹氫箟鐨勫垎鍓查潰銆傜畻娉曞涓嬶細
l 鍑芥暟 CALCULATE-SIDE
l 鍙傛暟 :
l Polygon1 – 紜畾鍏跺畠澶氳竟褰㈢浉瀵逛綅緗殑澶氳竟褰€?br>l Polygon2 – 紜畾鐩稿浣嶇疆鐨勫杈瑰艦銆?br>l 榪斿洖鍊?
l 澶氳竟褰?浣嶄簬澶氳竟褰?鐨勫摢涓杈?br>l 鍔熻兘:
l 閫氳繃絎竴涓杈瑰艦瀵圭浜屼釜澶氳竟褰笂鐨勬瘡涓涓《鐐硅繘琛屾嫻嬨傚鏋滄墍鏈夌殑欏剁偣浣嶄簬絎簩涓杈瑰艦鐨勬闈紝閭d箞澶氳竟褰?琚涓轟綅浜庡杈瑰艦1鐨?#8220;鍓嶉潰”銆傚鏋滅浜屼釜澶氳竟褰㈢殑鎵鏈夐《鐐歸兘浣嶄簬絎竴涓杈瑰艦鐨勫弽闈紝閭d箞澶氳竟褰?琚涓轟綅浜庡杈瑰艦1鐨?#8220;鍚庨潰”銆傚鏋滅浜屼釜澶氳竟褰㈢殑鎵鏈夐《鐐逛綅浜庣涓涓杈瑰艦涔嬩笂錛岄偅涔堝杈瑰艦2琚涓轟綅浜庡杈瑰艦1鐨勫唴閮ㄣ傛渶鍚庝竴縐嶅彲鑳芥槸鎵鏈夌殑欏剁偣鍗充綅浜庢闈㈡湁浣嶄簬鍙嶉潰錛岄偅涔堝杈瑰艦2琚涓烘í璺ㄨ繃澶氳竟褰?銆?br>CALCULATE-SIDE (Polygon1, Polygon2)
1 NumPositive = 0, NumNegative = 0
2 for each point p in Polygon2
3 if (CLASSIFY-POINT (Polygon1, p) = INFRONT)
4 then NumPositive = NumPositive + 1
5 if (CLASSIFY-POINT (Polygon1, p) = BEHIND)
6 then NumNegative = NumNegative + 1
7 if (NumPositive > 0 && NumNegative = 0)
8 then return INFRONT
9 else if(NumPositive = 0 && NumNegative > 0)
10 then return BEHIND
11 else if(NumPositive = 0 && NumNegative = 0)
12 then return COINCIDING
13 else return SPANNING
涓婇潰鐨勭畻娉曚篃緇欐垜浠В絳斾簡涓涓棶棰橈紝褰撲竴涓杈瑰艦妯法榪囧垎鍓查潰鏃跺浣曡繘琛屽鐞嗭紝涓婇潰鐨勭畻娉曚腑灝嗗杈瑰艦鍒嗗壊涓轟袱涓杈瑰艦錛岃繖鏍峰氨瑙e喅浜嗙敾瀹剁畻娉曚腑鐨勪袱涓棶棰橈細寰幆瑕嗙洊鍜屽杈瑰艦鐩鎬氦銆備笅闈㈢殑鍥懼艦鏄劇ず浜嗗杈瑰艦濡備綍榪涜鍒嗗壊鐨勩?br>
鍥?.4
濡傚浘1.4鎵紺猴紝澶氳竟褰?涓哄垎鍓查潰錛岃屽杈瑰艦2妯法榪囧杈瑰艦1錛屽鍥懼彸杈規墍紺猴紝澶氳竟褰㈣鍒嗗壊涓?銆?涓ら儴鍒嗭紝澶氳竟褰?浣嶄簬鍒嗗壊闈㈢殑“鍓嶉潰”鑰屽杈瑰艦3浣嶄簬鍒嗗壊闈㈢殑“鍚庨潰”銆?br>褰撳緩绔嬩竴涓狟SP鏍戞椂錛岄鍏堥渶瑕佺‘瀹氱殑闂鏄浣曚繚璇佷簩鍙夋爲鐨勫鉤琛★紝榪欐剰鍛崇潃瀵逛簬姣忎竴涓彾鑺傜偣鐨勫垎鍓叉繁搴﹁岃█涓嶈兘鏈夊お澶х殑宸紓錛屽悓鏃舵瘡涓涓妭鐐圭殑宸︺佸彸瀛愭爲闇瑕侀檺鍒跺垎鍓茬殑嬈℃暟銆傝繖鏄洜涓烘瘡涓嬈$殑鍒嗗壊閮戒細浜х敓鏂扮殑澶氳竟褰紝濡傛灉鍦ㄥ緩绔婤SP鏍戞椂浜х敓澶鐨勫杈瑰艦鐨勮瘽錛屽湪鍥懼艦鍔犻熷崱瀵瑰満鏅覆鏌撴椂浼氬姞閲嶆覆鏌撳櫒鐨勮礋鎷咃紝浠庤岄檷浣庡撫閫熴傚悓鏃朵竴涓笉騫寵 鐨勪簩鍙夋爲鍦ㄨ繘琛岄亶鍘嗘椂浼氳楄垂璁稿鏃犺皳鐨勬椂闂淬傚洜姝ゆ垜浠渶瑕佺‘瀹氫竴涓悎鐞嗙殑鍒嗗壊嬈℃暟浠ヤ究浜庤幏寰椾竴涓緝涓哄鉤琛$殑浜屽弶鏍戯紝鍚屾椂鍙互鍑忓皯鏂板杈瑰艦鐨勪駭鐢熴備笅闈㈢殑浠g爜鏄劇ず浜嗗浣曢氳繃寰幆澶氳竟褰㈤泦鍚堟潵鑾峰緱鏈浣崇殑鍒嗗壊澶氳竟褰€?br>l 鍑芥暟 CHOOSE-DIVIDING-POLYGON
l 鍙傛暟:
l PolygonSet – 鐢ㄤ簬鏌ユ壘鏈浣沖垎鍓查潰鐨勫杈瑰艦闆嗗悎銆?br>l 榪斿洖鍊?
l 鏈浣崇殑鍒嗗壊澶氳竟褰€?br>l 鍔熻兘:
l 瀵規寚瀹氱殑澶氳竟褰㈤泦鍚堣繘琛屾悳绱紝榪斿洖灝嗗叾鍒嗗壊涓烘渶浣沖瓙闆嗗悎鐨勫杈瑰艦銆傚鏋滄寚瀹氱殑闆嗗悎鏄竴涓?#8220;鍑稿杈瑰艦”鍒欒繑鍥炪?br>CHOOSE-DIVIDING-POLYGON (PolygonSet)
1 if (IS-CONVEX-SET (PolygonSet))
2 then return NOPOLYGON
3 MinRelation = MINIMUMRELATION
4 BestPolygon = NOPOLYGON
5 LeastSplits = INFINITY
6 BestRelation = 0
l 寰幆鏌ユ壘闆嗗悎鐨勬渶浣沖垎鍓查潰銆?br>7 while(BestPolygon = NOPOLYGON)
8 for each 澶氳竟褰1 in PolygonSet
9 if (澶氳竟褰1鍦ㄤ簩鍙夋爲寤虹珛榪囩▼涓病鏈変綔涓哄垎鍓查潰)
l 璁$畻琚綋鍓嶅杈瑰艦瀹氫箟鐨勫垎鍓查潰鐨勬闈€佸弽闈㈠拰妯法榪囧垎鍓查潰鐨勫杈瑰艦鐨勬暟閲忋?br>10 NumPositive = 0, NumNegative = 0, NumSpanning = 0
11 for each 澶氳竟褰2 in PolygonSet except P1
12 value = CALCULATE-SIDE(P1, P2)
13 if(value = INFRONT)
14 NumPositive = NumPositive + 1
15 else if(value = BEHIND)
16 NumNegative = NumNegative + 1
17 else if(value = SPANNING)
18 NumSpanning = NumSpanning + 1
l 璁$畻琚綋鍓嶅杈瑰艦鍒嗗壊鐨勪袱涓瓙闆嗗悎鐨勫杈瑰艦鏁伴噺鐨勬瘮鍊箋?br>19 if (NumPositive < NumNegative)
20 Relation = NumPositive / NumNegative
21 else
22 Relation = NumNegative / NumPositive
l 姣旇緝鐢卞綋鍓嶅杈瑰艦鑾峰緱鐨勭粨鏋溿傚鏋滃綋鍓嶅杈瑰艦鍒嗗壊浜嗚緝灝戠殑澶氳竟褰㈠悓鏃跺垎鍓插悗鐨勫瓙闆嗗悎姣斿煎彲浠ユ帴鍙楃殑璇濓紝閭d箞淇濆瓨褰撳墠鐨勫杈瑰艦涓烘柊鐨勫欓夊垎鍓查潰銆?br>l 濡傛灉褰撳墠澶氳竟褰㈠拰鏈浣沖垎鍓查潰涓鏍峰垎鍓蹭簡鐩稿悓鏁伴噺鐨勫杈瑰艦鑰屽垎鍓插悗鐨勫瓙闆嗗悎姣斿兼洿澶х殑璇濓紝灝嗗綋鍓嶅杈瑰艦浣滀負鏂扮殑鍊欓夊垎鍓查潰銆?br>23 if (Relation > MinRelation &&
(NumSpanning < LeastSplits ||
(NumSpanning = LeastSplits &&
Relation > BestRelation))
24 BestPolygon = P1
25 LeastSplits = NumSpanning
26 BestRelation = Relation
l 閫氳繃闄や互涓涓鍏堝畾涔夌殑甯擱噺鏉ュ噺灝戝彲鎺ュ彈鐨勬渶灝忔瘮鍊箋?br>27 MinRelation = MinRelation / MINRELATIONSCALE
28 return BestPolygon
綆楁硶鍒嗘瀽
瀵逛簬涓婇潰鐨勫嚱鏁版潵璇達紝鏍規嵁鍦烘櫙鏁版嵁澶у皬鐨勪笉鍚屽畠鍙兘鑺辮垂寰堥暱涓孌墊椂闂淬傚父閲廙INRELATIONSCALE鐢ㄦ潵紜畾鍦ㄦ瘡嬈″驚鐜椂鎵鍒嗗壊鐨勫瓙闆嗗悎澶氳竟褰㈡暟閲忕殑姣斿兼瘡嬈″噺灝戝灝戯紝涓轟粈涔堣浣跨敤榪欎釜甯擱噺鍛紝鑰冭檻涓涓嬶紝瀵逛簬緇欏畾鐨凪inRelation濡傛灉鎴戜滑鎵句笉鍒版渶浣崇殑鍒嗗壊闈紝閫氳繃闄や互榪欎釜甯擱噺灝嗘瘮鍊煎噺灝戞潵閲嶆柊榪涜寰幆鏌ユ壘錛岃繖鏍峰彲浠ラ槻姝㈡寰幆鐨勫嚭鐜幫紝鍥犳褰撹繖涓瘮鍊艱凍澶熷皬鏃舵垜浠繀瀹氬彲浠ヨ幏寰楀彲鎺ュ彈鐨勬渶浣崇粨鏋溿傛渶鍧忕殑浜嬫儏鏄垜浠湁涓涓寘鍚玁涓杈瑰艦鐨勯潪“鍑?#8221;闆嗗悎錛屽垎鍓插杈瑰艦灝嗛泦鍚堝垎鍓蹭負涓涓寘鍚玁-1涓杈瑰艦鐨勯儴鍒嗗拰涓涓寘鍚?涓杈瑰艦鐨勯儴鍒嗐傝繖涓粨鏋滃彧鏈夊湪鏈灝忔瘮鍊煎皬浜?/(n-1)鎵嶆槸鍙互鎺ュ彈鐨勶紙鍙傝冪畻娉曠殑19-23琛岋級銆傝繖鎰忓懗鐫MinRelation /MINRELATIONSCALEi < 1/(n-1)錛岃繖閲宨鏄驚鐜噸澶嶇殑嬈℃暟銆傝鎴戜滑鍋囪MinRelation鐨勫垵濮嬪寲鍊間負1錛岀敱浜庢瘮鍊兼案榪滀負0-1涔嬮棿鐨勫煎洜姝よ繖鏄渶鍙兘鐨勫鹼紙鍙傝冪畻娉曠殑19-22琛岋級銆傛垜浠湁
1 / MINRELATIONSCALEi < 1/(n-1)
1 < MINRELATIONSCALEi/(n-1)
(n-1) < MINRELATIONSCALEi
logMINRELATIONSCALE (n-1) < i
榪欓噷鐨刬娌℃湁涓婅竟鐣岋紝浣嗘槸鍥犱負i闈炲父鎺ヨ繎浜巐ogMINRELATIONSCALE (n-1)錛屾垜浠彲浠ョ畝鍗曠殑鍋囪涓よ呮槸鐩哥瓑鐨勩傚彟澶栨垜浠篃鍋囪MINRELATIONSCALE姘歌繙澶т簬鎴栫瓑浜?錛屽洜姝ゆ垜浠彲浠ユ湁
logMINRELATIONSCALE (n-1) = i
MINRELATIONSCALE >= 2
i = logMINRELATIONSCALE (n-1) < lg(n-1) = O(lg n)
鍦ㄥ驚鐜殑鍐呴儴錛屽澶氳竟褰㈢殑闆嗗悎闇瑕侀噸澶嶈繘琛屼袱嬈″驚鐜紝鍥犳瀵規垜浠潵璇存渶鍧忕殑鎯呭喌涓嬭繖涓畻娉曠殑澶嶆潅搴︿負O(n2lg n)錛岃岄氬父鎯呭喌涓嬭繖涓畻娉曠殑澶嶆潅搴︽帴榪戜簬O(n2)銆?br>鍦ㄥ嚱鏁癈HOOSE-DIVIDING-POLYGON鐨勫驚鐜腑鐪嬭搗鏉ュ鏋滀笉鍙戠敓浠涔堜簨鎯呯殑璇濆ソ璞℃案榪滀笉浼氬仠姝紝浣嗘槸榪欎笉浼氬彂鐢燂紝榪欐槸鍥犱負濡傛灉澶氳竟褰㈤泦鍚堜負闈?#8220;鍑?#8221;闆嗗悎鐨勮瘽鎬昏兘鎵懼埌涓涓杈瑰艦鏉ユ妸闆嗗悎鍒嗗壊涓轟袱涓瓙闆嗗悎銆侰HOOSE-DIVIDING-POLYGON鍑芥暟鎬繪槸閫夋嫨鍒嗗壊闆嗗悎鐨勫杈瑰艦鏁伴噺鏈灝戠殑澶氳竟褰紝涓轟簡闃叉閫夋嫨騫朵笉鍒嗗壊闆嗗悎鐨勫杈瑰艦錛屽垎鍓插悗鐨勫瓙闆嗗悎鐨勫杈瑰艦鏁伴噺涔嬫瘮蹇呴』澶т簬棰勫厛瀹氫箟鐨勫箋備負浜嗘洿濂界殑鐞嗚В鎴戜笂闈㈡墍璁茶В鐨勫唴瀹癸紝涓嬮潰鎴戝皢涓句竴涓緥瀛愭潵璇存槑濡備綍閫夋嫨涓涓杈瑰艦瀵逛竴涓緢灝戞暟閲忓杈瑰艦鐨勯泦鍚堣繘琛屽垎鍓層?/p>
鍥?.5
鍦ㄤ笂闈㈢殑渚嬪瓙涓棤璁轟綘閫夋嫨澶氳竟褰?銆?銆?榪樻槸澶氳竟褰?榪涜娓叉煋鏃墮兘涓嶄細鍒嗗壊浠諱綍鍏跺畠鐨勫杈瑰艦錛屾崲鍙ヨ瘽璇翠篃灝辨槸鎵鏈夌殑鍏跺畠澶氳竟褰㈤兘浣嶄簬榪欎簺澶氳竟褰㈢殑“姝i潰”銆?br>鍏充簬鍒嗗壊鏃墮夋嫨浜х敓澶氳竟褰㈡渶灝戠殑鍒嗗壊闈㈠彟澶栦竴涓笉澶ソ鐨勫師鍥犳槸澶у鏁版椂鍊欏畠鎵浜х敓鐨勫眰嬈℃爲閫氬父鏄笉騫寵 鐨勶紝鑰屼竴涓鉤琛$殑灞傛鏍戝湪榪愯鐨勬椂鍊欓氬父姣斾笉騫寵 鐨勫眰嬈℃爲鎬ц兘鏇村ソ銆?br>褰撹幏寰楁渶浣崇殑鍒嗗壊闈㈠悗浼撮殢鐫蹇呯劧浜х敓涓浜涜鍒嗗壊鐨勫杈瑰艦錛屽浣曞琚垎鍓茬殑澶氳竟褰㈣繘琛屽鐞嗗憿錛岃繖閲屾湁涓や釜鏂規硶錛?br>1. 寤虹珛涓涓甫鍙惰妭鐐圭殑浜屽弶鏍戯紝榪欐剰鍛崇潃姣忎竴涓杈瑰艦灝嗚鏀懼湪鍙惰妭鐐逛腑錛屽洜姝ゆ瘡涓涓鍒嗗壊鐨勫杈瑰艦涔熷皢琚垎寮鏀懼湪浜屽弶鏍戠殑涓杈廣?br>2. 鍙﹀涓涓柟娉曟槸灝嗚鍒嗗壊鐨勫杈瑰艦淇濆瓨鍒板叕鍏辮妭鐐逛腑錛屽姣忎竴涓瓙鏍戦噸澶嶈繖涓繃紼嬬洿鍒版瘡涓涓彾鑺傜偣閮藉寘鍚簡涓涓?#8220;鍑?#8221;澶氳竟褰㈤泦鍚堜負姝€?br>浜х敓甯﹀彾鑺傜偣鐨凚SP鏍戠殑綆楁硶濡備笅錛?br>l 鍑芥暟GENERATE-BSP-TREE
l 鍙傛暟:
l Node – 嬈插緩绔嬬殑綾誨瀷涓築SPTreeNode鐨勫瓙鏍戙?br>l PolygonSet – 寤虹珛BSP-tree鐨勫杈瑰艦闆嗗悎銆?br>l 榪斿洖鍊?
l 淇濆瓨鍒拌緭鍏ョ殑鐖惰妭鐐逛腑鐨凚SP-tree銆?br>l 鍔熻兘:
l 瀵逛竴涓杈瑰艦闆嗗悎浜х敓涓涓狟SP-tree銆?br>GENERATE-BSP-TREE (Node, PolygonSet)
1 if (IS-CONVEX-SET (PolygonSet))
2 Tree = BSPTreeNode (PolygonSet)
3 Divider = CHOOSE-DIVIDING-POLYGON (PolygonSet)
4 PositiveSet = {}
5 NegativeSet = {}
6 for each polygon P1 in PolygonSet
7 value = CALCULATE-SIDE (Divider, P1)
8 if(value = INFRONT)
9 PositiveSet = PositiveSet U P1
10 else if (value = BEHIND)
11 NegativeSet = NegativeSet U P1
12 else if (value = SPANNING)
13 Split_Polygon10 (P1, Divider, Front, Back)
14 PositiveSet = PositiveSet U Front
15 NegativeSet = NegativeSet U Back
16 GENERATE-BSP-TREE (Tree.RightChild, PositiveSet)
17 GENERATE-BSP-TREE (Tree.LeftChild, NegativeSet)
綆楁硶鍒嗘瀽
鍑芥暟CHOOSE-DIVIDING-POLYGON鐨勬椂闂村鏉傚害涓篛(n2 lg n)錛岄櫎闈炲嚭鐜伴掑綊璋冪敤鍚﹀垯瀹冨皢鎺у埗鍏跺畠鐨勫嚱鏁幫紝濡傛灉鎴戜滑鍋囪瀵瑰杈瑰艦闆嗗悎鐨勫垎鍓叉槸姣旇緝鍏鉤鐨勮瘽錛岄偅涔堟垜浠彲浠ラ氳繃鍏紡鏉ュ鍑芥暟GENERATE-BSP-TREE鐨勫鏉傚害榪涜琛ㄨ揪錛?br>T(n) = 2T(n/2) + O(n2 lg n)
閫氳繃鍏紡鎴戜滑鍙互鐭ラ亾榪欎釜鍑芥暟鐨勫鏉傚害涓篞 (n2 lg n)銆傝繖閲宯涓鴻緭鍏ョ殑澶氳竟褰㈤泦鍚堢殑澶氳竟褰㈡暟閲忋?br>涓嬮潰鎴戣鐢ㄤ竴涓緥瀛愭潵婕旂ず濡備綍浜х敓涓涓狟SP-tree銆備笅闈㈢殑緇撴瀯鏄竴涓杈瑰艦鐨勫師濮嬮泦鍚堬紝涓轟簡琛ㄧず鏂逛究瀵規瘡涓涓杈瑰艦閮借繘琛屼簡緙栧彿錛岃繖涓杈瑰艦闆嗗悎灝嗚鍒嗗壊涓轟竴涓狟SP-tree銆?/p>
鍥?.6
涓轟簡鑳藉榪愯榪欎釜綆楁硶鎴戜滑蹇呴』瀵瑰父閲廙INIMUMRELATION鍜孧INRELATIONSCALE榪涜璧嬪鹼紝鍦ㄥ疄闄呰繍琛屼腑鎴戜滑鍙戠幇褰揗INIMUMRELATION=0.8鑰孧INRELATIONSCALE=2鏃跺彲浠ヨ幏寰楁瘮杈冨ソ鐨勭粨鏋溿備絾鏄綘涔熷彲浠ュ榪欎簺鏁板艱繘琛岃瘯楠屾潵姣旇緝涓涓嬶紝閫氬父褰撳父鏁癕INIMUMRELATION姣旇緝澶ф椂鑾峰緱鐨勫眰嬈℃爲浼氭瘮杈冨鉤琛′絾鍚屾椂鍒嗗壊浜х敓鐨勫杈瑰艦涔熶細澶ч噺澧炲姞銆傚湪涓婂浘鏄劇ず鐨勫杈瑰艦闆嗗悎騫朵笉鏄竴涓?#8220;鍑?#8221;鐨勶紝鍥犳棣栧厛鎴戜滑闇瑕侀夋嫨涓涓悎閫傜殑鍒嗗壊闈€傚湪蹇熺殑瀵逛笂闈㈢殑緇撴瀯榪涜涓涓嬫祻瑙堝悗鎴戜滑鍙互鐭ラ亾澶氳竟褰紙1銆?銆?銆?2銆?8錛変笉鑳借鐢ㄦ潵浣滀負鍒嗗壊闈紝榪欐槸鍥犱負瀹冧滑瀹氫箟浜嗗寘鍚墍鏈夊杈瑰艦闆嗗悎鐨勫褰€備絾鏄叾瀹冪殑澶氳竟褰㈤兘鍙互浣滀負鍊欓夌殑鍒嗗壊闈€傚垎鍓蹭駭鐢熺殑澶氳竟褰㈡渶灝戝悓鏃跺垎鍓蹭負涓や釜瀛愰泦鍚堢殑澶氳竟褰㈡暟鐩箣姣斾負鏈浣崇殑澶氳竟褰㈡槸16涓?7錛屽畠浠綅浜庡悓涓鏉$洿綰夸笂鍚屾椂騫朵笉浼氬垎鍓蹭換浣曠殑澶氳竟褰€傝屽垎鍓插悗鐨勫瓙闆嗗悎鐨勫杈瑰艦鏁扮洰涔熸槸涓鏍風殑錛岄兘鏄?#8220;姝i潰”涓?3鑰?#8220;鍙嶉潰”涓?5銆傝鎴戜滑閫夋嫨澶氳竟褰?6浣滀負鍒嗗壊闈紝閭d箞鍒嗗壊鍚庣殑鐨勭粨鏋勫涓嬶細
鍥?.7
鐜板湪浠庡浘1.7鎴戜滑鍙互鐪嬪埌鏃犺鏄乏瀛愭爲榪樻槸鍙沖瓙鏍戦兘娌℃湁鍖呭惈“鍑?#8221;澶氳竟褰㈤泦鍚堬紝鍥犳闇瑕佸涓や釜瀛愭爲緇х畫榪涜鍒嗗壊銆?br>鍦ㄥ乏瀛愭爲涓杈瑰艦1銆?銆?銆?浣滀負澶氳竟褰㈤泦鍚堢殑“鍑歌竟”涓嶈兘鐢ㄥ仛鍒嗗壊闈紝鑰屽杈瑰艦4銆?0鍦ㄥ悓涓鏉$洿綰夸笂鍚屾椂娌℃湁鍒嗗壊浠諱綍澶氳竟褰紝鑰屽垎鍓插悗鐨勫杈瑰艦瀛愰泦鍚堬細“姝i潰”涓?鑰?#8220;鍙嶉潰”涓?闈炲父鐨勫鉤琛★紝鎴戜滑閫夋嫨澶氳竟褰?涓哄垎鍓查潰銆?br>鍦ㄥ彸瀛愭爲涓杈瑰艦16銆?7銆?2銆?3銆?8涓嶈兘浣滀負鍒嗗壊闈紝鑰屽杈瑰艦18銆?9銆?6銆?7铏界劧娌℃湁鍒嗗壊浠諱綍澶氳竟褰絾鏄垎鍓插悗鐨勫杈瑰艦瀛愰泦鍚堬細“姝i潰”涓?1鑰?#8220;鍙嶉潰”涓?錛?/11榪欎釜姣斿煎皬浜庢渶灝忔瘮鍊?.5鍥犳鎴戜滑闇瑕佸鎵懼叾瀹冩洿閫傚悎鐨勫杈瑰艦銆傚杈瑰艦20銆?1銆?4銆?5閮藉彧鍒嗗壊浜嗕竴涓杈瑰艦錛屼絾鏄杈瑰艦21鐪嬭搗鏉ュ垎鍓插悗鐨勭粨鏋滄洿鍚堢悊錛屽湪鍒嗗壊榪囧杈瑰艦22鍚庡杈瑰艦瀛愰泦鍚堢殑緇撴灉涓猴細“姝i潰”涓?鑰?#8220;鍙嶉潰”涓?銆?br>涓嬪浘鏄劇ず浜嗘搷浣滃悗鐨勭粨鏋滐細
鍥?.8
鍦ㄥ浘涓瘡涓涓瓙闆嗗悎榪樹笉鏄竴涓?#8220;鍑?#8221;闆嗗悎錛屽洜姝ら渶瑕佺戶緇繘琛屽垎鍓詫紝鎸夌収涓婇潰鐨勬硶鍒欏鍥?.8鎵紺虹殑緇撴瀯榪涜鍒嗗壊鍚庯紝緇撴灉濡備笅錛?br>
鍥?.9
涓婂浘鏄劇ず浜嗘渶鍚庣殑緇撴灉錛岃繖鍙兘涓嶆槸鏈浼樼殑緇撴灉浣嗘槸鎴戜滑瀵瑰畠榪涜澶勭悊鎵鑺辮垂鐨勬椂闂村茍涓嶅お闀褲?br>娓叉煋BSP
鐜板湪鎴戜滑宸茬粡寤虹珛濂戒竴涓狟SP鏍戜簡錛屽彲浠ュ緢瀹規槗瀵規爲涓殑澶氳竟褰㈣繘琛屾紜殑娓叉煋錛岃屼笉浼氫駭鐢熶換浣曢敊璇備笅闈㈢殑綆楁硶鎻忚堪浜嗗浣曞瀹冭繘琛屾覆鏌擄紝榪欓噷鎴戜滑鍋囪鍑芥暟IS-LEAF鐨勫姛鑳戒負緇欏畾涓涓狟SP鑺傜偣濡傛灉涓哄彾鑺傜偣榪斿洖鐪熷惁鍒欒繑鍥炲亣銆?br>鍑芥暟DRAW-BSP-TREE
鍙傛暟:
l Node – 琚覆鏌撶殑鑺傜偣銆?br>l Position – 鎽勮薄鏈虹殑浣嶇疆銆?br>l 榪斿洖鍊?
l None
l 鍔熻兘:
l 娓叉煋鍖呭惈鍦ㄨ妭鐐瑰強鍏跺瓙鏍戜腑鐨勫杈瑰艦銆?br>DRAW-BSP-TREE (Node, Position)
1 if (IS-LEAF(Node))
2 DRAW-POLYGONS (Node.PolygonSet)
3 return
l 璁$畻鎽勮薄鏈哄寘鍚湪鍝竴涓瓙鏍戜腑銆?br>4 Side = CLASSIFY-POINT (Node.Divider, Position)
l 濡傛灉鎽勮薄鏈哄寘鍚湪鍙沖瓙鏍戜腑鍏堟覆鏌撳彸瀛愭爲鍐嶆覆鏌撳乏瀛愭爲銆?br>5 if (Side = INFRONT || Side = COINCIDING)
6 DRAW-BSP-TREE (Node.RightChild, Position)
7 DRAW-BSP-TREE (Node.LeftChild, Position)
l 鍚﹀垯鍏堟覆鏌撳乏瀛愭爲銆?br>8 else if(value = BEHIND)
9 DRAW-BSP-TREE (Node.LeftChild, Position)
10 DRAW-BSP-TREE (Node.RightChild, Position)
鐢ㄨ繖涓柟娉曡繘琛屾覆鏌撳茍娌℃湁鍑忓皯娓叉煋鍒板睆騫曚笂鐨勫杈瑰艦鏁伴噺錛岀敱浜庝竴涓満鏅彲鑳藉寘鍚垚鐧句笂鍗冧釜澶氳竟褰㈠洜姝よ繖涓柟娉曞茍涓嶆槸寰堝ソ鐨勮В鍐蟲柟妗堛傞氬父鎯呭喌涓嬫湁澶ч噺鐨勮妭鐐瑰拰澶氳竟褰㈠茍娌℃湁澶勪簬鎽勮薄鏈虹殑瑙嗛噹鑼冨洿涔嬪唴錛屽畠浠茍涓嶉渶瑕佽娓叉煋鍒板睆騫曚笂錛屽浣曟煡鎵捐繖浜涗笉鍙鐨勮妭鐐瑰拰澶氳竟褰㈤槻姝㈠畠浠覆鏌撳埌灞忓箷涓婂憿錛岄殣钘忛潰鍓旈櫎灝辨槸涓轟簡瑙e喅榪欎釜闂鑰屾彁鍑轟竴欏規妧鏈紝鍦ㄤ笅涓鑺備腑鎴戜滑灝嗗榪欓」鎶鏈繘琛岃緇嗙殑闃愯堪銆?br>BSP鎶鏈瑙?
eXtreme3D
絎簩鑺?闅愯棌闈㈠墧闄?br> 瀵逛笉鍙鐗╀綋榪涜鍓旈櫎鏄父鎴忚涓氫負浜嗘弧瓚蟲彁楂樼敾闈㈡覆鏌撻熷害鐨勮姹傝屼駭鐢熺殑涓欏規妧鏈紝灝辨槸鍦ㄧ‖浠跺姞閫熸妧鏈璺冨彂灞曠殑浠婂ぉ錛岃櫧鐒剁幇鍦ㄥ凡緇忓彲浠ュ畬鎴愯澶氬湪榪囧幓琚涓烘槸涓嶅彲鑳藉疄鐜扮殑宸ヤ綔錛屼絾鏄浜庨殣钘忛潰榪涜鍓旈櫎浠嶆槸鍔犻熷浘褰㈡覆鏌撶殑涓欏歸噸瑕佹妧鏈傞氬父褰撲竴涓父鎴忚繍琛岀殑鏃跺欙紝瀹冩渶灝戦渶瑕佷互姣忕30甯х殑閫熷害榪愯銆傚湪鍑犲勾鍓嶈繖鎰忓懗鐫濡傛灉姣忎竴甯т綘娓叉煋鐨勫甫綰圭悊鐨勫杈瑰艦鏁伴噺瓚呰繃5000涓氨琚涓烘槸涓嶅彲鎺ュ彈鐨勶紝鑰岀幇鍦ㄥ嚑涔庢墍鏈夌殑鍟嗕笟鏄懼崱姣忎竴縐掗兘鍙互娓叉煋鍑犲崈涓囦釜澶氳竟褰€傚彲鏄幇鍦ㄤ粛鐒墮渶瑕佷嬌鐢ㄩ殣钘忛潰鍓旈櫎榪欓」鎶鏈紝榪欐槸涓轟粈涔堝憿錛熸樉鑰屾槗瑙侊紝瀵逛笉鍙鐗╀綋娓叉煋浠ュ悗灝嗕細琚彲瑙佺墿浣撻伄鎸′綇錛岃繖鏍峰仛鏃犺皳鐨勬氮璐逛簡鏄懼崱鐨勫甫瀹斤紝浣嗘槸鍚屾椂瀹冧篃澧炲姞浜嗗満鏅殑緇嗚妭錛屼嬌娓告垙鐢婚潰鐪嬭搗鏉ユ洿鍔犲惛寮曚漢銆傜幇鍦ㄧ殑闂鏄澶х▼搴︿笂鏉ュ墧闄ら殣钘忕殑澶氳竟褰紝璞iew frustum culling鍜宲ortal娓叉煋榪欐牱鐨勬妧鏈潵鍓旈櫎涓涓笉鍙澶氳竟褰㈡槸闈炲父鑰楄垂鏃墮棿鐨勶紝鐢ㄦ潵鍘誨仛榪欎簺璁$畻鐨凜PU鏃墮棿鍙互鐢ㄦ潵瀹屾垚鍏跺畠璇稿AI鎴栫鎾炴嫻嬭繖鏍風殑宸ヤ綔錛屽洜姝ゅ紑鍙戜竴涓殣钘忛潰鍓旈櫎綆楁硶蹇呴』娉ㄦ剰鍒拌繖涓鐐廣傚浜庣幇鍦ㄧ殑娓告垙鏉ヨ鍑犱箮娌℃湁涓涓槸灝嗘瘡涓涓殣钘忕殑澶氳竟褰㈤兘榪涜鍓旈櫎錛岃屾槸鍓旈櫎涓涓杈瑰艦鐨勯泦鍚堝涓涓妭鐐規垨涓涓墿浣撶瓑絳夈傚浜庝竴涓崟鐙殑澶氳竟褰㈠畠騫朵笉榪涜鍓旈櫎錛屽洜姝や竴涓紜殑闅愯棌闈㈠墧闄ゆ柟妗堟槸鍏佽涓瀹氱殑閲嶅娓叉煋鏉ラ傚綋鐨勫噺灝戣綆楅噺銆?br> 褰撳緩绔嬩竴涓狥PS娓告垙鏃惰繘琛岄殣钘忛潰鍓旈櫎鏈閫氬父鐨勬柟娉曟槸浣跨敤portal娓叉煋銆傝繖欏規妧鏈彲浠ラ潪甯稿厖鍒嗙殑鍒╃敤BSP鐨勪紭鐐癸紝浣嗘槸璇鋒敞鎰弍ortal鎶鏈茍涓嶄粎浠呭彧鑳界敤浜嶣SP涓侾ortal鎶鏈繕鍙互鐢ㄦ潵浜х敓涓浜涚壒鏁堝闀滃瓙鍜岀洃瑙嗗櫒絳夌瓑銆?br>Portal娓叉煋
鍦ㄨ繖閲屾垜灝嗕粙緇嶄竴涓媝ortal鎶鏈殑鍘熺悊錛岄氬父瀵逛簬涓涓鍐呭満鏅潵璇村畠鍙互琚弿榪頒負鐢變竴涓釜“媧炲彛”鐩鎬簰榪炴帴鐨?#8220;鎴塊棿”緇勬垚錛岃繖閲?#8220;媧炲彛”琚О涓簆ortal鑰?#8220;鎴塊棿”琚О涓簊ector錛岄氬父sector琚畾涔変負涓涓?#8220;鍑?#8221;鐨?#8220;闂悎”鐨勫杈瑰艦闆嗗悎錛屽畾涔変腑鐨?#8220;鍑?#8221;闃呰榪囧墠闈㈢殑鍐呭浣犲簲褰撳凡緇忚兘寰堝ソ鐨勭悊瑙d簡錛岃?#8220;闂悎”鏄粈涔堟剰鎬濆憿錛熷畠鎰忓懗鐫鍦╯ector鍐呴儴浠繪剰榪炴帴涓や釜欏剁偣鍋氫竴鏉$嚎孌碉紝榪欐潯綰挎涓嶄細鍜屽叾瀹冪殑澶氳竟褰㈢浉浜ゃ傛崲鍙ヨ瘽璇村鏋滀綘鎯沖湪sector鍐呴儴浠繪剰鐢諱竴鏉$嚎孌甸氬埌sector鐨勫閮ㄥ繀瀹氫笌緇勬垚sector鐨勫杈瑰艦鐩鎬氦銆傝繖涔熸剰鍛崇潃榪炴帴姣忎竴涓猻ector鐨?#8220;媧炲彛”蹇呴』琚竴涓粍鎴恜ortal鐨勫杈瑰艦鎵濉厖錛岃屽浜庢斁緗畃ortal澶氳竟褰㈡潵璇翠綘鏃㈠彲浠ユ墜宸ユ斁緗篃鍙互鐢辯▼搴忚嚜鍔ㄤ駭鐢燂紝鍦ㄦ垜璁茶В榪欓」鎶鏈箣鍓嶆垜蹇呴』鎻愰啋涓涓嬶紝鐢變簬紜歡鍔犻焃緙撳啿鐨勫嚭鐜板sector蹇呴』涓?#8220;鍑?#8221;鐨勯檺鍒跺凡緇忔秷闄わ紝鍥犳鏈夎澶氭父鎴忓紩鎿庡凡緇忎笉鍐嶉伒瀹堣繖涓爣鍑嗭紝浣嗘槸鍦ㄨ繖閲屾垜榪樻槸瑕佸榪囧幓鐨勬柟娉曡繘琛屼竴涓嬩粙緇嶃?br>涓涓猵ortal寮曟搸鐨勫熀鏈柟娉曟槸褰撲綘閫氳繃涓涓寚瀹氳瀵熶綅緗殑鍙騫蟲埅浣擄紙view frustum錛夎繘琛屾覆鏌撴椂錛屽鏋滀竴涓猵ortal鍑虹幇鍦ㄥ彲瑙嗚寖鍥村唴錛岄偅涔坧ortal灝嗗鍙騫蟲埅浣撹繘琛屽壀鍒囷紝榪欐牱涓庡叾鐩歌繛鐨剆ector灝嗕細閫氳繃涓涓瀵熶綅緗浉鍚屼絾宸茬粡鏀瑰彉榪囩殑鍙騫蟲埅浣撹繘琛屾覆鏌撱傝繖鏄竴涓潪甯哥畝鍗曡屼笖闈炲父閫傚悎榪涜閫掑綊璋冪敤鐨勬柟娉曪紝鐢變簬鍙騫蟲埅浣撹portal榪涜浜嗙簿紜殑闄愬埗錛屽洜姝よ闅愯棌鐨勭墿浣撳彲浠ュ緢綆鍗曡繘琛屽墧闄ゃ備笅闈㈢殑渚嬪浘鏄劇ず浜嗕竴涓猵ortal寮曟搸涓殑鍙騫蟲埅浣撴槸濡備綍琚壀鍒囩殑銆?br>
鍥?.10
鍦ㄥ浘6.10涓瀵熻呯殑浣嶇疆浣嶄簬V錛岃屽垵濮嬬殑鍙騫蟲埅浣撲負F1錛屽綋瀹冮氳繃涓涓猵ortal澶氳竟褰1鍚庤P1鍓垏浜х敓鏂扮殑鍙騫蟲埅浣揊2錛屾帴鐫褰撳畠閫氳繃portal澶氳竟褰2銆丳3鍚嶧2琚壀鍒囦負F3銆丗4錛岃孎3閫氳繃P4鍚庤鍓垏涓篎5鑰孎4琚壀鍒囦負F6銆傝瀵熻繖涓繃紼嬫垜浠彲浠ュ彂鐜皃ortal鎶鏈潪甯擱傚悎榪涜閫掑綊璋冪敤銆?br>鎺ョ潃闇瑕佽冭檻鐨勬槸濡備綍瀵圭墿浣撹繘琛屾嫞閫夊墧闄わ紝閫氬父瀵逛簬鎵鏈夌殑3D寮曟搸鏉ヨ閮介渶瑕侀氳繃涓緋誨垪姝ラ鏉ュ姞閫熻繖涓鐞嗚繃紼嬶紝鍥炲繂涓涓嬪墠闈㈣瑙g殑鍐呭錛岃繖涓繃紼嬮鍏堣璁$畻鍑虹墿浣撶殑“鏈澶у寘鍥寸悆”鎴栨槸“鏈澶у寘鍥寸洅”錛屽畠鏄寘鍚簡鐗╀綋鎵鏈夐《鐐圭殑鏈灝忓寘鍥翠綋錛屾帴鐫鐢ㄥ寘鍥翠綋鏉ュ拰“鍙騫蟲埅浣?#8221;姣忎竴涓壀鍒囬潰榪涜紕版挒媯嫻嬶紝濡傛灉鍖呭洿浣撲綅浜庢瘡涓涓壀鍒囬潰鐨?#8220;鍙嶉潰”閭d箞鐗╀綋灝嗕笉浼氳繘琛屾覆鏌擄紝涓嬪浘鏄劇ず浜嗚繖涓繃紼嬶細
鍥?.11
鍥句腑鐗╀綋1浣嶄簬鍙沖壀鍒囬潰鐨?#8220;姝i潰”浣嗕綅浜庡乏鍓垏闈㈢殑“鍙嶉潰”鍥犳瀹冨皢涓嶄細琚覆鏌擄紝鑰岀墿浣?涓嶄粎浣嶄簬宸﹀壀鍒囬潰鐨?#8220;姝i潰”鑰屼笖鏈変竴閮ㄥ垎浣嶄簬鍙沖壀鍒囬潰鐨?#8220;姝i潰”鍥犳灝嗕細琚覆鏌撳嚭鏉ャ?br>Portal鎶鏈渶鍒濈殑鎯蟲硶鏄氳繃鍓垏澶氳竟褰㈡潵淇濊瘉鍙湁鐗╀綋鍙鐨勯儴鍒嗚娓叉煋鍑烘潵錛屼篃灝辨槸鏃犳晥娓叉煋鐨勫杈瑰艦鏁伴噺涓?銆備絾鏄幇鍦ㄨ繖縐嶆兂娉曡璁や負涓嶆槸寰堢悊鎯籌紝鍥犱負瀹冩棤璋撶殑嫻垂浜嗗鐞嗘椂闂淬備絾鏄敱浜庝竴涓杈瑰艦鍦ㄩ掑綊寰幆榪囩▼涓皢琚亶鍘嗗嬈″洜姝ゆ垜浠渶瑕佺煡閬撳湪娓叉煋鍦烘櫙鏃跺畠鏄惁宸茬粡琚覆鏌撹繃錛屼竴涓緝濂界殑鏂規硶鏄嬌鐢ㄤ竴涓撫鏁版潵鏍囪瘑榪欎釜澶氳竟褰紝榪欐牱鍙互寰堝鏄撶殑鏉ユ弿榪拌繖涓杈瑰艦鍦ㄤ笂涓甯ф槸鍚﹁娓叉煋榪囥傚啀鐪嬩竴涓嬪浘6.10涓渶鍙寵竟鐨勫錛屽畠鍚屾椂閫氳繃F5鍜孎6鏉ヨ繘琛屾覆鏌擄紝閫氳繃瀵瑰畠榪涜鏍囪瘑鎴戜滑鍙互鐭ラ亾瀹冩槸鍚﹁娓叉煋榪囷紝鍚﹀垯灝變細浜х敓Z緙撳啿閿欒銆?br>涓轟簡渚夸簬鍦╬ortal寮曟搸涓繘琛屾覆鏌撴垜浠渶瑕佸“鍙騫蟲埅浣?#8221;榪涜涓涓嬪畾涔夛紝涓涓?#8220;鍙騫蟲埅浣?#8221;鏄竴涓繚瀛樹簡澶氫釜鍓垏闈㈢殑緇撴瀯錛屾瘡涓涓壀鍒囬潰鐨勬硶綰塊兘灝嗘寚鍚?#8220;鍙騫蟲埅浣?#8221;鐨勫唴閮紝鍥犳鍦ㄥ畠鍐呴儴灝嗕駭鐢熶竴涓棴鍚堢殑閿ヤ綋銆備笅闈㈢殑綆楁硶鏄劇ず浜嗗浣曡綆椾竴涓杈瑰艦鏄惁鍖呭惈鍦?#8220;鍙騫蟲埅浣?#8221;鐨勫唴閮ㄣ傚湪榪欎釜綆楁硶涓垜浠嬌鐢ㄤ簡涓涓嚱鏁癈LASSIFY-POINT錛屽畠浣跨敤涓涓壀鍒囬潰鍜屼竴涓偣浣滀負杈撳叆鍙傛暟銆?br>l 鍑芥暟INSIDE-FRUSTUM
l 鍙傛暟:
l Frustum – 鐢ㄤ簬媯嫻嬪杈瑰艦鏄惁浣嶄簬鍏朵腑鐨?#8220;鍙騫蟲埅浣?#8221;銆?br>l Polygon – 鐢ㄤ簬媯嫻嬬殑澶氳竟褰€?br>l 榪斿洖鍊?
l 澶氳竟褰㈡槸鍚︿綅浜?#8220;鍙騫蟲埅浣?#8221;鐨勫唴閮ㄣ?br>l 鍔熻兘:
l 浣跨敤“鍙騫蟲埅浣?#8221;鐨勬瘡涓涓壀鍒囬潰鏉ュ澶氳竟褰㈢殑姣忎竴涓《鐐硅繘琛屾嫻嬶紝濡傛灉鎵鏈夌殑欏剁偣閮戒綅浜庢墍鏈夊壀鍒囬潰鐨?#8220;姝i潰”錛岄偅涔堝杈瑰艦澶勪簬“鍙騫蟲埅浣?#8221;鐨勫唴閮ㄣ?
INSIDE-FRUSTUM (Frustum, Polygon)
1 for each point Pt in Polygon
2 Inside = true
3 for each plane Pl in Frustum
4 if (CLASSIFY-POINT (Pl, Pt) <> INFRONT)
5 Inside f false
6 if (Inside)
7 return true
8 return false
鍦ㄤ竴涓猵ortal寮曟搸涓畠鐨勪富娓叉煋鍑芥暟鍙互綆鍗曠殑鐢ㄤ笅闈㈢殑鏂規硶鏉ュ疄鐜般?br>鍑芥暟RENDER-PORTAL-ENGINE
鍙傛暟:
Sector – 瑙傚療鑰呮墍澶勭殑sector銆?br>ViewFrustum – 褰撳墠鐨?#8220;鍙騫蟲埅浣?#8221;銆?br>榪斿洖鍊?
None
鍔熻兘:
娓叉煋portal寮曟搸涓殑澶氳竟褰紝鍦烘櫙琚弿榪頒負鐢卞涓猵ortal榪炴帴鐨剆ectors鎵緇勬垚銆?br>RENDER-PORTAL-ENGINE (Sector, ViewFrustum)
1 for each polygon P1 in Sector
2 if (P1鏄竴涓猵ortal and INSIDE-FRUSTUM (ViewFrustum, P1))
3 NewFrustum = CLIP-FRUSTUM (ViewFrustum, P1)
4 NewSector = 鑾峰緱鐢卞綋鍓峴ector閫氳繃portal P1鐩歌繛鎺ョ殑sector
5 RENDER-PORTAL-ENGINE (NewSector, NewFrustum)
6 else if (P1浠葷劧娌℃湁琚覆鏌?
7 draw P1
8 return
濡備綍鏀劇疆portal
姝e鎴戝墠闈㈡彁鍒扮殑鍦ㄤ竴涓猵ortal寮曟搸涓渶澶х殑闂灝辨槸濡備綍鏀劇疆portal錛屽鏋滄墜宸ユ潵鏀劇疆瀹冪殑璇濋潪甯歌姳璐規椂闂達紝鍚屾椂瑕佹眰鍦板浘鐨勮璁¤呮湁鐔熺粌鐨勬妧宸с傚洜姝や竴涓壇濂界殑鑷姩鏀劇疆portal鐨勭畻娉曢潪甯告湁蹇呰錛屽湪榪欓噷鎴戝皢瑕佷粙緇嶄竴涓嬪叧浜庤繖鏂歸潰鐨勫嚑涓В鍐蟲柟妗堬紝榪欎簺鏂規閮戒嬌鐢ㄤ簡BSP銆?br>鎴戜粙緇嶇殑絎竴涓В鍐蟲柟妗堟槸鐢辯憺鍏窪ICE鍏徃鐨凙ndreas Brinck鎻愬嚭鐨勶紝瀹冪殑鍘熺悊闈炲父綆鍗曪紝瑙傚療涓涓嬩竴涓畬鏁寸殑BSP灞傛鏍戯紝鍙互鍙戠幇榪欐牱涓涓幇璞★紝瀵逛簬姣忎竴涓猵ortal鏉ヨ瀹冨繀瀹氫笌BSP灞傛鏍戜腑鐢卞垎鍓插杈瑰艦瀹氫箟鐨勫垎鍓查潰浣嶇疆鐩稿悓錛屽洜姝ゅ湪鐩稿悓鐨勪綅緗笂鎴戜滑鍙互鍦ㄥ垎鍓查潰涔嬪寤虹珛涓涓猵ortal澶氳竟褰紝portal澶氳竟褰㈣鍒濆鍖栦負涓涓煩褰紝榪欎釜鐭╁艦鐨勫ぇ灝忓皢瓚呰繃portal鎵澶勭殑BSP鑺傜偣鐨?#8220;鏈澶у寘鍥寸洅”鐨勫ぇ灝忥紝鎺ョ潃灝唒ortal澶氳竟褰㈡斁鍏ュ寘鍚畠鐨勮妭鐐規墍浣嶄簬鐨勫瓙鏍戜腑錛屽綋鑺傜偣涓嶆槸鍙惰妭鐐規椂錛岄偅涔坧ortal灝嗙戶緇浼犻佸埌鑺傜偣鐨勫瓙鏍戜腑錛岃繖鏍峰瓙鑺傜偣涓殑鍒嗗壊闈㈠皢瀵瑰畠榪涜鍒嗗壊錛岃屽綋鍖呭惈瀹冪殑鑺傜偣涓哄彾鑺傜偣鏃訛紝瀹冧篃浼氳鑺傜偣涓殑澶氳竟褰㈣繘琛屽壀鍒囷紝鍥犱負portal鍒濆鍖栫殑澶у皬瓚呰繃浜嗚妭鐐圭殑鑼冨洿銆傚綋portal琚垎鍓插悗錛岃鍒嗗壊鐨勪袱涓儴鍒嗕細緇х畫浼犻佸埌鏈欏跺眰鐨勮妭鐐歸噸澶嶈繖涓繃紼嬶紝鑰屽綋portal涓嶉渶瑕佽繘琛屽垎鍓叉椂錛屾牴鎹畠鎵澶勪簬鍒嗗壊闈㈢殑浣嶇疆鏉ユ斁緗埌鐩稿簲鐨勫瓙鑺傜偣涓紝濡傛灉浣嶄簬鍒嗗壊闈㈢殑“姝i潰”瀹冨皢琚斁緗湪鍙沖瓙鏍戜腑錛岃屽綋瀹冧綅浜庡垎鍓查潰鐨?#8220;鍙嶉潰”灝嗚鏀劇疆浜庡乏瀛愭爲涓傚鏋減ortal姝eソ浣嶄簬鍒嗗壊闈箣涓婂畠灝嗗悓鏃舵斁鍦ㄥ乏鍙沖瓙鏍戜腑銆?br>涓轟簡鏂逛究鏂逛究灝嗘墍鏈夌殑portal鏀劇疆鍒癇SP涓垜浠渶瑕佸畾涔夊浣曞涓涓杈瑰艦榪涜鍒嗗壊錛屼負浜嗘柟渚夸嬌鐢ㄦ垜浠亣璁懼畬鎴愯繖涓姛鑳界殑鍑芥暟涓篒NTERSECTION-POINT錛屽畠灝嗚繑鍥炰竴涓潰涓庝竴涓嚎孌電殑浜ょ偣銆?br>l 鍑芥暟CLIP-POLYGON
l 鍙傛暟:
l Clipper – 鍘誨垎鍓插叾瀹冨杈瑰艦鐨勫杈瑰艦鎴栭潰銆?br>l Polygon – 琚垎鍓茬殑澶氳竟褰€?br>l 榪斿洖鍊?
l 琚垎鍓插悗鐨勪袱涓儴鍒嗐?br>l 鍔熻兘:
l 鐢辨寚瀹氱殑鍒嗗壊闈㈡潵鍒嗗壊澶氳竟褰€傚鏋滃杈瑰艦娌℃湁琚垎鍓插皢浼氳繑鍥炰竴涓┖鐨勫杈瑰艦銆?br>CLIP-POLYGON (Clipper, Polygon)
1 RightPart = {}
2 LeftPart = {}
3 for each point edge E in Polygon
4 Side1 = CLASSIFY-POINT (Clipper, E.Point1)
5 Side2 = CLASSIFY-POINT (Clipper, E.Point2)
6 if (Side1 <> Side2 and
Side1 <> COINCIDING and
Side2 <> COINCIDING)
7 Ip = INTERSECTION-POINT (Clipper, E)
8 if (Side1 = INFRONT)
9 RightPart = RightPart U E.Point1
10 RightPart = RightPart U Ip
11 LeftPart = LeftPart U Ip
12 LeftPart = LeftPart U E.Point2
13 if (Side1 = BEHIND)
14 LeftPart = LeftPart U E.Point1
15 LeftPart = LeftPart U Ip
16 RightPart = RightPart U Ip
17 RightPart = RightPart U E.Point2
18 else
19 if (Side1 = INFRONT or Side2 = INFRONT or
Side1 = COINCIDING and Side2 = COINCIDING)
20 RightPart = RightPart U E.Point1
21 RightPart = RightPart U E.Point2
22 if (Side1 = BEHIND or Side2 = BEHIND)
23 LeftPart = LeftPart U E.Point1
24 LeftPart = LeftPart U E.Point2
25 return (RightPart, LeftPart)
鐜板湪鎴戜滑鍙互瀹氫箟濡備綍鍦ㄤ竴涓狟SP灞傛鏍戜腑瀵筽ortal榪涜鍒嗛厤浜嗭紝鍦ㄧ畻娉曚腑portal琚垵濮嬪寲涓轟竴涓ぇ浜嶣SP鏍硅妭鐐?#8220;鏈澶у寘鍥寸洅”鐨勫杈瑰艦銆?br>l 鍑芥暟PLACE-PORTALS
l 鍙傛暟:
l PortalPolygon – 鏀劇疆鍒癇SP涓殑澶氳竟褰€?br>l Node – 鎴戜滑褰撳墠閬嶅巻鐨勮妭鐐廣?br>l 榪斿洖鍊?
l None
l 鍔熻兘:
l 鏀劇疆涓涓猵ortal澶氳竟褰㈠埌BSP灞傛鏍戜腑錛屽鏋滈渶瑕佺殑璇濆瀹冭繘琛屽壀鍒囥傝繖涓嚱鏁板皢浼氫駭鐢熶竴涓妭鐐瑰皢鐢眕ortal榪炴帴鑰屾瘡涓涓妭鐐瑰皢鍖呭惈涓涓猵ortal澶氳竟褰㈠垪琛ㄧ殑BSP灞傛鏍戙?br>PLACE-PORTALS (PortalPolygon, Node)
1 if (IS-LEAF (Node))
l 灝唒ortal鍜岃妭鐐逛腑鐨勬瘡涓涓杈瑰艦榪涜媯嫻嬨傚綋portal鎵鍖呭惈鐨勫杈瑰艦鍜岀敱涓涓杈瑰艦瀹氫箟鐨勯潰鐩鎬氦鏃跺畠灝嗚榪欎釜闈㈣繘琛屽垎鍓詫紝鍒嗗壊鍚庣殑涓や釜閮ㄥ垎灝嗚閲嶆柊浼犻佸埌鏈欏跺眰鐨勮妭鐐逛腑緇х畫榪涜媯嫻嬨?br>2 for (each polygon P2 in Node)
3 IsClipped = false
4 if (CALCULATE-SIDE (P2, PortalPolygon) = SPANNING)
5 IsClipped = true
6 (RightPart, LeftPart) = CLIP-POLYGON (P2, PortalPolygon)
7 PLACE-PORTALS (RightPart, RootNode)
8 PLACE-PORTALS (LeftPart, RootNode)
9 if (not IsClipped)
10 浠庡綋鍓嶈妭鐐逛腑灝唒ortal鐨勫杈瑰艦鍓旈櫎錛屽洜涓哄畠鐨勪綅緗拰鑺傜偣涓竴涓杈瑰艦鐨勪綅緗浉鍚屻?br>l 鍙傝冧笅闈㈢殑鎻忚堪銆?br>11 娣誨姞褰撳墠鑺傜偣鍒皃ortal澶氳竟褰㈡墍榪炴帴鐨勮妭鐐歸泦鍚堜腑銆?br>12 else
13 if (褰撳墠鑺傜偣鐨勫垎鍓插杈瑰艦娌℃湁鏀劇疆鍦ㄦ爲涓?
14 寤虹珛涓涓杈瑰艦P錛屽畠鐨勫ぇ灝忓皢瓚呰繃鍖呭惈褰撳墠鑺傜偣鎵鏈夊杈瑰艦鐨勬渶澶у寘鍥寸洅鐨勮寖鍥達紝騫朵笖鍜屽垎鍓插杈瑰艦鐨勪綅緗浉鍚屻?br>15 PLACE-PORTALS (P, Node.LeftChild)
16 PLACE-PORTALS (P, Node.RightChild)
17 Side = CALCULATE-SIDE (Node.Divider, PortalPolygon)
18 if (Side = POSITIVE)
19 (RightPart, LeftPart) = CLIP-POLYGON(P2, PortalPolygon)
20 PLACE-PORTALS (RightPart, RootNode)
21 PLACE-PORTALS (LeftPart, RootNode)
22 if (Side = POSITIVE or COINCIDING)
23 PLACE-PORTALS (PortalPolygon, Node.RightChild)
24 if (Side = NEGATIVE or COINCIDING)
25 PLACE-PORTALS (PortalPolygon, Node.LeftChild)
涓嬮潰鎴戝皢瀵圭畻娉曚腑鐨勭10琛岃繘琛屼竴涓嬭В閲婏紝褰撳墧闄ゅ拰褰撳墠鑺傜偣涓竴涓杈瑰艦浣嶇疆鐩稿悓鐨刾ortal澶氳竟褰㈤儴鍒嗗皢浼氫駭鐢熶粈涔堟牱鐨勭粨鏋溿傚弬鑰冧竴涓嬪浘6.12銆?/p>
鍥?.12
鍦ㄥ浘6.12涓竴涓猵ortal宸茬粡鍒拌揪浜嗕竴涓彾鑺傜偣錛屽浘涓伆鑹茬殑鍖哄煙鏄槸portal澶氳竟褰㈠湪閬嶅巻BSP鏍戣繃紼嬩腑琚墧闄ょ殑鍖哄煙縐板畠涓?銆傝屽浘涓爣娉ㄤ負2銆?銆?鐨勪寒鐏拌壊閮ㄥ垎鏄拰portal澶氳竟褰綅緗浉閲嶅彔鐨勫杈瑰艦錛屽洜姝よ繖涓閮ㄥ垎鐨刾ortal澶氳竟褰篃灝嗕細琚墧闄わ紝鑰屽墿涓嬬殑閮ㄥ垎5灝嗚鐢ㄦ潵鍋氫負涓涓猵ortal銆?br>鍦ㄤ笂闈㈢殑綆楁硶絎竴嬈$湅鐨勮瘽浼氳鐨勯潪甯稿鏉傦紝浣嗗疄闄呬笂瀹冮潪甯哥畝鍗曞拰瀹規槗鐞嗚В錛屾渶緇堢殑緇撴灉灝辨槸姣忎竴涓猵ortal灝嗕細鍦ㄤ袱涓妭鐐逛笂緇撴潫鑰屽浜庝換涓涓猵ortal鏉ヨ瀹冨繀瀹氬彲浠ュ拰涓涓猵ortal涔嬮棿鐩鎬簰鍙銆傚湪涓嬮潰鎴戝皢鐢ㄤ竴涓疄闄呯殑渚嬪瓙鏉ヨВ閲婁竴涓嬭繖涓畻娉曘?/p>
鍥?.13
瀵逛簬鍥?.13涓殑緇撴瀯錛岄渶瑕佽繘琛屼笅闈㈢殑鍑犳錛?br>絎竴姝ワ紝portal澶氳竟褰1榪涘叆鑺傜偣n1涓?/p>
鍦ㄨ妭鐐筺1涓璸ortal澶氳竟褰1灝嗕細琚垎鍓詫紝鍥犱負瀹冪殑涓閮ㄥ垎鍜岃妭鐐逛腑闂寸殑涓涓杈瑰艦浣嶇疆鐩稿悓錛屽洜姝ortal澶氳竟褰1灝嗕細琚垎鍓蹭負涓ら儴鍒嗗垎鍒負p1銆乸2錛岄噸鍙犵殑閮ㄥ垎琚墧闄ゃ?br>絎簩姝ワ紝p1銆乸2榪涘叆鑺傜偣s2涓?br>鍦ㄨ妭鐐箂2涓敱浜巔1浣嶄簬鍒嗗壊闈2鐨?#8220;姝i潰”錛屽洜姝ゅ皢鍜屽垎鍓查潰s2涓璧瘋閫佸叆鍒拌妭鐐筺2涓紝鑰宲2鐢變簬浣嶄簬鍒嗗壊闈2鐨?#8220;鍙嶉潰”錛屽洜姝ゅ皢鍜屽垎鍓查潰s2涓璧瘋閫佸叆鍒拌妭鐐箂3涓傜敱浜巔1銆乸2娌℃湁鍜屽垎鍓查潰鐩鎬氦鍥犳榪欎竴姝ユ病鏈夊嚭鐜板垎鍓叉搷浣溿?br>絎笁姝ワ紝p1銆乻2榪涘叆鑺傜偣n2涓?/p>
鍦ㄨ妭鐐筺2涓璶2琚鍙綔涓轟竴涓猵ortal錛屽洜姝ゅ湪鑺傜偣n1鍜宯2涓畠涓嶄細鍐嶅彂鐢熶換浣曞彉鍖栥傝屽杈瑰艦p3鐨勪竴閮ㄥ垎灝嗕細琚墧闄わ紝鍥犱負瀹冪殑涓閮ㄥ垎鍜岃妭鐐逛腑闂寸殑涓涓杈瑰艦浣嶇疆鐩稿悓錛屽湪涓婁竴姝ヤ腑澶氳竟褰2涔熻閫佸叆鍒拌妭鐐箂3涓紝鑰屽湪榪欓噷瀹冨張琚О涓簆3銆?/p>
絎洓姝ワ紝p3鍜宻3榪涘叆鑺傜偣n3涓?/p>
鍦ㄨ妭鐐筺3涓杈瑰艦p3琚鍙負涓涓猵ortal錛岃屽杈瑰艦s3鐨勪竴閮ㄥ垎鍥犱負鍜屼笂闈㈢殑鍘熷洜涓鏍瘋鍓旈櫎錛屽悓鏃跺湪榪欓噷瀹冨張琚О涓簆4銆?/p>
絎簲姝ワ紝p2鍜宲4榪涘叆鑺傜偣s4涓?br>娌℃湁浠諱綍澶氳竟褰㈣榪涜鍒嗗壊錛屽洜姝ゅ杈瑰艦p2鍜宲4灝嗕笌s4涓璧瘋閫佸叆鑺傜偣n4涓紝鑰宻4灝嗚鍗曠嫭閫佸叆鑺傜偣n5涓?br>絎叚姝ワ紝p2銆乸4鍜宻4涓璧瘋繘鍏ヨ妭鐐筺4涓?/p>
鏃犺鏄痯2榪樻槸p4閮戒笉闇瑕佸垎鍓詫紝浣嗘槸鐢變簬s4鍜屼腑闂寸殑涓涓杈瑰艦瀹屽叏閲嶅彔鍥犳灝嗕細琚墧闄ゃ?/p>
絎竷姝ワ紝緇撴潫錛屾病鏈変換浣曞杈瑰艦榪涘叆鑺傜偣n5涓?br>榪欎釜鑺傜偣灝嗘病鏈塸ortal錛屽洜涓哄浜庝換浣曡妭鐐規潵璇村畠閮芥槸涓嶅彲瑙佺殑錛岃屼粠榪欎釜鑺傜偣浣嶇疆涓婂皢涓嶄細鐪嬭浠諱綍涓涓妭鐐廣?br>緇撴灉錛?br>portal p1鍚屾椂浣嶄簬鑺傜偣n1鍜宯2涓紱
portal p2鍚屾椂浣嶄簬鑺傜偣n1鍜宯4涓紱
portal p1鍚屾椂浣嶄簬鑺傜偣n2鍜宯3涓紱
portal p1鍚屾椂浣嶄簬鑺傜偣n3鍜宯4涓?/p>
涓婇潰鎴戞墍璁茶В鐨勫唴瀹規槸寤虹珛涓涓畝鍗曠殑portal寮曟搸鎵蹇呭鐨勫姛鑳斤紝瀹冭兘緇欐垜浠彁渚涗竴涓緝楂樼殑榪愯甯ч熴?br>PVS
涓涓猵ortal寮曟搸铏界劧鑳藉鎻愪緵璁稿闈炲父濂界殑鐗規э紝浣嗘槸瀹冪殑緇撴瀯澶鏉傘傚綋浣犱嬌鐢╬ortal鎶鏈潵鏋勫緩涓涓父鎴忓紩鎿庢椂浣犱細鍙戠幇瀹冨瓨鍦ㄨ澶氶棶棰橈紝鏈澶х殑涓涓棶棰樻槸鍦ㄦ覆鏌撳満鏅殑姣忎竴甯ч兘闇瑕佽繘琛屽彲瑙嗘ф嫻嬶紝榪欎細浜х敓澶ч噺鐨勫杈瑰艦鍓垏鎿嶄綔錛屽湪鍦烘櫙闈炲父澶嶆潅鐨勬儏鍐典笅錛岃繍綆楃殑璐圭敤浼氶潪甯哥殑楂橈紝鍥犳闇瑕佸鎵句竴縐嶆妧鏈潵瀵瑰満鏅腑鍙鎬ф嫻嬭繘琛岄璁$畻鑰屼笉鏄湪榪愯鏈熼棿榪涜璁$畻銆侾VS錛圥otentially Visible Set錛夊彲瑙嗘ч泦鍚堬紝灝辨槸涓轟簡瑙e喅榪欎釜闂鑰屽嚭鐜扮殑涓欏規妧鏈紝鍙互閫氳繃瀵笲SP涓瘡涓涓彾鑺傜偣璁劇疆涓涓狿VS錛岃繖涓狿VS淇濆瓨浜嗕粠絎竴涓彾鑺傜偣寮濮嬬湅鍒扮殑鍙惰妭鐐歸泦鍚堬紝瀹冧笉浠呭彲浠ョ敤鏉ュ府鍔╁姞閫熷満鏅覆鏌擄紝榪樺彲浠ョ敤鏉ュ姞閫熷満鏅腑鍏夌収榪愮畻鍜岃繘琛岀綉緇滀紭鍖栥?br>PVS鏄湪鍦烘櫙榪涜棰勬覆鏌撴椂璁$畻鍑烘潵鐨勶紝姣忎竴涓狟SP鐨勫彾鑺傜偣閮戒繚瀛樹竴涓彲瑙嗚妭鐐圭殑闆嗗悎錛屽綋瀵瑰満鏅繘琛屾覆鏌撴椂錛屾憚璞℃満鎵鍦ㄧ殑鍙惰妭鐐瑰皢琚覆鏌擄紝鍚屾椂淇濇寔鍦≒VS涓殑鍙惰妭鐐逛篃灝嗕細琚覆鏌撳嚭鏉ワ紝榪欓噷闇瑕佷竴浜涚畻娉曟潵閬垮厤鍦烘櫙閲嶅娓叉煋錛岀敱浜庝粖澶╃‖浠跺姞閫熷崱鐨勫彂灞曪紝瀹冩墍鎻愪緵鐨勭‖浠禯緙撳啿鐨勫ぇ灝忓凡緇忓彲浠ユ柟渚跨殑瑙e喅榪欎釜闂銆?br>璁$畻PVS
濡傛灉瑕佹眰PVS蹇呴』鍦˙SP鐨勫彾鑺傜偣涔嬮棿榪涜鏍囧噯鐨勫厜綰胯窡韙綆楋紝鏉ユ煡鎵句竴涓嬪湪涓涓彾鑺傜偣涓換涓涓偣鏄惁鍦ㄥ叾瀹冨彾鑺傜偣涓彲瑙併備負浜嗗姞閫熷厜綰胯窡韙殑璁$畻錛屽湪姣忎竴涓彾鑺傜偣涓繀欏繪寚鍑轟竴浜涘吀鍨嬬殑浣嶇疆鐐規潵閬垮厤鏃犺皳鐨勮綆楋紝鐜板湪鐨勯棶棰樺氨鏄浣曟斁緗繖浜涘吀鍨嬬殑鐐廣?br>瀵逛簬涓涓猵ortal寮曟搸鐨刾ortal鏉ヨ錛屽吀鍨嬬偣鍙互娌跨潃鏍戠殑鍒嗗壊闈㈡斁緗紝榪欐槸鍥犱負鍙湁鍦ㄤ袱涓猵ortal鏄浉浜掑紑鏀劇殑鎯呭喌涓嬫墠鍙互榪涜鍙鍖栨嫻嬨傚鏋滀綅浜庝竴涓彾鑺傜偣涓棿鐨勪竴涓偣琚粠鍙︿竴涓彾鑺傜偣鍙戝皠鍑烘潵鐨勫厜綰胯涓烘槸鍙鐨勮瘽錛岄偅涔堣繖鏉″厜綰垮繀鐒墮氳繃榪炴帴涓や釜鑺傜偣鐨刾ortal錛屽弬鑰冧笅鍥撅細
鍥?.14
鍦ㄥ浘6.14涓垜浠彲浠ョ湅瑙佸鏋滃湪涓涓妭鐐逛腑鐨勪竴涓偣鍙互浠庡叾瀹冭妭鐐圭湅瑙侊紝閭d箞瑙嗙嚎蹇呯劧閫氳繃涓や釜鑺傜偣鐩鎬簰榪為氱殑鍖哄煙銆傝繖鏄潪甯告槑鏄劇殑錛屽鏋滆綰胯鐗╀綋闃繪柇鐨勮瘽閭d箞涓ょ偣涔嬮棿蹇呭畾涓嶅彲瑙併傚洜姝ゅ皢鍏稿瀷鐐規斁緗湪涓や釜鑺傜偣涔嬮棿鎵寮鏀劇殑鍖哄煙鏄潪甯稿悎閫傜殑錛屼笅闈㈡弿榪扮殑綆楁硶灝嗗湪涓涓狟SP鏍戜笂鏀劇疆鍏稿瀷鐐廣傚浜庤繖涓嚱鏁伴渶瑕佷竴緇勫府鍔╁嚱鏁版潵鎶婄偣鏀劇疆鍦ㄤ竴涓妭鐐逛笂錛屽畠浠槸
l DISTRIBUTE-POINTS (Node) 榪欎釜鍑芥暟灝嗘寜鐓т竴瀹氱殑闂撮殧娌跨潃緇欏畾鑺傜偣鐨勫垎鍓查潰鏉ユ斁緗偣錛岀偣鐨勪綅緗細澶勪簬鑺傜偣鍖呭洿鐩掔殑鍐呴儴銆傚畠灝嗚繑鍥炰竴涓偣鐨勯泦鍚堬紝澶嶆潅搴︿負O(xy)錛岃繖閲寈涓鴻妭鐐瑰寘鍥寸洅鍐呭垎鍓查潰鐨勫搴︼紝鑰寉涓洪珮搴︺?br>l CLEANUP-POINTS (Node, PointSet) 浠庣偣鐨勯泦鍚堜腑鍓旈櫎涓嶅悎鏍肩殑鐐癸紝榪欎簺鐐瑰彲鑳藉拰鑺傜偣涓殑涓涓杈瑰艦浣嶇疆鐩稿悓錛屼篃鍙兘鏄綅浜庤妭鐐瑰寘鍥寸洅鐨勫閮ㄣ傚嚱鏁扮殑澶嶆潅搴︿負O(np)錛岃繖閲宯涓鴻妭鐐逛腑澶氳竟褰㈢殑鏁伴噺鑰宲涓洪泦鍚堜腑鐐圭殑鏁伴噺銆?br>l 鍑芥暟 DISTRIBUTE-SAMPLE-POINTS
l 鍙傛暟:
l Node – 褰撳墠鎴戜滑閬嶅巻鐨勮妭鐐廣?br>l PointSet – 鏀劇疆鍒扮粰瀹氳妭鐐瑰瓙鏍戜腑鐨勭偣鐨勯泦鍚堛?br>l 榪斿洖鍊?
l None
l 鍔熻兘錛?br>l 娌跨潃緇欏畾鑺傜偣鐨勫垎鍓查潰鏀劇疆鐐廣傚畠灝嗘寜鐓у垎鍓查潰鐨勪綅緗潵瀵硅緭鍏ョ殑鐐硅繘琛屾嫻嬶紝濡傛灉榪欎簺鐐瑰拰鑺傜偣涓殑涓涓杈瑰艦浣嶇疆鐩稿悓錛屾垨鑰呬綅浜庤妭鐐瑰寘鍥寸洅鐨勫閮ㄩ偅涔堝皢浼氳鍓旈櫎銆傛柊浜х敓鐨勭偣灝嗕細琚坊鍔犲埌宸︺佸彸涓や釜闆嗗悎涓紝褰撲竴涓偣鐨勯泦鍚堥亶鍘嗗埌涓涓彾鑺傜偣鏃墮偅涔堝畠灝辨槸榪欎釜鍙惰妭鐐圭殑鍏稿瀷鐐廣?br>DISTRIBUTE-SAMPLE-POINTS (Node, PointSet)
1 CLEANUP-POINTS (Node, PointSet)
2 if (IS-LEAF (Node))
3 璁劇疆鐐圭殑闆嗗悎涓哄綋鍓嶈妭鐐圭殑鍏稿瀷鐐廣?br>4 else
5 RightPart = NewPoints
6 NewPoints = DISTRIBUTE-POINTS (Node)
7 RightPart = NewPoints
8 LeftPart = NewPoints
9 for each point P in PointSet
10 Side = CLASSIFY-POINT (Node.Divider, P)
11 if (Side = COINCIDING)
12 RightPart = RightPart U P
13 LeftPart = LeftPart U P
14 if (Side = INFRONT)
15 RightPart = RightPart U P
16 if (Side = BEHIND)
17 LeftPart = LeftPart U P
18 DISTRIBUTE-SAMPLE-POINTS (Node.LeftChild, LeftPart)
19 DISTRIBUTE-SAMPLE-POINTS (Node.RightChild, RightPart)
綆楁硶鍒嗘瀽
姣忎竴嬈¤皟鐢ㄨ繖涓嚱鏁扮殑澶嶆潅搴︿負O(np + xy)錛堝弬鑰冨嚱鏁癈LEANUP-POINTS鍜?br>DISTRIBUTE-POINTS錛夛紝涓轟簡璁$畻瀹屾暣鐨勫鏉傚害鎴戜滑鍙互鐢ㄤ笅闈㈢殑鍏紡鏉ヨ〃紺猴紙鎴戜滑鍋囪鍏稿瀷鐐圭殑闆嗗悎鍚屾椂鍒嗗竷鍦ㄤ袱涓泦鍚堜箣涓級錛?br>T(n) = 2T(n/2) + O(np + xy)
榪欎釜鍑芥暟絎竴嬈¤皟鐢ㄦ椂灝嗕細浠嶣SP鏍戠殑鏍硅妭鐐瑰紑濮嬪茍浼氫紶鍏ヤ竴涓┖鐨勯泦鍚堛傛崲鍙ヨ瘽璇村畠鏄寜鐓т笅闈㈢殑鏂規硶榪涜鐨勶紝瀹冩槸浠庤BSP鏍戞牴鑺傜偣鎵瀹氫箟鐨勫垎鍓查潰涓婄殑鐐瑰紑濮嬬殑錛岀敱浜庝竴涓潰鐨勫ぇ灝忔病鏈夐檺鍒跺洜姝や篃浼氭湁鏃犻檺涓吀鍨嬬偣錛屽洜姝ゅ氨闇瑕佸鍏稿瀷鐐硅繘琛岄檺鍒訛紝榪欎釜鐜板湪灝辨槸鏍硅妭鐐圭殑鍖呭洿鐩掋?br>鍦ㄦ牴鑺傜偣涓婅幏寰楀悎鏍肩殑鍏稿瀷鐐瑰悗闇瑕佹妸鎵鏈夌殑鐐瑰彂閫佸埌鏍硅妭鐐圭殑涓や釜瀛愭爲涓紝褰撲竴涓吀鍨嬬偣鐨勯泦鍚堣繘鍏ヤ竴涓妭鐐瑰悗浼氳鍒嗗壊涓轟袱涓儴鍒嗭紝涓涓儴鍒嗗寘鍚簡鎵鏈変綅浜庤妭鐐瑰垎鍓查潰鐨?#8220;姝i潰”鐨勭偣錛岃屽彟涓閮ㄥ垎鍖呭惈浜嗘墍鏈変綅浜庤妭鐐瑰垎鍓查潰鐨?#8220;鍙嶉潰”鐨勭偣銆傝屼綅浜庡垎鍓查潰涓婄殑鐐瑰皢浼氬悓鏃舵斁鍦ㄤ袱涓泦鍚堜腑銆傛帴鐫“姝i潰”闆嗗悎灝嗕細琚紶鍏ュ埌鍙沖瓙鏍戜腑鑰?#8220;鍙嶉潰”闆嗗悎灝嗕細琚紶鍏ュ埌宸﹀瓙鏍戜腑銆傞噸澶嶈繖涓繃紼嬬洿鍒拌繘琛屽埌鍙惰妭鐐規椂緇撴潫錛屽湪榪欎簺鎿嶄綔鍚庢瘡涓涓彾鑺傜偣灝嗗寘鍚竴涓吀鍨嬬偣鐨勯泦鍚堬紝榪欎簺鐐歸兘浣嶄簬鑺傜偣鎵榪為氱殑鍦版柟銆?br>濡傛灉鎴戜滑鐜板湪鍦ㄨ繖涓樁孌靛姣忎竴涓妭鐐硅繘琛屽厜綰胯窡韙偅涔堟槸闈炲父鑰楄垂鏃墮棿鐨勶紝浣嗘槸濡傛灉鎴戜滑鐭ラ亾鍙惰妭鐐規槸涓庡摢涓涓妭鐐圭浉榪炵殑錛岄偅涔堣繖涓繃紼嬪皢浼氬彉鐨勭畝鍗曪紝鍥犱負榪欐牱鍙互鍑忓皯涓浜涗笉蹇呰鐨勫厜綰胯窡韙繍綆椼傛煡鎵劇浉浜掕繛鎺ョ殑鍙惰妭鐐歸潪甯哥畝鍗曪紝鍙互閫氳繃媯嫻嬫瘡涓涓彾鑺傜偣鐨勫吀鍨嬬偣鏉ユ煡鎵撅紝濡傛灉鍚屾椂鏈変袱涓妭鐐瑰叡浜竴涓偣閭d箞榪欎袱涓妭鐐瑰繀鐒舵槸鐩鎬簰榪為氱殑錛屽洜涓哄湪閬嶅巻BSP鏍戞斁緗吀鍨嬬偣鐨勮繃紼嬩腑錛岀偣涓嶆槸娌℃湁鏀劇疆鍒拌妭鐐逛笂灝辨槸鍚屾椂鏀劇疆鍦ㄤ袱涓妭鐐逛笂銆傚綋鎴戜滑鐭ラ亾鍝簺鑺傜偣鏄浉浜掕繛閫氱殑錛屽氨鍙互瀹氫箟榪涜鍏夌嚎璺熻釜鐨勭畻娉曚簡錛屼笉榪囬鍏堟垜浠渶瑕佸畾涔変竴浜涘府鍔╁嚱鏁般?br>涓轟簡鏂逛究榪涜鍏夌嚎璺熻釜鎴戜滑闇瑕佷竴浜涘熀鏈殑鍏夌嚎璺熻釜鍑芥暟錛孊SP鏍戞槸闈炲父閫傚悎榪涜鍏夌嚎璺熻釜鐨勭粨鏋勶紝鍥犱負澶ч儴鍒嗕笉鍙鐨勫尯鍩熼氳繃BSP鏍戝彲浠ュ緢綆鍗曠殑鍓旈櫎鎺夛紝涓嶇敤榪涜閬嶅巻錛屽洜姝よ姳璐圭殑鏃墮棿涔熼潪甯稿皯銆傛垜浠渶瑕佺殑鍑芥暟濡備笅錛?br>POLYGON-IS-HIT (Polygon, Ray) 榪斿洖鍏夌嚎鏄惁鍜屽杈瑰艦鐩鎬氦銆?br>RAY-INTERSECTS-SOMETHING-IN-TREE (Node, Ray) 榪斿洖鍏夌嚎鏄惁鍜岃妭鐐逛腑鐨勫瓙鏍戠浉浜ゃ?br>INTERSECTS-SPHERE (Sphere, Ray) 榪斿洖鍏夌嚎鏄惁鍜岀悆浣撶浉浜ゃ?br>CREATE-RAY (Point1, Point2) 閫氳繃涓や釜鐐規潵寤虹珛涓鏉″厜綰褲?br>涓婇潰鐨勫嚱鏁癛AY-INTERSECTS-SOMETHING-IN-TREE鏄竴涓潪甯告湁瓚g殑鍑芥暟錛屽洜涓哄畠鏄劇ず浜嗕竴浜汢SP鏍戠殑浼樼偣錛屽悓鏃朵篃鏄劇ず浜嗗浣曚嬌鐢˙SP鏍戞潵鍔犻熷厜綰胯窡韙殑澶勭悊銆傚畠鏄竴涓掑綊鍑芥暟錛岄鍏堝湪鏍戠殑鏍硅妭鐐逛笂浣跨敤錛屼吉綆楁硶濡備笅錛?br>l 鍑芥暟RAY-INTERSECTS-SOMETHING-IN-TREE
l 鍙傛暟錛?br>l Node – 鐢ㄦ潵榪涜璺熻釜鐨勮妭鐐廣?br>l Ray – 鐢ㄦ潵榪涜姹備氦鐨勫厜綰褲?br>l 榪斿洖鍊鹼細
l 鍏夌嚎鏄惁鍜岃妭鐐逛腑鐨勭墿浣撶浉浜ゃ?br>l 鍔熻兘錛?br>l 媯嫻嬪厜綰挎槸鍚︿笌緇欏畾鑺傜偣鏋佸叾瀛愭爲涓殑鐗╀綋鐩鎬氦銆?br>RAY-INTERSECTS-SOMETHING-IN-TREE (Node, Ray)
1 for each polygon P in Node
2 POLYGON-IS-HIT (P, Ray)
3 startSide = CLASSIFY-POINT (Ray.StartPoint, Node.Divider)
4 endSide = CLASSIFY-POINT (Node.EndPoint, Node.Divider)
l 濡傛灉鍏夌嚎鍜岃妭鐐圭殑鍒嗗壊闈㈢浉浜ゆ垨鍜屽垎鍓查潰鐨勪綅緗噸鍙狅紝瀵硅妭鐐圭殑涓や釜瀛愯妭鐐硅繘琛屾嫻嬨?br>5 if ((startSide = COINCIDING and endSide = COINCIDING) or
startSide <> endSide and startSide <> COINCIDING and
endSide <> COINCIDING)
6 if (RAY-INTERSECTS-SOMETHING-IN-TREE (Node.LeftChild, Ray))
7 return true
8 if (RAY-INTERSECTS-SOMETHING-IN-TREE (Node.RightChild, Ray))
9 return true
l 濡傛灉鍏夌嚎鍙綅浜庡垎鍓查潰鐨?#8220;姝i潰”瀵硅妭鐐圭殑鍙沖瓙鏍戣繘琛屾嫻嬨傚湪if璇彞涓嬌鐢╫r鎿嶄綔絎︽槸鍥犱負鍏夌嚎鐨勪竴涓鐐瑰彲鑳戒笌鍒嗗壊闈㈢殑浣嶇疆閲嶅彔銆?br>10 if (startSide = INFRONT or endSide = INFRONT)
11 if(RAY-INTERSECTS-SOMETHING-IN-TREE (Node.RightChild, Ray))
12 return true
l 濡傛灉鍏夌嚎鍙綅浜庡垎鍓查潰鐨?#8220;鍙嶉潰”瀵硅妭鐐圭殑宸﹀瓙鏍戣繘琛屾嫻嬨傚湪if璇彞涓嬌鐢╫r鎿嶄綔絎︽槸鍥犱負鍏夌嚎鐨勪竴涓鐐瑰彲鑳戒笌鍒嗗壊闈㈢殑浣嶇疆閲嶅彔銆?br>13 if (startSide = BEHIND or endSide = BEHIND)
14 if (RAY-INTERSECTS-SOMETHING-IN-TREE (Node.LeftChild, Ray))
15 return true
l 鍏夌嚎娌℃湁鍜屼換浣曠墿浣撶浉浜わ紝榪斿洖鍒頒笂涓灞傘?br>16 return false
綆楁硶鍒嗘瀽
鏈鍧忕殑鎯呭喌鏄厜綰塊亶鍘嗕簡BSP鏍戜腑姣忎竴涓妭鐐癸紝榪欐牱鍏夌嚎灝嗕笌鑺傜偣涓瘡涓涓崟鐙殑澶氳竟褰㈣繘琛屾嫻嬶紝榪欐椂鍑芥暟鐨勫鏉傚害灝嗕負O(n)錛岃繖閲宯涓築SP鏍戜腑鎵鏈夊杈瑰艦鐨勬暟閲忋備竴鑸儏鍐典笅鍏夌嚎騫朵笉浼氭嫻嬫爲涓殑姣忎竴涓妭鐐癸紝榪欐牱灝嗕細澶уぇ鍑忓皯榪涜媯嫻嬬殑澶氳竟褰㈡暟閲忋傛渶浣崇殑鎯呭喌鏄厜綰胯闄愬埗鍦ㄤ竴涓妭鐐逛腑錛岃繖鏃跺嚱鏁扮殑澶嶆潅搴︽帴榪戜簬錛?lg n)錛庤繖鍙栧喅浜嶣SP鏍戠殑緇撴瀯澶у皬銆?br>l 鍑芥暟CHECK-VISIBILITY
l 鍙傛暟錛?br>l Node1 – 寮濮嬪鐨勮妭鐐廣?br>l Node2 – 緇撴潫澶勭殑鑺傜偣銆?br>l 榪斿洖鍊鹼細
l Node2鏄惁鍙互琚玭ode1鐪嬭銆?br>l 鍔熻兘錛?br>l 鍦ㄤ袱涓彾鑺傜偣鐨勫吀鍨嬬偣涔嬮棿榪涜璺熻釜錛屾嫻嬩袱涓妭鐐逛箣闂存槸鍚﹀彲瑙併?br>CHECK-VISIBILITY (Node1, Node2)
1 Visible = false
2 for each 鍏稿瀷鐐筆1 in Node1
3 for each 鍏稿瀷鐐筆2 in Node2
4 Ray = CREATE-RAY (P1, P2)
5 if(not RAY-INTERSECTS-SOMETHING-IN-TREE(Node1.Tree.RootNode,
Ray)
6 Visible = true
7 return Visible
綆楁硶鍒嗘瀽
鍑芥暟CHECK-VISIBILITY闈炲父鑰楄垂鏃墮棿錛屽綋鎴戜滑鍦ㄤ袱涓彾鑺傜偣涔嬮棿榪涜鍏夌嚎璺熻釜鏉ユ嫻嬩袱鑰呬箣闂存槸鍚﹀彲瑙佹椂錛屾垜浠笉寰椾笉浠嶯ode1鐨勬瘡涓涓吀鍨嬬偣寮濮嬪Node2鐨勬瘡涓涓吀鍨嬬偣榪涜璺熻釜錛屾渶鍧忕殑鎯呭喌鏄瘡涓嬈¤窡韙兘灝嗗鏍戜腑鎵鏈夌殑澶氳竟褰㈣繘琛屾嫻嬶紝榪欐椂鍑芥暟鐨勫鏉傚害O(s1 s2 p)錛岃繖閲宻1涓篘ode1涓吀鍨嬬偣鐨勬暟閲忥紝s2涓篘ode2涓吀鍨嬬偣鐨勬暟閲忥紝p涓烘爲涓杈瑰艦鐨勬暟閲忋傞氬父瀹冪殑鎬ц兘鏄瘮杈冨ソ鐨勶紝鎺ヨ繎浜嶰(s1 s2 lg p)銆?br>l 鍑芥暟TRACE-VISIBILITY
l 鍙傛暟錛?br>l Tree – 鍘昏繘琛屽厜綰胯窡韙殑BSP-tree銆?br>l 榪斿洖鍊鹼細
l None
l 鍔熻兘錛?br>l 瀵逛簬鏍戜腑姣忎竴涓彾鑺傜偣錛屽畠灝嗚繘琛屽厜綰胯窡韙繍綆楁潵媯嫻嬪拰瀹冪浉榪炵殑鑺傜偣鐨勫彲瑙佹с傛瘡涓涓鍙戠幇鏄彲瑙佺殑鑺傜偣灝嗕細琚坊鍔犲埌褰撳墠鑺傜偣鐨凱VS涓傚綋涓涓彾鑺傜偣鍙戠幇鏄彲瑙佺殑錛屾垜浠繕瑕佸鍜屽畠鐩歌繛鐨勮妭鐐硅繘琛屽厜綰胯窡韙繍綆楁潵媯嫻嬪彲瑙佹с?br>TRACE-VISIBILITY (Tree)
1 for (each 鏍戜腑鐨勫彾鑺傜偣L)
2 for (each 鍜屽彾鑺傜偣L鐩歌繛鐨勫彾鑺傜偣C)
3 娣誨姞鑺傜偣C鍒拌妭鐐筁鐨凱VS涓?br>4 for (each 鏍戜腑鐨勫彾鑺傜偣L1)
5 while (鍦ㄥ彾鑺傜偣L鐨凱VS涓瓨鍦ㄤ竴涓彾鑺傜偣L2錛屽畠鎵榪炴帴鐨勮妭鐐規病鏈夎繘琛屽彲瑙佹ф嫻?
5 for (each 榪炴帴鍒拌妭鐐筁2涓殑鍙惰妭鐐笴)
6 if (鑺傜偣C娌℃湁浣嶄簬鑺傜偣L1鐨凱VS涓?and
CHECK-VISIBILITY (L1, C))
7 娣誨姞鑺傜偣C鍒拌妭鐐筁1鐨凱VS涓?br>7 娣誨姞鑺傜偣L1鍒拌妭鐐笴鐨凱VS涓?br>綆楁硶鍒嗘瀽
濡傛灉鎴戜滑娌℃湁浣跨敤鏍規嵁鍙惰妭鐐圭殑鐩歌繛鎯呭喌鏉ヨ繘琛屽鐞嗙殑浼樺寲鎶鏈紝閭d箞蹇呴』瀵規爲涓殑姣忎竴涓彾鑺傜偣榪涜媯嫻嬶紝榪欐椂鍑芥暟鐨勫鏉傚害涓篛(n2)錛岃繖閲宯涓烘爲涓彾鑺傜偣鐨勬暟閲忋傝瀵逛笂闈㈢殑綆楁硶浼拌涓涓澶勭悊榪囩▼鎻愰珮浜嗗灝戞ц兘鐨勫叿浣撴暟鍊奸潪甯稿洶闅撅紝鍥犱負瀹冧緷璧栦簬鎵澶勭悊鐨勭粨鏋勭殑澶у皬銆傚浜庢瘡涓涓彾鑺傜偣涓庡叾瀹冭妭鐐歸兘鏄彲瑙佺殑緇撴瀯錛岃繖涓畻娉曚笉浼氬仛浠諱綍浼樺寲銆傚浜庢瘡涓涓彾鑺傜偣鍙湁涓鍒頒簩涓彲瑙佺殑鑺傜偣鐨勭粨鏋勶紝榪欎釜綆楁硶灝嗕細浜х敓闈炲父澶т紭鍖栵紝瀹冪殑澶嶆潅搴︽帴榪戜笌O(n)銆?br>鐜板湪鍦ㄤ竴涓璁¤壇濂界殑鍦板浘涓婃墍浜х敓鐨勭粨鏋勫湪姣忎竴甯т笂灝嗕細閬垮厤媯嫻嬪ぇ閲忕殑澶氳竟褰€備竴涓璁¤壇濂界殑鍦板浘鍦ㄥ緩绔嬫椂灝嗕細鑰冭檻鐗╀綋鐨勫彲瑙佹э紝榪欐剰鍛崇潃搴斿敖鍙兘鐨勫湪鍦板浘涓斁鍏ヤ竴浜涜兘闅滅瑙嗙嚎鐨勭墿浣擄紝濡傚澹佺瓑銆傚鏋滃湪鍦板浘涓寘鍚竴涓湁澶ч噺緇嗚妭鐨勫ぇ鎴塊棿錛岄偅涔堝湪涓婇潰鐨勭畻娉曚腑錛堟垨鍦ㄤ竴涓猵ortal寮曟搸涓級榪涜鐨勯殣钘忛潰鍓旈櫎宸ヤ綔瀵瑰畠涓嶄細浜х敓浠諱綍鏁堟灉銆傝繖鏃舵垜浠渶瑕佷嬌鐢ㄥ叾瀹冪被浼間簬LOD榪欐牱鐨勬妧鏈潵榪涜澶氳竟褰㈠墧闄ゃ?/p>
闈欐佺墿浣?br>鑰冭檻涓涓嬭繖鏍風殑鍦烘櫙錛屼竴涓悆浣撲綅浜庝竴涓珛鏂逛綋鐨勪腑蹇冿紝濡傛灉鐢˙SP瀵瑰畠榪涜娓叉煋閭d箞灝嗕細浜х敓澶ч噺鐨勮妭鐐癸紝騫朵細浜х敓澶ч噺鐨勫垎鍓插杈瑰艦錛岃繖鏄洜涓哄湪鐞冧綋涓婄殑姣忎竴涓杈瑰艦閮戒細閫佸叆鍒板彾鑺傜偣涓傚鏋滅悆浣撴湁200涓杈瑰艦褰撴覆鏌撴椂灝變細浜х敓200涓彾鑺傜偣鐨凚SP鏍戙傝繖鏍峰仛闈炲父褰卞搷榪愯鐨勯熷害錛屽洜姝ゅ繀欏誨鎵句竴涓柟娉曟潵閬垮厤榪欑鐜拌薄鐨勫彂鐢熴?br>涓轟簡瑙e喅榪欎釜闂鍦板浘鐨勮璁¤呭彲浠ラ夋嫨緇勬垚鍦板浘鐨勫嚑浣曚綋錛屽湪涓婇潰鐨勪緥瀛愪腑涔熷氨鏄珛鏂逛綋錛屾帴鐫灝嗗墿浣欑殑鐗╀綋鍋氫負闈欐佺墿浣擄紝瀹冧滑灝嗕笉浼氱敤鏉ュBSP鏍戣繘琛屾覆鏌撴垨榪涘彲瑙佹ф嫻嬶紝浣嗘槸瀹冧滑浼氬弬涓庡埌鍦板浘鐨勫厜鐓ц繍綆楀綋涓幓銆傚綋榪涜鍙鎬ц繍綆楁椂姣忎竴涓潤鎬佺墿浣撲細琚坊鍔犲埌BSP鏍戜腑錛屾瘡涓涓潤鎬佺墿浣撶殑澶氳竟褰㈠皢浼氳娣誨姞鍒癇SP鏍戜腑錛岃繖涓繃紼嬪涓嬶細
l 鍑芥暟PUSH-POLYGON
l 鍙傛暟錛?br>l Node – 澶氳竟褰㈠綋鍓嶆墍鍦ㄧ殑鑺傜偣銆?br>l Polygon – 灝嗚娣誨姞鐨勫杈瑰艦銆?br>l 榪斿洖鍊鹼細
l None
l 鍔熻兘錛?br>l 灝嗗杈瑰艦娣誨姞鍒版爲涓傚鏋滃杈瑰艦鐨勪竴浜涚偣涓庤妭鐐圭殑鍒嗗壊闈㈢浉浜ゅ皢浼氳鍒嗗壊銆傚垎鍓插悗鐨勯儴鍒嗗皢浼氳緇х畫鍚戜笅浼犻併傚綋涓涓杈瑰艦榪涘叆涓涓彾鑺傜偣鍚庡畠灝嗚娣誨姞鍒板彾鑺傜偣鐨勫杈瑰艦闆嗗悎涓?br>PUSH-POLYGON (Node, Polygon)
1 if (IS-LEAF (Node))
2 Node.PolygonSet = Node.PolygonSet U Polygon
3 else
4 value = CALCULATE-SIDE (Node.Divider, Polygon)
5 if (value = INFRONT or value = SPANNING)
6 PUSH-POLYGON (Node.RightChild, Polygon)
7 else if (value = BEHIND)
8 PUSH-POLYGON (Node.LeftChild, Polygon)
9 else if (value = SPANNING)
10 Split_Polygon28 (P1, Divider, Front, Back)
11 PUSH-POLYGON (Node.RightChild, Front)
12 PUSH-POLYGON (Node.LeftChild, Front)
PUSH-POLYGON鏄竴涓掑綊鍑芥暟錛屽畠灝嗕竴涓杈瑰艦娣誨姞鍒癇SP鏍戜腑錛岃繖涓嚱鏁板姣忎竴涓潤鎬佺墿浣撶殑姣忎竴涓杈瑰艦閮戒細璋冪敤涓嬈★紝
鍦ㄨ繖涓繃紼嬪鐞嗕箣鍚庡彾鑺傜偣鍙兘涓嶅啀鎴愪負涓涓?#8220;鍑?#8221;闆嗗悎錛岃繖鍦ㄨ繘琛岀鎾炴嫻嬫椂鍙兘浼氫駭鐢熶竴浜涢棶棰橈紝鍚庨潰鐨勫唴瀹瑰皢浼氬榪欎釜闂榪涜闃愯堪銆?br>BSP鎶鏈瑙?
eXtreme3D
絎笁鑺?瀹ゅ唴鍦烘櫙涓厜鐓ц繍綆?br>鍏充簬Radiosity鐨勭畻娉曟渶鏃╂槸鐢盙oral銆丆indy M銆乀orrance銆並enneth E銆丟reenberg銆丏onald P銆丅attaile鍜孊ennett鍦ㄨ鏂囥奙odelling the interaction of light between diffuse surfaces銆嬫彁鍑虹殑銆備粬浠嬌鐢≧adiosity鏉ユā鎷熻兘閲忓湪婕弽灝勮〃闈箣闂磋繘琛屼紶閫侊紝婕弽灝勮〃闈㈠鐓у埌琛ㄩ潰涓婄殑鍏夌嚎鍦ㄦ墍鏈夌殑鏂瑰悜涓婇兘榪涜鐩稿悓鐨勫弽灝勶紝鍜屽畠鐩稿弽鐨勬槸闀滈潰鍙嶅皠琛ㄩ潰錛屽畠鍙湪鍙嶅皠鏂瑰悜涓婁紶鎾弽灝勫厜銆傜敱浜庢極鍙嶅皠琛ㄩ潰鐨勮繖涓壒鎬э紝榪欏氨鎰忓懗鐫瀵逛簬鎵鏈夌殑瑙傚療瑙掑害鑰岃█鐪嬭搗鏉ヨ〃闈㈤兘鏄浉鍚岀殑錛岃繖鏍峰浜庡満鏅腑鐨勬瘡涓涓〃闈㈠彧闇瑕佽繘琛屼竴嬈″厜鐓ц繍綆楋紝鑰屼笖鍙互鍦ㄥ満鏅殑棰勬覆鏌撴椂榪涜錛屽洜姝よ繖欏規妧鏈澶ч噺鐨?D娓告垙鎵閲囩敤銆?br>涓嬮潰鎴戝啀綆鐭殑璁茶В涓涓婻adiosity鏄浣曞伐浣滅殑錛岃屽皢涓昏鐨勭簿鍔涙斁鍦ㄥ浣曚嬌鐢˙SP鏍戞潵鍔犻烺adiosity鐨勮綆楋紝瀵逛簬Radiosity鐨勮緇嗕粙緇嶈鍙傝冨墠闈㈢殑绔犺妭銆俁adiosity鎶鏈槸璁捐鐢ㄦ潵浣垮満鏅腑鍏夌収鐪嬭搗鏉ユ洿鍔犵湡瀹炲拰鍏夋粦錛屽鏋滄垜浠嬌鐢ㄤ竴涓竴鐩村悜鍓嶄紶鎾屼笉鑰冭檻鍙嶅皠鐨勫厜鐓фā鍨嬶紝閭d箞褰撳満鏅腑鐨勭伅鍏夌収浜満鏅腑鐨勭墿浣撴椂錛屽茍涓嶄細璁$畻榪滃緇忚繃鍙嶅皠榪囨潵鐨勫厜綰匡紝榪欐牱鍦烘櫙涓殑闃村獎鐪嬭搗鏉ラ潪甯稿皷閿愯岀墿浣撹〃闈篃鐪嬭搗鏉ラ潪甯鎬笉鐪熷疄銆備負浜嗕嬌鐢╮adiosity鎶鏈垜浠渶瑕佹妸鍦烘櫙鍒嗗壊鎴愪竴鍧椾竴鍧楀緢灝忕殑閮ㄥ垎錛屾瘡涓閮ㄥ垎鎴戜滑縐板畠涓簆atch錛屾瘡涓涓猵atch閮芥湁涓涓垵濮嬪寲鐨勮兘閲忕駭鍒紝濡傛灉瀹冧笉鏄竴涓伅鍏夎繖鏍風殑鍙戝厜浣撶殑璇濋氬父涓?錛屾湁璁稿鏂規硶鏉ュ垎閰嶅満鏅腑鐨勮兘閲忥紝榪欓噷鎴戜滑灝嗚浣跨敤鐨勬柟娉曠О涓轟氦浜掑紡radiosity銆傝繖涓柟娉曠殑榪囩▼鏄垜浠粠鍦烘櫙涓湭鍙戦佽兘閲忕殑綰у埆鏈楂樼殑patch寮濮嬪彂閫佽兘閲忥紝鑳介噺緇忚繃浼犻掑悗灝嗕笉鍐嶅彂閫佽兘閲忕殑patch鐨勭瓑綰ц涓?錛岄噸澶嶈繖涓繃紼嬬洿鍒板満鏅腑鐨勬瘡涓涓猵atch鐨勮兘閲忕瓑綰ч兘灝忎簬涓涓瀹氬間負姝€?br>褰撹兘閲忎粠涓涓猵atch錛坖錛夊紑濮嬪彂閫佸埌鍙︿竴涓猵atch錛坕錛夋椂鎴戜滑浣跨敤涓嬮潰鐨勫叕寮忥細
Bi = Bi + Bj * Fij * Ai / Aj
榪欓噷Bi = patch錛坕錛夌殑鑳介噺綰у埆 Bj = patch錛坖錛夌殑鑳介噺綰у埆
Ai= patch錛坕錛夌殑浣滅敤鍖哄煙 Aj = patch錛坖錛夌殑浣滅敤鍖哄煙
Fij = patch錛坕錛変笌patch錛坖錛変箣闂寸殑緋繪暟
鍦ㄥ叕寮忎腑緋繪暟Fij鏄敱浠ヤ笅鍏紡鏉ョ‘瀹氱殑錛?br>Fij = (cos qi * cos qj) / d2 * Hij
榪欓噷Fij = patch錛坕錛変笌patch錛坖錛変箣闂寸殑緋繪暟
qi = patch錛坕錛変笌patch錛坖錛夋硶綰夸箣闂寸殑澶硅
qj = patch錛坕錛変笌patch錛坖錛夋硶綰夸箣闂寸殑澶硅
d = patch錛坕錛変笌patch錛坖錛変箣闂寸殑璺濈
Hij = patch錛坕錛変笌patch錛坖錛変箣闂寸殑鍙鎬х郴鏁般傚鏋滃湪涓や釜patch涔嬮棿鍙湁涓鏉″厜綰垮彲浠ヨ窡韙紝榪欎釜鍊間負1錛屽鏋滄病鏈夊厜綰垮彲浠ヨ窡韙負0銆備竴鑸儏鍐典笅鐢變簬姣忎竴涓猵atch閮戒笉鏄竴涓偣鑰屾槸涓涓尯鍩燂紝鍥犳鍏夌嚎鏈夊緢澶氭潯銆?br>浠庝笂闈㈢殑鍏紡涓垜浠彲浠ョ湅鍒板湪鍦烘櫙涓繘琛宺adiosity璁$畻鏄潪甯歌楄垂鏃墮棿鐨勩傝繖涓嚱鏁扮殑澶嶆潅搴︿負O(n3)錛岃繖閲岀殑n涓哄満鏅腑patch鐨勬暟閲忋傜敱浜庡浜庡満鏅腑姣忎竴涓猵atch浣犻渶瑕佸彂閫佹渶灝戜竴鏉″厜綰垮埌鍏跺畠patch涓婏紝鍥犳闇瑕佸鍦烘櫙涓殑鍑犱箮鎵鏈夌殑澶氳竟褰㈤兘榪涜鍏夌嚎璺熻釜璁$畻銆傚湪涓婇潰鐨勫叕寮忎腑緋繪暟H鐨勮綆楅潪甯歌楄垂鏃墮棿錛屼笅闈㈡垜浠皢鐪嬩竴涓嬪浣曞湪BSP鏍戜腑瀵瑰畠鐨勮綆楄繘琛屼紭鍖栥?
BSP鏍戜腑鐨剅adiosity璁$畻
鍦ㄨ繘琛屽満鏅腑鐨勫厜鐓ц綆椾箣鍓嶉渶瑕佹妸鍦烘櫙涓殑闈㈠垎鍓蹭負patch錛屼竴涓柟娉曟槸鍦ㄥ紑濮嬬殑鏃跺欒瀹氭瘡涓涓猵atch涓洪瀹氱殑澶у皬錛屽綋璁$畻姣忎竴涓猵atch鐨勮兘閲忔椂錛屽鏋滃湪patch涓婄殑鑳介噺瓚沖澶э紝瀵硅繖涓猵atch榪涜鍒嗗壊銆備笉榪囪繖涓柟娉曟槸闈炲父鑰楄垂鏃墮棿鐨勶紝鍥犳蹇呴』瀵繪壘涓涓洿濂界殑鏂規硶鏉ラ氳繃BSP鏍戝璁$畻榪涜浼樺寲銆?br>鍦╮adiosity鐨勪竴鑸畻娉曚腑鍦烘櫙涓殑姣忎竴涓厜婧愰兘琚湅浣滀負涓涓垨澶氫釜patch錛岃繖閲屾垜浠彲浠ユ敼榪涗竴涓嬶紝灝嗘瘡涓涓厜婧愭斁鍦ㄥ畠鎵浣嶄簬鐨勫彾鑺傜偣涓紝鎺ヤ笅鏉ユ瘡涓涓厜婧愰兘鍙戦佽嚜宸辯殑鑳介噺鍒板満鏅腑鎵鏈夌殑patch涓婏紝褰撹繖涓繃紼嬪畬鎴愬悗radiosity璁$畻涔熷氨緇撴潫浜嗐備負浜嗕嬌鏈鍚庣殑緇撴灉鐪嬭搗鏉ユ洿濂藉彲浠ヤ嬌鐢ㄤ竴縐嶇О涓?#8220;娓愯繘綺鵑?#8221;錛坧rogressive refinement錛夌殑鎶鏈潵瀵硅繖涓柟娉曡繘琛屽緢灝忕殑淇敼銆傚湪姣忎竴嬈¤繃紼嬩腑錛屽彾鑺傜偣涓叿鏈夐珮鑳介噺鐨刾atch灝嗗彂閫佽兘閲忓埌鍏跺畠浣庤兘閲忕殑patch涓婏紝榪欐牱鍋氱殑緇撴灉鏄珮浜害鐨刾atch灝嗗彂閫佽兘閲忓埌澶勪簬闃村獎涓璸atch涓娿傝繖鏄洜涓哄湪瀹為檯鐢熸椿涓茍娌℃湁鐪熸榛戞殫鐨勫湴鏂癸紝瀹冨澶氬皯灝戣鑾峰緱涓浜涘叾瀹冪墿浣撳弽灝勮繃鏉ョ殑鍏変寒銆?br>鐢變簬璁$畻闈炲父鑰楄垂鏃墮棿闇瑕佸仛涓涓嬩紭鍖栵紝浣跨敤娓叉煋BSP鏍戞椂鑾峰緱鐨凱VS淇℃伅鍙互鍦ㄩ夋嫨鍝簺patch灝嗘帴鍙楄兘閲忔椂鍓旈櫎涓浜涙棤鐢ㄧ殑璁$畻銆傚洜涓哄湪璁$畻PVS鏃朵嬌鐢ㄤ簡鐩稿悓鐨勬柟娉曟潵榪涜鍏夌嚎璺熻釜銆?br>閫氳繃鍦烘櫙鏉ュ垎閰嶈兘閲忕殑綆楁硶濡備笅錛?br>l 鍑芥暟RADIOSITY
l 鍙傛暟錛?br>l Tree – 榪涜radiosity璁$畻鐨凚SP鏍戙?br>l 榪斿洖鍊鹼細
l None
l 鍔熻兘錛?br>l 鍦ㄥ満鏅腑鐨刾atch涔嬮棿鍙戦佽兘閲忋?br>RADIOSITY (Tree)
1 for(each leaf L in Tree)
2 for(each light S in L)
3 for(each leaf V that is in L’s PVS)
4 Send S’s energy to the patches in V
l 涓嬮潰璇彞5鏄負浜嗚鍦板浘緙栬緫鑰呭湪浠諱綍鏃跺欓兘鍙互媯鏌ュ満鏅覆鏌撶殑鏁堟灉錛屽鏋滀粬鎰熷埌鐪嬭搗鏉ュ凡緇忚凍澶熷ソ浜嗗彲浠ヤ腑鏂兘閲忕殑浼犳挱銆?br>5 while(not looks good enough)
6 for(each leaf L in Tree)
7 for(each leaf V that is in L’s PVS)
8 Send energy from the patch with the most unsent energy in L
to all patches in V.
澶嶆潅搴﹀垎鏋?br>榪欎釜鍑芥暟鐨勮繍綆楄垂鐢ㄥ疄鍦ㄦ槸澶珮鏄備簡錛屽彲浠ョО涓烘椂闂存潃鎵嬶紝鍦ㄦ渶鍧忕殑鎯呭喌涓嬫瘡涓鏉″厜綰垮皢涓嶅緱涓嶆嫻嬪満鏅腑鐨勬瘡涓涓杈瑰艦錛屾鏃跺鏉傚害涓篛(n3)錛岃繖閲宯涓烘爲涓璸atch鐨勬暟閲忋備竴鑸儏鍐典笅鐢變簬榪涜浜嗕紭鍖栧彲浠ュ噺灝戝ぇ閲忕殑璁$畻錛屼絾鏄噺灝戝灝戝茍涓嶈兘璁$畻鍑烘潵錛屽洜涓鴻繖渚濊禆浜庢爲緇撴瀯鐨勫鏉傚害銆?br>涓婇潰鐨勫嚱鏁扮粰鍑轟簡涓涓厖鍒嗗埄鐢˙SP鏍戠殑浼樼偣鏉ュ姞閫熷満鏅厜鐓ц繍綆楃殑鏂規硶錛屽挨鍏舵槸鍙互鏄捐憲鐨勫噺灝戝厜綰胯窡韙殑璁$畻閲忥紝鑰屼笖鍦板浘璁捐鑰呭彲浠ユ潵鍐沖畾褰撳満鏅覆鏌撴椂濡傛灉娓叉煋鐨勬晥鏋滃彲浠ユ帴鍙椾腑鏂覆鏌撳驚鐜傝繖瀵瑰湴鍥劇殑棰勬覆鏌撳疄鍦ㄦ槸澶柟渚夸簡錛岃繍琛岀殑鏃墮棿鍙互鏍規嵁娓叉煋鐨勬晥鏋滄潵鍐沖畾銆?br>絎洓鑺?BSP鏍戠殑棰勬覆鏌?br>鐜板湪鎴戜滑闇瑕佸畬鎴愪竴涓畬鏁碆SP寮曟搸鐨勯澶勭悊榪囩▼錛屼笅闈㈢殑綆楁硶鏄劇ず濡備綍灝嗗満鏅覆鏌撳埌BSP鏍戜腑銆?br>l 鍑芥暟RENDER-SCENE
l 鍙傛暟錛?br>l Scene – 琚覆鏌撶殑鍦烘櫙
l 榪斿洖鍊鹼細
l 涓涓狟SP鏍戙?br>l 鍔熻兘
l 棰勬覆鏌撴潵鑾峰緱涓涓寘鍚満鏅俊鎭殑BSP鏍戙?br>RENDER-SCENE (Scene)
l 浣跨敤鎻忚堪鍦烘櫙涓浘鍏冪殑鐗╀綋鏉ユ覆鏌揃SP鏍戙?br>1 GeometryPolygons = {}
2 for (姣忎竴涓寘鍚満鏅浘鍏冪殑鐗╀綋object O)
3 GeometryPolygons = GeometryPolygons U O.PolygonSet
4 GENERATE-BSP-TREE (Tree.RootNode, GeometryPolygons)
l 鍒嗛厤鍙惰妭鐐逛笂鐨勫彇鏍風偣銆?br>5 DISTRIBUTE-SAMPLE-POINTS (Tree.RootNode, {})
6 TRACE-VISIBILITY (Tree)
7 for 姣忎竴涓満鏅腑鐨勯潤鎬佺墿浣搊bject O
8 for 鐗╀綋O涓瘡涓涓杈瑰艦P
9 PUSH-POLYGON (Node, P)
l 鍑芥暟CREATE-PATCHES鏄竴涓湭瀹氫箟鐨勫嚱鏁幫紝鐢變簬鎴戜滑鐨勮В鍐蟲柟妗堟晥鐜囧茍涓嶆槸澶ソ錛屽洜姝ゆ病鏈夊瀹冭繘琛岃緇嗙殑浠嬬粛銆?br>10 CREATE-PATCHES (Tree)
11 RADIOSITY (Tree)
澶嶆潅搴﹀垎鏋?br>鍑芥暟鐨勫鏉傚害濡備笅錛?br>鍑芥暟 鏈鍧忔儏鍐?涓鑸儏鍐?鎻忚堪
GENERATE-BSP-TREE O(n2 lg n) O(n2) n涓哄満鏅腑澶氳竟褰㈢殑鏁伴噺
DISTRIBUTE-SAMPLE-POINTS Q (np + xy) Q (np + xy) n涓烘爲涓杈瑰艦鐨勬暟閲忥紝p涓烘爲涓吀鍨嬬偣鐨勬暟閲忥紝x鍜寉涓哄垎鍓查潰鐨勫搴﹀拰楂樺害銆?br>TRACE-VISIBILITY O(n2) O(n lg n), n涓烘爲涓杈瑰艦鐨勬暟閲忋?br>RADIOSITY O(n3) O(n2 lg n) n涓烘爲涓璸atch鐨勬暟閲?br>鍦ㄤ竴鑸儏鍐佃繖涓鍒椾腑鏄劇ず浜嗙畻娉曢氬父鎵闇榪愯鐨勬椂闂達紝瀵圭畻娉曟椂闂村獎鍝嶆渶澶х殑鏄嚱鏁癛ADIOSITY錛屽畠浣挎暣涓畻娉曠殑澶嶆潅搴﹁秼鍚戜簬O(n3)銆?/p>
//--------------------------------------------------------------------------------
// Geometry Shader
//--------------------------------------------------------------------------------
[maxvertexcount(12)]
void GS( triangle GSPS_INPUT input[3], inout TriangleStream<GSPS_INPUT> TriStream )
{
GSPS_INPUT output;
//
// Calculate the face normal
//
float3 faceEdgeA = input[1].Pos - input[0].Pos;
float3 faceEdgeB = input[2].Pos - input[0].Pos;
float3 faceNormal = normalize( cross(faceEdgeA, faceEdgeB) );
float3 ExplodeAmt = faceNormal*Explode;
//
// Calculate the face center
//
float3 centerPos = (input[0].Pos.xyz + input[1].Pos.xyz + input[2].Pos.xyz)/3.0;
float2 centerTex = (input[0].Tex + input[1].Tex + input[2].Tex)/3.0;
centerPos += faceNormal*Explode;
//
// Output the pyramid
//
for( int i=0; i<3; i++ )
{
output.Pos = input[i].Pos + float4(ExplodeAmt,0);
output.Pos = mul( output.Pos, View );
output.Pos = mul( output.Pos, Projection );
output.Norm = input[i].Norm;
output.Tex = input[i].Tex;
TriStream.Append( output );
int iNext = (i+1)%3;
output.Pos = input[iNext].Pos + float4(ExplodeAmt,0);
output.Pos = mul( output.Pos, View );
output.Pos = mul( output.Pos, Projection );
output.Norm = input[iNext].Norm;
output.Tex = input[iNext].Tex;
TriStream.Append( output );
output.Pos = float4(centerPos,1) + float4(ExplodeAmt,0);
output.Pos = mul( output.Pos, View );
output.Pos = mul( output.Pos, Projection );
output.Norm = faceNormal;
output.Tex = centerTex;
TriStream.Append( output );
TriStream.RestartStrip();
}
for( int i=2; i>=0; i-- )
{
output.Pos = input[i].Pos + float4(ExplodeAmt,0);
output.Pos = mul( output.Pos, View );
output.Pos = mul( output.Pos, Projection );
output.Norm = -input[i].Norm;
output.Tex = input[i].Tex;
TriStream.Append( output );
}
TriStream.RestartStrip();
}
2.GS綺掑瓙
瀹炵幇鍍忕儫鑺變竴鏍風殑鏁堟灉銆?br>棣栧厛瑕佷簡瑙d簲縐嶅熀鏈矑瀛愩?br>Launcher Particles 鍙戝皠綺掑瓙錛氫笉縐誨姩涔熶笉姝誨幓錛岀敤鏉ュ彂灝凷hell綺掑瓙銆備竴鏃﹀彂灝勫畬Shell綺掑瓙錛屽氨閲嶇疆鏃墮棿銆?br>Shell Particles 鐢卞彂灝勭矑瀛愬彂灝勫嚭闅忔満閫熷害鐨勭殑Shell綺掑瓙錛屽湪鐢熷懡鍛ㄦ湡鍐呬笉鍙戝皠鏈被鍨嬬殑綺掑瓙錛岃屽彂灝勫嚭涓浜汦mber1鍜孍mber2綾誨瀷鐨勭矑瀛愩?br>Ember1 Particles 鐢盨hell綺掑瓙鍙戝皠錛屾嫢鏈夊緢鐭殑鐢熷懡鍛ㄦ湡錛岄殢鐫鏃墮棿鑰屾貳鍑烘鍘伙紝騫朵笉鍙戝皠綺掑瓙銆?br>Ember2 Particles 鐢盨hell綺掑瓙鍙戝皠錛屽湪鐢熷懡鍛ㄦ湡鏈彂鍑篍mber3綺掑瓙錛岀浜屾鐨勭垎鐐告簮銆?br>Ember3 Particles 綾諱技Ember1綺掑瓙錛岄櫎浜嗘湁涓嶅悓鐨勯鑹層?br>[maxvertexcount(128)]
void GSAdvanceParticlesMain(point VSParticleIn input[1], inout PointStream<VSParticleIn> ParticleOutputStream)
{
if( input[0].Type == PT_LAUNCHER )
GSLauncherHandler( input[0], ParticleOutputStream );
else if ( input[0].Type == PT_SHELL )
GSShellHandler( input[0], ParticleOutputStream );
else if ( input[0].Type == PT_EMBER1 ||
input[0].Type == PT_EMBER3 )
GSEmber1Handler( input[0], ParticleOutputStream );
else if( input[0].Type == PT_EMBER2 )
GSEmber2Handler( input[0], ParticleOutputStream );
}
D3DXGatherFragmentsFromFile( L"FragmentLinker.fx", NULL,
NULL, g_dwShaderFlags, &g_pCompiledFragments, NULL );
D3DXGatherFragmentsFromFile requires the .fx file, pointers to the #define and #include handlers (both set to NULL in this example), and the shader compile flags. The method returns a buffer which contains the compiled shader fragment. The method can return a second buffer with compile errors, which is set to NULL in this example because it is not used. D3DXGatherFragments is overloaded to handle loading fragments from a string, a file, or a resource.
Set your debugger to break on this method to look for compile errors in the debugger. The compiler can catch errors in syntax, but it cannot check for registers that are shared incorrectly due to the fact that it has no way to predict which parameters a user may want to share between fragments.
You need a fragment linker to manage the compiled fragments. Create the fragment linker by calling D3DXCreateFragmentLinker:
ID3DXFragmentLinker* g_pFragmentLinker = NULL; // Fragment linker interface
IDirect3DDevice9* pd3dDevice = NULL;
// Initialize the device before using it
...
// Create the fragment linker interface
D3DXCreateFragmentLinker( pd3dDevice, 0, &g_pFragmentLinker );
Then simply add the compiled fragments to the fragment linker using ID3DXFragmentLinker::AddFragments.
// Add the compiled fragments to a list
g_pFragmentLinker->AddFragments(
(DWORD*)g_pCompiledFragments->GetBufferPointer() );
ID3DXFragmentLinker::AddFragments requires a pointer to the DWORD stream that contains the compiled shader.
After compiling fragments and creating a fragment linker, there are several ways to link fragments. One way to link a vertex shader fragment is to call ID3DXFragmentLinker::LinkVertexShader. Here is an example that links two vertex shader fragments:
// Get a handle to each fragment
D3DXHANDLE fragmentHandle[2];
fragmentHandle[0] =
(D3DXHANDLE)g_pFragmentLinker->GetFragmentHandleByName("Ambient");
fragmentHandle[1] =
(D3DXHANDLE)g_pFragmentLinker->GetFragmentHandleByName("AmbientDiffuseFragment");
// Link the fragments together to form a vertex shader
IDirect3DVertexShader9* pVertexShader = NULL;
g_pFragmentLinker->LinkVertexShader( "vs_1_1", g_dwShaderFlags,
fragmentHandle, 2, &pVertexShader, NULL );
This requires a shader compile target, the shader compile and link flags, and a handle to each of the fragments to link. If the fragments are successfully linked, ID3DXFragmentLinker::LinkVertexShader returns a vertex shader (IDirect3DVertexShader9). The vertex shader needs to be set in the effect before rendering. But before this, here's how the shader is declared in the effect:
VertexShader MyVertexShader; // Vertex shader set by the application
The effect technique contains all the state set for a pass. This pass specifies the vertex shader like this:
technique RenderScene
{
pass P0
{
VertexShader = <MyVertexShader>;
PixelShader = compile ps_1_1 ModulateTexture();
}
}
With the effect's vertex shader created and initialized, the render code also sets the uniform constants and calls the render loop. Set the uniform constants similar to this:
// Update the uniform shader constants.
g_pEffect->SetMatrix( "g_mWorldViewProjection", &mWorldViewProjection );
g_pEffect->SetMatrix( "g_mWorld", &mWorld );
g_pEffect->SetFloat( "g_fTime", (float)fTime );
Then render the effect by setting the current technique and pass:
// Render the scene
if( SUCCEEDED( pd3dDevice->BeginScene() ) )
{
// Apply the technique contained in the effect
UINT cPasses, iPass;
g_pEffect->Begin(&cPasses, 0);
for (iPass = 0; iPass < cPasses; iPass++)
{
g_pEffect->BeginPass(iPass);
// Render the mesh with the applied technique
g_pMesh->DrawSubset(0);
g_pEffect->EndPass();
}
g_pEffect->End();
pd3dDevice->EndScene();
}
When setting uniform shader constants, it is more efficient to cache a handle to the parameter by calling ID3DXBaseEffect::GetParameterByName. This avoids the string lookup that is necessary when calling effect methods like ID3DXBaseEffect::SetMatrix.
// Instead of setting a uniform constant like this in the render loop
g_pEffect->SetMatrix( "g_mWorldViewProjection", &mWorldViewProjection );
// Get a handle to a uniform constant outside of the render loop
D3DXHANDLE hParameter;
GetParameterByName( hParameter,"g_mWorldViewProjection");
...
// Use the handle to set the uniform constant in the render loop
g_pEffect->SetMatrix(hParameter);
鏃燛ffect鐗堬細
LPD3DXCONSTANTTABLE pConstantTable;
LPD3DXBUFFER pShaderBuf;
IDirect3DVertexShader9* pVertexShader = NULL;
// Compile the fragments to a buffer.
D3DXGatherFragmentsFromFile( L"FragmentLinker.fx", NULL, NULL,
g_dwShaderFlags, &g_pCompiledFragments, NULL );
g_pFragmentLinker->AddFragments((DWORD*)g_pCompiledFragments->GetBufferPointer());
g_pFragmentLinker->LinkShader(
"vs_1_1",
g_dwShaderFlags,
aHandles,
NUM_FRAGMENTS,
&pShaderBuf,
NULL);
D3DXGetShaderConstantTable(
(DWORD*)pShaderBuf->GetBufferPointer(),
&pConstantTable );
pDevice->CreateVertexShader(
(DWORD*)pShaderBuf->GetBufferPointer(),
&pVertexShader);
RELEASE(pShaderBuf);
class PCZIntersectionSceneQuery;錛嶏紞錛嶏紞錛嶇浉浜ゆ煡璇?br> class PCZRaySceneQuery;錛嶏紞錛嶏紞錛嶏紞錛嶏紞錛嶅皠綰挎煡璇?br> class PCZSphereSceneQuery;錛嶏紞錛嶏紞錛嶏紞錛嶏紞鐞冮潰鏌ヨ
class PCZAxisAlignedBoxSceneQuery;錛嶏紞錛嶏紞錛嶏紞綆辨煡璇紙娌胯醬鍚戯級
class PCZPlaneBoundedVolumeListSceneQuery;-----錛嶏紞琛ㄦ煡璇?br>綆鍗曞湴鐪嬩簡OGRE鐨勫満鏅鐞嗭紝闄や簡OGREMAIN閮ㄥ垎錛岃繕鐢ㄤ簡PCZ鎻掍歡鏉ュ疄緇ф壙騫跺疄鐜般?br>錛坈lass PCZSceneManagerFactory : public SceneManagerFactory錛夋尯澶嶆潅鐨勶紝鐩告瘮涔嬩笅錛岄鐏殑鍦烘櫙綆$悊灝辯畝鍗曚簡錛?br>鍙皟鐢ㄥ縐嶈妭鐐廣?/p>
body.node=loadModel(cfg, "Look/Body/", device, sm, driver);
body.node_debug=sm->addCubeSceneNode(1, 0, -1, core::vector3df(0, 0, 0), core::vector3df(0, 0, 0),
cfg.Getval_vector("Body/Chassis/1/scale", core::vector3df(1, 1, 1))
);
body.node_debug->setMaterialTexture(0, driver->getTexture("data/misc/checked.jpg"));
2.杞﹁疆鐨勫睘鎬?br> Wheel #default
damp=30000
spring=50000
radius=0.38
weight=20
width=0.10 #not yet used if user specifies wheel model
brakes=0 # 0.0 - 1.0
Wheel_1 #fl
pos=1.39 -0.145 0.823
attr=STEER
brakes=0.8
rotation_z=1.5707963 #used just by client part
Wheel_2 #fr
pos=1.39 -0.145 -0.823
attr=STEER
brakes=0.8
rotation_z=4.7123889
Wheel_3 #rl
pos=-1.350 -0.15 0.823
attr=STRAIGHT|THURST
brakes=0.2
rotation_z=1.5707963
Wheel_4 #rr
pos=-1.350 -0.15 -0.823
attr=STRAIGHT|THURST
brakes=0.2
rotation_z=4.7123889
for (int i=0; ; i++) {
char buf2[128];
sprintf(buf2, "Body/Wheel_%d/", i+1);
buf=buf2;
if (!cfg.Getval_exists(buf+"attr")) break;
double radius=cfg.Getval_double((string)buf+"radius", cfg.Getval_double("Body/Wheel/radius", 1));
double width=cfg.Getval_double((string)buf+"width", cfg.Getval_double("Body/Wheel/width", 1));
scene::ISceneNode* node=loadModel(cfg, "Look/Wheels/", device, sm, driver);
CModelAttr wm;
scene::IMesh* cm=CreateCylinder(25, 2, 1);
scene::ISceneNode* node_debug=sm->addMeshSceneNode(cm);
node_debug->setScale(core::vector3df((f32)(radius), (f32)width, (f32)(radius)));
node_debug->setMaterialTexture(0, driver->getTexture("data/misc/checked.jpg"));
node_debug->getMaterial(0).EmissiveColor.set(255,255,255,255);
wm.arot=core::vector3df((f32)cfg.Getval_double(buf+"rotation_x", 0),
(f32)cfg.Getval_double(buf+"rotation_y", 0),
(f32)cfg.Getval_double(buf+"rotation_z", 0));
wm.node=node;
wm.node_debug=node_debug;
wheels.push_back(wm);
}
3.澹伴煶錛嶏紞錛嶈濺寮鍔ㄦ椂鐨勮槳楦e0
//load sounds
try {
snd_engine = new openalpp::Source((ALbyte*)("data/cars/"+profile+"/"+cfg.Getval_str("Sound/Engine/wave")).c_str());
if (!snd_engine.valid())
DBGCOUT("ALUT", "Coulnd't load file", ("data/cars/"+profile+"/"+cfg.Getval_str("Sound/Engine/wave")).c_str());
else {
snd_engine->setGain(1);
snd_engine->setPosition(0.0,0.0,0.0);
snd_engine->setLooping(true);
}
snd_engine_pitch_low=cfg.Getval_double("Sound/Engine/pitch_low");
snd_engine_pitch_high=cfg.Getval_double("Sound/Engine/pitch_high");
} catch(openalpp::Error e) {
std::cerr << e << "\n";
}
driver->endScene();
}
pd3dDevice->Draw(g_numRainVertices , 0 );
// Get back to normal
pBuffers[0] = NULL;
pd3dDevice->SOSetTargets( 1, pBuffers, offset );
// Swap buffers浜ゆ崲緙撳啿鍖?br> ID3D10Buffer* pTemp = g_pParticleDrawFrom;
g_pParticleDrawFrom = g_pParticleStreamTo;
g_pParticleStreamTo = pTemp;
firstFrame = false;
2.錛?錛塇LSL錛嶏紞浣跨敤Geometry shader Expanding
GeometryShader gsStreamOut = ConstructGSWithSO( CompileShader( vs_4_0, VSAdvanceRain() ), "POSITION.xyz; SEED.xyz; SPEED.xyz; RAND.x; TYPE.x" );
technique10 AdvanceParticles
{
pass p0
{
SetVertexShader( CompileShader( vs_4_0, VSAdvanceRain() ) );
SetGeometryShader( gsStreamOut );
SetPixelShader( NULL );
SetDepthStencilState( DisableDepth, 0 );
}
}
錛?錛塇LSL錛嶏紞浣跨敤Geometry shader Extruding
// GS for rendering rain as point sprites. Takes a point and turns it into 2 tris.
[maxvertexcount(4)]
void GSRenderRain(point VSParticleIn input[1], inout TriangleStream<PSSceneIn> SpriteStream)
{
float totalIntensity = g_PointLightIntensity*g_ResponsePointLight + dirLightIntensity*g_ResponseDirLight;
if(!cullSprite(input[0].pos,2*g_SpriteSize) && totalIntensity > 0)
{
PSSceneIn output = (PSSceneIn)0;
output.type = input[0].Type;
output.random = input[0].random;
float3 pos[4];
GenRainSpriteVertices(input[0].pos.xyz, input[0].speed.xyz/g_FrameRate + g_TotalVel, g_eyePos, pos);
float3 closestPointLight = g_PointLightPos;
float closestDistance = length(g_PointLightPos - pos[0]);
if( length(g_PointLightPos2 - pos[0]) < closestDistance )
closestPointLight = g_PointLightPos2;
output.pos = mul( float4(pos[0],1.0), g_mWorldViewProj );
output.lightDir = g_lightPos - pos[0];
output.pointLightDir = closestPointLight - pos[0];
output.eyeVec = g_eyePos - pos[0];
output.tex = g_texcoords[0];
SpriteStream.Append(output);
output.pos = mul( float4(pos[1],1.0), g_mWorldViewProj );
output.lightDir = g_lightPos - pos[1];
output.pointLightDir = closestPointLight - pos[1];
output.eyeVec = g_eyePos - pos[1];
output.tex = g_texcoords[1];
SpriteStream.Append(output);
output.pos = mul( float4(pos[2],1.0), g_mWorldViewProj );
output.lightDir = g_lightPos - pos[2];
output.pointLightDir = closestPointLight - pos[2];
output.eyeVec = g_eyePos - pos[2];
output.tex = g_texcoords[2];
SpriteStream.Append(output);
output.pos = mul( float4(pos[3],1.0), g_mWorldViewProj );
output.lightDir = g_lightPos - pos[3];
output.pointLightDir = closestPointLight - pos[3];
output.eyeVec = g_eyePos - pos[3];
output.tex = g_texcoords[3];
SpriteStream.Append(output);
SpriteStream.RestartStrip();
}
}
3.
娓叉煋鐐圭簿鐏?br>浣跨敤DX10鏂扮壒鎬exture Array
娓叉煋闆?br>榪愯鑼冧緥錛?br>鑼冧緥鏄劇ず涓や釜鐐瑰厜婧愬拰涓鏉$洿灝勫厜涓嬬殑妗ャ?br>宸﹂敭鎺у埗鐩村皠鍏夈?br>
鐒跺悗鍐嶈綆楁硶綰匡紝
recalculateNormals(Mesh);
2.ATMOSphere
澶槼鍢涳紝灝辨槸涓窡闅忔椂闂寸Щ鍔ㄧ殑BILLBOARD,杈圭紭鏈濂藉姞涓婇浘鍖栨晥鏋溿?br>3.鍦板艦緙栬緫鍣ㄤ唬鐮?br>