December 25, 2018

UE4 - Biasing Material Function

For one of my products, I needed a function that biased a gradient ramp toward a specified value without washing out the entire range. I came up with a solution that works like this:

  • Insert gradient ramp, bias setting, and influence control.
  • Gradient midpoint figured from bias setting.
  • Power node controls gradient midpoint and pinches/expands gradient around bias setting

This expression is purely linear, but does a fantastic job biasing values with controlled influence and without losing range.



The scale on the left shows how different values affect the gradient ramp. While the pixels at the left and right remain black and white, the middle value (set to 0.2 in this example) remains the same, but its influence increases from -1:, with -1 resulting in a sharp black/white cut, -1:0 resulting in a pinched gradient, 0 at neutral (bypass), and anything >0 spreading the gradient further.

The bump for this biasing technique is 11 pixel shading instructions.

This has a lot of practical applications from processing or blending colors and textures in materials to more useful technical purposes biasing values. I'm using this to bias values from random number/seed generators to favor one part of the spectrum over another without losing the full range.

The power node/Influence variable is a bit weird to use, as the negative range is particularly aggressive while the positive range progresses slowly and continues forever. It can be more helpful to square the Influence setting for positive values, but squares do not result in negative values at all.

December 1, 2018

Blender Useful Shortcuts


Blender is a fantastic 3D modeling program, AND it's free! However, one of my biggest gripes with it is how insanely important functions are not always visible in the UI: you just need to hear the command shortcut from someone else to figure it out. I've listed below some of the less obvious, yet by far my favorite and most useful shortcuts in Blender:

General:


T - Toggle Toolbox (left pane)
N - Toggle Smaller Properties Panel (right pane)

Numpad 5 - Toggle Perspective/Orthographic camera
Numpad 7 - Top
Numpad 1 - Side
Numpad 3 - Front
Numpad 9 - Flip Side

Shift + Tab - Toggle Grid Snapping (grid settings in Properties panel under Display)

Edit Mode:


L - Select component - Even when objects are joined, selects independent pieces. When selecting edges, this command selects UV islands.
A - Select entire object
Shift + Alt + Select edge - Selects edge loop
Shift + Ctrl + Select two edges/verts - Selects all edges/verts between two points

F - Make face - Select two edges, press F, face will be made, joining selection)
K - Knife tool - Draw splits in polygons

Shift + D - Duplicate selected

Object Mode


Shift + D - Duplicate selected objects
Ctrl + J - Join two components together

UV Editor:


W - Align commands - Use to straighten and align UVs. Auto align works great!
Q - UV Sculpt - Enters UV Sculpting mode to let you sculpt and relax UVs
  • Click and paint - Moves and sculpts UVs
  • Shift - Relaxes UVs
  • Shift (toggle border in left-hand options) - Relaxes UVs without pinning border. Important for getting square UVs from non-square objects.

Tips:

  • To add material slot, click the + button located in the top right hand corner of the material panel (4 icons from the right in the larger properties panel). To assign a material, select all faces, in edit mode, select your material from the slot, then click Assign.
  • To prep an object for UE4 normals, make sure to export edge normals and use one of the following prep options:
    • In Object Data (chain link icon), select Auto Smooth. Set the angle to something that makes sense. This is good for simple meshes where the sharp edges are obvious.
    • In Modifiers, select Edge Split. This will give you options for using sharp edge selections in edit mode as well as a separate edge angle.
  • The best viewport rendering mode to work in is Material. This allows you to see the definition of materials on the object and textures while still being able to edit and work.

February 25, 2018

Manatee Quiz Game - Post Mortem!



The untitled "Manatee Quiz Game" for Mote Marine Laboratories is a 10-question quiz game set in 4 stages of rising difficulty. The questions and answers are randomized, and there are 3 lifelines: 50/50, Ask a Manatee, and Change the Question. The game is played in front of a 65" TV at a full 4K resolution at 60 frames per second in 10-bit HDR. A bit overkill for a quiz game? Good! That sure makes things interesting! Let's dive into this journey together...

