丨針對(duì)海量數(shù)據(jù)如何優(yōu)化性能_第1頁(yè)
丨針對(duì)海量數(shù)據(jù)如何優(yōu)化性能_第2頁(yè)
丨針對(duì)海量數(shù)據(jù)如何優(yōu)化性能_第3頁(yè)
丨針對(duì)海量數(shù)據(jù)如何優(yōu)化性能_第4頁(yè)
丨針對(duì)海量數(shù)據(jù)如何優(yōu)化性能_第5頁(yè)
已閱讀5頁(yè),還剩12頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

但千萬(wàn)不要陷入到思維定式中。因?yàn)榻鉀Q這些特殊渲染需求,并沒(méi)有固定的路徑或方法,它是一個(gè)需要迭代優(yōu)化的過(guò)程,需要我們對(duì)WeGL的渲染機(jī)制非常了解,并深入思考,才能創(chuàng)造出最適合的方法來(lái)。在我們實(shí)際的工作里,還有許多其他的方法可以使用,你一定要根據(jù)自己的實(shí)際情況隨機(jī)應(yīng)變。如果我們要實(shí)現(xiàn)這些靜態(tài)的標(biāo)準(zhǔn)點(diǎn),方法其實(shí)很簡(jiǎn)單,用Canvas2D或者WeGL都可以輕松實(shí)現(xiàn)。就算點(diǎn)數(shù)量比較多也沒(méi)關(guān)系,因?yàn)殇秩緦?duì)性能影響也不會(huì)很大。不過(guò),如果我們想讓圓點(diǎn)運(yùn)動(dòng)起來(lái),比如,做出一種閃爍或者呼吸燈的效果,那我們就要考慮點(diǎn)的數(shù)量對(duì)性能的影響了。那面對(duì)這一類特殊的渲染的需求,我們?cè)撛趺崔k呢?下面,我們先用常規(guī)的做法來(lái)實(shí)現(xiàn),然后在這個(gè)方法上不斷迭代優(yōu)化。為了方便你理解,我就不繪制地圖了,只繪制這些隨機(jī)的小圓點(diǎn)。constcanvas constrenderer=new3constvertex=attributevec2uniformvec2uniformfloatuniformfloat9voidmain()vec3pos=vec3(a_vertexPosition,floatscale=0.7+0.3*sin(6.28*bias+0.003*mat3m=scale,0,0,scale,xy, gl_Position=vec4(m*pos, 20constfragment=#ifdefprecisionhighp uniformvec4voidmain()gl_FragColor= 32constprogram pileSync(fragment,functioncircle(radius=0.05)constdelta=2*Math.PI/constpositions=constcells=for(leti=0;i<32;i++)constangle=i*positions.push([radius*Math.sin(angle),radius*if(i>0&&i<31)cells.push([0,i,i+ return{positions,48constCOUNT=functioninit()constmeshData=const{positions,cells}=for(leti=0;i<COUNT;i++)constx=2*Math.random()-consty=2*Math.random()-constrotation=2*Math.PI*constuniforms=uniforms.u_color=uniforms.xy=2*Math.random()-2*Math.random()- uniforms.bias= renderer.uniforms.uTime=81functionupdate(t)renderer.uniforms.uTime=8890上面的代碼非常簡(jiǎn)單,關(guān)鍵思路就是用circle生成頂點(diǎn)信息,然后對(duì)每個(gè)需要繪制的圓應(yīng)用circle頂點(diǎn)信息,并設(shè)置不同的unifom參數(shù),最后在shader中根據(jù)參數(shù)進(jìn)行繪制就不過(guò)如果我們這么做的話,整體的性能就會(huì)非常低,比如在繪制500個(gè)圓的時(shí)候,瀏覽器的幀率就掉到十幾fps了。那我們?cè)撛趺磧?yōu)化呢?在學(xué)完Canvas和WebGL的性能優(yōu)化之后,我們知道,在繪制大量同種幾何圖形的時(shí)代代123456789constcanvasconstrenderer=newconstvertex=attributevec2a_vertexPosition;attributevec4color;attributevec2xy;attributefloatbias;uniformfloatuTime;varyingvec4voidmain()vec3pos=vec3(a_vertexPosition,floatscale=0.7+0.3*sin(6.28*bias+0.003*mat3mmat3(scale,0,0,scale,xy,vColor=gl_Position=vec4(m*pos,24}constfragment=#ifdefprecisionhighp varyingvec4voidmain()gl_FragColor= 37constprogram pileSync(fragment,functioncircle(radius=0.05)constdelta=2*Math.PI/constpositions=constcells=for(leti=0;i<32;i++)constangle=i*positions.push([radius*Math.sin(angle),radius*if(i>0&&i<31)cells.push([0,i,i+ return{positions,53constCOUNT=functioninit()const{positions,cells}=constcolors=constpos=constbias=for(leti=0;i<COUNT;i++)constx=2*Math.random()-consty=2*Math.random()-constrotation=2*Math.PI*1 2*Math.random()-2*Math.random()- renderer.uniforms.uTime=instanceCount:attributes:color:{data:[...colors],divisor:xy:{data:[...pos],divisor:bias:{data:[...bias],divisor: 9495functionupdate(t)renderer.uniforms.uTime=101103uniformattribute染100000個(gè)點(diǎn),瀏覽器的幀率也能達(dá)到30fps以上,性能提升了超過(guò)2000倍!JavaScriptWebGL20000繪制規(guī)則的圖形,我們還可以使用點(diǎn)圖元。還記得嗎?我們WebGL的基本圖元包括點(diǎn)、線、三角形等等。前面我們繪制圓的時(shí)候,都是用re函數(shù)生成三角網(wǎng)格,然后通過(guò)三角形繪制的。這樣,我們繪制一個(gè)圓需要許多頂點(diǎn)。但實(shí)際上,這種簡(jiǎn)單的圖形,我們還可以直接采用點(diǎn)圖元。在WebGL中,點(diǎn)圖元是最簡(jiǎn)單的圖元,它用來(lái)顯示畫布上的點(diǎn)。在頂點(diǎn)器里,我們可以設(shè)置gl_PointSize來(lái)改變點(diǎn)圖元的大小,所以我們就可以用點(diǎn)圖元來(lái)表示一個(gè)矩形。代代12345constcanvasconstrenderer=newconstvertex=attributevec266789uniformvec2voidmain()gl_PointSize=0.2*uResolution.x;gl_Position=vec4(a_vertexPosition,1,1);}constfragment=`#ifdefGL_ESprecisionhighpfloat;voidmain()gl_FragColor=vec4(0,0,1,}constprogrampileSync(fragment,renderer.uniforms.uResolution=[canvas.width,canvas.height];mode:renderer.gl.POINTS,positions:[[0,0]],如上面代碼所示,meshDaa的moe設(shè)為l.POITS,只繪制一個(gè)點(diǎn)(0,0)。在頂點(diǎn)器中,我們通過(guò)l_Pointize來(lái)設(shè)置頂點(diǎn)的大小。由于l_Pointize的單位是像素,所以我們需要傳一個(gè)畫布寬高uResoluion進(jìn)去,然后將lPosiion設(shè)為0.2*esolion,這就讓這個(gè)點(diǎn)的大小設(shè)為畫布的20%,最終在畫布上就呈現(xiàn)出一個(gè)藍(lán)色矩形。注意,這里你可以回顧一下之前我們采用的常規(guī)的方法繪制的矩形,我們是將矩形剖分為兩個(gè)三角形,然后用填充三角形來(lái)繪制的。而這里,我們用點(diǎn)圖元,好處是我們只需要一個(gè)頂點(diǎn)就可以繪制,而不需要用四個(gè)頂點(diǎn)、兩個(gè)三角形來(lái)填充。gl_PointSize代1234567代123456789attributevec2uniformvec2uResolution;varyingvec2vResolution;varyingvec2vPos;voidmain()gl_PointSize=0.2*uResolution.x;vResolution=uResolution;vPos=gl_Position=vec4(a_vertexPosition,1,}代代123456789#ifdefGL_ESprecisionhighpfloat;varyingvec2vResolution;varyingvec2vPos;voidmain()vec2st=gl_FragCoord.xy/vResolution;st=2.0*st-1.0;floatd=distance(st,d=1.0-smoothstep(0.195,0.2,d);gl_FragColor=d*vec4(0,0,1,1);}經(jīng)過(guò)前面課程的學(xué)習(xí),你應(yīng)該對(duì)造型函數(shù)的實(shí)現(xiàn)原理比較熟悉了,這里我們就是通過(guò)計(jì)算到圓心的距離得出距離場(chǎng),然后通過(guò)smoohsep將一定距離內(nèi)的圖形繪制出來(lái),這樣就得到一個(gè)藍(lán)色的圓。constcanvas constrenderer=new3constvertex=attributevec2attributevec47attributefloat89uniformfloatuniformvec2varyingvec4varyingvec2varyingvec2varyingfloatvoidmain()floatscale=0.7+0.3*sin(6.28*bias+*gl_PointSize=0.05*uResolution.x*vColor=vPos=vResolution=vScale=gl_Position=vec4(a_vertexPosition,1,}constfragment=#ifdefprecisionhighpvaryingvec4varyingvec2varyingvec2varyingfloatvoidmain()vec2st=gl_FragCoord.xy/st=2.0*st-floatd=step(distance(vPos,st),0.05*gl_FragColor=d*}45constprogram pileSync(fragment,constCOUNT=functioninit()88

constcolors=[];constpos=[];constbias=[];for(leti=0;i<COUNT;{constx=2*Math.random()-1;consty=2*Math.random()-1;constrotation=2*Math.PI*colors.push([Ma2*Math.random()-2*Math.random()-}renderer.uniforms.uTime=renderer.uniforms.uResolution=[canvas.width,renderer.setMeshData({mode:enableBlend:true,positions:pos,attributes:{color:{data:bias:{data:89functionupdate(t)renderer.uniforms.uTime=9698可以看到,我們沒(méi)有采用前面那樣通過(guò)circle函數(shù)來(lái)生成圓的頂點(diǎn)數(shù)據(jù),而是直接使用gl.POINTS來(lái)繪制,并在器中用距離場(chǎng)和造型函數(shù)來(lái)畫圓。這么做之后,我們大大減少了頂點(diǎn)的運(yùn)算,原先我們每繪制一個(gè)圓,需要32個(gè)頂點(diǎn)、30個(gè)三角形,而現(xiàn)在用一個(gè)點(diǎn)就解決了問(wèn)題。這樣一來(lái),就算我們要渲染200000個(gè)點(diǎn),幀率也可以保持在50fps以上,這里舉上面的這個(gè)例子,主要是想說(shuō)明一個(gè)問(wèn)題:即使是使用WebGL,不同的渲染方式,性能的差別也會(huì)很大,甚至?xí)_(dá)到數(shù)千倍的差別。因此,在可視化業(yè)務(wù)中,要學(xué)會(huì)根據(jù)不同的應(yīng)用場(chǎng)景來(lái)有針對(duì)性地進(jìn)行優(yōu)化。說(shuō)起來(lái)簡(jiǎn)單,要做到這一點(diǎn)并不容易,你需要對(duì)WeGL本身非常熟悉,而且對(duì)于GPU的使用、渲染管線等基本原理有著比較深刻的理解。這不是一朝一夕可以做到的,需要持續(xù)不斷地學(xué)習(xí)和積累。就像有些同學(xué)使用繪圖庫(kù)ThreeJS或者SrieJS來(lái)繪圖的時(shí)候,做出來(lái)的應(yīng)用性能很差,就會(huì)懷疑是圖形庫(kù)本身的問(wèn)題。實(shí)際上,這些問(wèn)題很可能不是庫(kù)本身的問(wèn)題,而是我們使用方法上的問(wèn)題。換句話說(shuō),是我們使用的繪圖方式并不是最適用于當(dāng)前的業(yè)務(wù)場(chǎng)景。而ThreeJS、SrieJS這些通用的繪圖庫(kù),也并不會(huì)自己針對(duì)特定場(chǎng)景來(lái)優(yōu)化。原因,我沒(méi)有把這門課程的重點(diǎn)放在庫(kù)的API的使用上,而是深入到圖形渲染的底層原針對(duì)場(chǎng)景的性能優(yōu)化方法其實(shí)非常多,我剛才講的也只是幾種典型的情況。為了幫助你在實(shí)戰(zhàn)中慢慢領(lǐng)悟,我再舉幾個(gè)例子。不過(guò)我要提前說(shuō)一下,我不會(huì)具體去講這些例子的代碼,只會(huì)重點(diǎn)強(qiáng)調(diào)常用的思路。學(xué)會(huì)這些方法之后,你再在實(shí)踐中慢慢應(yīng)用和體會(huì)就會(huì)容易很多了。我們已經(jīng)學(xué)習(xí)過(guò)使用后期處理通道的基本方法。實(shí)際上,后期處理通道十分強(qiáng)大,它最重要的特性就是可以把各種數(shù)據(jù)在紋理中。這樣在迭代處理的時(shí)候,我們就可以用GPU將這些數(shù)據(jù)并行地和處理,從而達(dá)到非常高效地渲染。這里是一個(gè)OGL官網(wǎng)上例子,它就是用后期處理通道實(shí)現(xiàn)了粒子流的效果。這樣的效果,在其他圖形系統(tǒng)中,或者WebGL不使用后期處理通道是不可能做到的。紋理中,然后利用GPU

溫馨提示

  • 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ù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論