{"id":86367,"date":"2019-03-04T19:41:00","date_gmt":"2019-03-04T19:41:00","guid":{"rendered":"http:\/\/www.gamasutra.com\/view\/news\/337927"},"modified":"2019-03-04T19:41:00","modified_gmt":"2019-03-04T19:41:00","slug":"dont-miss-rendering-the-player-as-a-form-of-pure-energy-in-recompile","status":"publish","type":"post","link":"https:\/\/sickgaming.net\/blog\/2019\/03\/04\/dont-miss-rendering-the-player-as-a-form-of-pure-energy-in-recompile\/","title":{"rendered":"Don&#8217;t Miss: Rendering the player as a form of pure energy in Recompile"},"content":{"rendered":"<p><strong><i><small> The following blog post, unless otherwise noted, was written by a member of Gamasutra\u0092s community.<br \/>The thoughts and opinions expressed are those of the writer and not Gamasutra or its parent company. <\/small><\/i><\/strong> <\/p>\n<hr \/>\n<p>Hi, I&#8217;m <a href=\"https:\/\/twitter.com\/phi6\" target=\"_blank\">Phi Dinh<\/a>, owner of Phigames and creator\/coder\/designer\u00a0of our upcoming atmospheric exploration platformer and environmental hacking game <em>Recompile<\/em>. I work closely with animator\/VFX artist\u00a0<a href=\"https:\/\/twitter.com\/Skepsisology\" target=\"_blank\">James Vincent Marshall<\/a> and together we have worked on this game for nearly 2 years.\u00a0In this post, I will be explaining and exploring the processes we used to generate the visuals for our protagonist, known to our players as The Program.<\/p>\n<p><a href=\"https:\/\/i.imgur.com\/oTMoFsr.png\" target=\"_blank\"><img decoding=\"async\" alt=\"\" src=\"http:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2019\/03\/dont-miss-rendering-the-player-as-a-form-of-pure-energy-in-recompile.png\" \/><\/a><\/p>\n<p>I have a background in Computer Science, and have worked for various technology companies including real estate, gambling and digital advertising. My real passion however, lies in games, so in 2013 I decided to take control over\u00a0my career and form my own game development studio, Phigames. My first commercial title was <a href=\"http:\/\/tinykeep.com\/\" target=\"_blank\">TinyKeep<\/a>, a hardcore dungeon surviving romp for the most masochists of gamers. The game had\u00a0a successful <a href=\"https:\/\/www.kickstarter.com\/projects\/phidinh\/tinykeep\" target=\"_blank\">Kickstarter<\/a> campaign, and I was able to quit my job and move to the North of England. The\u00a0cheaper accommodation and idyllic countryside vistas allowed my creative and technical juices to truly thrive.<\/p>\n<p>Recompile&#8217;s humanoid protagonist is rendered as a form of pure energy, using instanced cube meshes with a custom shader.<\/p>\n<p><img decoding=\"async\" alt=\"\" src=\"http:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2019\/03\/dont-miss-rendering-the-player-as-a-form-of-pure-energy-in-recompile.gif\" \/><\/p>\n<p>It works by drawing hundreds of cubes every frame, at positions where the player\u00a0mesh colliders intersect with a\u00a0quantized world-space grid.<\/p>\n<p><img decoding=\"async\" alt=\"\" src=\"http:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2019\/03\/dont-miss-rendering-the-player-as-a-form-of-pure-energy-in-recompile-1.gif\" \/><\/p>\n<p>This process can be broken down into the following steps. (Note: The terminlogy\u00a0and API references are Unity specific).<\/p>\n<p>1. Work out which positions in the world-space grid are enclosed within the mesh collider.<br \/>&#013;<br \/>\n2. Create an array of Matrix translations from these positions.<br \/>&#013;<br \/>\n3. Pass this array into a <a href=\"https:\/\/docs.unity3d.com\/ScriptReference\/Graphics.DrawMeshInstanced.html\" target=\"_blank\">Graphics.DrawMeshInstanced<\/a> call, on every Update loop.<\/p>\n<p>There is a major performance gotcha with #1, it is very expensive to calculate whether a position in world-space actually lies within a specific convex collider hull. We can get around this computation step by baking in a number of local positions\u00a0that we know are definitely inside the collider. This is easily done\u00a0by using <a href=\"https:\/\/docs.unity3d.com\/ScriptReference\/Physics.OverlapSphere.html\" target=\"_blank\">OverlapSphere<\/a>\u00a0with a very small radius over a sample set of test points. Whilst this is an\u00a0expensive operation, is doesn&#8217;t matter as\u00a0we are offloading it to be baked during\u00a0Editor time. When the game is running, all we have to do is transform these predefined positions and compare them to our quantized grid\u00a0at runtime.<\/p>\n<p><img decoding=\"async\" alt=\"\" src=\"http:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2019\/03\/dont-miss-rendering-the-player-as-a-form-of-pure-energy-in-recompile-2.gif\" \/><\/p>\n<p>The cubes themselves never actually move, but instead slip in and out of existence as the collider intersects with the cells from the quantized grid. We also animate the cube scaling\u00a0as they appear and disappear, giving the impression of smooth movement at a distance.<\/p>\n<p><img decoding=\"async\" alt=\"\" src=\"http:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2019\/03\/dont-miss-rendering-the-player-as-a-form-of-pure-energy-in-recompile-3.gif\" \/><\/p>\n<p>Even when the colliders rotate, the cubes always remain axis-aligned and fixed to the quantized grid, resulting in a distinctive\u00a0voxel-style look.<\/p>\n<p><img decoding=\"async\" alt=\"\" src=\"http:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2019\/03\/dont-miss-rendering-the-player-as-a-form-of-pure-energy-in-recompile-4.gif\" \/><\/p>\n<p>The resolution of the quantized grid can even be modified in real time, so we can change the character detail based on any number of gameplay parameters.<\/p>\n<p><img decoding=\"async\" alt=\"\" src=\"http:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2019\/03\/dont-miss-rendering-the-player-as-a-form-of-pure-energy-in-recompile-5.gif\" \/><\/p>\n<p>This is a quick test of the player run animation\u00a0at a medium grid resolution.<\/p>\n<p><img decoding=\"async\" alt=\"\" src=\"http:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2019\/03\/dont-miss-rendering-the-player-as-a-form-of-pure-energy-in-recompile-6.gif\" \/><\/p>\n<p>We can also pass an array of Colors to a <a href=\"https:\/\/docs.unity3d.com\/ScriptReference\/MaterialPropertyBlock.html\" target=\"_blank\">MaterialPropertyBlock<\/a> for the <a href=\"https:\/\/docs.unity3d.com\/ScriptReference\/Graphics.DrawMeshInstanced.html\" target=\"_blank\">Graphics.DrawMeshInstanced<\/a> call, they will be handled by the shader to tint the cubes on a per-instance basis. Handy for creating scanline effects, and for changing the color of the player based on gameplay factors such as health, level, damage etc.<\/p>\n<p>Finally, additional VFX and lighting are added to bring the player visuals to the next level of polish.<\/p>\n<p><strong>Why<\/strong><\/p>\n<p>The story of Recompile is set in a purely digital virtual world located inside a mysterious supercomputer complex. The art style for both the environment and the world&#8217;s inhabitants are largely geometric and low-poly, however for the player character we wanted something a little different. We needed to emphasize a more organic, fuzzy nature to reflect that this is an external entity created by humans &#8211; but still retain a glitchy, code-like feel.<\/p>\n<p><img decoding=\"async\" alt=\"\" src=\"http:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2019\/03\/dont-miss-rendering-the-player-as-a-form-of-pure-energy-in-recompile-7.gif\" \/><\/p>\n<p>For an early prototype we used a cube shaped character, complete with jelly-like\u00a0animations. Eventually we wanted to get away from this in favour of a humanoid model, as we felt this kind of abstract cube character\u00a0was starting to become somewhat of an indie game trope.<\/p>\n<p><img decoding=\"async\" alt=\"\" src=\"http:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2019\/03\/dont-miss-rendering-the-player-as-a-form-of-pure-energy-in-recompile-8.gif\" \/><\/p>\n<p>Instead of opting for a traditionally modelled, rigged and textured character design which we felt would be in danger of looking like other similar games, we went with the idea that the player was created from pure, volatile energy. Our artist has a background in animation &amp; VFX, so in order to play to our strengths we\u00a0emphasized\u00a0pure motion over art fidelity.<\/p>\n<p><a href=\"https:\/\/i.imgur.com\/uC9qRv7.png\" target=\"_blank\"><img decoding=\"async\" alt=\"\" src=\"http:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2019\/03\/dont-miss-rendering-the-player-as-a-form-of-pure-energy-in-recompile-1.png\" \/><\/a><\/p>\n<p>We also needed a contrasting color scheme, so that the character would stand out from the dark surroundings, and to create an iconic look that would become instantly recognizable in screenshots and social media.<\/p>\n<p><img decoding=\"async\" alt=\"\" src=\"http:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2019\/03\/dont-miss-rendering-the-player-as-a-form-of-pure-energy-in-recompile-9.gif\" \/><\/p>\n<p>We also needed the ability for our character to be very dynamic in its rendering, based on gameplay parameters such as health and progression. Being able to change resolution at any time, and morph into different shapes and colors was especially useful in providing vital feedback to the player.<\/p>\n<p>Finally, it was important to us that the player character remains gender ambiguous. A step further from the traditional silent protagonist of videogames, our solution emphasizes player action over identity. We want to tell the story about what the player does, not what they are.<\/p>\n<p>On the surface I feel we nailed the final aesthetic, it&#8217;s something unique that&#8217;s rarely seen in games before. It also <em>appears <\/em>technically innovative and impressive (even though it&#8217;s actually quite simple from an implementation standpoint) and the character&#8217;s design perfectly matches the lore and story of the game.<\/p>\n<p>Under the hood, we definitely ran into some performance issues. Our implementation uses instanced meshes drawn every frame, and whilst much more optimal than incurring GameObject overheads, it&#8217;s\u00a0still not 100% perfect.<\/p>\n<p>We are currently prototyping a new system that uses GPU\/Compute Shaders, which will potentially allow us to increase our cube count from what we have to something in the order of millions. However, there may be some problems getting this to work well with other platforms such as MacOSX and consoles. Much more research to be done on this on our part, but exciting times ahead!<\/p>\n<p><em>Recompile <\/em>is currently being developed by <strong>Phigames<\/strong>.<\/p>\n<p>Our core team consists of 3 multi-disciplined\u00a0individuals :-<\/p>\n<p><strong><a href=\"https:\/\/twitter.com\/phi6\" target=\"_blank\">Phi Dinh<\/a>, Creator\/Coder\/Designer<\/strong><\/p>\n<p><strong><a href=\"https:\/\/twitter.com\/Skepsisology\" target=\"_blank\">James Vincent Marshall<\/a>, Animator\/VFX Artist\/Art Director<\/strong><\/p>\n<p><strong><a href=\"https:\/\/twitter.com\/rbevansaudio\" target=\"_blank\">Richard Evans<\/a>, Sound Design &amp; Music<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The following blog post, unless otherwise noted, was written by a member of Gamasutra\u0092s community.The thoughts and opinions expressed are those of the writer and not Gamasutra or its parent company. Hi, I&#8217;m Phi Dinh, owner of Phigames and creator\/coder\/designer\u00a0of our upcoming atmospheric exploration platformer and environmental hacking game Recompile. I work closely with animator\/VFX [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":86368,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20],"tags":[],"class_list":["post-86367","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-news"],"_links":{"self":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts\/86367","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/comments?post=86367"}],"version-history":[{"count":0,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts\/86367\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/media\/86368"}],"wp:attachment":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/media?parent=86367"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/categories?post=86367"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/tags?post=86367"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}