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

    - Kevin Andersen

  • Adding the Toon Shader to the Engine (with Senior Software Engineer Eugene Elkin)

    With the shading model's proof-of-concept prototype complete, it's time to implement that shading model in code. While this is not a difficult task, it can be a bit time-consuming due the number, and varied locations, of small engine changes that are required to add all the proper variables.

    The easiest way to add a new shading model to the engine and editor is to follow the example of an extant shading model. The very first thing you'll want to do is add your new enum entry to the EMaterialShadingModel. You will have to use the search function to follow around some other enum entry to add your new enum to each place it exists. There are about seven or eight places you'll need to do this, to account for everywhere your shading model could be referenced, in-editor or at runtime.

    With the Shading Model enum propagated, you should have all the proper shader defines created as well. It's time to add our shading model's variables. The process here is similar as mentioned above. Add your enum entry to the EMaterialProperty. Once again use another entry from EMaterialProperty to find all the places that need to be edited.

    Once variables and shading model variables are created they need a good home inside the shader code to actually perform some logic. We start off in the FPixelShaderInOut_MainPS of BasePassPixelShader.usf by saving off our shading model's variables to GBuffer.CustomData.

                GBuffer.ShadingModelID = SHADINGMODELID_TOON_LIT;
                GBuffer.CustomData.x = GetMaterialToonLitRoughness(MaterialParameters);
                GBuffer.CustomData.y = GetMaterialToonLitBias(MaterialParameters);

    Once the roughness and bias variables are cached, we can use them to perform the shader calculations specified in the prototype. The toon shading equation is run once in the float4 GetDynamicLighting() and again in float3 SurfaceShading() to affect diffuse and specular respectively.

    After compiling the editor and engine, artists will now have a new shading model to choose, and additional properties to tweak in the material editor. The previously unlit prototype material's logic has been translated into a functioning shading model that can work with any number or kind of dynamic lights! Now the tech-art lead will stop bringing it up all the time when you're on smoke break.


    HAY GUYZ IT'S KEVIN I'M BACK. You know what I'm gonna say so here it goes: it's time we sat down and had a serious discussion about the clouds in "Sprint Vector." They're neat. They've been a hot topic ever since I insisted they were just now. Nearly one person has been asking how they came to be, so here's the full hot story:

    Concept artist Hadi Jalali made a cool hand-painted skydome for the E3 2017 demo, and we knew we couldn't just re-use that for everything, but we also didn't have the time to make unique, high-res, hand-painted skydomes for every map in the game. Part of my job-well most of it, at this point-is lighting all the levels, and that usually includes a lot of material, texture, and effects work as well. One of the highest ROI assets I made in that endeavor were the damn clouds.

    Above, you can see one of the cloud meshes and its vertex colors. I used xNormal to bake the AO and translucency maps, placed them into the red and green channels of a texture, then went back into maya and imported that file as a vertex color set for the mesh. This way, neither texture is ever actually used in game.

    Populating the sky with clouds that sell the game's atmosphere and aesthetic - but didn't kill performance - would require some additional planning and material work. I knew it had to be an extremely cheap material, but it also had to lend itself to myriad lighting conditions while always looking as stylized and colorful as the rest of the game world. All the clouds are the same 3 meshes, each with 3 LODs, rotated and flipped all over the sky in super artsy ways. I mentioned previously that UE4 gives you access to the sunlight's direction and color in your material setup, and that fact was again crucial to getting the cloud material to work in multiple levels with different outdoor lighting:

    As you can see, this material is also unlit and only has an emissive input. The clouds are affected by the sun, but only via AtmosphericLight nodes in the graph here; there is no actual lighting happening. Since the vertex colors contain the AO and thickness of the cloud meshes, I used that information to fake the ambient lighting and also the sunlight shining through them when they are near the sun.

    Translucency was simulated in the material by wrapping the sunlight influence further around the cloud from the angle of the light, attenuating it by both the thickness map (vertex red channel) and how close the cloud is to blocking the sun in the player's view (dot product of camera vector and AtmosphericLightVector). The ambient light around the cloud was a simple color parameter multiplied by the AO (vertex green channel). This material, in concert with the ‘directional in-scattering' feature of exponential height fog, proved fantastically versatile and was used on almost every level with an open sky.


comments powered by Disqus