Четверг, 19 Декабря 2024, 02:32

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Проблема с оперативной и видео памятью
robertonoДата: Понедельник, 11 Ноября 2013, 16:04 | Сообщение # 1
Чокнутый Кот
Сейчас нет на сайте
Всем привет! Пока я делал систему которая будет комбинировать по 100 объектов в 1 меш каждый кадр я наткнулся на такую проблему которая завела меня в тупик...
С каждым скомбинированным мешем через mesh.combineMeshes создается новый объект, а значит новый VBO и т.е. это всё пихается в видео память (как написано в Statistics), но вроде ещё пихается в оперативную тоже.
Дело в том что в окончательном варианте когда всё будет уже сделано, комбинирование мешей будет делаться каждые 2 - 5 секунды. И после большого времени игры видео и оперативная память полностью забьются. Делая Destroy объект из памяти не удаляется.
И вообщем я совсем не знаю что делать. У меня 8 GB RAM и 4 GB video, и всё равно быстренько всё забивается! Что делать?
Вообщем если у кого нибудь есть хотя бы какие нибудь идеи - пишите.
Заранее спасибо.
RangerДата: Понедельник, 11 Ноября 2013, 16:31 | Сообщение # 2
почти ветеран
Сейчас нет на сайте
что с количеством вершин и многоугольников на сцене?
Тоже растут?


robertonoДата: Понедельник, 11 Ноября 2013, 16:50 | Сообщение # 3
Чокнутый Кот
Сейчас нет на сайте
Ranger, допустим здание состоит из кубов, в сумме получается 2000 вершин, при комбинировании создается один меш, тоже 2000к вершин, а те кубы отключаются (setEnable)
RangerДата: Понедельник, 11 Ноября 2013, 17:11 | Сообщение # 4
почти ветеран
Сейчас нет на сайте
нее... ну посмотри по статистике.. я не помню как это назвается отображение DC и вершин.UnityStats.drawCalls ,UnityStats.triangles ,UnityStats.vertices

Я так понял, что запиливание в 1 меш было вызвано задачей оптимизации.
Я не ковырял, но, мне кажется Юнитине будет осекать вершины внутри мешей.

Добавлено (11.11.2013, 17:11)
---------------------------------------------

Цитата robertono ()
а те кубы отключаются (setEnable)

setenable, насколько помню, отключает только рендеринг.
В памяти они все равно держатся на случай, если ты их включишь.


robertonoДата: Понедельник, 11 Ноября 2013, 17:38 | Сообщение # 5
Чокнутый Кот
Сейчас нет на сайте
Ranger, удалять со сцены эти кубы нельзя. Это для того что бы я потом мог удалить скомбинированный меш изменить что то в этих кубах и опять скомбинировать.
setenable отключает рендеринг ,все скрипты и компоненты которые у объекта.
nwsxДата: Понедельник, 11 Ноября 2013, 19:13 | Сообщение # 6
постоянный участник
Сейчас нет на сайте
генерируй кубики и uv вершины процедурно, сразу в один меш ы

Westboro
Dungeon Journey на Google Play
robertonoДата: Понедельник, 11 Ноября 2013, 19:45 | Сообщение # 7
Чокнутый Кот
Сейчас нет на сайте
nwsx, это не всегда будут кубы, это будут столы и сотни других моделей

Добавлено (11.11.2013, 19:45)
---------------------------------------------
nwsx, таким способом я точно не могу делать.

seamanДата: Понедельник, 11 Ноября 2013, 23:05 | Сообщение # 8
старожил
Сейчас нет на сайте
Цитата
Делая Destroy объект из памяти не удаляется.

