All streams
Search
Write a publication
Pull to refresh
24
1.3
Костромин Кирилл @SadOcean

User

Send message
Я иногда себе могу контраргументов накидать кучу, что уж про остальных говорить
Ну, это тоже возможная архитектура. Гибкая даже.
Просто она достигает гибкости не за бесплатно — позднее связывание и дополнительные проверки/конвертации могут запутать код.
Если бы у вас было больше спецификаций и вы бы сделали базовый параметр с необходимыми базовыми свойствами — вышло бы лучше, но почему бы и нет.

Причем такая архитектура есть.
Android спокойно живет с активностями, данные через которые передаются через интенты — по сути словари строка-объект.
Каждая активность может сама создавать их и принимать/интерпретировать. О передаче посередине заботится система.

И ничего, живут как то, довольно простая и универсальная система.
Ну Я не спорю ведь: ООП — для людей, не для программ.
Время программистов дороже, чем машинное, все дела. Компьютерные мощности в мире и на 1 % не утилизируются так то.
Но если целевое оборудование определено или задача требует выжать максимум возможностей — проблемы процессоров и кешей становятся нашими проблемами.
Нужно уметь их решать.
Если ООП мешает — нужно решать в ущерб ООП.
Благо жить можно и так, к тому же такие места обычно редки — вполне можно пожертвовать сложностью и читаемостью ради них.
Да, а вот это уже круто.
Ну бубны то есть, просто их осуществляет unity.
Я проверил.
using UnityEngine;

public sealed class DrawMeshInstanced : MonoBehaviour {
    [SerializeField]
    private Mesh instancedMesh; // Set from editor
    [SerializeField]
    private Material material; // Set from editor
    [SerializeField]
    private int meshCount = 1023;

    private Matrix4x4[] matrices;
    private Vector3[] positions;
    private MaterialPropertyBlock block;

    private void Start() {
        matrices = new Matrix4x4[meshCount];
        for (int i = 0; i < matrices.Length; i++) {
            matrices[i] = Matrix4x4.TRS(Random.insideUnitSphere * 10f, Random.rotationUniform, Vector3.one * Random.Range(0.5f, 1f));
        }
        block = new MaterialPropertyBlock();
        block.SetColor("_Color", Color.red);
    }

    private void Update() {
        
        Graphics.DrawMeshInstanced(instancedMesh, 0, material, matrices, meshCount, block);
    }
}

Вот, у меня получилось 3 батча на 1000 кубиков.
Этим способом можно отрисовать одну сетку с одним материалом.
В MaterialPropertyBlock нельзя передать по сету свойств для каждой модели. Это модификация материала для всех GPU инстансов.
Таким образом, как Я и сказал, не получается один батч для разных анимаций.
Для разных анимаций нужно иметь либо разную сетку, либо разные свойства материала (не важно, время или сдвиг)
Можно использовать хаки — например вычислять разницу в анимации по физическому параметру, к примеру, позиции.
Поэтому метод работает, к примеру, для деревьев. Можно замутить отряд юнитов.
Но без разбиения батчинга не получится сделать управляемые разные анимации разным юнитам.

Не проблема получить 1 батч с одним материалом. Проблема получить с разными.

Впрочем, это нельзя сделать только через DrawMeshInstanced.
Я не утверждаю, что этого нельзя сделать в принципе.
Возможно, такие методы в новых api есть.
Просто сама возможность таких хаков противоречит тому, что Я читал про работу видеокарт. 1 отрисовка — 1 состояние, 1 набор всех стейтов отрисовки и юниформов параметров — света, кастомных переменных и прочего.
Ну 8000 значений для процессора — это экономия на спичках, даже если они упрятаны в объекты и каждый достается по ссылке. Но можно и так, это экономия ценой сложности обслуживания анимации объектов.
Моя претензия скорее к тому, что будет 8000 материалов с разными свойствами + текущее время — для видеокарты это все равно будет 8к материалов с переключением стейта (просто в первом случае будет меняться кадр в каждом материале, а в вашем случае — время в каждом материале).

Да, сами вы не будете изменять свойство материалов. Это будет делать Unity, пробрасывая в юниформ время вместе со свойствами очередного материала. В документации явно это обозначено.

Можно группировать юнитов с одинаковым временем кадра, делать им один инстанс материала и они будут батчится, тогда профит будет.

Товарищи выше говорят, что вроде есть варианты менять свойства материала во время одного батча в рамках одного DrawCall. Возможно для этого есть функционал в новых Api, в OpenGL <= 4 Я такого не встречал. Справедливости ради, это не моя сильная сторона, Я работаю с мобилками, там таких требований обычно не ставят.
Ну и в любом случае это хаки и оптимизации, специфичные для API платформы. Не из коробки.
Хотя если задача стоит, почему бы и нет.
Для всех материалов все равно придется передавать время ведь.
Все равно каждый кадр будет обновляться на всех материалах.
Я имел в виду только то, что хотя моделька одна и текстурка одна, время анимации передается через uniform, поэтому отрисовка каждой модельки со своим временем будет прерывать draw call чтобы изменить состояние рендер пайплайна.

Сам метод все равно довольно быстрый и хороший, кто спорит.
Действительно хорошо подойдет для стратегий.

Но если немножко нахачить с кадрами анимаций, например, чтобы бегущие юниты имели 2-3 тайминга на бег на всех и 2-3 тайминга на idle на всех, то материалы еще и батчились бы, что сделало бы рендер еще быстрее, позволив выводить впечатляющее количество юнитов.
Массив состояний — имеется в виду текстура?

Я имел в виду только то, что хотя моделька одна и текстурка одна, время анимации передается через uniform, поэтому отрисовка каждой модельки будет прерывать draw call чтобы изменить состояние рендер пайплайна.

Сам метод все равно довольно быстрый и хороший, кто спорит.
Собственно получается просто разный способ создания инстансов материалов — непосредственно в объектах или оптом через Api.
Материалы то все равно будут рендериться разные.
Не знал, что есть такая штука, но ниже отметили, что все равно отдельный DrawCall для отдельного состояния модели.
Под объектом Я имел в виду модель в своем состоянии, не важно, каким образом она выводится.
Юнити вроде умеет батчить одинаковые материалы с одинаковыми свойствами, но изменение шейдерного юниформа (а кадр анимации получается передается через него) в любом случае меняет стейт рендера, что обрывает Draw Call.
Если честно, Я ковырялся в вопросе довольно давно, возможно в новых Api есть методы для изменения свойств материала в рамках одного кола.
Можно придумать другие хаки, например, прикрепить информацию о сдвиге по времени в пиксели модели. Но не думаю, что это серьезно поможет.
Так можно добиться, чтобы куча одинаковых моделей использовала разное время одной анимации, но при этом для изменения относительного времени нужно будет перегенерить модель, к тому же получиться больше вершинных данных — по сути каждый сдвиг будет давать новую модель.
Я бы хотел возразить по поводу модификации состояния.
Цель ОО дизайна — абстрагирование. Сделать объект с максимально простым поведением (и интерфейсом) снаружи, скрывающий сложное состояние и реализацию внутри.
Это не значит, что объект должен фанатично скрывать свое состояние и выглядеть снаружи как stateless. Частью его поведения вполне может быть то, что использующие его агенты знают его состояние и переводят объект из состояния в состояние. Важно лишь то, что для внешних агентов это делается просто и понятно.
Например объект для взаимодействия с оборудованием вполне может иметь состояния «не подключен», «подключен» и «неисправность» с описанием ошибки. Прекрасный объект, который скрывает в себе константы кодов ошибок, сложное api общения с устройством, детали подключения через usb.
В этом случае даже просто публичная переменная не является нарушением инкапсуляции — она часть публичного контракта и те, кто используют объект, о ней знают.
Геттеры сеттеры — просто сахар для того, чтобы иметь возможность сделать этот контракт безопаснее, оставить его простым снаружи (как переменная), но добавить проверку целостности, логгирование доступа и прочее внутри.
В этом смысле они не нарушают инкапсуляцию, а наоборот, являются удобным инструментом ее обеспечения.
Судя по всему это может быть ООП (а может и не быть, зависит, какой еще код будет)
Если вы будете и дальше каким то образом организовывать Person, методы работы с ним и методы поддержания согласованности в одном месте, и точно так же организовывать другие объекты, с которым работает Person или которые работают с ним — получится вполне себе ОО дизайн.
У вас будет объект Person, с которым вы будете работать через выделенный интерфейс.
Другое дело, что если у вас нет языковых инструментов, то будет тяжело провести это разграничение (его можно будет сделать только организационно) и его могут очень легко поломать.
Занятно, но так себе холст. Мерцание очень сильное.
Сами по себе базовые программистские задачи (ткань, змейка, 3д) гораздо интереснее.
Но почему бы и нет, нормальное экзотическое программирование.
Мы делали игру «жизнь» на двух сменяемых текстурах — буфферах.
Очень бодро бегает.
С производительностью будет сравнительно плохо, разные объекты будут иметь разные материалы (разные параметры времени анимации в шейдере). Впрочем, не уверен, возможно автор в этой деме делал тоже разные материалы.
В любом случае будет радикально лучше, чем если делать это на процессоре.
Определять текущее состояние можно только по таймингу.
Состояния как такового в этой системе нет — данные о нем теряются, остается только набор анимаций, идущий подряд.
Но таймер анимации хранится в компоненте и каждый кадр растится процессором и передается в материал. Так как управляется это со стороны процессора, никто не мешает в этом компоненте сохранить диапазоны анимаций и при управлении указывать стейт, и в компоненте доставать из информации о диапазоне время.
В любом случае, этот компонент должен как то работать с этой информацией — именно он управляет зацикленностью и режимом анимаций, для шейдера это просто число от 0 до 1.
Ну можно конечно и ECS, но вообще ситуация разруливается прекрасно и в рамках ООП.
Причем можно использовать сразу несколько методов, и все будут правильными.
Нет, вроде есть и объективные проблемы, проистекающие из типичных способов организации.
Например, организация объектов по ссылкам делает объекты удобными для понимания, но недружными к кешу процессора.
Есть подходы, когда данные реорганизуют под производительность. ECS
Впрочем тяжело сказать, является это проблемой прямо ООП или его нынешних организаций.
Нет, это просто значит, что вы построили хорошую и гибкую архитектуру данных, которая позволяет отложить часть решений по дальнейшей архитектуре данных (реализацию ткацкого станка) на потом.
Но вы все еще придумали архитектуру данных завода до или вместе с кодом завода и архитектуру данных станка до или вместе с кодом станка.

В этом смысле Я пожалуй согласен со статьей — Data-First
Но в остальном так себе — соломенное чучело ООП
Проблема в том, что и это будет данными — они будут отражать какую-то структуру и связи объектов.

Information

Rating
1,463-rd
Location
Ставрополь, Ставропольский край, Россия
Date of birth
Registered
Activity