How to render 3D in 2D canvas - Mamboleoo

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

This article shows how to render 3D by only using the native 2D Canvas API ... To get started, we need to add a canvas element in our HTML. October13,2021 Lastupdated: November02,2021 ThisarticlewasfirstpublishedonBaseDesignwebsite. Aswewereexploringoptionsonhowtobestillustrateabrandstory recently,wecameupwithaprettyinterestingprototype:amulti-step animationthatstartswitharotatingglobefullofparticles. SeethePen3DGlobe(Purecanvas)byBaseDesign(@mamboleoo)onCodePen. Fromatechnicalperspective,thatfirststepwasdefinitelythemost interestingone.Becauseasallthefollowinganimationstepswere plain2D,Icouldn’tusea3DrenderersuchasThree.js.AndsoIhadtofigureouthowtorendera3DshapeusingonlytheCanvas2DAPI. Inthisarticle,I’llshowyouhowIfinallydidit.I’llfirst explainhowtorenderabasicshapefroma3DsceneusingtheJavaScript Canvas2DAPI.Theninthesecondpartofthispost,I’llshowyouhow tomakeeverythingabitfancierwithsometexturesand3Dvolumes. 1.Setupthecanvasscene Togetstarted,weneedtoaddacanvaselementinourHTML.WealsoneedtoaddanidsoitwillbeeasiertoselectitfromJavaScript.That’sallweneedintheHTML! FortheCSS,weneedtoremovethedefaultmarginsonthebodyand preventscrollbarsfromappearingbyusing‘overflow:hidden;’.Because wewantourcanvastobefullscreen,wedefineitswidthandheightat 100%oftheviewport. TosetupafullscreenCanvasdemoinJavaScript,weneedtoselect thecanvasfromtheDOMandgetitsdimensions.Therestofthesetupis mostlyabouthandlingtheuserresizingtheirscreen. 2.Createparticles ToeasilymanageahighnumberofparticlesinJavaScript,theeasiestwayisbyusingaclass (introducedwithECMAScript2015).Thiswillallowustodefinerandom propertiesforeveryparticlewhilestillsharingcommonmethodsbetween allofthem. Thefirstpartofaclassistheconstructormethodandweuseittostorethecustompropertiesofeachparticle.Wealsocreatetwomethodsforourdots:project()anddraw().Theprojectmethodiswerethemagichappens:weconvertthe3Dcoordinatesofourparticletoa2Dworld.Finally,thedrawmethodiswherewedrawtheparticleonourcanvasafterwecalculatetheprojectedvalues. YoumayhavenoticedweareusingaPERSPECTIVEconstant.Thisvaluewilldefinethebehaviorofthe‘camera’wearesimulatingintheprojectmethod. Ifyouincreaseitsvalue,youwillnoticethattheperspectiveis gettinglessandlessvisible,everythingwilllookflat.Ifyoudothe oppositeandlowerthevalue,theperspectivewillbemuchmoreintense. 3.Renderthescene Nowthatwehaveallourparticlesreadytoberenderedonthe screen,weneedtocreateasmallfunctionthatloopsthroughallthe dotsandrendersthemonthecanvas. Ifyoutrythecodeasis,youwillgetsomethingverystaticbecausewearenotmovingthedotsinour3Dscene. Tomakeeverythingmovetherearemanyoptionsandthereisnoperfectsolution.InmycaseI’mgoingtousetheTweenMaxpluginmadebyGreenSockbecauseitdoesn’trequirealotofsetupandisprettystraightforward. SeethePen3DWorldin2D(Purecanvas)byMamboleoo(@mamboleoo)onCodePen. Youmaythinkitisnotthatinterestingtowritesomuchforso little.Wecouldgetawaywithsimulatingthecomplexmath.But,now thatthehardpartisdone,wecangocrazy! Makingaglobe Tocreateaglobeoutofparticles,weneedtocalculatetheir coordinatesonitssurface.Thecoordinatesofapointalongasphere don’tusetheclassicCartesianCoordinates(x,y,z)butthreedifferentvaluesfromthePolarCoordinateSystem: Radius:TheradiusofthesphereTheta:Thepolarangle(between0and360°)Phi:Theazimuthangle(between-90°and90°) Inourcasewewantrandomvaluesforeverydot,sowewilldefine theThetaandPhivaluesrandomlywhenwecreateanewone.Theradius beingthesameforeverydotwecanstoreinintoaglobalvariable. Youmaybewonderingwhywearenotusingamorebasicwayto generatearandomvalueforPhi.Ifweweretodoso,thedistribution alongthespherewouldn’tbeuniformandwoulddisplaymoreparticles aroundthepoles.ThisiswhyweareusingusinganArcCosine(acos)functiontofixthisissue. FinallyweneedtoconvertthecoordinatesfromPolartoCartesianto matchourcurrent3Dworldeverytimewewanttoprojectthedotonthe 2Dcanvas.Wearealsodrawingitusingacirclethistime,insteadofa rectangle. Depthsorting SofarwehaveonlyusedabasicmonochromeshapefromtheCanvas API.Ifwewanttouseacustomtextureforourparticles,wefacea problem.Intherenderfunctionwearedrawingtheparticlesbasedontheirorderinthedots array.Whenweusetexturesitwillbecomenoticeablethatweare drawingparticlesontopofothers,withouttakingtheirdepthvalue intoaccount.Thiswillcreateaweirdresultwithfurtherparticles beingdisplayedovercloserones. Tofixthisissue,weneedtosortthearrayofdotsbasedontheirZ positionrightbeforewedrawthemsothefurthestdotswillbedrawn firstandtheclosestoneslast.WecallthismethodDepthSorting! SeethePen3DGlobein2D(Depthsorting)byMamboleoo(@Mamboleoo)onCodePen. Rendering3Dvolumes Let’sgetreallycrazyandseeifwecanrendermorethanjustflat shapeswithourscript!(Spoileralert:wecan)Ifwethinkofacubeas data,wecandecomposeitsconstructionintwoparts:8verticesand12 lines. Withthatinformation,wecansettwovariablesinourscripttostorethisdata. Thefirstvariablecontainsthecoordinatesofeveryvertexofcube.Thesecondvariableisanarrayof12pairsofverticesstoredbytheirindex. Wewillusethissecondvariabletodrawthelinesbasedonthose pairs.Forexamplethefirstpair[0,1]meansthatweconnectthe vertex[0]tothevertex[1]. Fromthosetwovariableswecangeneraterandomcubesinourscene andstartanimatingthembymovingtheverticesinour3Dworld. SeethePen3DCubes2D(Purecanvas)byMamboleoo(@Mamboleoo)onCodePen. Youcouldgoevenfurtheranddrawthefacesofthecubesinsteadof theiredges.Todosoyouwillneedtoknowwhatverticesmustbe connectedforeveryfaceandcheckwhatfacesmustbedrawnfirst. — Donothesitatetoforkanydemoandexploremorecrazyideas!Ifyou haveanyquestionorremarkaboutthisarticle,donothesitatetoping meonTwitter@MamboleooorgocheckmyworkonInstagram. Cheers🦊🦓🐹🐨Louis



請為這篇文章評分?