кастомная функция позволит обращаться к другим сервисам в системе, получать данные, что-то проверять.
для макро и инклюд все данные должны быть уже готовы.
макро удобней инклюдов для мелких вещей, типа инпутов тем что их можно кучу поместить в один файл и синтаксис более простой.
но делать все макросами плохо - они загружаются каждый раз, в отличие от инклюдов, которые подгружаются только когда надо.
UPD подведу итог, я бы рекомендовал
1) использовать кастомные твиг функции, когда требуется какая то сложная логика или запрос данных из системы, но не рекомендовал бы ее для генерации html, просто потому что html в пхп не гуд. но в кастомной функции вы можете вызвать render другого шаблона, это норм, просто может ухудшить поиск верстки для фронтендеров (в случае инклюда для них все очевидно).
2) макросы - для кучки небольших вещей которые используются часто и повсеместно (инпуты)
3) инклюды для остальных кейсов, то есть когда данные уже есть и нужно их оформить в html