Сорри, я нормально с combineMeshes не разбирался, но все же четкое ощущение, что тут просто обычная утечка памяти. Т.е. мало удалить объект, нужно чтобы на массив его вершин, трисов и т.п. никто не ссылалася, иначе этот массив так и будет сидеть в памяти. Новое создание - новый массив, который вечно сидит в памяти. Тут нужно смотреть в первую очередь на архитектуру приложения, т.к. утечки на шарпе - это достаточно явная промашка программиста.
robertonoДата: Понедельник, 11 Ноября 2013, 23:42 | Сообщение # 9
Чокнутый Кот
Сейчас нет на сайте
seaman, Ваши слова мне почти ничего не сказали понятного... Просто VBO этот , это как бы уникальный объект которого ещё небыло на сцене. После комбинирования он и создается. Даже если его удалить он ещё остается в памяти. Тут вот я и не знаю что делать. Как удалить объект отовсюду ? Со сцены, из памяти..
RangerДата: Вторник, 12 Ноября 2013, 05:22 | Сообщение # 10
почти ветеран
Сейчас нет на сайте
Цитата seaman ()
просто обычная утечка памяти

seaman, Тут скорее задвоение (затроение, и т.д.)
robertono не удаляет базовые меши после создания большого меша

robertono, посмоьтри и попробуй следующее:
1. возможна ошибка в скрипте : в новый меш входит старый меш + все(!) меши объектов, а не только новорожденные

2. оценивай количество памяти соразмерно генерации объектов. количество занятой памяти должно рости линейно от количества объектов. если растет по экспоненте, значит ты дублируешь данные в меш. (см п.1)

3. Посмотри Destroy чего ты делаешь. Возможно, что Destroy убивает объект, а не удаляет меш. Сделай руками вызов дестроя меша из скрипта.
проверь экземпляр меша он д.б. равен null




Сообщение отредактировал Ranger - Вторник, 12 Ноября 2013, 05:31
robertonoДата: Вторник, 12 Ноября 2013, 17:07 | Сообщение # 11
Чокнутый Кот
Сейчас нет на сайте
Цитата Ranger ()
1. возможна ошибка в скрипте : в новый меш входит старый меш + все(!) меши объектов, а не только новорожденные

Комбинирую я меш так: сначала беру первые 100 кубов из массива, комбинирую, потом следующие 100 + тот который уже скомбинирован и так делается меш.

Цитата Ranger ()
Возможно, что Destroy убивает объект, а не удаляет меш.

Destroy(GameObject)
Удаляю тот объект, который в компонентах содержит Mesh Filter (здесь сам скомбинированный меш) и Mesh Renderer.
Из памяти он не пропадает.
seamanДата: Вторник, 12 Ноября 2013, 21:37 | Сообщение # 12
старожил
Сейчас нет на сайте
Цитата
Удаляю тот объект, который в компонентах содержит Mesh Filter

Утечка - если на mesh этого Mesh Filter где-то есть ссылка он не удалится. Удалится объект, который удаляешь, компоненты, которые на нем висят, а mesh - нет.
1. Проверяешь нет ли на них ссылок. Если нашел - обнуляешь, или лучше перестраиваешь приложение так, чтобы этих ссылок просто не было.
2. Если найти не сумел. Пробуешь перед удалением объекта обнулить все ресурсоемкие его части MeshFilter.mesh = null. Это костыль и лучше делать как в 1.
robertonoДата: Четверг, 14 Ноября 2013, 23:31 | Сообщение # 13
Чокнутый Кот
Сейчас нет на сайте
seaman, спасибо большое, появится время попробую!

Добавлено (14.11.2013, 23:09)
---------------------------------------------

Цитата seaman ()
1. Проверяешь нет ли на них ссылок. Если нашел - обнуляешь, или лучше перестраиваешь приложение так, чтобы этих ссылок просто не было.

Нету, всё было обнулено.

Не то это всё.
Прочитал на ансверсах юнити3д.ком о таких вещах, как : не нужно делать new Mesh(); .
на unity3d.ru прочитал что нужно делать resources.unloadunusedassets(); и что это связанно с VBO. Однако это не повлияло ни на что. Память всё равно заполняется. Сейчас повторю ещё тесты с Resources. Говорят это как раз то что очищает память после Destory и делать это нужно желательно smile

Цитата Ranger ()
я не помню как это назвается отображение DC и вершин.UnityStats.drawCalls ,UnityStats.triangles ,UnityStats.vertices

