版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
前 零.地形簡(jiǎn) 一.地形生成算 Fault MidpointDis 二.小紋理生成大地形紋 地形紋理介 小紋理插值生成大紋理 添加細(xì)節(jié)紋 添加光照貼 三.四叉樹LOD渲染地 地形LOD介 地形四叉樹LOD詳細(xì)介 頂點(diǎn)管理 渲染地 四.相機(jī)剪裁地 五.天空 六.簡(jiǎn)單海 七. 八.光 九.地形場(chǎng)景物體與 構(gòu)造四叉樹 渲染四叉樹 十.陰影 渲染陰影 十一.碰 三種碰撞基元算 地形算 十二.無(wú)限地 三.四叉樹LOD這一部分是后加進(jìn)來(lái)的,把讀者當(dāng)成對(duì)地形一點(diǎn)沒有了解的人。AndreLaMothe是最寫的很詳細(xì)。翻譯人員也沒有辜負(fù)他,他的兩本書都翻譯的很棒! 現(xiàn)在就開始了。計(jì)算機(jī)模擬地形,還是沒有逃離基于頂點(diǎn)的三角形,當(dāng)然現(xiàn)在基本所有的圖有連三角形(紅色的線,只是為了大家看方便連接三角形有很多方法,下面就是法。圖連接三角形有多方法。當(dāng)然真正的地形就是把頂點(diǎn)高度都相對(duì)降低和提升,給的例子是一個(gè)平地。一但降低和提升后,就能出來(lái)地形,當(dāng)然你別瞎提升和降低,弄得個(gè)地形很詭異,要得2其實(shí)地形生成算法有很多,在《FOCUSON3DTERRIAN》介紹2種,這里也主要介紹這2256824RGB0圖例如高程數(shù)組HeightMap[2][3]變成頂點(diǎn)為(2*WidthRatio,HeightMap[2][3]*下面Fault圖如圖如果你的地形是m*n的寬度(其實(shí)多大尺寸都一樣量,不是搞物理或者數(shù)學(xué)的所以很難給出一個(gè)嚴(yán)格定義,但向量確實(shí)是數(shù)學(xué)和物理的基礎(chǔ)東圖2D2D3D的主要目的是判斷,那些點(diǎn)在直線L一端,那些點(diǎn)在直線L另一端,2A,BA,BAB2A,BAABLLcLACABACABCOS0,表示在直線一側(cè),如果小于//重復(fù)這個(gè)迭代過(guò)程,也就是直線取多少條 tions表示取直線條for( tion=0; tion< tions; tion++{//每次增加的高度 表示想要的最大最小高//高度為什么用這個(gè)等式 也不是很清楚,書上也沒說(shuō),只留下了關(guān)于這個(gè)算法的fHeight=nMaxHeight((nMaxHeight-nMinHeight)* tion*1.0f)/ //nRandX1=rand()%m_nSize;nRandZ1=rand()%{nRandX2=rand()%m_nSize;nRandZ2=rand()%}while(nRandX2==nRandX1&&nRandZ2==nRandZ1nDirX1=nRandX2-nRandX1;nDirZ1=nRandZ2-//遍歷所有點(diǎn),看點(diǎn)都位于直線Lfor(intz=0;z<m_nSize;z++{for(intx=0;x<m_nSize;x++{//和A點(diǎn)做向量nDirX2=x-nRandX1;nDirZ2znRandZ1;//大于0if((nDirX2*nDirZ1-nDirX1*nDirZ2)>0{pTempBuffer[(z*m_nSize)+x]+=(float}}}//FilterHeightField(pTempBuffer,fFilter}fFilter是表示濾波指標(biāo)B=fFilter*A+(1-fFilter)*//lefttofor(i=0;i<m_nSize;i++FilterHeightBand(&fpHeightData[m_nSize*i],1,m_nSize,fFilter//righttofor(i=0;i<m_nSize;i++FilterHeightBand(&fpHeightData[m_nSize*i+m_nSize-1],-1,m_nSize,fFilter//toptofor(i=0;i<m_nSize;i++FilterHeightBand(&fpHeightData[i],m_nSize,m_nSize,//bottomtofor(i=0;i<m_nSize;i++FilterHeightBand(&fpHeightData[m_nSize*(m_nSize-1)+i],-m_nSize,m_nSize,fFilterFilterHeightBand(float*fpBand,intnStride,intnCount,floatfFilter{floatv=fpBand[0];intj=nStride;inti;for(i=0;i<nCount-1;i++{fpBand[j]=fFilter*v+(1-fFilter)*}}ChangeDange(pTempBuffer,0.0f,Void {floatfMin,fMax;floatfHeight;floatfHeightDelta;return;//fHeightDelta fMaxheight-if(fHeightDelta<0)return;fMax=//for(inti=1;i<m_nSize*m_nSize;i++{if(fpHeightData[i]>fMax)fMax=elseif(fpHeightData[i]<fMin)fMin=fpHeightData[i];}//這就是一個(gè)線形方程變換,如果你這個(gè)不明白說(shuō)明你的數(shù)學(xué)真的是很 for(i=0;i<m_nSize*m_nSize;i++fpHeightData[i]=((fpHeightData[i]-fMin)/fHeight}象象圖MidpointDis2n次方,后面要做四叉樹LOD,2n1樹LOD。現(xiàn) 開始講解原始算法圖AECEA,B,C,D的四個(gè)點(diǎn)求中點(diǎn)E,然后再求邊界G和F。第一AFEG,F(xiàn)DHE,EHDI,GEIC(之所以求G和F是為了下一迭代,也就是求AFEG的中點(diǎn)做準(zhǔn)備,為什么不求H和I呢?下一步FBHE也要求中點(diǎn)需要H值,之所以不求H和I,是因?yàn)镠和G是相等的,F(xiàn)和I是相等的。前面,這個(gè)算法有個(gè)限制是必須是2的n次方,算法要求,超出邊界就要取模運(yùn)算,就在這里。大家仔細(xì)看實(shí)說(shuō)坐標(biāo)點(diǎn)有可能超出SizeG(i,jRectSize2,G4(ijSize左面點(diǎn)為((i-RectSize/2+RealSize)%RealSize,j+RectSize/2,這里也用到了模,這樣才能保證地((i-現(xiàn)在intiRealSizem_nSize1;floatfHeight=//這個(gè)算法是一個(gè)廣度遞歸,用函數(shù)處理每個(gè)方塊是深度遞歸,只有當(dāng) 所有中{ =(a+b+c+d)/4+Inthecodea=b=c=d=e=for(i=0;i<iRealSize;i+=iRectSize{for(j=0;j<iRealSize;j+=iRectSize{nj=(j+iRectSize)%iRealSize;mj=(j+iRectSize/2pTempBuffer[mi+mj*m_nSize]=(float pTempBuffer[i+j*m_nSize]+ pTempBuffer[i+nj*m_nSize]+pTempBuffer[ni+nj*m_nSize])/4+RangedRandom(-fHeight/2,fHeight/2)}}循環(huán)當(dāng)iRectSize為1時(shí),就會(huì)進(jìn)行平均計(jì)算,把邊界算進(jìn)去 g=(d+f+a+b)/4+h=(a+c+e+f)/4+Inthecodea=b=c=d=e=f=g=h=for(i=0;i<iRealSize;i+=iRectSize{for(j=0;j<iRealSize;j+=iRectSize{ni=(i+iRectSize)%iRealSize;nj=(j+iRectSize)%iRealSize;mj=pmi=(i-iRectSize/2+iRealSize)%iRealSize;//pTempBuffer[mi+j*m_nSize]=(float)(( pTempBuffer[mi+mj*m_nSize])/4+RangedRandom(-fHeight/2,fHeight/2)//pTempBuffer[i+mj*m_nSize]=(float)((pTempBuffer[mi+mj*m_nSize])/4+RangedRandom(-fHeight/2,fHeight/2)}}iRectSize/=//fHeight*=}RangedRandom(-fHeight/2,fHeight/2)而每次迭代后fHeight*=fHeightReducerfHeightReducer是平滑因子, ,floatfHeightReducer=(float)pow(2,-1*fRoughness);圖最后一個(gè)要處理的,因?yàn)長(zhǎng)OD2n次方+1memcpy(&pTempBuffer[(m_nSize-for(intcolumn=0;column<m_nSize;column{pTempBuffer[column*m_nSize+m_nSize-1]}pTempBuffer[m_nSize*m_nSize1pTempBuffer[0];最后別忘了,把高度數(shù)據(jù)縮放到0到255之間。ChangeDange(pTempBuffer,0.0f,255.0f); 配合你地形生成出來(lái)的。當(dāng)然地形高程數(shù)據(jù),也是用作圖工具生成的FOCUSON3DTERRAIN》這圖圖for(intindex_z=0;index_z<m_nSize;{intz_width=index_z*for(intindex_x=0;index_x<m_nSize;{m_pVertex[z_width_x].texture.x=index_x*((1.0f)/(m_nSize-1));m_pVertex[z_width_x].texture.y=index_z*((1.0f)/(m_nSize-1));}}(6,8(6/17,8/17其中C(0)=A,當(dāng)t1C(1)=B。也就是說(shuō),給定一個(gè)t,在ABC(tC(t)A+(BA)t 圖 圖圖 圖413圖14圖15圖讓用戶指定每個(gè)圖表示的高度范圍。程序沒有指定,就按照這樣均等劃分,效果也很好。做完了范圍劃分,你還要處理一個(gè)問題,就是紋理過(guò)渡帶的問題。例如相臨兩個(gè)點(diǎn)A,B圖 圖 圖 圖如果X255/5*2,小于255/5*3,按線性插值來(lái)求占百分比X255/5*2)/(255/5*3 {intm_iLowHeight; intm_iOptimalHeight;//影響最好值(100%)intm_iHighHeight; //影響最高值(0%)FOR所有小紋理{ucColor=當(dāng)前紋理i上的一個(gè)象素點(diǎn)。//if(ucFinalHeight< ucFinalHeight>當(dāng)前紋理最大高度影響值iHighHeight){
if(ucFinalHeight>=當(dāng)前紋理最好高度影響值{}{}}
floatfTemp1=m_iHighHeight-m_iOptimalHeight;floatfTemp2=m_iHighHeight-ucFinalHeight;fBlend=fTemp2/fTemp1;floatfTemp1=m_iOptimalHeight-floatfTemp2=ucFinalHeight-m_region.m_iLowHeight;fBlend=fTemp2/fTemp1;//fTotalColor+=ucColor*}XU*WidthSize1m1)YV*高程圖heightSize1)/(nU>= U<=m- V>=0 V<=n-其實(shí),這里的X,Y都取了整數(shù)部分,這樣做是很不精確的。因此,采用了雙線形濾波,重新求得高度。圖,素對(duì)應(yīng)高度。但實(shí)際上,要混合(5,6(6,6(5,7(6,7)這四個(gè)點(diǎn),最后求得最終高度。可以看出所求高度占(5,6)30%*30%(注釋(1–(5.7–5)和(1–(6.7–6,占(6,6)為70%*30%,占(5,7)30%*70%,占(6,7)70%*70%floatfMapRatio=(float)((m_nSize-1)*1.0f)/(nSize-////就ZfloatfHeightDateZ=z*intiHeightDateZ_1=iHeightDateZ+1;iHeightDateZ_1=floatfPercentZ_1=fHeightDateZ-iHeightDateZ;floatfPercentZ=1.0f-fPercentZ_1;floatfHeightDateX=x*fMapRatio;intiHeightDateX= iHeightDateX_1=iHeightDateX+if(iHeightDateX_1>=m_nSize)iHeightDateX_1=iHeightDateX;floatfPercentX_1=fHeightDateX-iHeightDateX;floatfPercentX=1.0f-fPercentX_1;UCHAR =UCHARucHeightZ_1_X_1=GetHeightDate(iHeightDateX_1,iHeightDateZ_1);UCHARucFinalHeight=UCHAR(ucHeightZ_X*fPercentX*fPercentZucHeightZ_X_1*fPercentX_1*fPercentZ+ucHeightZ_1_X*fPercentX*fPercentZ_1+ucHeightZ_1_X_1*fPercentX_1*下標(biāo)X,Z的象素值。=還是采用了《FOCUSON3DTERRIAN》上的方法,按照D3D紋理映射方式來(lái)取得圖紅色為小紋理的方式,黑色為大紋理,大紋理上一個(gè)點(diǎn)X,Z,映射到小紋理坐標(biāo)X%TileWidthZ%TileHeight,TileWidth,TileHeight圖圖圖為什么要添加細(xì)節(jié)紋理?這個(gè)問的好,先舉個(gè)例子,你看了就明白。然后其實(shí)很簡(jiǎn)單,D3D圖圖for(intindex_z=0;index_z<m_nSize;{intz_width=index_z*for(intindex_x=0;index_x<m_nSize;{intz_width_x=z_width+m_pVertex[z_width_x].texture1.x=index_x*((1.0f)/m_nSize)*m_niDetailRepeat;m_pVertex[z_width_x].texture1.y=index_z*((1.0f)/m_nSize)*}}m_niDetailRepeat 貼圖的次數(shù)至于紋理混合運(yùn)算,用的MODULATE2XD3D中WRAP如果地形中沒有光照,那實(shí)在是太沒意思了。D3D4使用,環(huán)境光,點(diǎn)光圖2008621日,他的,天氣熱的要命,都不愿意動(dòng)了。又是一個(gè)四六級(jí)的日子,72.5,靠,63年半前,考了59,郁悶死了。上時(shí)就考了一次,還沒過(guò),實(shí)在沒時(shí)間復(fù)習(xí)6級(jí),真的不是借口為了學(xué)好游戲編程,堅(jiān)實(shí)的打好每一個(gè)基礎(chǔ),大師編程的2本書,代碼 重寫,十幾萬(wàn)行呀,還要學(xué)D3D,學(xué)引擎。不是 學(xué)看3DGAMEENGINEPROGRAMING1000多頁(yè)全英文, 引擎里面了,6級(jí)英語(yǔ)和 學(xué)計(jì)算機(jī)英語(yǔ)真是2馬事,花同樣的時(shí)間, 3D編程要比花到6級(jí)英語(yǔ)上效率高的多,收獲的也很多。請(qǐng)讓 真的很討厭6級(jí)”。用的是《FOCUSON3DTERRIAN圖看到?jīng)]有?是不是很COOL?知道你一定很著急!再不介紹給你,你就要打前面,這個(gè)算法是實(shí)際上是2D的。假設(shè)你的光照紋理圖是m*n,開始時(shí),你紋理圖里圖被遮擋,A就形成了陰影。fShade=1.0f-(ucFinalHeight_D-fShade為象素值強(qiáng)度,ucFinalHeight_D為B的高度,ucFinalHeight為A的高度,fShade也越小,光照強(qiáng)度也小,所以陰影就越大。if(fShade<m_fMinBrightnessfShade=m_fMinBrightness;if(fShade>m_fMaxBrightness)m_fMinBrightness,m_fMaxBrightness這2個(gè)是讓用戶指定的最小強(qiáng)度和最大強(qiáng)度,必須是255,Coo=(255,0,濾波,直接取整。當(dāng)不得不告訴你。當(dāng)你光照貼圖尺寸大于地形高程圖尺寸時(shí),就會(huì)失真。圖33,黑色是光照貼圖尺寸大于地形高程圖尺寸,蘭色是光照貼圖尺寸小于地形高程圖尺寸,圖所以對(duì)于一個(gè)頂點(diǎn)只能有8個(gè)方向。圖1(-11(-1(0,1(0,-1(-1,0(1,0圖 for(inti=0 i<8;{m_FindTable[i]=cosf((1/16.0f+i}fCosAnglefDirectionXsqrtf(fDirectionX*fDirectionXfDirectionZ*fDirectionZ);{if(m_FindTable[0]<fCosAngle&&fCosAngle<={m_iDirectionZ=m_iDirectionX=}elseif(m_FindTable[1]<fCosAngle&&fCosAngle<={m_iDirectionZ=m_iDirectionX=}elseif(m_FindTable[2]<fCosAngle&&fCosAngle<={m_iDirectionZ=m_iDirectionX=}elseif(m_FindTable[3]<fCosAngle&&fCosAngle<={m_iDirectionZ=m_iDirectionX=-}elseif(-1.0f<=fCosAngle&&fCosAngle<={m_iDirectionZ=m_iDirectionX=- if(-1.0f<=fCosAngle&&fCosAngle<={m_iDirectionZ=m_iDirectionX=-}{m_iDirectionZ=-m_iDirectionX=-}{m_iDirectionZ=-m_iDirectionX=}{m_iDirectionZ=-m_iDirectionX=}elseif(m_FindTable[7]<=fCosAngle&&fCosAngle<={m_iDirectionZ=m_iDirectionX=}}floatfShade=floatfMapRatio=(float)((m_nSize-1)*1.0f)/(m_nLightSize-1);for(intz=0;z<m_nLightSize;z++){for(intx=0;x<m_nLightSize;x++{//求出ucFinalHeight_D和 沒有用雙線形濾波,直接用的取floatfHeightDateZ=z*fMapRatio;floatfHeightDateX=x*fMapRatio;if(izTemp<0)izTemp=m_nLightSize-1;if(izTemp>=m_nLightSize)izTemp=floatfHeightDateZ_D=izTemp*fMapRatio;if(ixTemp<ixTemp=m_nLightSize-1;if(ixTemp>=m_nLightSize)ixTemp=floatfHeightDateX_D=ixTemp*fMapRatioUCHARucFinalHeight=GetHeightDate(fHeightDateX,fHeightDateZ);UCHARucFinalHeight_D=GetHeightDate(fHeightDateX_D,fHeightDateZ_D);if(fShade<m_fMinBrightness)fShade=if(fShade>m_fMaxBrightness)fShade=m_ucpLight[(x+z*m_nLightSize)*3]=(unsignedchar)(fShade*255m_ucpLight[(x+z*m_nLightSize)*3+1]=(unsignedchar)(fShade*255);m_ucpLight[(x+z*m_nLightSize)*3+2]=(unsignedchar)(fShade*255);}}這是一個(gè)關(guān)鍵的地方,馬上就要揭示怎么用D3DLOD什么是LOD?LOD的英文縮寫LevelOfDetail,中文翻譯過(guò)來(lái)就是細(xì)節(jié)層次。3D用這個(gè)細(xì)D3DPMESH函數(shù)接口支持網(wǎng)格的層次細(xì)節(jié),也就是它有算法可以刪除和增加頂點(diǎn)而使模型網(wǎng)格盡量不失真。這個(gè)函數(shù)大家可以實(shí)驗(yàn)下,D3D自己帶的例子里面有,在這里面就不說(shuō)對(duì)于紋理的細(xì)節(jié)層次,最常見的就是紋理MIP,遠(yuǎn)處的物體不要用那么高分辨率的紋理LOD,LOD地形上用LODFOCUSON3DTERRAIN》上介紹了3第一種是GEOMIP-MAPLOD,這種LOD有點(diǎn)象紋理MIP,算法很簡(jiǎn)單,唯一值得注意的就是,根據(jù)視點(diǎn)到PATCH距離決定PATCH等級(jí),這個(gè)距離事先取定的,而四叉樹LOD是計(jì)算的。也就是說(shuō)多少到多少距離PATCH等級(jí)是1,多少到多少距離PATCH等級(jí)是2,等等。如果取PATCH1,這樣就形成了裂縫(Crack。怎么處理,這個(gè)就不介紹了,《FOCUSON3DTERRAIN》由于它距離取的好,所以沒有形成裂縫,實(shí)際上它沒有處理的。第二種是ROAM,這個(gè)算法是屬于三角拋分,作者寫的太不詳細(xì)了,它的代碼幾乎晦澀難懂, 間決定看下。因?yàn)樽髡邔?shí)現(xiàn)四叉樹LOD時(shí),有些細(xì)節(jié) 第三種就是四叉樹LOD,不得不說(shuō),作者寫的真不是很詳細(xì),有些細(xì)節(jié)讓讀代碼,它的代碼寫的真是龐大而且晦澀難東,可以驕傲的說(shuō),代碼寫的比他好,而且實(shí)現(xiàn)整個(gè)思者根本不想詳細(xì)寫,作者認(rèn)為都是高手。這里要感謝《VisualC++DirectX93D引導(dǎo)》這本書,很多知識(shí)參考了它,因?yàn)檫@本書四叉樹LOD基本思路還是對(duì)的,只是有些關(guān)鍵問題他沒有解決好,比如:這本書的LOD簡(jiǎn)直無(wú)法運(yùn)行,慢的,有2個(gè)致命的速度屏障作者根本沒有解決,不明白作者沒有處理好這個(gè)問題為什么還要寫出來(lái)。GPGLLOD1LOD1LOD以用PVS算法處理被遮擋的PATCH。但如果不同等級(jí)的PATCH距離沒有取好,就要形成用第3種算法實(shí)現(xiàn),LOD等級(jí)隨便調(diào)節(jié),而且可以預(yù)處理,無(wú)論怎么渲染都沒有裂縫。但對(duì)于被遮擋的PATCH,還沒有想出一個(gè)快速的算法,如果你有,請(qǐng)的思路寫出來(lái),告訴3D)當(dāng)時(shí)流水線是基于單個(gè)三角形的,當(dāng)時(shí)為了快速渲染地形、實(shí)現(xiàn)相機(jī)剪裁,做了一個(gè)地形四叉樹。這里要說(shuō)的是地形四叉樹LOD和地形四叉樹不一樣,地形四叉樹,只不過(guò)是把地形的三角形用四叉樹的方式進(jìn)行分類,來(lái)進(jìn)行快速相機(jī)剪裁或者是碰撞處理,而地形四叉樹LOD和地形四地形四叉樹三角形網(wǎng)格不變的,而地形四叉樹LOD網(wǎng)格隨著視點(diǎn)動(dòng)態(tài)變化的。地形四叉樹三角形網(wǎng)格相當(dāng)于四叉樹LOD網(wǎng)格的最次。地形四叉樹LOD知道你已經(jīng)等不及了,現(xiàn)在就來(lái)介紹基本算法,記住只是基本算法,具體細(xì)節(jié)先不說(shuō),圖把整個(gè)空間等4等分。圖圖圖上面的過(guò)程說(shuō)明了四叉樹劃分過(guò)程,下面 來(lái)正式介紹地形LOD四叉樹地形LOD四叉樹是基于一個(gè)劃分矩陣的,這個(gè)劃分矩陣根據(jù)一個(gè)劃分方法來(lái)記錄每次的劃分法”是什么方法,后面說(shuō),后面還有很多細(xì)節(jié)要說(shuō)。下面介紹這個(gè)劃分矩陣。劃分矩陣和高程圖矩陣是同樣大小的,而且為了做四叉樹LOD2n1圖 圖理LOD渲染很容易的。當(dāng)劃分矩陣形成,渲染函數(shù)要用劃分矩陣來(lái)進(jìn)行渲染,當(dāng)遇到1的時(shí)圖 A 其中L是視點(diǎn)到劃分正方形頂點(diǎn)的距離, 如圖45和43從這個(gè)方程里面看,LFDF性就越大,C越大,F(xiàn)越小,劃分的可能性就越大。圖圖圖圖2,3。32if(iEdgeLength>3{if( }{
intiChildOffset;intiBlend;fViewDistance=(float)(fabs(m_fViewX-m_pVertex[iX+iZ*m_nSize].position.x)+f=fViewDistance/(iEdgeLength*m_fMinResolution*if(f<1.0fiBlend=iBlend=SetLODMatrix(iX,iZ,iBlend);{ =((iEdgeLength-1)>>2);iChildEdgeLength=(iEdgeLength+1)>>1;//lower ODNode(iX-iChildOffset,iZ-iChildOffset,iChildEdgeLength//lower ODNode(iX+iChildOffset,iZ-iChildOffset,iChildEdgeLength//upper ODNode(iX-iChildOffset,iZ+iChildOffset,iChildEdgeLength//upper ODNode(iX+iChildOffset,iZ+iChildOffset,iChildEdgeLength}}}2個(gè)條件都介紹完畢,在生成劃分矩陣之前,你還要用一個(gè)DH矩陣來(lái)的值,就象劃分矩陣一樣,只不過(guò)這里的不是0、1,而是高度值,這個(gè)DH矩陣不用每次更新,它是固定的。當(dāng)然生成它很簡(jiǎn)單,但這里要說(shuō)的是一個(gè)關(guān)鍵性的問題。為什么要修改DH矩陣直接用這個(gè) 到整個(gè)大的地形正方形,都求得,然后存在DH矩陣?yán)锩?,不可以嗎?圖縫(Crack,用刨除點(diǎn)的方法(當(dāng)然也可以用補(bǔ)點(diǎn)的方法,這個(gè)方法很麻煩)A、B2個(gè)點(diǎn)拿掉,進(jìn)行渲染。具體怎么處理到后面渲染再詳細(xì)說(shuō),這里只是要說(shuō)明,只能處理層次差別等于1的,當(dāng)然層次相等根本用不著處理。圖圖50角度來(lái)想這個(gè)問題,盡量保證相臨的層次差別保持到小于等于1圖圖蘭色的,讓它層次變小,不劃分,另一個(gè)是讓紅色的層次變大,進(jìn)行劃分。采用了依據(jù)小的正樣保證相臨層次小于等于1?,F(xiàn)在假設(shè)蘭色劃分值為F1,紅色為F2那么F2<F1<1就可以保證,這個(gè)條件 因 ,所因?yàn)閐22*d1,如果要滿足條件必須,H2H1
圖也就是說(shuō)紅色的最大高度<蘭色最大高度*K現(xiàn)在說(shuō)下就DH矩陣具體算法。2(引擎里用的頂點(diǎn)數(shù),也就是說(shuō)邊長(zhǎng)為n,則連接H8intiEdgeLength3;while(iEdgeLength<={intiEdgeOffsetiEdgeLength-11;//intiChildOffset=(iEdgeLength-1)>>2;//for(intz=iEdgeOffset;z<m_nSize;z+=(iEdgeLength-1){for(intx=iEdgeOffset;x<m_nSize;x+=(iEdgeLength-1){if(iEdgeLength=={intiDH[6];iDH[0]= z+iEdgeOffset)+GetHeightDate(x+iEdgeOffset,z+iEdgeOffset))>>1)-GetHeightDate(x,z+iEdgeOffset))iDH[1]= z+iEdgeOffset)+GetHeightDate(x+iEdgeOffset,z-iEdgeOffset))>>1)-GetHeightDate(x+iEdgeOffset,z))iDH[2]= z-iEdgeOffset)+GetHeightDate(x+iEdgeOffset,z-iEdgeOffset))>>1)-GetHeightDate(x,z-iEdgeOffset)) GetHeightDate(x-iEdgeOffset,z+iEdgeOffset)+GetHeightDate(x-iEdgeOffset,z-iEdgeOffset))>>1)- z-iEdgeOffset)+GetHeightDate(x+iEdgeOffset,z+iEdgeOffset))>>1)-GetHeightDate(x,z)) z-iEdgeOffset)+GetHeightDate(x-iEdgeOffset,z+iEdgeOffset))>>1)-GetHeightDate(x,z))//求最大{if(iDHMAX<iDH[i])}}{
intiDH[14];intiNumDH=floatfK=1.0f*m_fMinResolution/(2.0f*(m_fMinResolution-1.0f)//LEFTTWOintiNeighborX=x-(iEdgeLength-1);iNeighborZ=z;if(iNeighborX>{ iNeighborX=xiNeighborZ=z-(iEdgeLength-if(iNeighborZ>{}
iDH[iNumDH]=GetDHMatrix(iNeighborX-iChildOffset,iNeighborZ+iDH[iNumDH]=GetDHMatrix(iNeighborX+iChildOffset,iNeighborZ
//RIGHTTWOiNeighborX=x+(iEdgeLength-1);iNeighborZ=z;if(iNeighborX<{iDH[iNumDH]=GetDHMatrix(iNeighborX-iChildOffset,iNeighborZiDH[iNumDH]=GetDHMatrix(iNeighborX-iChildOffset,iNeighborZ
//BOTTOMTWOiNeighborX=xiNeighborZ=z+(iEdgeLength-if(iNeighborZ<{iDH[iNumDH]=GetDHMatrix(iNeighborX-iChildOffset,iNeighborZiDH[iNumDH]=GetDHMatrix(iNeighborX+iChildOffset,iNeighborZ //然后求自身的//BOTTOMiDH[iNumDH]= z+iEdgeOffset)+GetHeightDate(x+iEdgeOffset,z+iEdgeOffset))>>1)-GetHeightDate(x,z+iEdgeOffset))iDH[iNumDH]=(int)ceil(abs(((GetHeightDate(x+iEdgeOffset,z+iEdgeOffsete(x+iEdgeOffset,z-iEdgeOffset))>>1
GetHeightDate(x+iEdgeOffset,z))iDH[iNumDH]=(int)ceil(abs(((GetHeightDate(x-iEdgeOffset,z-iEdgeOffset)+GetHeightDate(x+iEdgeOffset,z-iEdgeOffset))>>1)-GetHeightDate(x,z-iEdgeOffset))iDH[iNumDH]=(int)ceil(abs(((GetHeightDate(x-iEdgeOffset,z+iEdgeOffset)+GetHeightDate(-iEdgeOffset,z-iEdgeOffset))>>1GetHeightDate(x-iEdgeOffset,z)));iDH[iNumDH]=(int)ceil(abs(((GetHeightDate(x-iEdgeOffset,z-iEdgeOffset)+GetHeightDate(+iEdgeOffset,z+iEdgeOffset))>>1
GetHeightDate(x,z))DH[iNumDH]= z-iEdgeOffset)+GetHeightDate(x-iEdgeOffset,z+iEdgeOffset))>>1)-GetHeightDate(x,z))intiDHMAX=for(inti=1;i<iNumDH;{if(iDHMAX<iDHMAX=}SetDHMatrix(x,z,(int)ceil(fK*}}}}DH矩陣。以上過(guò)程已經(jīng)生成了LODD3DD3DC++DirectX93D游戲開發(fā)引導(dǎo)》渲染慢的另一個(gè)。那么要怎么處理CPUGPU先說(shuō)下,CPUGPU之間經(jīng)常出現(xiàn)的問題是,CPUGPUGPUCPU數(shù)據(jù),這樣等待浪費(fèi)了大量的時(shí)間。很難把CPUGPU協(xié)調(diào)到最優(yōu)的程度,但能盡量保CPUGPUCPU,有數(shù)據(jù)進(jìn)行渲染。解決它有一個(gè)最簡(jiǎn)單的方法就是,CPU處理完一部分?jǐn)?shù)據(jù),馬上讓GPU渲染,在GPU渲染的同時(shí),然后CPU再處理另一部分?jǐn)?shù)據(jù),當(dāng)CPUGPU渲染,循環(huán)這個(gè)過(guò)程。CPUGPU從上面的方法可以看出,CPU處理的數(shù)據(jù),然后給GPU渲染,這些數(shù)據(jù)是動(dòng)態(tài)改變的,否則CPUGPU由于地形LOD頂點(diǎn)數(shù)據(jù)是動(dòng)態(tài)改變的,要用上面的方法進(jìn)行管理。好,現(xiàn)在想象下,動(dòng)態(tài)頂點(diǎn)管理器中,應(yīng)該有什么東西?說(shuō)到這里很棘手,因?yàn)橐胬锩孢€有材質(zhì)和紋理管理器,頂點(diǎn)管理器包括動(dòng)態(tài)頂點(diǎn)管理和靜態(tài)頂點(diǎn)管理。如果這些全都講了,好象在說(shuō)一個(gè)小引擎怎么做?工作量真的很大,其實(shí)這些大部分內(nèi)容來(lái)自《3DGAMEENGINGEPROGRAMING》只不過(guò)改了很多,但基本思想是一樣的。所以這里給出偽代碼,相信如果你3D編程能力還過(guò)得去,加上參考《3DGAMEENGINGEPROGRAMING》,應(yīng)該自己可以實(shí)現(xiàn)的。 classVSCacheD3D{ m_nNumVertsMax;//最大頂點(diǎn)個(gè)數(shù) m_dwFVF;////D3D //頂點(diǎn)管理器}#define { VSCacheD3D//class{vector<VSCACHED3DFVF>}圖圖53說(shuō)明了整個(gè)類之間的組織管理,現(xiàn)在的問題時(shí), 數(shù),頂點(diǎn)索引,頂點(diǎn)索引個(gè)數(shù),還有材質(zhì)紋理ID。(D3D(ALPHA,深度緩存,世界矩陣等等,你仔細(xì)思考下后,其實(shí)這個(gè)過(guò)程很容易理解。,還有最后還有一個(gè)問題就是,如果你當(dāng)前頂點(diǎn)格式并且指定的材質(zhì)紋理ID的頂點(diǎn)數(shù)據(jù),大于一般設(shè)置可以容納8000頂點(diǎn)大小, LOCK,即使添加完數(shù)據(jù)也不是馬上渲染的,所以這個(gè)最后一個(gè)問題就是創(chuàng)建材質(zhì)紋理頂點(diǎn)緩沖時(shí),要用D3D的D3DUSAGEDYNAMIC,這個(gè)可以讓用戶修改D3D頂點(diǎn)緩沖。整個(gè)動(dòng)態(tài)管理的過(guò)程,就介紹完了,當(dāng)然很多實(shí)現(xiàn)的細(xì)節(jié)沒有說(shuō),但相信,如果你水平還GAMEENGINGEPROGRAMING》這本書,至少要部分細(xì)節(jié)地方做的不好,不方便用戶的使用,所 引擎里面都改了過(guò)來(lái)。當(dāng)然要把握它前終于走到地形渲染,很不容易,不知道上面的你是否看明白,已經(jīng)寫的很詳細(xì)了,千萬(wàn)別寫的太。就不會(huì)蒙。)D3D讓正式入題,由于沒有用D3D自帶的扇形渲染,而頂點(diǎn)管理器只接受頂點(diǎn)和頂點(diǎn)索引。所以要自己定義一個(gè)扇形類。typedefstructVERTEX_TYPE{D3DXVECTOR3position;D3DXVECTOR3normal;D3DXVECTOR2texture;}VSVERTEX,//class{{m_iNumVertex= =} //最多8個(gè)三角形,24 inlinevoidAddVertex(constVSVERTEX&Vertex){if(m_iNumVertex>={m_wFanIndex[m_iNumIndex]=m_iNumVertex-2;m_wFanIndex[m_iNumIndex]=m_iNumVertex-1;}}void{m_iNumVertex= =} // //圖1 相臨的正方形層次等級(jí)小于等于1。DH歷,希望你能弄明白這個(gè)為什么只能用深度遞歸,不能用廣度遍歷。果你仔細(xì)觀察這個(gè)問題,記住相臨的正方形層次等級(jí)小于等于1,再看圖54,可能刨除的頂點(diǎn)是頂點(diǎn)2,4,6,8。而0,1,3,5,7是 圖2、4、6、8。 形對(duì)應(yīng)劃分矩陣是否為1, 道方位處理就變得很容易,這樣考慮2、4、6、8居,頂點(diǎn)2直接添加。圖HRESULTVSTerrain::RendLODNode(intiX,intiZ,intiEdgeLength,int{//iX,iZ劃分矩陣節(jié)點(diǎn)位置,邊長(zhǎng) 用的是頂點(diǎn)個(gè)數(shù),iChild兒子方intiBlend=if(iBlend==1){intiChildOffset =((iEdgeLength-1)>>2);intiChildEdgeLength=(iEdgeLength+1)>>1;//lowerRendLODNode(iX-iChildOffset,iZ-iChildOffset,iChildEdgeLength,//lowerRendLODNode(iX+iChildOffset,iZ-iChildOffset,iChildEdgeLength,//upperRendLODNode(iX-iChildOffset,iZ+iChildOffset,iChildEdgeLength,//upperRendLODNode(iX+iChildOffset,iZ+iChildOffset,iChildEdgeLength,{intiEdgeOffset=(iEdgeLength-1)>>1;intiNeighborZ;intintiNeighborParentZ;intVertex=GetRealDate(iX-iEdgeOffset,iZ-iEdgeOffset);Vertex=GetRealDate(iX,iZ-iEdgeOffset);iNeighborZ=iZ-(iEdgeLength-1);iNeighborX=iX;if(iChild==3||iChild=={} if(iNeighborZ>0)//{////如果上面鄰接點(diǎn) 0,則還要考慮鄰接點(diǎn)的父親節(jié)點(diǎn),如//鄰接點(diǎn)的父親節(jié)點(diǎn)是0,就不能添加這個(gè)點(diǎn),如果鄰接點(diǎn)的父親節(jié)//點(diǎn)是1//DH矩陣的算法,已經(jīng)保證相臨層次不大與,所以不用再進(jìn)一步檢測(cè)鄰接點(diǎn)的父親節(jié)點(diǎn)的父親節(jié)點(diǎn)。下面的算法同if(iChild=={if(GetLODMatrix(iNeighborX,iNeighborZ)== //{}else//{iNeighborParentX=iNeighborX+iEdgeOffset;-if(GetLODMatrix(iNeighborParentX,iNeighborParentZ)=={}}}elseif(iChild=={if(GetLODMatrix(iNeighborXiNeighborZ)==1 {}else{iNeighborParentX=iNeighborX-iEdgeOffset;iNeighborParentZ=iNeighborZ-iEdgeOffset;if(GetLODMatrix(iNeighborParentX,iNeighborParentZ)=={}}}}{}}Vertex=GetRealDate(iX+iEdgeOffset,iZ-iEdgeOffset);Vertex=GetRealDate(iX+iNeighborZ=iZiNeighborX=iX+(iEdgeLength-if(iChild==1||iChild=={} if(iNeighborX<m_nSize)//{if(iChild=={if(GetLODMatrix(iNeighborX,iNeighborZ)== //{}else//{iNeighborParentX=iNeighborX+iEdgeOffset;iNeighborParentZ=iNeighborZ+iEdgeOffset;if(GetLODMatrix(iNeighborParentX =={}}}elseif(iChild=={if(GetLODMatrix(iNeighborX,iNeighborZ)== //{}else//{iNeighborParentX=iNeighborX+iEdgeOffset;iNeighborParentZ=iNeighborZ-iEdgeOffset;if(GetLODMatrix(iNeighborParentX,iNeighborParentZ)=={}}}}{}}//RIGHT-BOTTOMVertex=GetRealDate(iX+iEdgeOffset,iZ+iEdgeOffset);//BOTTOM-Vertex=GetRealDate(iX,iZ+iNeighborZ=iZ+(iEdgeLength-1);iNeighborX=iX;if(iChild==1||iChild=={}{{
if(iNeighborZm_nSize)//是否有下鄰居if(iChild3){if(GetLODMatrix(iNeighborXiNeighborZ)== {}else{iNeighborParentX=iNeighborX+iEdgeOffset;iNeighborParentZiNeighborZiEdgeOffset;if(GetLODMatrix(iNeighborParentX,iNeighborParentZ)=={}}}{if(GetLODMatrix(iNeighborXiNeighborZ)== {}else{iNeighborParentX=iNeighborX-iEdgeOffset;iNeighborParentZiNeighborZiEdgeOffset;if(GetLODMatrix(iNeighborParentX,iNeighborParentZ)=={}}}}{}}
Vertex=GetRealDate(iX-iEdgeOffset,iZ+iEdgeOffset);Vertex=GetRealDate(iX-iEdgeOffset,iZiNeighborZ=iZiNeighborX=iX-(iEdgeLength-if(iChild==2||iChild=={}{
if(iNeighborX>0){if(iChild=={if(GetLODMatrix(iNeighborXiNeighborZ)== {}else{iNeighborParentZ=iNeighborZ+iEdgeOffset;if(GetLODMatrix(iNeighborParentX=={}}}
elseif(iChild=={if(GetLODMatrix(iNeighborX,iNeighborZ)==1 //{}else//{iNeighborParentX=iNeighborX-iEdgeOffset;iNeighborParentZ=iNeighborZ-iEdgeOffset;if(GetLODMatrix(iNeighborParentX,iNeighborParentZ)=={}}}}{}}
Vertex=GetRealDate(iX-iEdgeOffset,iZ-iEdgeOffset); AddFan();//}渲染數(shù)據(jù),在頂點(diǎn)管理器說(shuō)了,渲染的情況。圖元)劃分矩陣放在一起的遞歸過(guò)程,如果當(dāng)前正方形PATCH被剪裁掉,就把當(dāng)前正方形劃分矩陣設(shè)22LOD理了劃分矩陣為10的情況。6PACHTAABB如果AABB全都不在視景體里面就剪裁掉,部分在視景體里面,也是要繼續(xù)遞歸的。圖簡(jiǎn)介很多碰撞檢測(cè)都用包含物體的最小AABB處理,雖然AABB實(shí)現(xiàn)。AABB22X,Y,Z小的兩個(gè)頂點(diǎn),圖57點(diǎn)A和點(diǎn)B。也可以用點(diǎn)和三個(gè)軸的長(zhǎng)度來(lái)定義。 6AABB其實(shí)希望每個(gè)學(xué)3D的人能真正把3D流水線弄明白,說(shuō)的弄明白你要親自寫代碼,然后運(yùn)行,這樣你才能深刻理解。所以很推薦《3D游戲編程大師技巧》(它十幾萬(wàn)代碼,都自己用C++重新了,當(dāng)然也有40%代碼是COPY它的,但60%是理解后寫的。,但它的3D現(xiàn)在D3D的3D物體的LOCAL圖58,可以看見世界坐標(biāo)系下的視景體和投影后的視景體,對(duì)于一個(gè)世界坐標(biāo)系下點(diǎn)W, 們一般都用左手坐標(biāo)系,如果對(duì)坐標(biāo)系定義不是很了解,對(duì)角度正負(fù)是逆時(shí)針還是順時(shí)針分不清的,希望看看《DD如果想要更高級(jí)的還有本《計(jì)算機(jī)圖形學(xué)集合工具算法詳解》這兩本里面有代碼的,所以才說(shuō)它好。如果你理論和實(shí)Matematics.fo.3D.GaPoramg.a.Computer.Graphics)不能把整個(gè)數(shù)學(xué)基礎(chǔ)都說(shuō)了,是太大的工作量,希望大家諒解。繼續(xù)如果想了解怎么插值進(jìn)行Z緩沖測(cè)試,看《3D游戲編程大師技巧》。–p,y–q,z-w)(其)為平面上任意一個(gè)點(diǎn),K(p,q,w)為定點(diǎn))垂直,也就是正交。所以平面方程為(A,B,C)*(xpyqzw)=0最后形式為Ax+By+cZ+D0DpA-qB-wCD3D中 left面為-x-10(x10near面為-z=0假設(shè)ViewProj為相機(jī)矩陣和投影矩陣的乘積,1)ViewProj=經(jīng)過(guò)變換后的點(diǎn)的范圍-1x1,-1<=y<=1,0z<=假設(shè)平面位于世界坐標(biāo)下的方程為ax+by+cz+d=則,1)( )= d假設(shè)平面變換后的方程為a'x+b'y+c'zd'=則有(x',y',z',1)( )= 和(1)結(jié)合導(dǎo),1)ViewProj( )= 和(2) )=ViewProj(c' 出太多艱辛和努力,如果你自己吃不了苦,那可以說(shuō),你真的不適合學(xué)3D。{//leftp[0].m_vcN.y=-(m_mViewProj._24+m_mViewProj._21);p[0].m_vcN.z=-(m_mViewProj._34+m_mViewProj._31);//right//top//bottomp[3].m_vcN.x=-(m_mViewProj._14+m_mViewProj._12);p[3].m_vcN.y=-(m_mViewProj._24+m_mViewProj._22);p[3].m_vcN.z=-(m_mViewProj._34+m_mViewProj._32);//near//farfor(int{floatfL=p[i].m_vcN.GetLength();p[i].m_vcN/=fL;}return要處理第2個(gè)問題了,怎么判斷視景體和AABB剪裁。把這個(gè)問題說(shuō)廣點(diǎn),也就是怎么判斷封閉的多面體和AABB剪裁。 declspec(dllexport){VSVectorvcMin,vcMax;//最大,最小邊界VSVectorvcCenter; //VSAabb(void){;}inlinevoidSet(constVSVector&_vcMin,constVSVectorvoidConstruct(constVSObb//AABB位置關(guān)系 Cull(const ne nes,int void ne boolContains(constVSRay&Ray,float////(算法boolIntersects(constVSRay&Ray,float////(算法boolIntersects(constVSRay&Ray,floatfL,floatboolIntersects(constVSAabbboolIntersects(constVSVector};// 這個(gè)是AABB//AABB位置關(guān)系 Cull(const ne nes,int (所有函數(shù)算法來(lái)自《計(jì)算機(jī)圖形學(xué)幾何工具算法詳解釋自己想象一個(gè)這個(gè)問題,現(xiàn)在有一個(gè)多面體S是封閉的,要判斷一個(gè)6面體(AABB)和它的位置關(guān)系,3AABBS裁就是AABB和S相交,可以就是AABB完全在S內(nèi)。 YZAABBLA、B,也就是按照平面法向量方向重新計(jì)算。因?yàn)锳ABB邊界和坐標(biāo)軸垂直,所以用軸分離方法很容易求A、B。圖看圖59,AABB在蘭色坐標(biāo)軸下的最大最小點(diǎn)為紅色的MAX和MIN照平面L的法向量N方向重新計(jì)算后的最大最小點(diǎn),為綠色的MAX和MINMIN0MIN0。MAX0,則intVSAabb::Cull(const ne nes,int {VSVectorvcMin,vcMax; nes;{//if nes[i].m_vcN.x>={}{}//
vcMin.x=this->vcMin.x;vcMax.x=this-vcMax.x=this-if nes[i].m_vcN.y>={vcMin.y=this->vcMin.y;}elsevcMax.y=this-}//if nes[i].m_vcN.z>={}{}
vcMin.z=this->vcMin.z;vcMax.z=this-vcMax.z=this-if(((pnes[i].m_vcN*vcMin)+pnes[i].m_fD)>0.0f)returnVSCULLED;if(((pnes[i].m_vcN*vcMax)+pnes[i].m_fD)>=0.0f)bIntersects=true;}//returnVSVISIBLE;}//LAABBAABBL0,那么AABB這個(gè)代碼這個(gè)剪裁方法都介紹完了。下面介紹怎么求地形正方形PATCH的AABB,由于地形初始完成后,每個(gè)正方形PACHT都已經(jīng)確定(除非你想動(dòng)態(tài)改變地形,所以它的AABB也確定了。這里在弄一個(gè)矩陣,它的數(shù)據(jù)類型是AABB,先求邊長(zhǎng)為2AABB,然后在求它上一個(gè)層次的AABB,迭代這個(gè)過(guò)程,最后求出最大的正方形AABB。算法過(guò)程和求DH矩陣很{intiEdgeOffset=(iEdgeLength-1intiChildOffset=(iEdgeLength-1for(intz=iEdgeOffset;z<m_nSize;z+=(iEdgeLength-1){for(intx=iEdgeOffset;x<m_nSize;x+=(iEdgeLength-1){if(iEdgeLength=={iHeight[0]=GetHeightDate(x,ziHeight[1]=GetHeightDate(x-iEdgeOffset,z-iEdgeOffset//TOP-iHeight[2]=GetHeightDate(x,z-iEdgeOffset//TOP-iHeight[3]=GetHeightDate(x+iEdgeOffset,z-iEdgeOffsetiHeight[4]=GetHeightDate(x+iEdgeOffset,ziHeight[5]=GetHeightDate(x+iEdgeOffset,z+iEdgeOffset)//BOTTOM-iHeight[7]=GetHeightDate(x-iEdgeOffset,z+iEdgeOffsetiHeight[8]=GetHeightDate(x-iEdgeOffset,intiHeightMAX=iHeight[0];for(inti=1;i<9;i++){iHeightMAX=iHeight[i];iHeightMin=}}{
*Vertex=Vertex=floatiEdgeSize=(iEdgeLength-1)*m_fWidthRatio;VSVectorvcMin,vcMax;vcMin.y=iHeightMin*m_fHeightRatio;vcMin.z=Vertex->position.z-iEdgeSize;vcMax.x=Vertex->position.x+iEdgeSize;vcMax.y=iHeightMAX*m_fHeightRatio;vcMax.z=Vertex->position.z+iEdgeSize;VSAabbAabb;//LEFT-TOPCHILDfloatfHeightMin=pAabb-pAabb=GetAABBMatrix(x+iChildOffset,z-iChildOffset);fHeightMax=pAabb-if(fHeightMin>pAabb->vcMin.y)fHeightMin=pAabb-pAabb=GetAABBMatrix(x+iChildOffset,z+iChildOffset);if(fHeightMax<pAabb->vcMax.y)fHeightMax=pAabb->vcMax.y;if(fHeightMin>pAabb->vcMin.y)fHeightMin=pAabb-pAabb=GetAABBMatrix(x-iChildOffset,z+iChildOffset);if(fHeightMax<pAabb->vcMax.y)fHeightMax=pAabb->vcMax.y;if(fHeightMin>pAabb->vcMin.y)fHeightMin=pAabb- *Vertex=Vertex=floatiEdgeSize=(iEdgeLength-1)*m_fWidthRatio;VSVectorvcMin,vcMax;vcMin.x=Vertex->position.x-iEdgeSize;vcMin.y=fHeightMin;vcMin.z=Vertex->position.z-vcMax.x=Vertex->position.x+iEdgeSize;vcMax.y=fHeightMax;vcMax.z=Vertex->position.z+iEdgeSize;VSAabbAabb;}}}}if(pAabb->Cull(m_pnes,6)==VSCULLED){SetLODMatrix(iX,iZ{}后面講到的時(shí)候會(huì)進(jìn)一部說(shuō)明,遇到的問題??傊绻阋鲆粋€(gè)至少和你遇到問題時(shí),Visualc++Direct93D游戲開發(fā)引導(dǎo)》和《FOCUSON3DTERRAIN》里面有整個(gè)詳細(xì)算法。相對(duì)渲染天廢話少說(shuō),圖BackTextureLeftTextureFrontTexturefloatfHlafSize=fSize/m_TopVer[0].position=D3DXVECTOR3(-fHlafSize,fHlafSize,-fHlafSize);m_TopVer[2].position=D3DXVECTOR3(fHlafSize,fHlafSize,fHlafSize);m_TopVer[0].normal=D3DXVECTOR3(0.0f,-1.0f,0.0f);m_TopVer[1].normal=D3DXVECTOR3(0.0f,-1.0f,0.0f);m_TopVer[2].normal=D3DXVECTOR3(0.0f,-1.0f,0.0f);m_TopVer[3].normal=D3DXVECTOR3(0.0f,-1.0f,0.0f);m_BottomVer[0].normal=D3DXVECTOR3(0.0f,1.0f,0.0f);m_BottomVer[1].normal=D3DXVECTOR3(0.0f,1.0f,0.0f);m_BottomVer[2].normal=D3DXVECTOR3(0.0f,1.0f,0.0f);m_BottomVer[3].normal=D3DXVECTOR3(0.0f,1.0f,0.0f);m_LeftVer[0].position=D3DXVECTOR3(-fHlafSize,fHlafSize,-fHlafSize);m_LeftVer[1].position=D3DXVECTOR3(-fHlafSize,fHlafSize,fHlafSize);m_LeftVer[2].position=D3DXVECTOR3(-fHlafSize,-fHlafSize,fHlafSize);m_LeftVer[3].position=D3DXVECTOR3(-fHlafSize,-fHlafSize,-fHlafSize);m_LeftVer[3].normal=D3DXVECTOR3(1.0f,0.0f,0.0f);m_RightVer[0].position=D3DXVECTOR3(fHlafSize,fHlafSize,fHlafSize);m_RightVer[1].position=D3DXVECTOR3(fHlafSize,fHlafSize,-fHlafSize);m_RightVer[2].position=D3DXVECTOR3(fHlafSize,-fHlafSize,-fHlafSize);m_RightVer[3].position=D3DXVECTOR3(fHlafSize,-fHlafSize,fHlafSize);m_RightVer[0].normal=D3DXVECTOR3(-1.0f,0.0f,0.0f);m_RightVer[1].normal=D3DXVECTOR3(-1.0f,0.0f,0.0f);m_RightVer[2].normal=D3DXVECTOR3(-1.0f,0.0f,0.0f);m_RightVer[3].normal=D3DXVECTOR3(-1.0f,0.0f,0.0f);m_FrontVer[0].position=D3DXVECTOR3(-fHlafSize,fHlafSize,fHlafSize);m_FrontVer[1].position=D3DXVECTOR3(fHlafSize,fHlafSize,fHlafSize);m_FrontVer[2].position=D3DXVECTOR3(fHlafSize,-fHlafSize,fHlafSize);m_FrontVer[3].position=D3DXVECTOR3(-fHlafSize,-fHlafSize,fHlafSize);m_FrontVer[0].normal=D3DXVECTOR3(0.0f,0.0f,-1.0f);m_FrontVer[3].normal=D3DXVECTOR3(0.0f,0.0f,-1.0f);m_BackVer[0].position=D3DXVECTOR3(fHlafSize,fHlafSize,-fHlafSize);m_BackVer[1].position=D3DXVECTOR3(-fHlafSize,fHlafSize,-fHlafSize);m_BackVer[2].position=D3DXVECTOR3(-fHlafSize,-fHlafSize,-fHlafSize);m_BackVer[3].position=D3DXVECTOR3(fHlafSize,-fHlafSize,-fHlafSize);m_BackVer[3].normal=D3DXVECTOR3(0.0f,0.0f,1.0f);{設(shè)置索引,下面說(shuō)下紋理坐標(biāo),按照普通方法設(shè)置紋理坐標(biāo)成(00)(10)(11)(01)設(shè)置時(shí),你會(huì)發(fā)現(xiàn)渲染天空盒時(shí),在邊界處沒有拼接上,出現(xiàn)了一個(gè)細(xì)線。出現(xiàn)這個(gè)問題的,是因?yàn)镈3D紋理影射本身的。D3DTx(U*Mx)0.5TyV*My))–0.50.50MxMy也就是說(shuō)當(dāng)Tx0U0.5MxTy0V0.5MyTxMxU10.5MxTyMy時(shí)V1 AA的距離。大家都知道A經(jīng)過(guò)相換后,從世界坐標(biāo)變成了相機(jī)坐標(biāo),這個(gè)過(guò)程經(jīng)歷了平移和旋23不做平移變換,只做旋轉(zhuǎn)就可以AA,A變的,而改變相對(duì)距離的只能是平移。不用平移變換物體AADelta.x=vcCamPos.x;Delta.y=vcCamPos.y;Delta.z=vcCamPos.z;for(inti=0;i<4;{m_TopTempVer[i]=m_TopVer[i].position+Delta;m_BottomTempVer[i]=m_BottomVer[i].position+Delta;m_LeftTempVer[i]=m_LeftVer[i].position+Delta;。}Delta.x=vcCamPos.x;Delta.y=vcCamPos.y;Delta.z=vcCamPos.z;Delta.x=-vcCamPos.x;Delta.y=-vcCamPos.y;Delta.z=- 空盒Z大小都寫了進(jìn)去,導(dǎo)致超出天空盒大小的場(chǎng)景渲染不了,而且還要最先渲染,否則因?yàn)閷?shí)際上就弄一個(gè)正方形,然后加入一個(gè)海水的紋理,海水紋理要用WRAP貼圖,否則海平面很大,被拉神了可不好看了,當(dāng)然還要用半透明APHLA。流動(dòng)的函數(shù)就是讓紋理坐標(biāo)每次更新就m_Vertex[0].texture.x=m_Vertex[1].texture.x=(m_fWidth*1.0f)/Texture->nWidth;m_Vertex[2].texture.x=(m_fWidth*1.0f)/Texture->nWidth;m_Vertex[3].texture.x=0.0f;m_Vertex[1].t
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度債權(quán)轉(zhuǎn)股權(quán)資產(chǎn)證券化專項(xiàng)合同
- 2025年借款合同反擔(dān)保書編制指南范本正本
- 2025年度環(huán)氧地坪施工與智能監(jiān)控系統(tǒng)合同
- 2025年度建筑門窗安裝工程結(jié)算合同范本
- 2025年度冷鏈運(yùn)輸合同范本:食品安全保障協(xié)議
- 2025年度建材材料行業(yè)人才培養(yǎng)與合作合同
- 2025年度建筑節(jié)能材料采購(gòu)及施工合同
- 2025年度國(guó)際貿(mào)易公司銷售合同糾紛處理與解決合同
- 2025年度綠色環(huán)保廣告材料批量采購(gòu)合同書
- 2025年度特種卷簾門定制與特殊場(chǎng)合安裝合同
- 湯臣一品推廣策略
- 血液透析個(gè)案護(hù)理兩篇
- GB/T 32691-2016汽車空調(diào)電磁離合器
- 第八章 客戶關(guān)系管理
- 新版人教版高中英語(yǔ)選修一、選修二詞匯表
- 2022年河北邯鄲世紀(jì)建設(shè)投資集團(tuán)有限公司招聘筆試試題及答案解析
- 萬(wàn)物有靈且美(讀書心得)課件
- 住院患者跌倒墜床質(zhì)量控制管理考核標(biāo)準(zhǔn)
- 戰(zhàn)略規(guī)劃培訓(xùn)luqiang課件
- 高三日語(yǔ)一輪復(fù)習(xí)之自謙語(yǔ)句型課件
- YYT 0325-2022 一次性使用無(wú)菌導(dǎo)尿管
評(píng)論
0/150
提交評(píng)論