There is a hack that let you pass additional per-instance data.
However, it can be done only if you make new drawable component and manually fill or edit batches (maybe inherited from existing one).
float distance_{};
/// Geometry.
Geometry* geometry_{};
/// Material.
SharedPtr<Material> material_;
/// World transform(s). For a skinned model, these are the bone transforms.
const Matrix3x4* worldTransform_{&Matrix3x4::IDENTITY};
/// Number of world transforms.
unsigned numWorldTransforms_{1};
/// Per-instance data. If not null, must contain enough data to fill instancing buffer.
void* instancingData_{};
/// %Geometry type.
GeometryType geometryType_{GEOM_STATIC};
};
/// Base class for visible components.
class URHO3D_API Drawable : public Component
{
URHO3D_OBJECT(Drawable, Component);
friend class Octant;
void SetVSMMultiSample(int multiSample);
/// Set post processing filter to the shadow map.
void SetShadowMapFilter(Object* instance, ShadowMapFilter functionPtr);
/// Set reuse of shadow maps. Default is true. If disabled, also transparent geometry can be shadowed.
void SetReuseShadowMaps(bool enable);
/// Set maximum number of shadow maps created for one resolution. Only has effect if reuse of shadow maps is disabled.
void SetMaxShadowMaps(int shadowMaps);
/// Set dynamic instancing on/off. When on (default), drawables using the same static-type geometry and material will be automatically combined to an instanced draw call.
void SetDynamicInstancing(bool enable);
/// Set number of extra instancing buffer elements. Default is 0. Extra 4-vectors are available through TEXCOORD7 and further.
void SetNumExtraInstancingBufferElements(int elements);
/// Set minimum number of instances required in a batch group to render as instanced.
void SetMinInstances(int instances);
/// Set maximum number of sorted instances per batch group. If exceeded, instances are rendered unsorted.
void SetMaxSortedInstances(int instances);
/// Set maximum number of occluder triangles.
void SetMaxOccluderTriangles(int triangles);
/// Set occluder buffer width.
void SetOcclusionBufferSize(int size);
/// Set required screen size (1.0 = full screen) for occluders.
void SetOccluderSizeThreshold(float screenSize);