I previously had one of Mote's scientists (Dr. Hall) as an instructor in Ringling College. My first official project with Mote was 2115. What started off as a class project eventually made its way to an exhibit on permanent display in the aquarium. I learned so much from that project. The quiz project started off from an e-mail I received from a man named Evan B. (Assistant VP of Mote) that appeared in my junk folder. He loved the 2115 project so much, he wanted me to make another game. I check my junk folder every day now.

The original 2115 video, made in UDK at Ringling College of Art and Design (2012)

Mote wanted a game with manatees as part of their exhibit. A couple ideas we bounced included a manatee-counting game (similar to aerial surveys taken by field researchers), and a quiz game. I was able to make a working prototype of a quiz game that shuffled the questions and answers from a bank at random in just 2 hours using UE4's Blueprints and UMG on a mobile device. I've played quiz games at museums before: they're usually about as fun as a job training quiz. However, the information can be very interesting, and there is potential there with a more dramatic approach. Mote knew full well how dramatic I was: I worked with my friend Meng Wang and his roommate Pat Vadanathorn on 2115, a short "video of a game" to teach others about Ocean Acidification. That video was inspired by Metroid Prime: set 100 years in the future in an underwater seascape, you are armed with a scanner to find information about objects in the world. Not a very traditional concept, but one that definitely appealed to judges and Mote staff to make a reality!

So, I didn't want this quiz to be traditional, either! I was a huge fan of Who Wants To Be A Millionaire growing up. I found a lot of strength in the classic answer questions, few lifelines, hard loss, no-gimmicks, no-nonsense kind of gameplay. But that still wasn't enough. A couple weeks of sitting on a project that seemed to be going nowhere, it happened in an instant, and something clicked: why not follow a manatee on a migration? I didn't quite have a word for the concept until I explained it to Evan and he immediately responded "Oh, it's like a journey!" The best publishers are the ones who know exactly what you want even before you do and are totally OK with it!



With the journey in place, the game had real motivation. You want to see what lies ahead and get to the end. 10 questions, 4 sections of difficulty. To attract guests initially the game runs a track mode cinematic showing off the different environments (a deep shelf, a jellyfish basin, a canal, and a mangrove forest). I made sure to show angles not usually seen in the game for the cinematic track mode and marketing materials to keep the gameplay experience unique.



Once we latched onto the journey concept I knew the sound I wanted to go for: a prominent piano with staccato strings and some orchestral backing (composed in MuLab 7 with Miroslav Philharmonik). I listened to Finding Nemo's sweeping orchestra (mainly Nemo Egg) and Who Wants to be a Millionaire's themes and progression for inspiration, but I didn't want the orchestra to sit in the background. The Game Over theme was the first one created: an upbeat melody played with somber notes and tempo.



Eventually I was able to figure out the Easy Questions theme, a much more active arpeggio, which became the base for all the other question themes. The violins play slowest on the easy questions and speed up as the quiz progresses, naturally making players feel more excited as the quiz progresses. The harp actually slows down by 1/3 for the middle questions, meeting the strings in the middle, the peak of "anxiety" in the quiz where losing becomes a definite possibility. It was easy to simply speed up the arpeggio for the hard questions. The electronic sweep was inspired by the sound of a car passing over a metal-grated drawbridge. The final question just needed to be the polar opposite: a very calm loop. The songs were made so they can interweave together during the quiz. Funnily enough, this may not have been necessary as the scene changes with the music.



