Smooth foliage like in Breath of the Wild / Europa by Helder Pinto - Mini tutorial

high dynamic range
Offline / Send Message
Obscura high dynamic range
Hey people. Recently I started working on a small stylized meadow scene, inspired by the beautiful work of Helder Pinto, called Europa. It has a very painterly look, similar to BotW. I was able to achieve similar style / looking foliage in a fairly easy way and I thought I would share my experiences with you guys, regarding stylized foliage shading.

For teasing purposes, this is how my results looks currently:


As some of you may already know, edited vertex normals are often used on foliage meshes, to smooth the shading of the cards. If this isn't done, the rotation of the cards will make ugly, sudden changes in the shading. This is one of the things that needs to be fixed, but there is more.

Here is a tree mesh without edited vertex normals, to demonstrate the issue:



Not too bad, but we can clearly see those shading changes everywhere. Now here is a tree with edited vertex normals:



Despite the world normal pass looking smooth, we can still see some darker leaves. This is because the leaf  planes has darker shading on the back face of them. This is a natural behavior, but it looks like we don't want it. Luckily, we can make both sides of the planes have the same lighting using a simple trick in the material. In Unreal, you can do this, and hook it up to the normal input:

We simply flip the normals on the back faces.

And the result will look like this:

You can play with the shadow bias and resolution settings to adjust the falloff of the shadows.

I did the same tricks with the grass in this scene:

Before:

After:


Grass world normals after the tricks applied:


Now these tricks might not be applicable in all cases, and may not look as good with realistic art style, but it definitely works very nicely with heavily stylized assets, for almost zero rendering cost and a little bit of work with the normals(which is actually automatic, because its done with a script.).

I hope that this breakdown will be useful for some people. Have a nice day!


Replies

  • bitinn
    Offline / Send Message
    bitinn polycounter lvl 2
    Another simple trick is to use Pixel Depth to lerp between 2 subtly different leaf colors, which also can give the foliage a bit more volume.
  • Obscura
    Offline / Send Message
    Obscura high dynamic range
    I actually have a parameter in the material setup to darken the leaves towards the center of the tree, but It doesn't look the way I wanted, so I only added a slight darkening. There is also actually a way to fake this ao effect cheaper than dfao. You can take the distance to the center of the x and y component of the bounding box of the mesh, after subtracting 0,5 from the local position. This works if you have the trunk of the tree roughly on the middle of the mesh. Then you can lerp between a brighter and a darker color based on this distance. Simple ssao also works nicely. I have some on these renders.
  • Berserker44
    Offline / Send Message
    Berserker44 polycounter lvl 5
    Great job! these look awesome. What was your workflow when editing the normals in 3ds max? Would love to try the same with my trees. 
  • Obscura
    Offline / Send Message
    Obscura high dynamic range
    @Berserker44 - I used the normal thief script to transfer the normal directions of an elongated hemisphere to the foliage. The grass normals were hand edited.
  • melviso
    Offline / Send Message
    melviso polycounter lvl 8
    Nice work, mate. Looking nice. I think Non photorealistic shading/look should be tried out more in games. 
  • thomasp
    Offline / Send Message
    thomasp sublime tool
    Great trick with the TwoSidedSign! That solves a longstanding problem for me.

  • Obscura
    Offline / Send Message
    Obscura high dynamic range
    I'm glad to hear that @thomasp :)
  • Maximum-Dev
    Offline / Send Message
    Maximum-Dev Polycount Sponsor
    Obscura said:
    You can take the distance to the center of the x and y component of the bounding box of the mesh, after subtracting 0,5 from the local position.
    Hi Obscura,

    Can you please share your setup for that?
  • radiancef0rge
    Offline / Send Message
    radiancef0rge Polycount Sponsor
    Obscura said:
    Applying this technique to realistic moss looks nice too.
    are those moss fibers cards?
  • Obscura
    Offline / Send Message
    Obscura high dynamic range
    Hello guys. Its the same setup as the grass in the stylized example. I had some small slightly angled planes for the moss, and I projected  The vertex normals of the underlaying geo to their vertex normal so in the shading you don't see that they are actually perpendicular cards. This at least doubles the vertex count in this particular case(the many small cards), but you can always do a lod without the moss cards. The texture atlas was like this, but not this particular one. I can't find the actual one right now.
    https://quixel.com/assets/shrkeiwi2

    Example image from wiki:

    The only difference is that my ones were only cards instead of these axis aligned crossed planes.


  • Yerus
    Offline / Send Message
    Yerus triangle
    Vertex tweaking is key when talking about NPRS. It's important to have the proper tools.
    Blender have a built-in normal tranfer for it's own, and I've seen a result pretty similar to that one. 
    Also, take a look at this vertex control: https://www.youtube.com/watch?v=6BdzaK2z43s
  • Obscura
    Offline / Send Message
    Obscura high dynamic range
    Obscura said:
    You can take the distance to the center of the x and y component of the bounding box of the mesh, after subtracting 0,5 from the local position.
    Hi Obscura,

    Can you please share your setup for that?
    @Maximum-Dev - This is how to do that.  Just a quick mockup, but I think its straight forward. I would call this a distance to point function. You can move the point by changing the value of the subtract to a vector parameter. You could also stretch the point by either dividing or multiplying the output of the subtract, before hooking it up to the distance node. Changing the length and falloff of the gradient can be done in multiple ways...You could also have more points than one by rolling the thing into a function and placing it multiple times. I'm also thinking that something like this would be doable for automatic spherical normals, by generating world space normals instead of gradients. But I haven't tried that.


    Example usage:


  • Maximum-Dev
    Offline / Send Message
    Maximum-Dev Polycount Sponsor
    Obscura, Thanks for sharing. The issue is when foliage is distributed procedurally it picks up the entire volume bounds instead of each meshes' inside the volume. Below you can see the dark spot is in the center of the large volume. Works fine when placed as single static mesh though.





  • Obscura
    Offline / Send Message
    Obscura high dynamic range


    @Maximum-Dev - In case of instanced static meshes, you could do it like this. Unfortunately the object radius has to be manually set. I didn't find a way to stabilize it. 
  • Maximum-Dev
    Offline / Send Message
    Maximum-Dev Polycount Sponsor
    Obscura, One remaining issue is with scale variation the dot can't be centered on all instances anymore. But that has very good potential and already a good start for me to play around and improve the foliage lighting with this. Many thanks

  • Maximum-Dev
    Offline / Send Message
    Maximum-Dev Polycount Sponsor
    Obscura, Ended up selecting some verts in the middle of the tree and doing a green vert paint. Inverting it in material and plugging to AO slot. Looks fine now regardless of scale variation.


  • Obscura
    Offline / Send Message
    Obscura high dynamic range
    Can't try it currently, but I think if you would multiply the constant object radius parameter from my example, by an object scale node, it should work with scale variation too. Will check it out later.
  • warvlax
    Hey obscura ! thanks for your advices but i struggle to get the result i wish and i thought that maybe you can help me ? 

    The tree on the right is using your tech and the one on the left as just cast shadows disabled how can i reduce / remove all the small inner shadows when cast shadows is on ? 

    i've tried playing with bias but only putting it to something between 5 and 7 would make them vanish which is way to high for other objects. 

    Changing shadow resolution doesn't work also i'm using dynamic lighting !

    Thanks in advance !
  • Obscura
    Offline / Send Message
    Obscura high dynamic range
    Hi @warvlax . Try adjusting the shadow bias setting of the light source.
Sign In or Register to comment.