[{"data":1,"prerenderedAt":219},["ShallowReactive",2],{"DefaultLayouten":3,"language-blog-slug-upgrade-design-with-webgl-i18n-slugs":134,"language-blog-slug-en-upgrade-design-with-webgl":138},{"app":4,"menu":31,"footer":66},{"githubUrl":5,"youtubeUrl":6,"linkedinUrl":7,"phoneNumber":8,"emailAddress":9,"legal":10,"addresses":20},"https:\u002F\u002Fgithub.com\u002Fvoorhoede\u002F","https:\u002F\u002Fwww.youtube.com\u002Fchannel\u002FUCzHuhQVYFRixtQN2-swcuGg","https:\u002F\u002Fwww.linkedin.com\u002Fcompany\u002Fde-voorhoede","+31 20 2610 954","post@voorhoede.nl",[11,14,17],{"title":12,"value":13},"KvK","56017235",{"title":15,"value":16},"BTW","NL851944620B01",{"title":18,"value":19},"IBAN","NL14TRIO0320142078",[21,26],{"address":22,"city":23,"googleMapsLink":24,"postalCode":25},"Koivistokade 70","Amsterdam","https:\u002F\u002Fwww.google.com\u002Fmaps\u002Fplace\u002FDe+Voorhoede+%7C+Front-end+Development\u002F@52.396847,4.8700823,17z\u002Fdata=!3m1!4b1!4m5!3m4!1s0x47c5e21d502d2d59:0xbf570944a96ebf45!8m2!3d52.347647!4d4.8502154","1013 BB",{"address":27,"city":28,"googleMapsLink":29,"postalCode":30},"Koornmarkt 22","Delft","https:\u002F\u002Fwww.google.nl\u002Fmaps\u002Fplace\u002FKoornmarkt+22,+2611+EG+Delft\u002F@52.0093477,4.3573054,17z\u002F","2611 EG",{"title":32,"callToActions":33,"links":39},"Site Menu",[34],{"id":35,"title":36,"link":37},"163140902","Contact",{"__typename":38},"ContactRecord",[40,46,51,56,61],{"id":41,"title":42,"link":43},"163140904","Impact",{"__typename":44,"slug":45},"PageRecord","impact",{"id":47,"title":48,"link":49},"163140905","Services",{"__typename":50},"ServiceOverviewRecord",{"id":52,"title":53,"link":54},"163140906","Cases",{"__typename":55},"CaseOverviewRecord",{"id":57,"title":58,"link":59},"163140908","About us",{"__typename":44,"slug":60},"about-us",{"id":62,"title":63,"link":64},"d6WdFJq2SOuc3dWtpibbXQ","Work at",{"__typename":44,"slug":65},"work-at",{"links":67,"copyrightTitle":93,"copyrightLabel":94,"copyrightLink":95,"privacyTitle":96,"privacyLabel":97,"privacyLink":98,"certificatesGrid":99},[68,71,74,77,82,85,88],{"id":69,"title":42,"link":70},"144185264",{"__typename":44,"slug":45},{"id":72,"title":48,"link":73},"144185265",{"__typename":50},{"id":75,"title":53,"link":76},"144185266",{"__typename":55},{"id":78,"title":79,"link":80},"144185267","Blog",{"__typename":81},"BlogPostOverviewRecord",{"id":83,"title":58,"link":84},"144185268",{"__typename":44,"slug":60},{"id":86,"title":36,"link":87},"144185269",{"__typename":38},{"id":89,"title":90,"link":91},"144185270","FAQ",{"__typename":44,"slug":92},"faq","Creative Commons licence and disclaimer","CC BY 4.0","https:\u002F\u002Fcreativecommons.org\u002Flicenses\u002Fby\u002F4.0\u002F","De Voorhoede privacy statement (pdf)","Privacy statement","https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1763455455-vh-isms-006-privacy-statement-de-voorhoede-en.pdf",[100,112,123],{"id":101,"image":102,"link":107},"Xq4bBfg_TZ6Fkjax9mkbLQ",{"url":103,"alt":104,"width":105,"height":106},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1687353463-b-corp-logo-black-rgb.png","B Corp logo",404,680,{"__typename":108,"id":109,"title":110,"url":111},"ExternalLinkRecord","fGW1ak8XQYaYDLkBSyncog","B Corp","https:\u002F\u002Fwww.bcorporation.net\u002Fen-us\u002Ffind-a-b-corp\u002Fcompany\u002Fde-voorhoede\u002F",{"id":113,"image":114,"link":119},"c5mCXRTiSraRIB25fw1p7Q",{"url":115,"alt":116,"width":117,"height":118},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1687353461-dda-boxlogo-black.png","Dutch Digital Agencies logo",627,480,{"__typename":108,"id":120,"title":121,"url":122},"P6Jh7B0cTv2cKyNEeKVWVQ","Dutch Digital Agencies","https:\u002F\u002Fdutchdigitalagencies.com\u002Fleden\u002Fde-voorhoede\u002F",{"id":124,"image":125,"link":129},"MT5SCyNxSTSr_v5eeATMZw",{"url":126,"alt":127,"width":128,"height":128},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1775730283-dnv.png","DNV logo",518,{"id":130,"title":131,"link":132},"BRtNB5HnT5i-7HkA8IYzBw","DIV",{"__typename":44,"slug":133},"impact\u002Fdigitale-producten-privacy-by-design",[135],{"locale":136,"value":137},"en","upgrade-design-with-webgl",{"page":139},{"slug":137,"i18nSlugs":140,"social":142,"title":147,"subtitle":79,"isArchived":148,"headerIllustration":149,"date":150,"authors":151,"introTitle":160,"items":161,"pivots":216,"relatedBlogPosts":217,"tags":218,"onMountedScript":154,"onUnmountedScript":154},[141],{"locale":136,"value":137},{"title":143,"description":144,"image":145},"Upgrade your design with WebGL | De Voorhoede","We see WebGL being used in more and more sectors, like 3D visualizations in games, physics simulations and artwork. Let’s delve deeper into this topic.\n",{"url":146},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1661247986-linkedin-blog-alternatief-5.png","Upgrade your design with WebGL",false,null,"2022-08-23T02:00:00.000+02:00",[152],{"name":153,"lastName":154,"slug":155,"image":156},"Ben","","ben",{"url":157,"alt":149,"width":158,"height":159},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1683534636-placeholder.jpg",1235,1646,"What would the modern web be without WebGL? We see it being used in more and more sectors, like 3D visualizations in games and VR, physics simulations, data simulations and artwork. Let’s delve deeper into this topic so that you don’t fall behind the future of web design.",[162,167,177,181,185,196,200,204,208,213],{"__typename":163,"id":164,"title":165,"body":166},"TextSectionRecord","123822373","What is WebGL?","\u003Cp>\u003Cspan style=\"font-weight: 400;\">WebGL could best be described as a JavaScript API for implementing interactive 2D and 3D vector graphics in the browser using the client&rsquo;s graphics processing unit (GPU). It&rsquo;s based on the OpenGL library that has been around since 2002. Some practical examples: the Google Maps 3D function and Unity&rsquo;s game engine. \u003C\u002Fspan>\u003C\u002Fp>",{"__typename":168,"id":169,"image":170,"caption":175,"fullWidth":148,"captionPosition":176},"ImageRecord","123822374",{"url":171,"alt":172,"width":173,"height":174},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1661242318-schermafbeelding-2022-08-23-om-10-11-35.png","Google Maps 3D display of Delft",3426,1748,"Google Maps 3D display of the office of De Voorhoede in Delft","bottom",{"__typename":163,"id":178,"title":179,"body":180},"123822375","How to use WebGL: a step by step guide","\u003Cp>\u003Cspan style=\"font-weight: 400;\">For our client Deltares we added an animation in the project about the Global Water Watch. The goal was not necessarily to help the user, but to make the website more visually appealing. While designing, we wanted to have a graphical or visual element that refers to water.&nbsp;\u003C\u002Fspan>\u003C\u002Fp>\n\u003Cp>\u003Ci>\u003Cspan style=\"font-weight: 400;\">Also read: \u003C\u002Fspan>\u003C\u002Fi>\u003Ca href=\"https:\u002F\u002Fwww.voorhoede.nl\u002Fen\u002Fblog\u002Ffigma-as-a-cms-where-design-and-development-collide\u002F\">\u003Ci>\u003Cspan style=\"font-weight: 400;\">using Figma as a CMS\u003C\u002Fspan>\u003C\u002Fi>\u003C\u002Fa>\u003Ci>\u003Cspan style=\"font-weight: 400;\">. \u003C\u002Fspan>\u003C\u002Fi>\u003C\u002Fp>",{"__typename":163,"id":182,"title":183,"body":184},"123822376","How to start?","\u003Cp>\u003Cspan style=\"font-weight: 400;\">First things first. We constructed a wavy graphic in Adobe Illustrator and saved it as a .svg file. This svg file was imported into the design (a Figma file). That creates a nice overview for how the final design should look.\u003C\u002Fspan>\u003C\u002Fp>",{"__typename":186,"id":187,"mute":148,"loop":148,"autoplay":148,"caption":154,"video":188,"gif":149},"ResponsiveVideoRecord","123822377",{"url":189,"title":190,"height":191,"width":192,"provider":193,"providerUid":194,"thumbnailUrl":195},"https:\u002F\u002Fvimeo.com\u002F707944156","WebGL animation",78,426,"vimeo","707944156","https:\u002F\u002Fi.vimeocdn.com\u002Fvideo\u002F1428669526-d8acc38a02834c7de1461db33f863ef12c47b6acd88412665292bb41c1722039-d_295x166",{"__typename":163,"id":197,"title":198,"body":199},"123822378","6 options for web animation","\u003Cp>\u003Cspan style=\"font-weight: 400;\">In order to make an animation out of an static design, we had multiple options:\u003C\u002Fspan>\u003C\u002Fp>\n\u003Col>\n  \u003Cli>\u003Cspan style=\"font-weight: 400;\">Take the already constructed .svg that was used in the design and animate it using an animation library, like \u003C\u002Fspan>\u003Ca href=\"https:\u002F\u002Fanimejs.com\u002F\" target=\"_blank\" rel=\"noopener\" style=\"font-weight: 400; letter-spacing: 0px;\">\u003Cspan>animeJs.\u003C\u002Fspan>\u003C\u002Fa>\u003C\u002Fli>\n  \u003Cli>\u003Cspan style=\"background-color: transparent; font-family: inherit; font-size: inherit; font-style: inherit; font-variant-ligatures: inherit; font-variant-caps: inherit; letter-spacing: 0px;\">Use HTML elements, like spans and animate it using an animation library like animeJs.\u003C\u002Fspan>\u003C\u002Fli>\n  \u003Cli>\u003Cspan style=\"font-weight: 400;\">Use the native \u003C\u002Fspan>\u003Ca href=\"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FAPI\u002FCanvas_API\" target=\"_blank\" rel=\"noopener\" style=\"font-weight: 400; letter-spacing: 0px;\">\u003Cspan>HTML canvas element\u003C\u002Fspan>\u003C\u002Fa>\u003Cspan style=\"font-weight: 400;\"> to draw the lines and animate it using an animation library like animeJs. \u003C\u002Fspan>\u003C\u002Fli>\n  \u003Cli>\u003Cspan style=\"font-weight: 400;\">Use an abstraction of the native HTML canvas like \u003C\u002Fspan>\u003Ca href=\"https:\u002F\u002Fpixijs.com\u002F\" target=\"_blank\" rel=\"noopener\" style=\"font-weight: 400; letter-spacing: 0px;\">\u003Cspan>PixiJs\u003C\u002Fspan>\u003C\u002Fa>\u003Cspan style=\"font-weight: 400;\"> or \u003C\u002Fspan>\u003Ca href=\"https:\u002F\u002Fp5js.org\u002F\" target=\"_blank\" rel=\"noopener\" style=\"font-weight: 400; letter-spacing: 0px;\">\u003Cspan>p5Js\u003C\u002Fspan>\u003C\u002Fa>\u003Cspan style=\"font-weight: 400;\">.\u003C\u002Fspan>\u003C\u002Fli>\n  \u003Cli>\u003Cspan style=\"font-weight: 400;\">Use a WebGL library like \u003C\u002Fspan>\u003Ca href=\"https:\u002F\u002Fthreejs.org\u002F\" target=\"_blank\" rel=\"noopener\" style=\"font-weight: 400; letter-spacing: 0px;\">\u003Cspan>threeJs\u003C\u002Fspan>\u003C\u002Fa>\u003Cspan style=\"font-weight: 400;\">. \u003C\u002Fspan>\u003C\u002Fli>\n  \u003Cli>\u003Cspan style=\"background-color: transparent; font-family: inherit; font-size: inherit; font-style: inherit; font-variant-ligatures: inherit; font-variant-caps: inherit; letter-spacing: 0px;\">Write our own native WebGL implementation&nbsp;\u003C\u002Fspan>\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>\u003Cspan style=\"font-weight: 400;\">We chose to write our own native WebGL implementation. Why? Using native WebGL wins over native Canvas because we can partly use \u003C\u002Fspan>\u003Ca href=\"https:\u002F\u002Fwww.khronos.org\u002Fopengl\u002Fwiki\u002FOpenGL_Shading_Language\" target=\"_blank\" rel=\"noopener\">\u003Cspan style=\"font-weight: 400;\">GLSL\u003C\u002Fspan>\u003C\u002Fa>\u003Cspan style=\"font-weight: 400;\"> code which is executed on the \u003C\u002Fspan>\u003Ca href=\"https:\u002F\u002Fwww.intel.com\u002Fcontent\u002Fwww\u002Fus\u002Fen\u002Fproducts\u002Fdocs\u002Fprocessors\u002Fwhat-is-a-gpu.html\" target=\"_blank\" rel=\"noopener\">\u003Cspan style=\"font-weight: 400;\">GPU\u003C\u002Fspan>\u003C\u002Fa>\u003Cspan style=\"font-weight: 400;\">. In comparison, all the options above require the CPU to do all the work (including native canvas). As the wavy graphic was fairly simple to build (it&rsquo;s not even 3D, so no complicated calculations needed), we decided to build it in native WebGL. This meant having to write the smallest possible amount of JS, whilst getting the best possible performance when \u003C\u002Fspan>\u003Ca href=\"https:\u002F\u002Fwebglfundamentals.org\u002Fwebgl\u002Flessons\u002Fwebgl-shaders-and-glsl.html\" target=\"_blank\" rel=\"noopener\">\u003Cspan style=\"font-weight: 400;\">using shaders\u003C\u002Fspan>\u003C\u002Fa>\u003Cspan style=\"font-weight: 400;\"> (written in GLSL). \u003C\u002Fspan>\u003C\u002Fp>",{"__typename":163,"id":201,"title":202,"body":203},"123822379","How to bend WebGL to your will","\u003Cp>\u003Cspan style=\"font-weight: 400;\">While making wonderful animations, there could also be some struggles when using WebGL. Here&rsquo;s how to tackle them:\u003C\u002Fspan>\u003C\u002Fp>\n\u003Cul>\n  \u003Cli>\u003Cb style=\"letter-spacing: 0px;\">Drawing lines\u003C\u002Fb>\u003Cspan style=\"font-weight: 400;\"> in WebGL is easy, but not very flexible. Not all browsers allow us to set the width of the line. So instead of lines you could opt for \u003C\u002Fspan>\u003Cb style=\"letter-spacing: 0px;\">rectangles\u003C\u002Fb>\u003Cspan style=\"font-weight: 400;\">. That way you could define the width of each &lsquo;line&rsquo; (1, 2 or whatever size in pixels).\u003C\u002Fspan>\u003C\u002Fli>\n  \u003Cli>\u003Cspan style=\"background-color: transparent; font-family: inherit; font-size: inherit; font-style: inherit; font-variant-ligatures: inherit; font-variant-caps: inherit; letter-spacing: 0px;\">Drawing, let&rsquo;s say, \u003C\u002Fspan>\u003Cb style=\"letter-spacing: 0px;\">100 rectangles requires 100 draw calls\u003C\u002Fb>\u003Cspan style=\"font-weight: 400;\"> in WebGL, which is quite expensive for performance. A better option would be to use a method called \u003C\u002Fspan>\u003Ca href=\"https:\u002F\u002Fwebglfundamentals.org\u002Fwebgl\u002Flessons\u002Fwebgl-instanced-drawing.html\" style=\"font-weight: 400; letter-spacing: 0px;\">\u003Cb>instanced drawing\u003C\u002Fb>\u003C\u002Fa>\u003Cspan style=\"font-weight: 400;\">. This comes down to having one source shape that is copied into different positions. This way we only have \u003C\u002Fspan>\u003Cb style=\"letter-spacing: 0px;\">one draw call\u003C\u002Fb>\u003Cspan style=\"font-weight: 400;\">.\u003C\u002Fspan>\u003C\u002Fli>\n  \u003Cli>Use the GPU to do all the heavy animation computation by using \u003Cb style=\"letter-spacing: 0px;\">shaders\u003C\u002Fb>\u003Cspan style=\"background-color: transparent; font-family: inherit; font-size: inherit; font-style: inherit; font-variant-ligatures: inherit; font-variant-caps: inherit; letter-spacing: 0px;\"> (written in GLSL). Also, try to keep the CPU (JS) calculation at a minimum.\u003C\u002Fspan>\u003C\u002Fli>\n\u003C\u002Ful>",{"__typename":163,"id":205,"title":206,"body":207},"123822380","Our approach","\u003Col>\n  \u003Cli class=\"p1\">We started off by creating a Vue component that renders an amount of rectangles equally distributed horizontally to a canvas element.\u003C\u002Fli>\n  \u003Cli class=\"p1\">Then, we recalculated the amount of instances when the available space changes (resize of browser).\u003C\u002Fli>\n  \u003Cli class=\"p1\">Hereafter, we transformed each instance (scale on the y-axis) continuously to achieve the wave form.\u003C\u002Fli>\n  \u003Cli class=\"p1\">We used the perlin noise (a type of gradient noise used to increase the appearance of realism) to get the random wavy shape.\u003C\u002Fli>\n  \u003Cli class=\"p1\">Finally, there is the vertex shader code. This calculates the position and transformation for each rectangle individually.\u003C\u002Fli>\n\u003C\u002Fol>",{"__typename":209,"id":210,"language":211,"body":212},"CodeBlockRecord","123822381","Javascript","import snoise from '.\u002Fsnoise'\n \nconst vertexShader = `\n  uniform float u_delta;\n  uniform float u_spread;\n \n  attribute vec4 a_vertex;\n  attribute float a_offset;\n \n  ${snoise}\n \n  void main() {\n    float noise = snoise( vec3(-u_delta, u_delta, 1.0) + vec3(a_offset, 0.0, 0.0) );\n    vec4 noise_position = vec4(1.0, noise * u_spread, 1.0, 1.0);\n \n    vec4 offset_position = vec4(a_offset * 2.0, 0.0, 0.0, 1.0);\n \n    gl_Position = (a_vertex + offset_position) * noise_position;\n  }\n`\n \nexport default vertexShader\n",{"__typename":163,"id":214,"title":154,"body":215},"123822382","\u003Cp>\u003Cspan style=\"font-weight: 400;\">Check out the result of our \u003C\u002Fspan>\u003Ca href=\"https:\u002F\u002Fwww.globalwaterwatch.io\u002F\">\u003Cspan style=\"font-weight: 400;\">animation on the website of Global Water Watch\u003C\u002Fspan>\u003C\u002Fa>\u003Cspan style=\"font-weight: 400;\">. \u003C\u002Fspan>\u003C\u002Fp>",[],[],[],1776256149648]