Gameplay-wise I wanted this game to be challenging and rewarding. Playtesting proved quite successful as everyone from gamedev groups to co-workers enjoyed guessing the questions and moving forward in the quiz. The graphics were universally praised. The one negative I sometimes hear was with regards to the harshness of the Game Over and starting back at the beginning. Well, even before I had all the mechanics figured out, I knew I wanted that Game Over! There should be a sense of satisfaction and accomplishment for completing a difficult task, but that sense diminishes when the task is too easy. Of course this quiz can be beaten by anyone, given enough time to memorize the questions and get a more favorable question selection. I stick to my guns: there must be a lose state. I know not everyone will be able to make it to the end, and not everyone will love the Game Over, but I do believe they will love the game. That matters to me so much more than just the moment.

The most important feature was the wrong guess forgiveness: you can guess a 4-answer question incorrectly, find out it was wrong, and guess again. This game is filled with hope spots: spots with risky high stakes where you know you can fail, but you still have the confidence to progress and succeed. A straight game places a lot of pressure on just playing the game, which removes confidence, fun, and ultimately progress. The ability to fail and continue progressing keeps the game moving and adds a second tier between the fail and success state: a "caution" state, where the old "progress" state used to lie. This tiered dynamic means the player plays through the game alternating not between success and failure, but between success and caution, adding a layer of depth that was previously absent.





Visually I like my worlds to be vibrant, lively, and fun in the mundane. But it's never a lie. When I was a child, I went fishing on a boat in the inter-coastal waterways of Venice, FL and swimming/walking along beaches all over Sarasota County. A real underwater scene doesn't look so grandiose, but this is how I imagine Florida's gulf and inter-coastal waters would like to present themselves if they had a choice. I once had an experience at the beach where I was caught off-guard by a barely-visible oddly-shaped plastic bag in the water. It took me a second to realize I wasn't face-to-face with a sandwich bag!

Graphically, I wanted to shoot for the moon: 4K, 60f, HDR. The best possible specs available right now. And it wasn't easy: even with a GTX 1070, I had to optimize every shader I worked on to get the best results without killing the pixel budget. This can be seen nowhere better than the sand: since UE4's landscape is already tessellated, I bumped it up closer to the camera using custom code and quickly fade it out in the distance. That's real geometry for every bump of sand. In 4K, the rendering cost of pixel shading is 4x that of 1080p, so if an effect could be achieved through geometry, that would always be significantly preferred over pixel shaders... so I blew the vertex budget to get that sand and was gimped the rest of the project! That turned out to be well worth the hassle as I didn't need so many polygons in the distance anyways.



The grass movement used a new method I came up with called "Temporal Circular Displacement." Using sine/cosine waves to generate a circular motion and textures to offset that displacement, I can create the illusion of water currents ruffling sea grass around. Similar effects in math alone would've required significantly more vertex instructions. There is parallax occlusion on the concrete pillars, subsurface scattering on the sponges, and even a normal-based semi-metallic iridescent effect on all the fish, which wave their tails through standard parallax mapping. There is volumetric scattering in the water, actual refraction and translucency for the surface, and the whole world is lit by caustics. Not only are the caustics displaced by a panning normal map, but they also blur and darken towards the bottom of  the ocean floor, simulating light scattering. While I made many optimizations in all these techniques (single texture displaced by normal map, blurring achieved via mip-biasing), this light is still far more complex than a solid directional term, bumping up the complexity of every single thing in the world. Between the volumetric fog, tesselation, refractive translucent surface, quality shaders, and caustics lighting, it is a miracle this project runs so effortlessly.

Optimizations were strong, but not fierce. Lower scalability settings were used for effects and shadows (High, not Epic). Instead of TXAA, I used FXAA and motion blur. Surprisingly, this did not look bad at all. Everything past the fog quickly drops LOD and culls out, especially the landscape. I had to decimate the heck out of my Mangrove roots: originally modeled with 60 thousand polygons, they never appear more than 8k in the game, and quickly get reduced to 2k. The water surface above is a grid mesh that calculates fog per-vertex. The concrete pillars have only 32 faces on a straight cylinder. There are no SSRs, just a few reflection probes, and culling is very aggressive. The fish are GPU sprites (and very convincing!). In probably one of my less inspired moves, I even took out cascaded shadow maps for the grass and relied entirely on screen-space shadowing. Just in an effort to maintain a solid 4K at 60f in HDR... with V-sync on. When your project is taking up a giant 65" TV in 4K, small issues with frame tearing or blurry resolutions become magnified many times over. This game might not be the most artistically complex masterpiece ever (most objects are very simple), but boy does it look good!