что это ? В юнити такого нету.
А кстати, можно ли как то в OnGUI вывести из статистики что то конкретное? Например сколько сейчас памяти видео заполнено.

Добавлено (14.11.2013, 23:31)
---------------------------------------------
Повторил тесты с unloadunusedassets : потрясающая вещь, очищает кучу памяти, одно здание с примерно 2300 кубов комбинировалось по 100 кубов за 1 кадр а потом в один целый меш и без очистки набирается 42 МБ , а после очистки 8 МБ. Конечно прирост большой smile На одну проблему меньше, вопросы выше ещё в силе, тему пока не заканчиваю.

RangerДата: Пятница, 15 Ноября 2013, 06:20 | Сообщение # 14
почти ветеран
Сейчас нет на сайте
Цитата robertono ()
Комбинирую я меш так: сначала беру первые 100 кубов из массива, комбинирую, потом следующие 100 + тот который уже скомбинирован и так делается меш.


Накидал код по быстрому взяв за основу пример. Сам меши не ковырял, но ,думаю, ты допилишь до рабочего.

Код
public Mesh MycombineMesh(Component Mymesh,Component[] meshFilter){
    Mesh NewMesh;
    Component[] WorkMeshFilters = new Component[meshFilter.length];
    CombineInstance[] combine = new CombineInstance[meshFilters.Length];
      
    combine[0].mesh = Mymesh.sharedMesh;
          combine[0].transform = Mymesh.transform.localToWorldMatrix;
      
    int i = 1;
    while (i < meshFilters.Length) {
              combine[i].mesh = meshFilters[i].sharedMesh;
              combine[i].transform = meshFilters[i].transform.localToWorldMatrix;
              i++;
          }
    NewMesh = new Mesh();
    NewMesh.CombineMeshes(combine);
    Destroy(Mymesh.sharedMesh); //!!!!!!!!!!! =|=============> здесь грохается старый меш
    return NewMesh;
      
   }


Из полезного тебе здесь только
Код
Destroy(Mymesh.sharedMesh); //!!!!!!!!!!! =|=============> здесь грохается старый меш


Удачи.

Добавлено (15.11.2013, 06:20)
---------------------------------------------

Цитата robertono ()

Цитата Ranger ()
UnityStats.drawCalls ,UnityStats.triangles ,UnityStats.vertices

что это ? В юнити такого нету.
А кстати, можно ли как то в OnGUI вывести из статистики что то конкретное? Например сколько сейчас памяти видео заполнено.

У них какая то хрень с документацией.. Через скрипт референс не ищется.
Еле нашел через гугл (возможно в новой версии не поддерживается):
Правда страница на японском wink
http://docs-jp.unity3d.com/Documentation/ScriptReference/UnityStats.html




Сообщение отредактировал Ranger - Пятница, 15 Ноября 2013, 05:39
robertonoДата: Пятница, 15 Ноября 2013, 17:26 | Сообщение # 15
Чокнутый Кот
Сейчас нет на сайте
Ranger, возможно не ищется потому что в референсе только UnityEngine.
Ещё есть UnityEditor, где и есть этот UnityStats.
UnityEditor.UnityStats.vboTotal
Можно прописать в using.

Добавлено (15.11.2013, 17:23)
---------------------------------------------

Цитата Ranger ()
Накидал код по быстрому взяв за основу пример. Сам меши не ковырял, но ,думаю, ты допилишь до рабочего.

Незнаю зачем Вы сделали для меня этот пример... Хотя я вроде не говорил что всё уже готово..
Мой код-велосипед из 318 строчек, выполняющий покадровое комбинирование. Я всё таки выложу это.


Добавляются туда меши с помощью функции AddToQueue, до этого обрабатывается в моём MeshMerger:



Если нужно скомбинировать меш, то просто нужно вызвать что то типо такого:
GameObject.Find("Another Scripts").GetComponent<MeshMerger> ().Combine(gameObject);

Добавлено (15.11.2013, 17:26)
---------------------------------------------
В скрипте CombineQueue очень много закомментированных строчек если что)

  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг