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