Unity и VR для сложных строительных CAD-моделей

Я работаю в строительстве, и мы пытаемся визуализировать наши проекты, используя Unity и Oculus Rift.

В основном все наши модели создаются с использованием Revit, и мы экспортируем их в fbx и переносим в Unity. Для каждой модели, которая у нас есть (электрическая, механическая, архитектурная, фасадная...), мы генерируем fbx в Revit и приводим в Unity.

Модели содержат от 3000 до 60000 объектов (сеток) и от 3 до 40 миллионов полигонов. Когда мы пытаемся визуализировать модели в Unity, мы получаем очень низкий FPS, около 2–3 кадров в секунду, и вызовы пакетной отрисовки около 15000–20000.

Я считаю, что проблема заключается в сложности всех наших моделей, которые мы объединяем в Unity. Интересно, есть ли способ оптимизировать его, я уже пробовал децимацию, отключение теней, окклюзию, но, похоже, ничего не работает. Объединение моделей в один объект не вариант, потому что мы должны позволить пользователю выбирать и проверять отдельные элементы.

2 ответа

Я работаю над чем-то похожим, и я могу поделиться опытом для подобных задач со многими вершинами или сетками. Я пытаюсь визуализировать облака точек в Unity, и это очень сложная задача. В моем случае я сам создаю облака точек и не триангулирую их. Это помогает, но я все еще должен применить оптимизации.

Из моего опыта, если у вас есть вершины более 10 миллионов визуализированных в кадре, у вас начнутся проблемы с fps. Это может варьироваться в зависимости от вашего оборудования, конечно. Также я уверен, что это будет еще хуже с триангулированными сетками. Что я сделал, чтобы оптимизировать вещи следующие:

  1. Я начал с рендеринга объектов, находящихся в Camera Frustum. Для этого я использовал функцию IsVisibleFrom который является продолжением Renderer как это:

    используя UnityEngine;

    public static class RendererExtensions
    {
          public static bool IsVisibleFrom(this Renderer renderer, Camera camera)
          {
                Plane[] planes = GeometryUtility.CalculateFrustumPlanes(camera);
                return GeometryUtility.TestPlanesAABB(planes, renderer.bounds);
          }
    }
    

Затем вы можете использовать его следующим образом:

Renderer grid;
IEnumerator RenderVisibleGameObject()
{

    for (int i = 0; i < PointCloud.transform.childCount; i++)
    {
        grid = PointCloud.transform.GetChild(i).GetComponent<Renderer>();
        if (!grid.IsVisibleFrom(cam))
        {
            grid.gameObject.SetActive(false);
        }
        else
        {
            grid.gameObject.SetActive(true);
        }


        if (i == (PointCloud.transform.childCount - 1))
            yield return null;

    }

    StartCoroutine(RenderVisibleGameObject());
}
  1. Второй вариант будет, если это возможно, и если вы можете создавать сетки с более низкой детализацией, используя уровень детализации. По сути, он рендерит меши с низкой детализацией, которые находятся дальше от камеры.
  2. Последний вариант, который я могу порекомендовать, - это использование окклюзии. Это похоже на первый вариант, но он также заботится о окклюзиях, что было не так для меня, потому что у меня были только очки.

Вы также можете найти интересный набор инструментов Forge Unity AR/VR:

Как вы, наверное, знаете, Forge высоко оптимизирован для профессиональной визуализации больших CAD-моделей.

Другие вопросы по тегам