Terrain tesselation and dynamic shadows

While creating a terrain material I’ve ran into a performance issues with tessellation,namely with shadowcasting.

I am using quite large landscape and one dynamic light with far shadow cascade and having tessellation enabled on terrain material cripples performance.
GPU profiler show roughly 5.0ms increased time for shadowed lights, ShadowDepthsFromOpaque. And that is only by just enabling tesselation in material parameters, having tessellation multiplier at 0.
I can safely say that I did not experience this issue around UE 4.6 or so.

For the sake of consistency, I’ve reproduced the issue in a blank project.

    1. Create a blank project.
    1. Create Default level.
    1. Change directional light to
      movable.
    1. Create a new terrain, 505x505 or
      any larger size.
    1. Create a new material.
    1. Plug a simple Const Vec3 into base
      color.
    1. Assign this material to the
      landscape.
    1. Check performance.
    1. Enable flat tesselation in
      material settings.
  • 10 Observe unjustified performance
    drop.

Please note, that it happens only with landscape. If I replace terrain with a mesh of comparable density, I get no shadowcasting performance drop untill i start cranking tessellation multiplier way up.

I’m linking 4 somewhat similar posts I’ve found.
Post1
Post2
Post3
Post4

Hey Deathrey,

We are aware of the performance issues with tessellated landscapes and have a report in to improve this feature (UE-14253). I have increased the community interest and added a link to this post to the report. We appreciate you taking the time to investigate and provide additional posts where users are reporting a similar issue.

Let me know if you have further questions or need additional assistance.

Thank you,

Good day. Just noticed that UE-14253 has been marked as resolved in 4.13
Up to 4.13 preview 2 the issue is still present.

I just ran some tests and cannot confirm what you are reporting. I followed your steps as well as made a more complex material and did not get any sort of drop in performance when enabling tessellation on landscapes. Below are the contents and results of my test in the 4.13 preview 2 release.

Without Tessellation

Notice the frames per second.

Landscape Material

Flat Tessellation enabled with displacement. Created parameters for material instance.

With Tessellation

This issue is fixed on my end. Let me know if you have further questions or need additional assistance.

Cheers,

Still able to consistently reproduce it in a clean project on 4.13 p2

    1. Create new project, blueprints,
      3rd person template
    1. Create new level, default preset
    1. Turn off smooth fps in project
      settings
    1. Make a terrain material, exactly
      as displayed on your screenshot
    1. Set tessellation multiplier to
      zero
    1. Compile material, and create its
      instance
    1. Create a landscape, 505 resolution
      63 quads per section, 1 section per
      component
    1. Assign above-mentioned material
      instance to the landscape
    1. Create landscape layer data for
      two layers, weight-blended

Second part, due to character limit:

    1. Paint landscape fully with first
      layer
    1. Paint some spots with second
      layer
    1. Select Light Source, change it to
      movable, set Far Shadow Cascade to 1
    1. Play in standalone
      process.@1920x1080
    1. During play mode while looking
      from various angles, take several
      readings from GPU profiler and note
      Scene/BasePass time and
      Scene/ShadowDepths. At this point,
      for me they are averaging at roughly
      0.80ms and 0.40ms respectively. That is on GTX 770
    1. Close play in standalone window
    1. Open landscape material.
    1. Enable flat tessellation, disable
      crack free and adaptive tessellation.
    1. Recompile and save the material.
    1. Play in standalone process
    1. During play mode while looking
      from various angles, take several
      readings from GPU profiler and note
      Scene/BasePass time and
      Scene/ShadowDepths. At this step my
      average readings are 1.10ms and
      2.70ms correspondingly.
    1. Try roughly aligning the camera
      with Light Source’s direction(Sun is
      directly behind the camera). For me
      ShadowDepth is peaking 4ms here.
      Without actual tessellation load
    1. If that is not convincing enough,
      expand the material to include
      distance-based tessellation, exactly
      as it is described here, and
      check how tremendous is the
      performance hit, even with low values
      for distance and multiplier. For reference, you can cross-compare performance with a mesh plane, that has roughly 250k vertices. There are no performance issues with a static mesh of comparable density.

So I ran some more tests using your newly provided steps and am still not seeing the drop in performance. Silly question, but can you make sure you are on the preview 2 release? Could you also provide me with your ‘dxdiag’ so I can take a look at your system specifications.

I even increased the Tessellation to 4.0 and the displacement along VertexNormalWS to a multiplier of 25.0 and still did not see an unexpected drop in performance. Made sure ‘Crack Free Displacement’ and ‘Adaptive Tessellation’ were both turned off, took multiple screenshots using the ProfileGPU console command, and had no significant change in the ms.

I will say, your new steps are more complex than the original that got the issue to occur which means this could be part of the issue. If enabling flat tessellation on a landscape using a default set up while disabling ‘Crack free displacement’ and ‘Adaptive Tessellation’ does not reproduce the original performance drop issue, then it is determined as fixed.

Let me know if you have further questions or need additional assistance.

Cheers,

Good day again, Andrew. Thank you for your time investigating this.
Your question is absolutely valid. Yep, I am on 4.13 preview 2, launcher version.[Dx Diag file as requested][1]


My screens(windowed standalone,1280@720):


No Tessellation

Flat tessellation, crack free and adaptive disabled, zero tess multiplier

Flat tessellation,crack free and adaptive disabled, 4 tess multiplier


