POM Landscape performance optimization help requested

As the tittle says, I have a landscape material that uses POM that I am looking for help optimizing the performance with. I am fairly new to making materials. The reason I am looking at using POM is because I am working in dx 12 and I am using engine 4.22.1. The material is an auto material with some extra layers to “override” the auto layer. I have all of my samplers set to shared wrap. While the material is compiling, and the POM looks great, I am having a hard time getting good performance. Even with the POM turned off, I am still getting around 30-40 ms in fullscreen. I am using Cinematic Quality, which oddly enough is giving better performance than Epic quality. Additionally, even though I was using forward rendering when I started making the material, after switching off of it to check performance, when I switch back to forward rendering I am experiencing dx 12 related crashes. Any help with fixing my material would be greatly appreciated!

Here is the Material Layer function that I created:

Here is the full material:

In addition, I tried blending out the POM from a distance, but I think that is making things worse. For textures, I am using 4k diffuse and normal with 2k everything else, except layer 6, where I am using an 8k height texture. Again, any help would be greatly appreciated! Thanks!

PS. Here is what it looks like

Your landscape material is too complex, I would suggest you hard code some parameters, there are way too many parameters and this might affect performance. POM cost depends on the screen coverage. Since the landscape covers most of your screen space it will end up being slow to render. Try to split up your terrain into multiple tiles and make a simpler version of the material without POM to use in the middle ground and background. You never get to see the POM effect that far anyways.
If you want to debug the performance, I would try adding a switch to turn OFF and ON POM just to make sure that the issue isn’t coming from there.
Also note that the amount steps used in the POM Mfunction dramatically affects performance.

On the other hand POM isn’t really recommended for shading landscapes. POM cost will go up for each landscape layer added. IIRC POM is around 300 instructions and if you multiply that by the number of landscape layers you will realize that you will easily go over 3000 instructions for 5 layers (Normal and Albedo).
Use Tessellation when possible and POM for only some areas that need some details as a separate mesh or decal.

Optimization steps for POM include the following:

  1. Rewrite POM function to use several refinement steps instead of one, tracing in n coarse steps and m fine steps.
  2. Use bi linear filtering on heightmap with calculated LOD instead of automatic LOD calculation and anisotropic filtering.
  3. Consider using lower resolution heightmap.
  4. Make sure that you use either RGB texture compression, where heightmap is one of the channels, or single channel compression for heightmap. Heightmap in alpha channel is a strict no-go.
  5. Consider using fixed number of steps and unrolled loops for POM.
  6. Consider re-writing self-shadowing to be horizon-based, sampling through all relevant LOD levels of the texture.

With that in mind, POM should perform 3-4 times faster than stock material function.

Note, that using more than 4 layers with this is unrealistic.
Likewise, tessellation on large landscape is unrealistic with stock terrain rendering system.

Thank you for your reply, however, as I said I am working in dx 12. As far as I know tessellation isn’t possible in dx 12. If you looked at the function, I have a distance blend to fade out POM and as I said, this issue is present even with POM turned off. I have a switch built into the function to outright turn it off. As far as steps, that doesn’t seem to be the limiting factor as the performance is the same from 8 max to 64 max. I would hard code the params, however, as I said I am pretty new to materials and don’t know enough on how to hard code, do you mean make a c++ material function and put the params in there?

Thanks again.

Thank you for your reply. As far as the texture resolution I am using 2048 resolution that in the POM I shrink to 64. I’m not sure how to rewrite the POM function as you instruct. How would I increase the refinement steps and change to bilinear? While I have programmed quite a bit in c++, I haven’t ever messed with the custom coded shaders like POM. Lastly how would I make the shadowing horizon based? Also, I am at the moment only using my auto layer which only has 4 layers, so the performance is only based on 4, but I also have a distance blend to blend out the POM.

Thanks again!

tessellation works just fine in DX12. why makes you think otherwise?

It literally says D3D11 is required in the material editor? That and I have had crashes everytime I’ve loaded a project with a tessellated material into dx 12.Is there some way to enable Tessellation in dx12 for materials? I’ve looked online and not found anything on it for dx 12.

I guess that is writed down before DX12 was a thing. So I would read it like dx11 or higher.

DirectX12 > DirectX11
everything that DirectX11 has, DirectX12 also has it.
(D3D = DX in case you haven’t noticed)

however UE4’s DX12 implementation is a bit unstable at this point. and except for raytracing, DX12 doesn’t really do anything more than DX11 at this point in UE4.
in theory DX12 should give a bit better performance in UE4 projects but in my own experience, so far it doesn’t (I even get worse performance)

the way to enable tessellation in DX12 is exactly the same way as with DX11, which is covered by the documentation.
or are you really telling me tessellation is greyed out / unavailable if you run on DX12 but working fine on DX11?

It’s not greyed out, but it’s clearly marked that d3d11 is a requirement (yes I am aware thats dx). So far, everytime I have enabled it in my materials using dx12 I have experienced immediate crashes, which is why I thought about using POM. I did get POM working much faster just by reducing the number of params. As far as the performance vs dx11, I have experienced better overall performance on both my 1060 and rx 590. I did figure out what was wrong with forward shading though, turns out there’s a bug with MSAA and forward shading in dx12.

well usually when you have something higher than a requirement, you still meet the requirement :slight_smile:
but sure, it could be better if it said it requires DX11 or highe

I can confirm that also now (4.25.2) Unreal crashes immediately when Tesselation is enabled, so it seems the software does not agree with you :wink:

Edit: Actually, it only crashes when the UV input is based on BumpOffset. With regular UVs I’m getting Tesselation functioning normally.

So what options do we have in 2021 to get large landscape not looking like a 15 years old landscape?
Bump offset?

And why tessellation is unrealistic on large landscape? If I set tessellation multiplier to 1 with adaptive tessellation and 0 after let’s say 1000 unit beyond the camera, it will still kill framerate?