Camera facing foliage for trees via material

Hello dear people,

for the last five days i desperately searched for a way to make my tree foliage align with the camera direction via the material.

Unfortunately the math-hall (2.21) solution doesn’t work because it shrinks all billboards and merges them onto one vector.
Epics stylized foliage material solution doesn’t work either, because it only rotates on one axis but more importantly, it rotates all billboards around the object center. But for the right effect, each billboard should rotate around their own pivot point.
Im afraid we can’t use a particle system either for several reasons, one being the algorithm we made to place the trees as instant static meshes.

This GIF of Test Drive Unlimited shows exactly the effect im trying to archive via the material.

But the closest i came so far is this effect, below (made by Pontus Karlsson on YouTube). His effect works perfectly fine but unfortunatly only with UV spheres, causing in a stylized look, that doesn’t fit the style of our project.

If anyone can help me out here, you couldn’t imagine how thankful i’d be!

Best regards, Jan!

1 Like

Bumping this old thread as I’m also searching for a solution to this!

did you ever find how to do this?

@brisck1 @Quittzer Hmm… the thing that makes this so tough is the tex coord to world position translation, since each billboard location needs to be evaluated individually. While I’m not sure of the method for that, I might have an idea for a workaround.

Most billboard shaders do a comparison between the object position and the world position, and this is where something like leaves on a tree will fail, since the object position will be the tree base. Using instances for the leaves could solve this issue, since then you can use instance position instead.

OR… what if you store the leaf offset from object position in the vertex color of the 4 vertices of the leaf billboard? This will localize the rotation values and should give you the desired result- admittedly with a lot of setup. I believe vertex colors clamp the floats though, so you’d have to set the location/1000 or some similar number.

What that logic might look like:

Replacing the object position in a shader such as this:

And in your DCC, a leaf billboard with a pivot location of -300,500,150 would have its vertices saved as vertex color -.3,.5,.15. If you have the coding skills, a process like this should be very easy to automate through Python or Houdini.

@sarahlenker not sure i understand, but here is my node setup ive already got, it works great for single planes like the sun in my scene but not for trees

Yeah, so those Object Position nodes are where you would replace it with the logic I sent. The solution I sent though will require you to make changes to your trees in a 3D modeling program.

Here is an example tutorial on how to set up vertex colors in Blender

As I mentioned earlier, you would want to set the vertex color value equal to the billboard pivot location (assuming the tree’s pivot location is set to 0,0,0).

The reason your current billboard setup doesn’t work with trees is because the Object Location is grabbing the pivot point of the tree. In reality, to move the leaves, you need to grab the pivot location of the individual leaf planes. This solution allows you to do that.

Let me know if there’s anything in particular you need explained more in-depth.

thanks! i appreciate you explaining this, i do got a couple more questions. do i need to paint every leaf card a seperate color? or do i make all the leaf cards one color? here is my tree model, maybe you can point me more in the right direction on how to do this.

Hi there! Sorry for the late reply, this missed my notifications.

Sorry for the poor quality haha, I don’t have my Wacom tablet right now. I’m going to try and break this down further so hopefully you can understand exactly why we’re doing this.

A is the world origin, and will be the origin of the tree when you import this into Unreal. If we create a billboard material and grab the Object position, this is the point that it will grab by default. That is why the billboarding fails, because it’s trying to orient itself around this point, which is relative to the entire mesh but not the individual leaves.

B is the origin of the leaf plane. THIS is the point that we want to orient the billboard around. So how do we make that conversion? Well, that’s where the vertex color comes into play. We can’t grab this world location because it’s pretty arbitrary, so we need to set it manually.

(You can skip this section if it’s going to confuse you, but I’m going to go into the full detail of how this works for your reference) So let’s say we set the vertices of a single leaf plane to the value of their pivot. Why do we need the logic in the material of Object Position + Vertex Color? Well, that pivot point is relative to the origin of the tree. If we moved a tree into Unreal and set its world location to 0,0,0, just using the vertex color would work. However, when you move the tree to a new location, this vertex color value will no longer be relevant. By adding it to the object position, our values stay localized to the tree and thus will always be correct.

So, what values are we setting and why? C in this diagram are the vertices of the leaf plane. Since we want the billboard to happen per-leaf plane, these vertices need to all have the same value, and they need to be the value of the plane’s pivot point (B).

So, how do we do that? I’m not confident that the vertex color can save large values, so we will need to make the value under 1. How do you do that? You divide your original number. In my example above, we’ll divide by 1000, then later in the material, multiply that back in to get the correct pivot location again. So, let’s say the pivot point B’s world location is 450, 233, 600. You need to paint the RGB values as .45 R, .233 G, .6 B. We do this because for all intents and purposes, a color is just a vector, and we use vectors to determine world locations, making the vertex color value compatible with the pivot location.

Let me know if that breakdown helped!