JavaScript WebGL framebuffer object - SegmentFault 思否
文章推薦指數: 80 %
When How I built a wind map with WebGL , framebuffer was used in it, so I checked the data and tried it out. 注册登录问答专栏课程招聘活动发现✓使用“Bing”搜本站使用“Google”搜本站使用“百度”搜本站站内搜索注册登录首页专栏javascript文章详情1JavaScriptWebGLframebufferobjectXXHolic发布于2月1日中文IntroductionWhenHowIbuiltawindmapwithWebGL,framebufferwasusedinit,soIcheckedthedataandtrieditout.OriginMyGitHubframebufferobjectWebGLhastheabilitytousetherenderingresultasatexture,whichisthe(framebufferobject).Bydefault,thefinalWebGLdrawingresultisstoredinthecolorbuffer,andtheframebufferobjectcanbeusedinsteadofthecolorbuffer,asshowninthefollowingfigure,theobjectsdrawnintheframebufferarenotdirectlydisplayedontheCanvas,soThistechniqueisalsoknownas(offscreendrawing).ExampleToverifytheabovefunctionality,theexampledrawsanimageintheframebuffer,andthendrawsitagainasatexturefordisplay.Basedonusingthepictureexample,therearemainlythefollowingchanges:dataframebufferobjectdrawdataDrawingintheframebufferisthesameasnormaldrawing,butitisnotdisplayed,sotheremustbecorrespondingdrawingareasize,vertexcoordinatesandtexturecoordinates.offscreenWidth:200,//离屏绘制的宽度 offscreenHeight:150,//离屏绘制的高度 //部分代码省略 //针对帧缓冲区绘制的顶点和纹理坐标 this.offScreenBuffer=this.initBuffersForFramebuffer(gl); //部分代码省略 initBuffersForFramebuffer:function(gl){ constvertices=newFloat32Array([ 0.5,0.5,-0.5,0.5,-0.5,-0.5,0.5,-0.5, ]);//矩形 constindices=newUint16Array([0,1,2,0,2,3]); consttexCoords=newFloat32Array([ 1.0, 1.0,//右上角 0.0, 1.0,//左上角 0.0, 0.0,//左下角 1.0, 0.0,//右下角 ]); constobj={}; obj.verticesBuffer=this.createBuffer(gl,gl.ARRAY_BUFFER,vertices); obj.indexBuffer=this.createBuffer(gl,gl.ELEMENT_ARRAY_BUFFER,indices); obj.texCoordsBuffer=this.createBuffer(gl,gl.ARRAY_BUFFER,texCoords); returnobj; }, createBuffer:function(gl,type,data){ constbuffer=gl.createBuffer(); gl.bindBuffer(type,buffer); gl.bufferData(type,data,gl.STATIC_DRAW); gl.bindBuffer(type,null); returnbuffer; } //部分代码省略Bothvertexshadersandfragmentshaderscanbenewlydefined,andasetissharedhereforconvenience.framebufferobjectTodrawintheframebuffer,youneedtocreatethecorrespondingframebufferobject.//帧缓冲区对象 this.framebufferObj=this.createFramebufferObject(gl); //部分代码省略 createFramebufferObject:function(gl){ letframebuffer=gl.createFramebuffer(); lettexture=gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D,texture); gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, this.offscreenWidth, this.offscreenHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null ); //反转图片Y轴方向 gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,true); //纹理坐标水平填充s gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE); //纹理坐标垂直填充t gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE); //纹理放大处理 gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR); //纹理缩小处理 gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR); framebuffer.texture=texture;//保存纹理对象 //关联缓冲区对象 gl.bindFramebuffer(gl.FRAMEBUFFER,framebuffer); gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0 ); //检查配置是否正确 vare=gl.checkFramebufferStatus(gl.FRAMEBUFFER); if(gl.FRAMEBUFFER_COMPLETE!==e){ console.log("Framebufferobjectisincomplete:"+e.toString()); return; } gl.bindFramebuffer(gl.FRAMEBUFFER,null); gl.bindTexture(gl.TEXTURE_2D,null); returnframebuffer; } //部分代码省略createFramebufferfunctiontocreateaframebufferobject,thefunctiontodeletetheobjectisdeleteFramebuffer.Afterthecreation,youneedtoassignatextureobjecttothecolorassociationobjectoftheframebuffer.Thetextureobjectcreatedbytheexamplehasseveralcharacteristics:1.Thewidthandheightofthetextureareconsistentwiththewidthandheightofthedrawingarea;2.WhenusingtexImage2D,thelastparameterisnull,Thatis,ablankareaforstoringtextureobjectsisreserved;3Thecreatedtextureobjectisplacedontheframebufferobject,whichisthislineofcodeframebuffer.texture=texture.bindFramebufferThefunctionbindstheframebuffertothetarget,andthenusestobindthepreviouslycreatedtextureobjecttotheframebuffer'scolor-linkedobjectgl.COLOR_ATTACHMENT0.checkFramebufferStatusCheckthattheframebufferobjectisconfiguredcorrectly.drawThemaindifferencewhendrawingisthatthereisaswitchingprocess://部分代码省略 draw:function(){ constgl=this.gl; constframeBuffer=this.framebufferObj; this.canvasObj.clear(); constprogram=this.shaderProgram; gl.useProgram(program.program); //这个就让绘制的目标变成了帧缓冲区 gl.bindFramebuffer(gl.FRAMEBUFFER,frameBuffer); gl.viewport(0,0,this.offscreenWidth,this.offscreenHeight); this.drawOffFrame(program,this.imgTexture); //解除帧缓冲区绑定,绘制的目标变成了颜色缓冲区 gl.bindFramebuffer(gl.FRAMEBUFFER,null); gl.viewport(0,0,gl.canvas.width,gl.canvas.height); this.drawScreen(program,frameBuffer.texture); }, //部分代码省略FirstusebindFramebuffermakethedrawingtargetbecometheframebuffer,andyouneedtospecifythecorrespondingviewport.Aftertheframebufferisdrawn,itisunboundandrestoredtothenormaldefaultcolorbuffer.Itisalsonecessarytospecifythecorrespondingviewport,andmoreparticularly,thetextureofthebufferobjectisused.Thisindicationisobtainedfromtheframebuffer.Plottheresult.observeandthinkTherelevantexamplesfoundontheInternetfeelmorecomplicated,andtherearesomeobservationsandthoughtsbelowintheprocessoftryingtosimplify.framebuffer.textureanexistingattributeoranartificialaddition?Thereisthislogicwhencreatingtheframebufferobject:framebuffer.texture=texture,thendoestheframebufferobjectitselfhavethetextureattribute?Theprintlogfoundthatthisattributewasnotpresentwhenitwasjustcreated,soitispresumedthatitshouldbeaddedartificially.framebuffer.texturehavecontent?Whentheframebufferobjectisinitialized,thestoredtextureisblank,butfromthefinalresult,aftertheframebufferisdrawn,thetexturehascontent,soframebuffer.textureattributehavecontent?Inthedrawinglogic,thestatementsrelatedtotexturesare:gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D,texture); gl.uniform1i(program.uSampler,0); gl.drawElements(gl.TRIANGLES,6,gl.UNSIGNED_SHORT,0);Itisspeculatedthatthegl.drawElementsmethodisstoredinthecolor-relatedobjectoftheframebuffer.Thecolor-relatedobjectoftheframebufferisassociatedwiththeblanktextureobjectcreatedduringinitialization.framebuffer.texturepointstothesameblanktextureobject,sofinallythereiscontent.Whydoesn'tthefinaldisplayfilltheentirecanvas?Whenthedisplayablecontentisfinallydrawn,itcanbefoundthattheverticescorrespondtotheentirecanvas,andthetexturecoordinatescorrespondtotheentirecompletetexture,butwhyistheentirecanvasnotcovered?Thetextureusedinthefinaldrawingofthedisplayablecontentcomesfromthedrawingresultoftheframebuffer,andtheverticesoftheframebuffercorrespondtohalfoftheentirebufferarea.Ifthedrawingresultoftheentireframebufferisregardedasatexture,drawthevisibleareaaccordingtothefinaldrawing.Ifthescaleisscaled,thenthefinaldrawingisnotfull,whichistheexpectedcorrectresult.Thisisa161f912bd416e4examplecanvas,justadjustthebufferverticestocorrespondtotheentirebuffersize.ReferencesWebGLProgrammingGuideFramebufferExampleWebGLFramebuffersWebGLdisplayframebuffer?javascripthtml5canvaswebgl阅读1.3k发布于2月1日赞1收藏1分享本作品系原创,采用《署名-非商业性使用-禁止演绎4.0国际》许可协议XXHolic[链接]325声望1.1k粉丝关注作者0条评论得票最新提交评论XXHolic[链接]325声望1.1k粉丝关注作者文章目录跟随宣传栏▲11
延伸文章資訊
- 1WebGLRenderingContext.bindFramebuffer() - Web APIs | MDN
Binding a frame buffer. var canvas = document.getElementById('canvas'); var gl = canvas.getContex...
- 2JavaScript webgl framebuffer object | Develop Paper
By default, the final drawing result of webgl is stored in the color buffer, and the frame buffer...
- 3WebGL基础学习篇(Lesson 8) - GitHub
这个方法更易于实现而且也更利于大家了解选取的工作原理。 最基础的思想就是将每个物体都渲染成不同的颜色,并且将场景渲染到offscreen framebuffer中。接着,当用户 ...
- 4WebGL中图片多级处理(FrameBuffer) - 纸异兽- 博客园
FBO(Frame Buffer Object)是被推荐用于将数据渲染到纹理对象的扩展。 FrameBuffer就像是一个webgl显示容器一样,平时我们使用gl.drawArrays或者gl.
- 5WebGL Framebuffers
This article is meant to try to give you a mental image of what a framebuffer is in WebGL. Frameb...