Get the latest Education e-news
  • Getting The World Of Sprint Vector Over The Finish Line

    - Kevin Andersen

  • Populating A Cartoon World

    The characters needed more detail to give them real personality, so their design simply could not be flat-color and sharp edges like the rest of the game world. They were all made by one mister Damon Woods in the traditional Maya/ Zbrush/Photoshop workflow, and they all had the full complement of texture maps.

    Unreal's default lighting model, however, was just not equipped to make them look like anything but plastic, wood, or metal. Also, since the game is forward-rendered (for that sweet sweet MSAA), a subsurface-scattering material was also not an option, even if we wanted one. But we totally didn't. So there.

    In the above comparison, the Cosmo on the right looks like an action figure. In still-renders that's not bad, but when it moves around in VR it looks creepy as hell. At this point, a majority of the important effects had already been made, and were all purely cartoony. They looked great in our simplified environments with their hand-painted skydomes, and they really sold the overall aesthetic. Those plastic characters, however, clashed with the effects in a way that made it look like they both came from two different downloadable asset-packs and we just slapped them together in the same game. We needed these characters to render less like haunted mannequins and more like comic book illustrations, using a stylized lighting mode that did their design and modelling justice. There is no cel-shaded lighting model in Unreal 4, so we had to make one. It was time to prototype.

    You'll notice that the above material graph is unlit and only has an emissive input. That's because this is not yet a real shading model; it only provides an example of what the result would be if this logic were used to light a surface from a single light source. A stepped, off/on lighting model would cause obvious aliasing that would not be solved with MSAA and would also get worse as the lights got brighter. Instead, I aimed to crunch the basic lambertian falloff down to a thin gradient between larger areas of fully-lit and fully-dark, without ever making the transition pixel-sharp.

    To do this, I simply remapped the dot product of light vector and surface normal (lambert lighting model) from -1:1 to -n:n (where n = the bias of the lit and unlit areas toward each other), and then clamped the result back to 0:1, which would then be multiplied by the product of base color and light color for the final result for that light. The rim highlight was a simple fresnel that scaled up the direct lighting contribution as it approached an edge, then crushed the resulting gradient in the same manner to match the style. An additional ambient rim light was later added as a material function to some materials as well.

    Getting this logic into an actual lighting model, i.e. usable with any number and kind of lights, requires making significant changes to the rendering code. I'm not an engineer, or even a first-try high school graduate, but I've used Unreal long enough to remember when UE3 (UDK) had a custom-lighting input in its material editor that allowed you to construct your own lighting model purely from your own node-logic. UE4 doesn't give you access to any of that anymore, but you can access two specific lighting contributions: the atmospheric sun light's direction and its color.

    With those as representatives of any given light, I constructed the pictured material graph to develop the look of a hypothetical cel-shaded lighting model before handing it off to our rendering engineer, Eugene Elkin, to do all the actual work-work. Eugene will take over the next section, to provide his own insight into the rest of this process, since I'm not a programmer and you know I'd just be making things up like I have been for five paragraphs now.


comments powered by Disqus