Overall, this Manatee Quiz game was the best professional project I've ever worked on. I had complete control: nothing appears in the game that I didn't make myself, and the final product ended up better than I have imagined it. It didn't start off as such a grand idea, but grew its ambition over time. It's a lot easier to dress up a simple idea than to decimate a complex one (KISS!). Nothing but good choices were made throughout, and I learned so much working on it. The game can be played today at Mote Marine Laboratories and Aquarium in the manatee exhibit!



PS - If you're up for it, there is a secret play mode hidden in this game. At any time during the quiz, hit the lifeline buttons left - center - right - center - left - right - left. Good Luck!...

January 3, 2017

The Best Grass Ever: Circular Temporal Displacement

Rendering grass by itself is fairly easy: texture, mesh, masked material, grass tool, done. Unfortunately more complex features like vertex displacement on grass cards can get very expensive and unwieldy if you don't have a solid plan to tackle the motion and normals. Some novices may be tempted to use the included Simple Grass Wind function in the engine, but the motion from Simple Grass Wind is very repetitive, unnatural, and faltering. Also, the node does not include proper normal output. I have spent years trying to find a good solution for grass, and through texture-based vertex displacement I believe I have found it.



I call this technique Circular Temporal Displacement. Grass movement is based off of a circular motion though the use of sine and cosine waves. These waves are displaced by a panning texture not affecting the vertex displacement directly, but by bending the inputs to the sine waves generating the circular motion. That motion feeds the grass normals and vertex displacement. This technique involves a combination of world-aligned panning grayscale texture maps, time, sine and cosine (circular) waves, and UV distortion to provide the movement. The colors of the grass can be enhanced through fresnel shading and hue-shifting textures per instance. The quality and performance of this grass is remarkable, with large landscapes receiving plenty of 3D grass coverage with fully featured normals, lighting, UV splines, and vertex displacement (allowing for correct full scene shadows) for not even 1ms difference, mostly from pixel overdraw of translucency. The technique is incredibly well optimized for mid-spec PC and can be scaled to greater heights.

Benefits of this technique:
  • Beautiful swirling motion with real vertex displacement
  • Smooth spline-like waving along plane
  • Relatively easy setup
  • Beautiful normals facing the top of the blade
  • Normals from vertex displacement (retrieved for free with little hassle)
  • Great artistic control (from the motion texture to parameters)
  • Parameters can match stiff, dry grass in a field or flowing underwater grass
Limitations:
  • Vertex movement is locked to a simplified rotate around the Z axis in world space: no vertical displacement, and can be odd for grass planes placed at an angle
  • Normals are not physically accurate



The reason I do not use a texture to directly control the position of the grass is because textures have an immediate "lock" on their position which results in stiff motion. The results never seem to look natural with textures. It was much easier to control the grass by creating a generic circular motion that always runs and then changing the temporal distance along that motion. It gave me the constant natural smooth motion I was looking for with the added benefit of complex wind behavior.

This perfectly uniform vertex motion is then combined with vertex normals from the grass card (facing directly up from the base of the mesh). I was looking for beautiful grass and achieves good performance in 4K. The movement is very inexpensive.

While the quickest and easiest way to mask from base to height is through the use of a single masked channel of a texture coordinate, there is a higher per-pixel cost in using this method as opposed to taking advantage of the vertex color. Since a basic grass card only has 4 vertices, the vertex method is extremely simple and easy to setup and very cheap as well. To make the effect more interesting, try different patterns on the panning grayscale motion texture, or blending two textures at once.

