webgl Tutorial => Getting started with webgl

文章推薦指數: 80 %
投票人數:10人

At a base level WebGL is an engine that runs 2 user supplied functions on the GPU. One function is called a vertex shader. A vertex shader's job is to compute ... Downloadwebgl(PDF) webgl Gettingstartedwithwebgl State webgl Gettingstartedwithwebgl State webgl Gettingstartedwithwebgl Remarks WebGLisarasterizationAPIthatgenerallyrunsonyourGPUgivingyoutheabilitytoquicklydraw2Dand3Dgraphics.WebGLcanalsobeusedtodocomputationsonarraysofdata. WebGLisaverylow-levelAPI.AtabaselevelWebGLisanenginethatruns2usersuppliedfunctionsontheGPU.Onefunctioniscalledavertexshader.Avertexshader'sjobistocomputevertexpositions.BasedonthepositionsthefunctionoutputsWebGLcanthenrasterizevariouskindsofprimitivesincludingpoints,lines,ortriangles.Whenrasterizingtheseprimitivesitcallsasecondusersuppliedfunctioncalledafragmentshader.Afragmentshader'sjobistocomputeacolorforeachpixeloftheprimitivecurrentlybeingdrawn. ThesefunctionsarewritteninalanguagecalledGLSLthatissomewhatC/C++likeandstrictlytyped. It'suptotheprogrammertosupplythosefunctionstomakeWebGLdraw2d,3dorcomputesomething.NearlyeverypieceofWebGLisaboutsettingupthose2functionsandthensupplyingdatatothem. Datacanbesuppliedfrom4sources. Uniforms Uniformsareinputstoshaderfunctionsverymuchlikefunctionparametersorglobalvariables.Theyaresetoncebeforeashaderisexecutedandremainconstant duringexecuting Attributes Attributessupplydatatovertexshadersonly.Attributesdefinehowtopulldataoutofbuffers.Forexampleyoumightputpositions,normal,andtexturecoordinatesintoabuffer.AttributesletyoutellWebGLhowtopullthatdataoutofyourbuffersandsupplythemtoavertexshader.Avertexshaderiscalledauserspecifiednumberoftimesbycallinggl.drawArraysorgl.drawElementsandspecifyingacount.Eachtimethecurrentvertexshaderiscalledthenextsetofdatawillbepulledfromtheuserspecifiedbuffersandputintheattributes Textures Texturesare2Darraysofdataup4channels.Mostcommonlythose4channelsarered,green,blue,andalphafromanimage.WebGLdoesn'tcarewhatthedataisthough.Unlikeattributesandbuffers,shaderscanreadvaluesfromtextureswithrandomaccess. Varyings Varyingsareawayforavertexshadertopassdatatoafragmentshader.Varyingsareinterpolatedbetweenthevaluesoutputbythevertexshaderasaprimitiveisrasterizedusingafragmentshader HelloWorld Likeitmentionsintheremarkssectionweneedtosupplytwofunctions.Avertexshaderandafragmentshader Let'sstartwithavertexshader //anattributewillreceivedatafromabuffer attributevec4position; //allshadershaveamainfunction voidmain(){ //gl_Positionisaspecialvariableavertexshader //isresponsibleforsetting gl_Position=position; } IftheentirethingwaswritteninJavaScriptinsteadofGLSLyoucouldimagineitwouldbeusedlikethis //***PSUEDOCODE!!*** varpositionBuffer=[ 0,0,0,0, 0,0.5,0,0, 0.7,0,0,0, ]; varattributes={}; vargl_Position; drawArrays(...,offset,count){ for(vari=0;i TheninJavaScriptwecanlookthatup varcanvas=document.getElementById("c"); NowwecancreateaWebGLRenderingContext vargl=canvas.getContext("webgl"); if(!gl){ //nowebglforyou! ... NowweneedtocompilethoseshaderstoputthemontheGPUsofirstweneedtogetthemintostrings.Youcangetyourstringsanywayyounormalgetstrings.Byconcatenating,byusingAJAX,byputtingtheminnon-JavaScripttypedscripttags,orinthiscasebyusingmultilinetemplateliterals varvertexShaderSource=` //anattributewillreceivedatafromabuffer attributevec4position; //allshadershaveamainfunction voidmain(){ //gl_Positionisaspecialvariableavertexshader //isresponsibleforsetting gl_Position=position; } `; varfragmentShaderSource=` //fragmentshadersdon'thaveadefaultprecisionsoweneed //topickone.mediumpisagooddefault precisionmediumpfloat; voidmain(){ //gl_FragColorisaspecialvariableafragmentshader //isresponsibleforsetting gl_FragColor=vec4(1,0,0.5,1);//returnredish-purple } `; Thenweneedafunctionthatwillcreateashader,uploadthesourceandcompiletheshader functioncreateShader(gl,type,source){ varshader=gl.createShader(type); gl.shaderSource(shader,source); gl.compileShader(shader); varsuccess=gl.getShaderParameter(shader,gl.COMPILE_STATUS); if(success){ returnshader; } console.log(gl.getShaderInfoLog(shader)); gl.deleteShader(shader); } Wecannowcallthatfunctiontocreatethe2shaders varvertexShader=createShader(gl,gl.VERTEX_SHADER,vertexShaderSource); varfragmentShader=createShader(gl,gl.FRAGMENT_SHADER,fragmentShaderSource); Wethenneedtolinkthose2shadersintoaprogram functioncreateProgram(gl,vertexShader,fragmentShader){ varprogram=gl.createProgram(); gl.attachShader(program,vertexShader); gl.attachShader(program,fragmentShader); gl.linkProgram(program); varsucesss=gl.getProgramParameter(program,gl.LINK_STATUS); if(success){ returnprogram; } console.log(gl.getProgramInfoLog(program)); gl.deleteProgram(program); } Andcallit varprogram=createProgram(gl,vertexShader,fragmentShader); Nowthatwe'vecreatedaGLSLprogramontheGPUweneedtosupplydatatoit.ThemajorityoftheWebGLAPIisaboutsettingupstatetosupplydatatoourGLSLprograms.InthiscaseouronlyinputtoourGLSLprogramispositionwhichisanattribute.Thefirstthingweshoulddoislookupthelocationoftheattributefortheprogramwejustcreated varpositionAttributeLocation=gl.getAttribLocation(program,"position"); Attributesgettheirdatafrombufferssoweneedtocreateabuffer varpositionBuffer=gl.createBuffer(); WebGLletsusmanipulatemanyWebGLresourcesonglobalbindpoints.YoucanthinkofbindpointsasinternalglobalvariablesinsideWebGL.Firstyousetthebindpointtoyourresource.Then,allotherfunctionsrefertotheresourcethroughthebindpoint.So,let'sbindthepositionbuffer. gl.bindBuffer(gl.ARRAY_BUFFER,positionBuffer); Nowwecanputdatainthatbufferbyreferencingitthroughthebindpoint //three2dpoints varpositions=[ 0,0, 0,0.5, 0.7,0, ]; gl.bufferData(gl.ARRAY_BUFFER,newFloat32Array(positions),gl.STATIC_DRAW); There'salotgoingonhere.ThefirstthingiswehavepositionswhichisaJavaScriptarray.WebGLonotherhandneedsstronglytypeddatasothelinenewFloat32Array(positions)createsanewarrayof32bitfloatingpointnumbersandcopiesthevaluesfrompositions.gl.bufferDatathencopiesthatdatatothepositionBufferontheGPU.It'susingthepositionbufferbecauseweboundittotheARRAY_BUFFERbindpointabove. Thelastargument,gl.STATIC_DRAWisahinttoWebGLabouthowwe'llusethedata.Itcantrytousethatinfotooptimizecertainthings.gl.STATIC_DRAWtellsWebGLwe'renotlikelytochangethisdatamuch. Nowthatwe'veputdataintheabufferweneedtotelltheattributehowtogetdataoutofit.Firstoffweneedtoturntheattributeon gl.enableVertexAttribArray(positionAttributeLocation); Thenweneedtospecifyhowtopullthedataout varsize=2;//2componentsperiteration vartype=gl.FLOAT;//thedatais32bitfloats varnormalize=false;//usethedataasis varstride=0;//0=movesize*sizeof(type)eachiteration varoffset=0;//startatthebeginningofthebuffer gl.vertexAttribPointer( positionAttributeLocation,size,type,normalize,stride,offset) Ahiddenpartofgl.vertexAttribPointeristhatitbindsthecurrentARRAY_BUFFERtotheattribute.InotherwordsnowthatthisattributeisboundtopositionBufferwe'refreetobindsomethingelsetotheARRAY_BUFFERbindpoint. notethatfromthepointofviewofourGLSLvertexshaderthepositionattributewasavec4 attributevec4position; vec4isa4floatvalue.InJavaScriptyoucouldthinkofitsomethinglikeposition={x:0,y:0,z:0,w:0}.Abovewesetsize=2.Attributesdefaultto0,0,0,1sothisattributewillgetitsfirst2values(xandy)fromourbuffer.Thez,andwwillbethedefault0and1respectively. AfterallthatwecanfinallyaskWebGLtoexecuteareGLSLprogram. varprimitiveType=gl.TRIANGLES; varoffset=0; varcount=3; gl.drawArrays(primitiveType,offset,count); Thiswillexecuteourvertexshader3times.Thefirsttimeposition.xandposition.yinourvertexshaderwillbesettothefirst2valuesfromthepositionBuffer.The2ndtimeposition.xywillbesettothe2nd2values.Thelasttimeitwillbesettothelast2values. BecausewesetprimitiveTypetogl.TRIANGLES,eachtimeourvertexshaderisrun3timesWebGLwilldrawatrianglebasedonthe3valueswesetgl_Positionto.Nomatterwhatsizeourcanvasisthosevaluesareinclipspacecoordinatesthatgofrom-1to1ineachdirection. BecauseourvertexshaderissimplycopyingourpositionBuffervaluestogl_Positionthetrianglewillbedrawnatclipspacecoordinates 0,0, 0,0.5, 0.7,0, Howthosevaluestranslatetopixelsdependsonthegl.viewportsetting.gl.viewportdefaultstotheinitialsizeofthecanvas.Sincewedidn'tsetasizeforourcanvasit'sthedefaultsizeof300x150.Convertingfromclipspacetopixels(oftencalledscreenspaceinWebGLandOpenGLliterature)WebGLisgoingtodrawatriangleat clipspacescreenspace 0,0->150,75 0,0.5->150,112.5 0.7,0->255,75 WebGLwillnowrenderthattriangle.Foreverypixelitisabouttodrawitwillcallourfragmentshader.Ourfragmentshaderjustsetsgl_FragColorto1,0,0.5,1.SincetheCanvasisan8bitperchannelcanvasthatmeansWebGLisgoingtowritethevalues[255,0,127,255]intothecanvas. Thereare3majorthingswestillhaven'tcoveredfromtheremarks.Textures,varyings,anduniforms.Eachofthoserequiresit'sowntopic. InstallationorSetup WebGLisabrowsertechnologysothereisn'tmuchtosetupotherthantohaveabrowser.YoucangetstartedwithWebGLonJSFiddleorCodepenorJSBInoranynumberofothersitesthatletyoueditHTML,CSS,andJavaScriptonlinethoughtherewillbeafewlimitations(seebelow).Youcanalsohostopensourcefilesongithubpagesorsimilarservices. Ontheotherhandatsomepointyou'reprobablygoingtoworklocally.Todothatit'srecommendedyourunasimplewebserver.Thereareplentytochoosefromthataresimpletouseandrequireverylittlesetup. Usingnode.jsasaserver installnode.js Openaterminalornodecommandpromptandtypenpminstall-ghttp-server(onOSXputsudoinfrontofthat. typehttp-servertostartservingthefilesinthecurrentfolderORhttp-serverpath-to-foldertoserveradifferentfolder Pointyourbrowsertohttp://localhost:8080/name-of-filetoviewyourWebGLwebpage Usingdevdasaserver Downloaddevd Openaterminalandrundevdwitheitherdevd.toserverfilesfromthecurrentfolderordevdpath-to-foldertoserveadifferentfolder Pointyourbrowsertohttp://localhost:8000/name-of-filetoviewyourWebGLwebpage UsingServezasaserver DownloadServez InstallIt,Runit Choosethefoldertoserve Pick"Start" Gotohttp://localhost:8080orpick"LaunchBrowser" Using"WebServerforChrome"ChromeExtension InstalltheWebServerFromChrome LaunchitfromtheAppsicononanewtabpage. Setthefolderwhereyourfilesarethenclickthehttp://127.0.0.1:8787link LimitationofWebGLonOnlineServices InWebGLitisverycommontoloadimages.InWebGLtherearerestrictionsonhowimagescanbeused.SpecificallyWebGLcannotuseimagesfromotherdomainswithoutpermissionfromtheserverhostingtheimages.Servicesthatcurrentlygivepermissiontouseimagesincludeimgurandflickr.SeeLoadingCrossDomainImages.Otherwiseyou'llneedtohavetheimagesonthesameserverasyourwebglpageoruseothercreativesolutionslikegeneratingimageswithacanvastag PDF-Downloadwebglforfree Previous Next ThismodifiedtextisanextractoftheoriginalStackOverflowDocumentationcreatedbyfollowingcontributorsandreleasedunderCCBY-SA3.0 ThiswebsiteisnotaffiliatedwithStackOverflow SUPPORT&PARTNERS Advertisewithus Contactus PrivacyPolicy STAYCONNECTED Getmonthlyupdatesaboutnewarticles,cheatsheets,andtricks.  Subscribe



請為這篇文章評分?