I'm still banging my head on the foliage topic to find my own workflows/methods/techniques.
Trees may be dimmed a success.
Now on to grass (again, actually).
I've already tried, and I keep trying, to achieve a full-3D to cards transition to improve performance, but it seems it is not possible to make cards match the look of full 3D grass.
I'm open to alternatives, like full 3D but with a lower polycount. Which is what I achieved with UE4's built-in automatic LOD generator.
The result is impeccable, to my eyes, but I wonder if the polycount is acceptable at all. On my 980Ti, the framerate in the reduced view pane fluctuates between ~100 and ~110 and I wonder: is this ok?
I've taken some screenshots of the same landscape in different modes, but I cant interpret what I see. Help, please....?
The same landscape screenshot'd in "lit", "lod levels", "shader complexity" and "shader complexity + quad overdraw".
Obviously, the shader complexity is nearly non-existent, since every single strand is a 3D mesh without transparencies.
Quad overdraw is not a thing for the same reason.
The framerate, however, is quite unstable and I dont know how to interpret it.
Is it ok to have such an amount of triangles, for a grass-covered terrain?
I've tried using cards, but, let alone the awful transition, something looks terribly wrong with lighting. And I dont understand why.....
To answer some of the most probable questions:
.- yes, those are crossed cards
-. yes, they have normal maps from a projection of the 3D strands onto a plane
.- yes, I've used the 2SidedSign node to invert normals on back faces
I'll keep trying while waiting for advice.
Thank you.
Replies
I know how the LOD colour coding works, sorry for giving you the impression that was a mystery to me too.
Here's a screenshot with just quad overdraw on (full 3D grass blades)....
I've watched a number of tutorials on grass and none ever mentioned "alpha mipping" or "normal skewing".
Anyway, just for the sake of completeness, here's my LOD1 and 2 normal map (they use the same shader, which is very simple)....
That normal map is the result of a projection of these strands on a plane....
Then I cut the plane around the projection to get LOD 1 (960 tris) and 2 (378 tris)....
Each "patch of grass" covers a round area of 1 meter in radius (2 meters diameter).
I *did* manipulate the plane's vertex normals to point straight upwards, btw.
These are LOD 1 and 2 from top view....
I'm very grateful for your help, dont give up! ^.^
This is because SP doesnt feature options for alpha and high-poly textures baking.
Yes, I made the planes wavy in an attempt to emulate what I've seen on a couple of tutorials and I've been told by other people during my previous 6 attempts at making good looking grass.
I guess I could furtherly simplify the test by just cutting a square around the grass alpha, without minding eccessive transparent areas too much.
If with "aliasing" you refer to how it looks in Blender, I think that's just a thing of the 3D view, when it's rendered through Cycles it looks sharp and without any white-ish edge....
What do you mean with "turning off your Tangent Space Normals in your material details"?
You mean unplugging the normal map from the shader in UE4?
Or just baking the normal map in object space?
EDIT (2019.03.09 01.50pm): this is how it looks when I use flat cards only for LOD0 (no LOD 1 and 2)...
It *obviously* yields a nearly steady 120fps, and despite the abominable quad overdraw....
I'm starting to question the absolute truth that quad overdraw is a performance killer.... ^^'
I *did* set SP to bake tangent space normals, though, why would I not? And what made you think I didnt?
At the moment it's no use to make LODs other than 0, it wouldnt make any difference since the current cards are just clean rectangles (hence the unsightly amount of quad overdraw). Right?
Anyway, this is the same cards, but tilted and with a brighter subsurface colour (and tangent space back on, of course)...
I've also lowered all of the quality settings to "Lowest", for LOD 1 and 2, which did not impact the visual quality at all...apparently.
This is how it looks with LODs....
I can't really hope to get something *this* good at a first attempt.....
[ https://80.lv/articles/tutorial-grass-creation-for-games/ ]
But I could settle for something like this (although with normal maps projected from a high-poly mesh, that's not negotiable)....
https://www.youtube.com/watch?v=q7IZStYmImY
See how you cant really tell where the cards start or end? Especially in the first one....although, let's be honest, without some nice trick, that grass will look flat as hell, from the wrong angle!!
There's something I'm missing, here, some step or gimmick that I just cant grasp.
The technical part is sound, I believe, then what am I doing wrong?
And WHY aint the first artist minding quad overdraw at all?! It's like he got a "get out of jail free" Monopoly card for overdraw!!
Aaaaaaaargh!!!!! >O<
Yes, I did cut the plane to minimize overdraw.
Yes, I did set 2 LODs.
It's a circular patch of grass that covers about 1 meter in diameter and reaches about 35cm in height...
How may I improve it?
More strands per plane and less planes?
More triangles to cut closer to the alpha? (wouldnt work well, with this amount of blank space, I'm afraid)
I went with the grass density shown in the lvl80 tut, but I guess it's not applicable to a large field of lush grass....?
EDIT (2019.03.10 4.22pm): I've tried making a denser bunch to limit the overdraw and the amount of planes needed, but it seems I'm back to the initial problem, which is how it looks....
Performance has improved drastically, though....obviously....
I got an idea on how to get both, performance and good looks....but if you have an ace up your sleeve, pull it out, I'm starting to get kinda frustrated.... -.-
This means it's simply impossible....nice. Good to know.
Thank you. ^^
Ok, I think I'm slowly getting there....
....but the overdraw is still too prohibitive. =[
I've found the setting you told me to switch and, with mip mapping off, the more distant grass strands' contours got grainy; but at the same time the overall overdraw improved by a good 20% (eyeballing it).
A "quid pro quo", I guess.
I couldnt arrange Grass_08 (the model you picked as a good start) the way you suggested, I dont think it would work out.
Mostly because I'm having a hard time tracking each card in the screenshot, but also because I'm afraid the overdraw would be unbearable. Grass_08 has a VERY sparse amount of grass blades per card, transparent areas are everywhere...
Instead I'm thinking of varying density and height within the same bundle.
Tall, sparse strands on a card and short, denser ones on another. And maybe some loose triangles with single strands to dissimulate the regular edges of the external cards.
Triangles that, being short, wont participate in the surface overdraw, and that I can recklessly remove in the LODs along with several of the shorter, more internal cards.
This way, the only cards that will contribute to the overdraw will be the few tall ones, while the shorter ones should actually occlude the lower part of the bundle and limit the number of overlapping transparencies from a certain point up.
Yep, it should work very well....it does, in my mind. But it's also true I'm going through an annoying flu and my brain is bathing in something like five gallons of phlegm, so....we'll see.
More updates will follow. But probably not today. My head feels like a medicine ball. -.-
Also if you were do it in the same bundle yes technically speaking would work, however you lose control of placement at that point you can no longer differentiate patches of grass. For instance large patches of weeds or taller grass or the smaller patchier grass found towards trails or roads which leads into a field. You only have your one highly varied mesh. I would say leave the mesh you have now alone, you have good variation in itself but what you need is mesh/bundle variation first and then dimension or scale variation in engine (via the foliage paint tool) when you are applying your grass to your environment.
Try not to focus on the quad draw issue for right now. Let's get the look nailed down first and then we can talk optimization. I say this just because it is easier to learn one thing at a time and not get caught up in optimizing while you're still trying to make it look good.
It's already cut more or less in that way, it seems we're surfing on the same wave.... x)
https://80.lv/articles/creating-next-gen-grass-in-ue4/
I feel like crying and laughing at the same time: this is a screenshot from september 2018, when I was already testing the idea of skipping cards altogether and using a "pure mesh" approach instead.
It was mostly a test and I didnt think too much about polycount/shadows, just wanted to see what would have happened to overdraw and shader complexity.
I ditched the idea because I couldnt achieve a satisfactory density and lushness while keeping a good FPS, but I guess I could give it another try, now. x)
Anyway, I'll also try to create mid-tall grass type using "tight cards". Basically the kind I created in the latest update, but with separate cards for each strand.
Correct me if I'm wrong, though, as I believe the "tight cards" approach is good only for the kind of tall grass that always stays perfectly upright. Bent strands would require extra polygons(?).
Same goes for the "pure mesh" type, unless you wanna spend up to 13 tris for each strand like I did in my very first test (madness, I know!). I guess...?
Also, he mentions not using shadows, but then he shows 4 gifs of some "game ready" scenes of his and I noticed pretty sharp shadows cast by each and every strand.
I see contradiction, there, or maybe my fading flu is still bogging down my mind and I missed some relevant detail...?
Also the tight cards can be used for a lot of different types of grass from the looks of it. I believe that giving those taller pieces of grass their own tight cards allows for a greater level of realism due to the nature of tall strands of grass waving a different way in the wind.
@Obscura Would the overdraw be reduced if a camera based system were implemented similar to Horizon Zero Dawn's? Haven't had a chance to test it yet but it kind of makes sense in my head that having the cards curve from lying flat to straight up as the view gets away from the camera would reduce overdraw some what.
What you see here are patches of 2 meters in diameter covered in strands 20 to 40 cm tall, 2 to 6 tris per strand. About 4.8k tris per patch.
This is what it looks like without mipmapping. This screenshot cannot deliver the painful graininess of the strands waving in the wind.
Unbearable!
With mipmapping on, instead, the strands simpy disappear into thin air few meters away from the camera, which is obviously unacceptable.
This is not a viable solution, unless some wizard descends upon us to cast his unfathomable knowledge on me.
I'm moving on to testing mixed size/density cards....
And yes, the goal is still to achieve a lush, dense grass type, performant enough to cover whole fields without melting a GPU.
Alright, so weird enough, I was just experimenting with foliage these days, and I can tell you guys, those colorations in the debug views should be changed, as we are having way stronger hardware now. The problem with the detailed meshes is clearly the vertex/tris count, but overdraw created by overlapping alpha tests, has somewhat different effect on current gen hardware than one from say 5 years ago. I'm using medium sized planes for my grass and per leaf plane for my tree in my scene, the debug views shows red/white here and there and I have more than 200 fps on a gtx1080 on 1080p. So long story short, I would say try to find the balance between what looks good vs what renders fast. So in your case, this should be fine:
You can uncap the fps by typing "t.maxfps 200" into the console for example to see the real performance.
Anyways, you should match the underlaying tiling texture to the actual grass better. It helps hiding the seams and you won't need to much density to make it look good. At least you should use the same hue/sat or similar. This will also hide the culling a lot better.
That grass looks bad, to me, and I keep giving my attempts a green-ish colour just for the sake of being morally allowed to call them "grass".
If it cant stay above 100-110 on a GTX980Ti when all you see is the terrain and some good looking grass, achieving 180fps when the grass looks like something that came out of the rear end of a bovine is no achievement.
The underlying terrain texture was a test itself, this is all about learning (Substance Designer, in that case).
It's not good yet? Double effort!!
Brb with my next attempt.
PS: could you share a screenshot of your grass? I'm interested.
https://polycount.com/discussion/209623/smooth-foliage-like-in-breath-of-the-wild-europa-by-helder-pinto-mini-tutorial#latest
I think I mentioned, its a very different art style, but I'm tackling the same issues with them and I'm seeing similar results to yours in the debug views. For example this is how my plane density looks like:
This gives me such shader complexity with dithered alpha test:
And such quad overdraw:
Lit view:
Keep in mind, its a different style, but performance rules are general.
While I have around 200 fps regardless of the view. So I would say take these buffer values with a grain of salt, especially considering current hardware. Obviously, its bad if its all white, but your one on the picture I re-posted, should be similar to this with reasonable density. Also, consider matching the underlaying texture
LODs are handmade to ensure a reduction in polygons only where it doesnt cause a discrepancy between near and distant bundles; even the transition is barely visible, and only if you focus on it.
Performance modes...
(Dont mind the FPS in "lit mode", it was because I was bringing up the screenshot software, it's actually between 100 and 110!)
It still shows some straight lines, when looked at from above, but now I know how to break those lines and make them virtually unnoticeable.... ^o^
Two odd things:
1) the FPS in "Play mode" is better than in edit mode....the heck I understand why...
2) the FPS is better with the alpha map's mip mapping on...seriously, there's a huge difference and obviously the visual quality is better too. Maybe it needs some investigation? *shrug*
2, That makes sense,you do a lot of over sampling when mips are off.
You can also gain some performance in editor by simple going into "game mode" by pressing the g button while the viewport is in focus.
The first step was managing to craft a tall, dense, good looking grass. Which I think I accomplished.
Second step will be improving it visually with other types of grass as you've already suggested. I think I'll actually pick two or three weeds from the pic you posted! ^o^
I'll also try to give strands some colour variation, but nothing too flashy or it might make repetition noticeable.
@Obscura ;
The type of grass I'm trying to achieve is completely different from yours, I can see why tilting the cards to such extreme angles worked fine for you, consequently giving you less issues with overlapping transparencies.
Thanks for the heads up about the different performance levels between edit, play and stand alone modes. I shall take that into account. =o
What do you mean with "foliage presets"? What is that? And how would that prevent full culling over distance?
Actually, I made the lower part of the grass darker just because I planned to try turning shadows off so to chip off some more performance. You say it's better to spend a bit more on shadows and let them do the job? Or maybe make them just a bit less dark? =o
Yeah, I didnt like how grass looked at its root, in the Cry Engine example. Cards were very distinguishable. But I liked how they blended in the upper part, where it was no longer possible to tell cards apart.
How do I dither the alpha map? I'd like to give it a try and see how it looks.
For the dither you can throw a Dither Temporal AA on your opacity mask.
But how do I activate the dither?
Also, I hate AA, it takes away hard edges, but also details from the textures... =p
https://www.youtube.com/watch?v=ieHpTG_P8Q0
Please correct me if I am wrong. In that video it's not AA in the traditional sense that you normally would talk about AA. The dither temporal AA is what causes the opacity mask to dither.
About fading them at culling:
https://www.google.com/search?rlz=1C1GCEU_enHU838HU838&q=unreal+engine+foliage+dither+fade&spell=1&sa=X&ved=0ahUKEwieiMqqzIvhAhWP_CoKHWMQAjwQBQgoKAA&biw=1920&bih=969
Root fading can be done by enabling the dithered opacity mask option in the material properties, and then hook up some vertical gradient to the opacity mask input. I used the V channel of my texture coordinates and applied some power on it to push the dark part of the gradient to the root of the grass cards.
About dithered culling.
I've tried following the examples in the forum thread that comes up as the first result in the google search page you linked me. The results vary from "nope" to "not worth fiddling with it any longer".
I might be doing something wrong, but after playing with a simple PerInstanceFadeAmount node for a bit I've decided the resulting effect is more than acceptable (given the overall quality of my grass).
The concept is intriguing, but I believe it's something more suitable for single cards grass strands, and not for the classic billboard approach.
For some reason the flowers get darkened, when lit, but I can understand what causes it.
Also, it's not a homogeneous darkening, it looks like it depends on the direction they bend toward.
Shadow casting is off.
@zachagreg
I have no idea how to tell whether it's baked or dynamic, but I doubt it's baked, since it's not always the same flower that gets darkened.....
This is the master shader I composed for this type of foliage....
The base textures are all a 16x16px placeholder crafted just for this purpose.
They're all turned into parameters, so that all I have to do for each new foliage mesh is create an instance and fill in the actual textures.
"Fillers" are just full white 3vectors tha can be turned to 0 when there's an actual texture input.
The TwoSidedSign node is there, as you can see.
It's really just about what direction each flower faces, in fact sometimes it's the taller flower, sometimes the shorter one and sometimes they're both darkened.
And yes, it's a 2sided material, otherwise you'd notice transparent elements like the stem and the bottom face of the petals.
And these are the vertex normals, I didnt manipulate them....
EDIT (2019.03.20 02.34): Apaprently, it has something to do with the material, but I just cant understand what it is.
I've tried making a stand-alone material and it works fine....
The heck I know why, though. =p
I shall investigate the issue....unless you already know the answer. ^^
@Obscura ; you?
Also, similar instructions will be collapsed into a single instruction by the compiler. For example, chaining up 5 adds will be 1 instruction at the end.
Actually, I got the same idea as zachagreg, I've replaced the add/multiply nodes with "parametric static switch", which does the same thing as the static switch, but through a manual parameter (you tick a box in the instance).
This said, I still have no idea what makes the instanced master generate that odd shading while the stand-alone material works flawlessly.
[ MASTER ]
[ STAND-ALONE ]
As you can see I've over-simplified the stand-alone material (very little parameter'd values) to speed up the test, but everything's there. And it works just fine.
The UV coordinates node in the master was just a test to take out every possible cause that came to my mind. Did not change anything.
As zachagreg said, it shouldnt affect the lighting anyway, when I plug in an actual normal map.
Also, where did you get that 0,0,1?!
For all I know, which is not all but it's not little, the *flat* normal map colour is halfway red (128), halfway green (128) and full blue (255).
If you set red and green to 0, basically you're telling the engine that the surface is fully tilted toward the upper-left corner of the UV (in DicrectX).
[0, 0, 1] Full Blue
[0.5, 0.5, 0.5] Grey
[0.5, 0.5, 1] Normal map flat colour
Anyway, no, it cant be the normal map, because light bounces just fine in the mesh's preview pane.
It has something to do with how light is calculated when the mesh is placed as foliage into the world.
Could it be because I didnt set the metallic value? I highly doubt, but I'll check....
EDIT (2019.03.22 03.15): I've spotted the culprit!
It was the normal map "placeholder". The texture node's sampler type wasnt set to "Normal" (detail I never had to set because of UE4's inherent automation).
Now everything's fine, with weed_02's lighting.
@Obscura ;
What about "Static Switch Parameter"? Does it add up to the shader instructions as much as the normal "Static Switch"? Or is it lighter, since it's set before compiling and cant be changed after (can it)?
@zachagreg ;
I seem to remember you telling me something about baking alpha maps for foliage in Substance Painter, but maybe....it wasnt you? And/or it wasnt SP?
My next attempt at weeds will be aconite...