Now a silly question from me. You are mentioning that you are not seeing performance drop when cranking up multiplier to 4. That sounds dead wrong to me. You should observe performance drop, and with 505 grid tessellated 4 times, this drop should be significant. And your two screenshots earlier from your post show a fps of 120. Please, rule out your FPS being capped by framerate limit or vsync.


I am quite positive that I am not the only one affected by this issue. It would be only to my entire joy finding out, that this issue is in my hardware/software, but whole team is being affected by that. Additionally, users from the forum thread do report the same. There is also another answer hub post on exactly this issue, the one with 50 votes on it.

Thanks for pointing out the framerate options as I did indeed overlook that setting. With that said, I ran some more tests and can see a performance hit, but nothing outside of what is expected. You can open the images in a new tab to view the original sizes in order to make the text legible.

Tessellation Disabled

Tessellation On

Tessellation with High Values

So as you can see, I am getting a drop in performance in regards to my Scene rendering ShadowDepths, but it is nothing as significant as what you are reporting. The final image is expected as the tessellation multiplier of 4.0 is a pretty high number to tessellate a landscape. The shadow depths are going to increase the more I displace the landscape as well since it is pushing the vertices along VertexNormalWS and creating new shadows.

Let me know if you have further questions or need additional assistance.

Cheers,

Tessellation multiplier 4.0 with Displacement of 20.0 (3d shot) is totally expected.
.


~~12% frame render time increase between No Tessellation and Flat Tessellation with zero multiplier(I understand it might lie within normal framerate fluctuations, thought i am never getting frame to frame difference that high, unless something actually changes on the screen) on your hardware(I assume that to be somewhat equivalent to GeForce 900 series) can easily transfer to ~30% on 700 series. around 30% is the minimum difference I was getting between enabled and disabled tessellation. I would really expect virtually no performance difference here.


I see shadows on your shots, thus the camera is not oriented to have light source behind the camera. The reason, why I am specifically pointing out light orientation relative to camera in step 21, is that number of landscape components rendered, when facing away from directional light source is maximal, and minimal, when looking facing the light. The issue manifests itself much more clearly, when facing away(components behind the camera are still being rendered into the shadow map). In this case my total frame render time increase is peaking up to 90% increase between no tessellation and flat tessellation with zero multiplier.

Additionally, as soon as I increase landscape size beyond 505, things go much much worse. Shots for 4k landscape:


No tessellation:


Flat tessellation, zero multiplier

Epic,

Please have a look at the OP here as well.

Okay so I looped in some additional devs after completing another round of tests where I was unable to reproduce the same drop in performance you are reporting. In regards to tessellation simply being enabled and using 0.0 as their values, I was given a more technical explanation as to why it is unrealistic to expect no performance impact.

There will be some non-zero cost to have tessellation enabled regardless of the tesselation factor, because with tessellation enabled the topology format is D3D11_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST rather than D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST and the adjacency data is supplied to the domain shader, which consumes more memory bandwidth. The domain shader also needs to run for each set of control points, even if it returns 0 or something that evaluates to 0.

With that being said, I ran your tests again and still did not get the same drop in performance. Would you be able to provide me with the test project you are using so I can simply open the project and confirm what you are reporting?

Thank you,

Well, when I mentioned “virtually no performance difference”, I sort of accounted for that. There is an overhead, but by all means it can’t be held responsible for doubled frame render time on a heightfield as simple as 255K verts.


Link to a project, hope it can clear something up.

My thanks.

Thanks for the test project. I was able to confirm what you are reporting and have gone ahead and entered a bug report for the issue. You can track the issue following the link below on our new Public Issues Tracker.

UE-35097

Once the issue has been addressed by our engineers, the fix will be added to the release notes for fixed issues within an upcoming full engine or hotfix release.

Let me know if you have further questions or need additional assistance.

Cheers,

Glad that you were able to reproduce it finally. Just have to say that I don’t state that the issue is view angle dependent between the directional light source vector and the player’s view angle, like it is stated in the ticket. That is number of landscape components required to be rendered depends on that. It is not part of an issue and was referenced here to better highlight performance difference.

So it’s been 8 months. Did this bug report fall off the table?

No, it is still on the horizon to be fixed. As you can see it is marked as backlogged which means it does not have a high priority at the moment.

Alright thanks. Can you please update the Affect Versions to show 4.15.1 too?
And on a side note, Andrew, can you help us out a little? I know it’s not a priority for Epic’s internal projects but we’ve all been waiting for a very long time for this fix and it’s crucial for a large number of projects, what should we do so the engineers take a look at this?

@Deathrey, It does seem view angle has some influence here too.

Looking towards directional light:

http://uupload.ir/files/6p0n_11.jpg

Looking behind:

http://uupload.ir/files/ccj5_22.jpg

Yeah, increased cost when looking against the light is expected, since more landscape components are in shadow frustum.

Earlier in this thread mentioned 12 control point vertex data being responsible for increased baseline cost. This is not the case at all, because for flat tessellation without crack free displacement 3 point patch data is used, but ugly baseline cost issue still persists. The issue should be somewhere around vertex factory->hull shader(something gets interpolated more times than needed? At first glance HStoDS struct looks a bit strange too.)

In addition to that, for better tessellation performance there should be an option to allow you to selectively render shadow depth with tess disabled for each cascade separately. In typical usage scenarios you are extremely unlikely to still have tessellation beyond 1st/2nd cascade. In theory 4.13 change not to render tess past LOD0 should have dealt with it, but on practice LOD0 is commonly present in all cascades, making that change arguably useless for dynamic shadows.