Amazing! Thank you very much for sharing all these tutorials!
@tuna1867
2 ай бұрын
really appreciate you explaining all these nuances
@TechArtAlex
2 ай бұрын
Sure thing, thanks!
@medmel2160
2 ай бұрын
This is more and more looking like Ghost of Tsushima grass! Keep it up!
@topraktunca1829
Ай бұрын
First of all I want to thank you and say these tutorials are one of a kind on this topic. I have never seen a video covering foliage in this much detail. And explaining everything crystal clear. Also my pc is not that great and the meshes caused some frame drops, at first I thought this is normal. But I experimented and found out that using hierarchical instanced sm instead of normal instanced sm makes a day and night difference fps drops completely gone and noticeble performance boost. When you freeze the rendering you can see hism does culling more aggresively. Instanced sm does that too but some kind of a half loaded thing idk (mesh is loaded but probably just not rendered in).
@TechArtAlex
Ай бұрын
Thanks! On my machine it didn't make any difference what type of instance I selected, but yes in theory HISM or Foliage instances should perform better than standard instances. They also cull in grid clusters instead of individual instances which is faster, but in some cases you may notice a blockiness to the culling.
@BooneyTune
2 ай бұрын
I would like to see more on the optimization. I don't have much experience with it but this is great tutorial series to get to know more about it and learn.
@TechArtAlex
2 ай бұрын
I'm not sure there's a whole lot more that can be done besides controlling these elements more tightly or cutting features. For example, one can cull the grass much more aggressively than I did. Ghost of Tsushima culled 75% of blades at each cascade, whereas I'm only culling 25%. But if I think of any easy performance wins I'll make sure to mention them.
@christopherfrancique9912
2 ай бұрын
bro looks so good coming along so well
@TechArtAlex
2 ай бұрын
Thank you!
@ScorpyX
2 ай бұрын
Gold information
@Stygmire
2 ай бұрын
Thanks-again. FWIW, and it might be my specific implementation + stupid-compiler-tricks but I was able to save a few (3) instructions by swapping-out the MakeFloat2 for Wind_Speed_X and Wind_Speed_Y for a 4vec parameter, using a component-mask off the top (white) pin and the B channel for the Wind_Speed_Multi parameter. YMMV, but try it; every savings helps! I find, generally, any time you use an append-vector it will cost you at-least-one instruction. It's part of my performance pass to see where I can eliminate such ops and pack values. Not always, for sure, but more often than not, I find I can scrounge a decent savings when doing so. Also, my understanding is that a power() function is just-expensive to load and run, not something that is reflected in the instruction-count. Unless one uses a large/very-small value for the exponent; eg: it's better to multiply-out a power-3 or power-4 vs using a power() function (confirm/thoughts)? For the power-functions on the camera-tilt, I swapped out the power(0.5) for a divide by 0.1 -> Saturate (seems close-enough in the visual comparison of the gradient), and the power(0.33) for a divide by .025 -> Saturate. Doing so saved me several more instructions.. Additionally, as I have grass going out to ~500 meters (I mean how much do you really need), and at that point it's almost sub-pixel size, I added a distance-gradient to scale-up the WPO operations (straight multiply) for the final bezier-curve, the tilt-power, and the y-scaling of the mesh. At a very-far distance this helps 'fatten' the grass and back-fill screenspace, helping to provide good mesh coverage/saturation at a distance. Even just doubling it, at that distance you wouldn't notice the scaling of the mesh and it will keep more of the mesh in the visual-field. If you just multiply the last-part of the WPO-chain, it will mush the grass at a distance, so you have to spot-multiply those three places. EDIT: I moved the scaled WPO multiply to earlier in the tilt-calculations so it increases the amount of tilt based on distance vs just increasing tilt overall. Dumb on my part... Finally, I enabled the Early-z-pass option for masked-only in project-settings, switched the grass-shader from opaque to masked, and plugged in a smooth-stepped PerInstanceFadeAmount into opacity-mask. This did garner a few extra FPS in testing, and made a very nice fade out you can't really notice. I added a shaderbin link: blueprintue.com/blueprint/510z4it9/ (updated!) Hope these help, and keep the lessons coming! :D
@TechArtAlex
2 ай бұрын
I have seen append go either way when it comes to instruction counts. Vector packing can also go either way in frame times, but I'd still consider it good form. That said, in a complete implementation wind params probably should be coming in from a collection parameter node anyway as it will probably be part of a larger global wind system so those were all just placeholders since I don't plan on building all of that out. Pow is in theory more expensive, but in practice most compilers are doing lots of automatic optimizations that may make that mostly irrelevant. For example if you put in a power of 2, it'll generally just multiply by itself anyway - although there are more sophisticated tricks being used as well. But it doesn't hurt to avoid potentially costly operations. I'm always quite skeptical of instruction counts, but if we can observe a frame time reduction then I'm all in. Like you said - doesn't hurt to try and see what happens. I'll have to test these changes out. Grass takes up a lot of screen space, and in this case has lots of verts, so every little bit counts. As for scaling the grass at a distance, I think this is generally a good approach. It is basically what nanite volume preservation does - and it is what outerra proposed in their blogpost that inspired Sucker Punch. Every time they cut the polygons in half, they double the surface area of the remaining grass. This can help reduce quad overdraw, reduce aliasing and lots of other goodies. Ideally I'd cull much more aggressively than I did in this demo, but I kind of wanted to show off a ridiculous number just because I figured people would want to see it haha. I've also been experimenting with importance based culling, but I'll probably make a separate video on that rather than bundling it in this series. Basically, rather than using distance alone, we can assign an importance value to grass based on things like proximity to a mesh. For example, if the grass is near a certain mesh, it should be culled later - since that grass is visually more important to the scene as its silhouette is contributing much more detail than a random blade in a field. The result is quite good I think. Another example would be that grass on a hilltop is more important than grass in a rut, although that's a bit harder to procedurally define. As for culling, I prefer to shrink and/or sink the grass blades while blending their normal towards the underlying terrain. This avoids the need for a masked material while still making the transition basically invisible. When I get around to the next video, it will probably be about blending out in more detail, and how to get the underlying terrain normal vector without needing to sample a virtual texture (thanks once again to PCG data packing). Thanks for the feedback and sticking around!
@Stygmire
2 ай бұрын
@@TechArtAlex >as for culling, I prefer to shrink and/or sink the grass blades while blending their normal towards the underlying terrain. How does this work? I have been informed/learned that using WPO to move a grass mesh, for example 10,000 down the Z-axis so it's culled and never drawn. Is flattening the mesh the same kind of thing? Does it prevent the mesh from being drawn in the first place? Genuinely eager to learn. From what I recall Final Fantasy had a similar/same thing with moving particles around the camera to be culled. Is flattening the grass the same thing?
@TechArtAlex
2 ай бұрын
@@Stygmire Pretty much, yeah. Using the vertex shader this way doesn't completely remove the mesh, because its verts technically still exist. However, because they occupy zero screen space, there is no fragment/pixel shading happening. And because they're instances, the verts were cheap anyway. This is the same reason why the extra/wasted triangle is basically free. Yes that vertex exists, but ideally no fragments are being shaded. If the grass sinks below the ground, then the z- pass can make sure the fragments are skipped too. Eventually the instance is entirely culled, but by that time it is already invisible. Using several cascades like I have cleans up the nullified meshes regularly to keep the instance count down, even if many are not really drawn. I tried assigning random cull values on a per instance basis, but it was not scalable to this many instances. But that might work for other things.
@dcrookz
Ай бұрын
I'm interested in the transition to grass textures at distance that you mention here, if you've got the juice to do another video on grass!
@TechArtAlex
Ай бұрын
Still planning on it! Just needed a bit of a break haha. Maybe sometime this week.
@UnrealArtist
2 ай бұрын
Great tutorial, I guess its the final video for this series? I have been following this series since the start. One question. Why are you using PCG? Why not traditional landscape mesh spawning system for certain material layer? And what if we want to universaly control the direction and speed of wind for grass and other foliage meshes? Like in the ghost of tsushima? I would love to see your approach oin this.
@TechArtAlex
2 ай бұрын
You certainly can use more traditional methods like landscape grass types, but PCG gives a lot of extra control. PCG allows us to communicate more than just landscape layer/material data to the grass, but basically anything we want - without needing to compute it every frame or bake it into a texture. For example, culling the grass in spots that overlap scenery meshes could be done with a virtual texture, but sampling virtual textures incurs a runtime cost. For controlling wind variables globally, you'd just want to set up a material parameter collection and set the values with bp/code instead of setting the parameters in the material instance.
@TechArtAlex
2 ай бұрын
And I am planning on doing one or two more.
@avilxy8305
2 ай бұрын
Hello Alex, I am loving this series and have managed to get a similar result to yours but I would like to add player interaction. I have created an interaction system that works on most foliage but when I add it to the WPO output of the grass it produces a very strange stretching/deformation affect. I believe this is because I am not controlling the individual control points. Any ideas on how I could go about adding a normal WPO interaction to this grass?
@TechArtAlex
2 ай бұрын
In theory as long as it is the last thing you do, after applying all other modifications, you should be able to use regular deformation. But I would strongly recommend using and shifting the control points with your interaction system instead. This will make sure you have correct normals, and we have built in the length preservation system already it can take advantage of.
@avilxy8305
2 ай бұрын
@@TechArtAlex I can't work out how to directly affect the points. Do u have any idea on how I can apply normal WPO (regular deformation) such as simplegrasswind to the grass blades. Using an add node does not work as it creates the same stretching affect. Any rough idea would be appreciated.
@TechArtAlex
2 ай бұрын
@@avilxy8305 Directly applying to the points would be done in exactly the same was as the wind video. In that case we added and subtract from the control points coordinate based on the wind sine wave. But we can also push it based on things like our interaction system render target. The Simple grass wind always stretches meshes, which is part of why I recommended against using it in the wind video in favor of my method, which is capable of estimating and preserving approximate length.
@halftempted1047
2 ай бұрын
Do you intend to cover grass interaction?
@TechArtAlex
2 ай бұрын
Not currently planning on it, but if I did, it'd probably be done in the conventional way - with a render target.
@Cloroqx
2 ай бұрын
@@TechArtAlex Yeah, grass interaction with this setup would be interesting to see.
@halftempted1047
2 ай бұрын
@@TechArtAlex If you can find the time, I’d love to see your implementation. Your ability to maintain performance is refreshing in comparison to others.
@zeon3d755
Ай бұрын
where can i get the code pls
@bartosztitkin2700
Ай бұрын
Make it yourself from part 1 to achieve knowledge and understand how it works!
Пікірлер: 30