It is highly recommended for grass cards to use contact shadows (from the directional light) and screen space ambient occlusion (from post process) to get the best looking results. One thing I know for sure, this grass looks stunning in motion.

December 18, 2016

UE4 - Quick Tips, Tricks, and Optimizations

I have been learning a lot about Unreal Engine over the past few years. My training in the engine officially began in the fall of 2012, and since that time I have spent all of my efforts in learning all I can about the new engine and how it works. Whether you're a seasoned veteran or just getting started, there are plenty of tricks that you can use to help improve your material building:

General Material Building
  • UE4 has a lighting, reflection, and shadow environment built-in. Using the standard system will always give you the best results. Purely custom code will not blend as well in the environment and won't be as optimized.
  • Reuse code often: even if you have a cheaper method to calculate something, when you reuse branches of code for other purposes in the shader, the result is cached and duplicated. When you use cheaper methods, you recalculate what is already done.
    • If you can reuse code for vertex displacement in the normals, you can save a LOT of instructions for very complex materials!
  • Use textures instead of procedural methods. While this may sound like a bad idea, textures use a simple array lookup while procedural methods require tons of calculations. Textures are also very complex and artist-driven, so it is much better and easier to use a large 2k texture for wind displacement than some complex procedural code.
    • Keep in mind transforms only work in world position offset, not tessellation. Limit your tessellation usage to only what's necessary.
  • For objects with high vertex instruction cost, limit the vertex count as much as possible. Vertex shading is multiplied per-vertex. Grass meshes only need 4 vertices. Water planes, unless you need translucent fog, only need 4 as well. When translucent vertex fog is necessary, try to keep the vertex count under 4,000.
  • Power of 0.5 and 2 are cheaper than a power of 3 or 4, those are cheaper than powers of 5, and that is cheaper than powers of 5.75. This is due to the Power node using different methods to compress exponents: inverse square and square compress as if you multiplied with or without one-minusing the result, and is much cheaper than anything else. Multiples of that (4, 8, 16, etc.) are cheaper than that. Exponents that are a whole number calculate using the Exponent expression in HLSL. Decimals require the Power expression, and are the least efficient. But all this can be done simply using the Power node without the need for multiplying by itself.
  • Don't just slap a texture, normals, and roughness on an object and call it done! Overlay two textures on top of each other and get some more variation out of it! These layered texturing techniques were pioneered in Banjo Kazooie and Ocarina of Time. They are minimally difficult to render, and the end result is well worth the effort.
  • Frenel shading in a PBR environment is welcome! Custom reflections, however, are not. Use reflection captures and stationary skylights for areas that need a reflection. If you must use a custom reflection, the object may not match the physical environment it's placed in.
Translucency
  • Translucent rendering is cheapest when unlit. However, you lose the benefit of shadowing and local lighting. Non-directional per-vertex (on lower polycounts) is the second cheapest. Per-vertex directional is third cheapest. Unless you need localized reflections on translucency, those lighting models can save you a hundred or more instructions over Surface Translucency Volume and Forward Shading models.
  • All forms of translucent rendering don't feature GGX specular rendering. You can bring it back by adding a light vector blueprint in your level and using the engine's HLSL code for GGX specularity.

    Custom Node:

    float a = Roughness * Roughness;
    float a2 = a * a;
    float d = ( NoH * a2 - NoH ) * NoH + 1;
    return a2 / ( PI*d*d );
  • Traditionally, translucency does not fare well for cheap depth of field methods like Gaussian blur. Seperate translucency is unaffected by DoF, and disabling separate translucency is always affected by Dof, there is no in-between. However, you can fade out the translucent object as it recedes into the distance, and you can use MipValueMode > MipBias to blur a textured translucent surface into the distance. The cheapest and easiest way is to use the pixel depth to increase the bias and blur into the distance. Use a power of 0.5 to get the blending just right. Keep in mind, this is all done with "Seperate translucency" enabled so your translucent material stays nice and crisp up front, but blurrier in the back.
