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. Это может варьироваться в зависимости от вашего оборудования, конечно. Также я уверен, что это будет еще хуже с триангулированными сетками. Что я сделал, чтобы оптимизировать вещи следующие:
Я начал с рендеринга объектов, находящихся в 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());
}
- Второй вариант будет, если это возможно, и если вы можете создавать сетки с более низкой детализацией, используя уровень детализации. По сути, он рендерит меши с низкой детализацией, которые находятся дальше от камеры.
- Последний вариант, который я могу порекомендовать, - это использование окклюзии. Это похоже на первый вариант, но он также заботится о окклюзиях, что было не так для меня, потому что у меня были только очки.
Вы также можете найти интересный набор инструментов Forge Unity AR/VR:
Как вы, наверное, знаете, Forge высоко оптимизирован для профессиональной визуализации больших CAD-моделей.