Landscape performance issue

can I ask how you dealt with the Texcoord Frac, Mipmapping and/or Texture Filtering issues related to using a texture atlas? quick rundown of my experience:

  • Texcoord Frac is easy but expensive (use the ddx/ddy mip bias)
  • Mipmapping poses the biggest challenge, as sub-textures start to bleed on higher mips. the usual “solution” (sacrificing a big chunk of the texture to use as gutter) isn’t at all acceptable, as you end up having to limit the mips (getting noisy textures on the distance) or having to sacrifice a big part of your texture (for 2k textures I found I could basically use a 1024 of unique non-gutter data)
  • Texture filtering issues are what would come if you try to filter the textures manually in the shader to avoid the aforementioned mipmapping issues, but you end up with sub-par texture filtering (looks bad at grazing angles)

Looking into the future I’m specially interested in this.

  • Would texture arrays “just work” (and avoid the problems inherent to atlasing) if I were to integrate the pull request myself? (or wait until Epic does it)
  • Since Dynamic Flow Control is backlogged, what’s the best way to use it without ending up with your entire material in the Custom node?

I am building the texture arrays with the “PVRTexTool”.

Instead of plugging just a TexCoord0 node into the UVs of the texture sample, I just plug this into the UVs:

http://puu.sh/uoost/18f7cb37fb.png

The second UV channel (TexCoord1) has a value between 0 and 255 in the R value, and that value specifies which texture from the texture array is used. That’s all, its really simple.

Essentially, I did not deal with it. Ended up using padding(worth 1/8 of texture space) and capped lowest mip, before switching to arrays. Top down view was forgiving in that respect. That is not a viable solution for quality FPS/ third person.

Yep. Can’t say definitely about specific PR though.

Back then we ended up bypassing material editor for terrain shader completely.
Besides that, You do not really have other options.
Now I think it might be possible to modify MaterialTemplate.USF, adding an include with terrain shader code and set of ifdefs, to be later called from custom node, which also does define.

Hmm, so were mostly out of options. For me, working in pvr isnt too bad, but having the padding issues mean its not really worth it to implement the PR. This is a good thread though, I hope epic or takes a look at these issues, as what we can do now currently, is make pretty screenshots that emulate the look of other games, with the difference being that other games can actually run, whereas ours cant.

For me the issue isnt so much the number of layers, I actually see other game companies do very much restrict how many mats their using on their landscape to at least 10 or less, its more that we cant use tesselation or pom in any way. Its basically impossible to emulate the look else is getting on other engines, without some kind of bump or shadow producing tech, beyond normals. A LOT of other games are doing this, and while not possible for low end users, it works for their high end, and screenshots sell games, but having tesselation on in ue4 reduces your game to a screenshot!

Has anyone had any luck with working with bump off set or any of the cheaper techniques? Im actually not that fussed about having the silouette tesselation gives you, i just want more depth and self shadowing in the foreground.

Padding is the case only when using atlas. PR deals with arrays and basically solves the issue.

Tessellation itself works quite well. It is just that dynamic shadowcasting performance with tessellation seems to be off.
As for pom, there is nothing that stops you from using it on landscape.

Ahhhh, ok cool, thx for clearing that up. Arrays would be a big help at least for landscape, and making arrays externally is not too bad if you have your textures finalised. Ill have to take another look

pom is a pain to use in the material editor, due to the way it blends. It doesent make for very friendly workflows, whereas tessellation at least works on a combined heightmap right at the end of the shader flow, making it relatively straightforward to add into an existing material with blending using heightmaps :smiley:

I agree, the actual tessellation in ue4 works great, its the shadowing that is insanely expensive if you look at the gpu visualiser.

For me the performance hit by POM is off the roof. Again in cryengine I set 256 steps for POM and don’t even see 1 fps drop. But 32 steps in UE4 just costs too much. Don’t you think so?

You can look at the POM code and there is nothing specially wrong in UE4 implementation. I optimized it for our own usage and managed to only make if faster by 10%. There is no way that cryengine could have 8 times faster POM.

if you dont mind self-shadowing to only come from the Sun light, try looking into Iterative Parallax Mapping (which is basically several stacked BumpOffsets) with SelfShadowing (just replace the UDK LightVector with the Atmospheric sun direction node in UE4, which IIRC you have to negate)

I kinda have to fully agree with this. There is not much you can do. Moving few calculations from pixel to vertex shader, and getting rid of dot product for heightmap channel selection, and a few minor ones, but otherwise it is all the same across different implementations.
Where the difference comes from? Firstly, you have to branch out pom in a such way, that it is only calculated for few meters in front of the camera, and not on entire terrain. Secondly, you need an effective approach to blend several POM layers. I also have an impression that I saw POM steps were hardcapped in CE.

Thing is that having POM on terrain takes more effort and it is impractical to do it in material editor only. It does not cost more in UE4. Doing self-shadowing needs even more work. Frankly saying, I did not invent anything better than using gbuffer custom data for POM self shadowing.

Yeah, thats the bit for me that doesent make it very useful on landscapes, the inability to blend heightmaps before it gets passed into pom. That and i found getting self shadowing to work to be super hacky.

EDIT: There is actually a way to blend heightmaps, by having three heightmaps in one texture object, but its pretty impractical to use in a wider workflow.

@Chockster, thanks for the headsup on the sun thingy, ill take a look!

dat has to be the worst typo I’ve ever seen in my nickname :eek:

You can’t blend height maps for POM. Tracing against height field is binary problem. Ray is either above or below surface.

And how is performance/shader complexity after using texture array?

I have never used anything else than texture arrays for this, so have not compared it with anything else. I would expect a texture array to result in the same shader complexity and performance like a single individual texture.

Hmmm, Wow. Well it’s a little confusing then. So basically while I get red shader complexity with 5 layers I’d get green with 10 layers? :confused:

I don’t know how the landscape layering system works, was a long time ago when I last used landscapes.

Texture arrays just allow you to address a larger texture area in a single lookup, that is, you can select from a variety of textures, without incurring considerable performance hit. It would have no effect on pixel instruction count, thus no change for what you are referring to as shader complexity.

The number of textures present in a material affects shader complexity by itself, i.e hooking up 2 textures and then 5 textures gives very different shader complexity color, so I’m wondering if using texture array changes that?

You are kinda missing the point. To have 16 layers on a single component, you would need 32 texture lookups(provided it is two textures per layer, base color and normals). With texture arrays you can have 16 layers on the same component, while using only 4 texture lookups(with a limitation that you cannot blend more than 2 layers at the same place). Think of it as having only 2 layers instead of 16, but you can select freely from 16 sub-layers for both of these layers. So in regards to pixel shader strain, It would be slightly less than 8 times better.