Calculating the screen size of a foliage instance using object bounds?

So for a long time, I’ve been wanting to find a way to calculate the screen size (or radius) of foliage instances via a material for various reasons, but until recently, there didn’t seem to be a solution, as there was no per-instance information available on an instance’s current size/radius. However, recently, I saw this tweet:

Which got me wondering, if we now have access to foliage instances’ worldspace bounds, could the screen size be extrapolated from that information?
I’ve tried multiple things here but I have to admit it’s all a bit over my head, especially the process of converting things from worldspace to screenspace/clipspace.

Does anyone have any ideas? Thanks!

1 Like

Hi, Thanks for sharing that information - not being able to get the instance bounds has frustrated me for a long time, I wasn’t aware that we could now.

I added a system into a tool to create UVs that expressed the pixel position to overcome the issue for me (didn’t need to know the actual bounds or radius) but this looks like a much more elegant solution (for 5.1 and up).

By the looks that information is stored in the shaders uniform struct, so it will need a custom HLSL node to get that information - I’m going to give that a try soon, I’ll post any results I get and a shapshot of the code.

Regarding the ScreenSize - are you wanting the perspective corrected size or just the radius of the mesh itself in the material? I think I’m probably over-thinking it regarding the perspective part but though I should ask.

Hi,

Basically what I want to do is something like this:

However, as I don’t have the Object Radius data with foliage instances, I’m wondering if radius can be calculated from the Worldspace Bounds instead, now that they are available?

Edit: When you say you’ll need an HLSL node to access the data, are you referring to the instance bounds? If so you can do it with normal nodes - see the second tweet for an example.

I see - yes just the radius.

The first time I looked at the 2nd link it was broken, I can’t find anything in the UE source code for an InstanceBounds Node or an InstanceCenter - but I did find HLSL code that references them - I’ll keep looking.

No I can’t find anything in there as far as nodes - I think his post on “Custom HLSL” is meaning he has made is own Nodes for that or in a custom source base.

You’re right, looks like I didn’t dig into it enough - seems like they are calling these in custom HLSL nodes:

GetPrimitiveData(Parameters).InstanceLocalBoundsExtent.xyz
GetPrimitiveData(Parameters).InstanceLocalBoundsCenter.xyz

Thanks again - this is a great step forward with instancing!

Here’s a simple radius from the distance of the extents:

Edit: (add a *0.5 to the return otherwise it’s a diameter…)

Thanks for sharing! I replicated your custom HLSL node with the addition you suggested, which looks like this:

float3 be=GetPrimitiveData(Parameters).InstanceLocalBoundsExtent.xyz;
return distance(be/2.0,-be/2.0)*0.5;

With my material now looking like this:

However it doesn’t seem accurate.

I did a test with the above method on a static mesh with the standard radius node, and on a foliage instance with the HLSL code, both have no scaling, and get the following discrepancy

Not sure where I’m going wrong yet, but I feel much closer than I’ve been before!
Any ideas? :slight_smile:

Also noticed the foliage scale is not taken into account either, but that’s a separate problem

That amazing if true, but when I try that in my HLSL node I get completely different results between instances and static meshes (black is a foliage instance, green is a static mesh):

The Result is the same with a HLSL node and a normal Object Radius node… I wonder if something is wrong with how I’m calculating the object’s screen space percentage

Here’s the result with just the object radius plugged into the debug node in both materials

Sorry, I was testing with ISMs which apparently work - tested it with foliage and I’m getting the same issue - it should be as simple as multiplying the return extent vector by the scale - I’ll add that to the code shortly.

1 Like

Sounds good, and thanks again for your help! :slight_smile:

None of the scale values reflect the instance either, the transform matrix is the same - almost back to square one.

Even stranger is that it has stopped working in the ISMs and HISMs! (I’m sure I didn’t change the code either, but it does now act as I thought it has in the past at least)

There’s something I saw in the UE code which seemed to get the InstanceManager and Instance Index and find the transform from there - I’ll take a look at that this evening…

Otherwise - you could add UVs to the mesh as I did in my tool to give you the position (0-1) of the pixel (it would take 2 sets of UVs to get all 3 dimensions oc) - or another method could be to store the scaled radius in the instance custom data…

Anyway, here’s a link to rdMeshTools which can create those UVs - but I’d still like to try the InstanceData access way anway.

The ObjectScale node seems to reflect the correct scale, so something like this kind of works:

The Custom node is just “return GetPrimitiveData(Parameters).InstanceLocalBoundsExtent.xyz;”

The only problem now is that the rotation is wrong…

Is that the desired effect?

3 Likes

@RecourseDesign Sorry for the late response, my PC crapped out shortly after you posted this so haven’t been able to try it out until just now.

Just wanted to say this worked perfectly, and thankyou for you expertise - I’ve learned a lot from this! :slight_smile:

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.