Lighting
  • Use a skylight! Skylights account for all light not directly hit by the sun. This is what allows your environment to be lit all around.
  • To save on the cost of rendering dynamic GI in an outdoor environment, use a skylight and change the bottom color to a greenish hue. This will emulate the bounce light provided by green grass. The results are not perfect, but very similar. You can change the color to whatever you want, and the result is easy to render and looks pleasing.
  • Keep your use of dynamic lights to a minimum. While the engine was designed to handle multiple lights overlapping each other, the pixel cost spikes in areas where lights overlap. If you do have overlapping lights and are using the precomputed lightmass process for GI, do not exceed 4 lights overlapping at once. Otherwise, lightmass will need to bake more than 4 channels for light GI to be rendered. The fewer stationary overlap the better, but if you need more, switch to dynamic and use soft static lights for indirect lighting.
Particles
  • Small particles like sparks are best handled by the GPU. They can collide cheaply and spawn in the millions. Large particles like dust clouds are best handled by the CPU. You get the power of particle cutouts and subimage UVs to limit overdraw while providing variation. Unless you have more than 1000 CPU particles onscreen at once, you do not need to worry too much.
  • Very small particles can get cut out with various AA methods. TXAA is the most aggressive. Switch to FXAA if you need small particles, or increase your particle size.
Landscape
  • Draw calls are cheap nowadays. Maximize efficiency by making more component sizes at fewer quads per section. This allows unused components to be culled out.
  • In some cases, tessellation is preferable to parallax occlusion. For exceptionally steep, not-too-sharp detail and low-vertex environments, tessellation is already implemented on Landscape, so you can handle triangle explosion without killing the card. But for crisp, sharp detail that doesn't need to be tessellated, POM is much better.

October 15, 2016

Jake Progress




Jake is my personal pet project. I use this project to learn new techniques, and I've made some good progress over time. I first started working on the project with the 4.6 build of UE4, and I've continued to update it ever since. Somewhere around version 4.10 I decided to completely scrap the old project and start all over. I didn't like the direction of the original, which had very small islands, portals, and very little space to work with. Now, it has taken a life of its own.

I'll get into the details of the character Jake and the rest of the gameplay later. For now, you can just enjoy this gorgeous WIP shot of the windmill section in this game.

And now the technical details: The grass and flowers are procedurally generated using UE4's grass tool, developed for the Kite Demo. It uses the landscape's surface information to position the grass. Unfortunately, the flowers and grass must be combined together, so you cannot have multiple different kinds of grass layers with different flowers.

The grass and flowers blow in the wind based off of some combined normal maps that pan over the surface (via world position mapping). Normal maps contain information in a -1:1 range. The normal maps are then converted from local space to world space to determine the actual normals and positioning of the meshes. This saves a lot of shader instructions because we use textures instead of expensive procedural methods or vertex normal tangents to determine the normals and positioning, and the same code feeds both. It's relatively easy to set up, too. However, this method is not to be confused with tessellation as tessellation does not support local space transforms. The object vertices are the only ones needed for the animation.

The rope fence is one of my favorite personal touches and details in this project. The project looked very barren without some environmental aspect to it, but I needed something non-invasive to really blend in with the landscape. Then I recalled Super Mario Sunshine's elastic ropes. My ropes do sway in the breeze with vertex animation, again using local transform to swing the ropes from side to side. The post itself is a custom Blueprint where I can select the next post in sequence and the rope is spawned automatically. Using look at rotation, I can spawn the ropes with the right rotation and scale them to the right length. A squareish shape for the rope actually aids in the gameplay (flat top side is obviously up) and also in the vertex count. A single rope only has 160 vertices.

The windmills themselves have the Perfect Tile System assets applied, and they also have parallax occlusion mapping on them. The modeling is very basic, but I take good care of my surface materials to make sure it looks right in the scene. The cloth uses the two-sided shader. The wood is opaque. Shadows are cast on the cloth, and the cloth casts shadows as well.

