Bug: ObjectPosition / ActorPosition In Conjunction With Instanced Foliage

,

I use ActorPosition (or ObjectPosition) in a material that is appled to instanced foliage. Unfortunately that doesn’t seem to work as it returns the position of their container InstancedFoliageActor, rather than the trees themselves. I imagine that this is a bug so I am filing it as such.

Best regards,
Damir H.

Are you spawning in the foliage objects with a foliage spawner or are you painting them on manually? Does this occur in a clean, blank project with no additional content? Can you show me a screenshot of the material setup you are using?

Hey there ,

I did 3 tests: Procedural generation using the spawner, painting a foliage type, and painting a static mesh directly.

Here is my material:


The results for the first two were the same - The actor position is taken from the InstancedFoliageActor.


When I painted the static mesh directly all the instances took the color based on the position of the cluster center (Image, Image).


Hey , I managed to “fix” it. Namely, I was digging through the shader code and found this in MaterialTemplate.usf:

/** Return the object's position in world space */
float3 GetObjectWorldPosition(FMaterialPixelParameters Parameters)
{
	return Primitive.ObjectWorldPositionAndRadius.xyz;
}

float3 GetObjectWorldPosition(FMaterialTessellationParameters Parameters)
{
	return Primitive.ObjectWorldPositionAndRadius.xyz;
}

/** Return the object's position in world space. For instanced meshes, this returns the instance position. */
float3 GetObjectWorldPosition(FMaterialVertexParameters Parameters)
{
	#if USE_INSTANCING || PARTICLE_MESH_FACTORY
		return Parameters.InstanceLocalToWorld[3].xyz;
	#else
		return Primitive.ObjectWorldPositionAndRadius.xyz;
	#endif
}

Seeing this, it’s obvious that only the Vertex shader portion respects instanced meshes. So I changed my material to use the vertex shader and it worked:



I suppose it technically still is a bug, but this is the workaround.

Hi ,

I did some digging and found what is going on. It turns out this is not a bug. The workaround you posted is actually one of the correct methods to do what you are wanting to do. This is because foliage objects are treated as instances of the same single object. So when doing Object position it is getting data from the single origin point as opposed to a per instance, so all of the foliage instances are receiving the same exact data. If you want to affect each instance individually, use a Per Instance Random node or follow the steps you have already taken to be able to affect them per instance as opposed to as one object.

Hey there ,

Thanks for the clarification. Unfortunately it’s a bit unwieldy to get all 3 world coordinates since texture coords only outputs a vector2… meaning I have to plug XY into one custom channel, and the Z into another, then combine them when I use it. Is this a big performance overhead?

Best regards,
Damir H.

There shouldn’t be a major performance hit.

Hm… For some reason such trick work for XY coordinates but not Z (but works for Z for non-instanced mesh). I know UV are only vector2.
Do you have any idea?

UPDATE:
Nevermind, instanced meshes just have different object bounds sometimes (need to add offset)