The sky is a custom shader I made myself that takes normals into account for the clouds. It's entirely unlit, but I use light vector information to model shading in the clouds. The horizon is much brighter than the zenith, giving a sense of atmosphere in the distance and better contrast with the clouds up above.

September 28, 2016

Tessellation for Landscape


Tessellation is something of a holy grail for graphics: the ability to physically shape the surface based off of displacement maps and smooth out the surface with more polygons on the fly. But for the longest time it was seen as an impossibility that was extremely inefficient at best. Tessellation first appeared in UDK's DX11 renderer 5 years ago, but it wasn't until UE4 that the method was really perfected. The preferred method to tessellation was a pre-tessellated higher-poly base mesh, and for landscape some extremely inefficient parallax occlusion mapping. However, with UE 4.13, tessellation will only be applied to the lowest LOD. This allows the triangle explosion to only impact the closest meshes. And with DirectX 12 significantly reducing the impact of draw calls, I was able to achieve a better framerate using tessellation than POM on a landscape material with very few blends.

Pros to tessellation on landscape:
  • Use artistic displacement maps to bump real geometry!
  • Does not require premade geometry, only landscape material and displacement map!
  • Proper sillhouettes! Proper ambient occlusion and shadows! Proper depth! Etc.
  • Extremely and easily customizable! Since tessellation is realtime generated, surface values can change over time and are impacted immediately.
  • Can be blended with other materials very easily.
  • Tessellation can be baked into physical properties of the landscape heightfield.
  • Cheaper than POM (in some cases)!
Limitations of tessellation on landscape:
  • ...None!
  • Some distant objects will render flat, but their depths would typically not be noticed anyways, and other methods would reveal more artifacts.
  • In some extremely large landscapes with far less efficient LODs, POM or simple parallax is more performant than tessellation.
It is recommended that landscapes with tessellation have a very efficient LOD system. More sections and components at somewhat smaller sizes (31x31 quads or smaller) would render more efficiently than larger sizes and fewer components. This is because the triangle explosion result of tessellation would yield too many polygons for large sections and components to render efficiently. Also, DirectX 12 cuts draw call times by 1/8, so you can render more draw calls and components efficiently.

In order for tessellation to be enabled, go down the basic material settings under the Tessellation category and under D3D11 Tessellation Mode choose "Flat Tessellation." PN Triangles does smooth out the surface through splines, but the differences won't be noticeable under either method, and Flat Tessellation will be cheaper. I left adaptive tessellation checked on to lower the LOD in the distance, but it might be forcibly enabled just by being a landscape material, so your selection there may not matter.


The easiest setup for tessellated displacement is to multiply your heightmap by the vertex normal, then multiply that by a scalar parameter for your displacement. If you are blending heightmaps together, the final blend will be fine. I also recommend setting the tessellation multiplier down to 0.5 to save a bit on performance. The "reference plane" defaults to the ground, and all tessellation is lifted from the standard surface level. To change this to displace downwards (like POM default settings), subtract your heightmaps by 1. Subtract by 0.5 for an even 50:50 displacement above and below the surface (though the exact balance depends on the range of your heightmaps as well).

To make less triangles explode, under Project Settings > Rendering > Tessellation > Adaptive pixels per triangle, set this to a higher number (default is 48). For a game running in 4K using tessellation on landscape for medium-sized bumps, you might be able to get away with 200-600 pixels per triangle. Keep in mind the distance LOD is controlled by the Tessellation Multiplier while the number of triangles is controlled by the adaptive pixels-per-triangle value in the Project Settings when optimizing.

Also make sure to keep in mind that tessellation, while correctly calculating shadows, will not calculate the new surface normal. You will still need to provide a proper normal map with your displacement map to get accurate shading and lighting. Once you enable tessellation, you can even do things like animated displacement for lava flow. And since tessellation is compatible with texture maps, you are not limited to vertices for your shading. Your only limit is your imagination!