Рендеринг в параллельном потоке в Unity3D 3.5

Раздел, посвящённый самому важному - скорости.

Рендеринг в параллельном потоке в Unity3D 3.5

Сообщение VBProgr 17 янв 2012, 22:02

Есть мысли по поводу нерационального торможения рендеринга при использовании события Update.

Знакомая ситуация: пока во всех Update всех объектов выполняется код n-е количество мс, рендер мог бы показать за это время еще несколько кадров, если бы не ждал их завершения. В таком случае, следующий апдейт мог бы быть вызван сразу, как только будет завершен предыдущий.

Может возникнуть ситуация, когда часть объектов переместилось, потом произошел рендеринг - и игрок видит, что часть объектов висит в воздухе (если мы перемещали не родительский объект, а его дочерные объекты по отдельности внутри Update).

Чтобы такого не было, изменения параметров объектов в Update должны быть типа транзакций, т.е. пока не закончиться выполнение Update изменения transform и пр. не будут переданы рендеру, но в тоже время должны быть сохранены. Это означает введение своеобразного кэша объектов для рендера (изменения физики и встроенных компонентов (понятно, что не всех) должны попадать в кэш сразу после очередного настоящего кадра, без транзикций, а вот изменения параметров объекта из Update - по завершению очередного прохода этого самого Update).

Понимаю, что тут есть множество ньюансов и все-такое, но схема претендует на значительное увеличение FPS.

Для выполнения кода действительно в каждом кадре можно использовать, например OnPreRender и т.п.

Кто уже знаком с новой юнити, этот рендеринг в другом потоке - он реализует подобную схему? Если да - то юнити зэбест :)

Кстати, надо проверить, мб это можно реализовать через InvokeRepeating... если выполнение Invoke не замедляет рендер и, при том, позволяет добиться той же частоты вызова, что и Update.
skype: vbprogr
Добавить vbprogr в Skype
VBProgr
UNITрон
 
Сообщения: 319
Зарегистрирован: 24 сен 2011, 14:11

Re: Рендеринг в параллельном потоке в Unity3D 3.5

Сообщение DbIMok 17 янв 2012, 22:35

VBProgr писал(а):рендер мог бы показать за это время еще несколько кадров

кому показать? монитор рисует картинку 60 раз в сек
VBProgr писал(а):рендер мог бы показать за это время еще несколько кадров

кадров с чем? изменяем мы transform.position, не дождались расчетов, послали старые координаты. зачем?
VBProgr писал(а):но схема претендует на значительное увеличение FPS.

вам надо того, в [unity 3D] идти работать )
VBProgr писал(а):он реализует подобную схему?

он реализует разделение рендеринга на потоки. за счет этого на десктопах и XBOX получилось разнести по разным ядрам (если они есть).
правильный вопрос - половина ответа. учитесь формулировать вопросы понятно.
Новости > _Telegram чат @unity3d_ru (11.6k/4.8k online) > _Telegram канал @unity_news (4.7k подписчиков) > Телеграм тема > "Спасибо"
Аватара пользователя
DbIMok
Адепт
 
Сообщения: 6372
Зарегистрирован: 31 июл 2009, 14:05

Re: Рендеринг в параллельном потоке в Unity3D 3.5

Сообщение VBProgr 17 янв 2012, 22:43

Ок, в transform будут те же значения и картинка будет прежней. А о партиклах, к примеру, Вы подумали? Они то могут перемещаться встроенными компонентами, тогда их рендеринг не будет зависеть от тормозов Update.

InvokeRepeating вместо Update может иметь значение только если он будет выполняться отдельно от рендера. Т.е. можно тупо вставить в функцию инвока System.Threading.Thread.Sleep(100) и, если количество FPS не упадет, - решение найдено. У кого установлена Unity 3.5 - проверьте и отпишитесь, что получилось.

Мне нужно события, которое будет вызываться так же часто, как Update, но код внутри этого события не должен замедлять переход к следующему кадру, т.е. рендер не должен ждать завершения работы процедуры.
skype: vbprogr
Добавить vbprogr в Skype
VBProgr
UNITрон
 
Сообщения: 319
Зарегистрирован: 24 сен 2011, 14:11

Re: Рендеринг в параллельном потоке в Unity3D 3.5

Сообщение DbIMok 17 янв 2012, 23:05

VBProgr писал(а):Они то могут перемещаться встроенными компонентами

а могут и скриптом, и что?
VBProgr писал(а):но код внутри этого события не должен замедлять переход к следующему кадру, т.е. рендер не должен ждать завершения работы процедуры.

то что вам нужно, называется Coroutine, нет?
правильный вопрос - половина ответа. учитесь формулировать вопросы понятно.
Новости > _Telegram чат @unity3d_ru (11.6k/4.8k online) > _Telegram канал @unity_news (4.7k подписчиков) > Телеграм тема > "Спасибо"
Аватара пользователя
DbIMok
Адепт
 
Сообщения: 6372
Зарегистрирован: 31 июл 2009, 14:05

Re: Рендеринг в параллельном потоке в Unity3D 3.5

Сообщение VBProgr 17 янв 2012, 23:34

На Unity 3.4 Coroutine не работают независимо от рендера.

Т.е.
Синтаксис:
Используется csharp
while(true) {
 Thread.Sleep(100);
 yield return new WaitForSeconds(0.01f);
}
намертво вешает FPS.

Вы можете проверить, изменилась ли ситуация на Unity 3.5?
skype: vbprogr
Добавить vbprogr в Skype
VBProgr
UNITрон
 
Сообщения: 319
Зарегистрирован: 24 сен 2011, 14:11

Re: Рендеринг в параллельном потоке в Unity3D 3.5

Сообщение DbIMok 17 янв 2012, 23:41

в 3.5 остановка потока делает тоже самое что и в 3.4 - останавливает поток. хотите останавливать поток не влияя на основной - создайте отдельный.
правильный вопрос - половина ответа. учитесь формулировать вопросы понятно.
Новости > _Telegram чат @unity3d_ru (11.6k/4.8k online) > _Telegram канал @unity_news (4.7k подписчиков) > Телеграм тема > "Спасибо"
Аватара пользователя
DbIMok
Адепт
 
Сообщения: 6372
Зарегистрирован: 31 июл 2009, 14:05

Re: Рендеринг в параллельном потоке в Unity3D 3.5

Сообщение VBProgr 17 янв 2012, 23:47

Но я ведь не смогу управлять из другого потока объектами юнити. На самом деле мне не нужно выполнение отдельно от основного потока, я просто хочу, чтобы рендер игнорировал (он то все-равно в 3.5 в отдельном потоке) что корутина выполняется и делал свою работу.

Остановка потока останавливает основной поток. А рендер должен работать. Он же там теперь в отдельном потоке.
skype: vbprogr
Добавить vbprogr в Skype
VBProgr
UNITрон
 
Сообщения: 319
Зарегистрирован: 24 сен 2011, 14:11

Re: Рендеринг в параллельном потоке в Unity3D 3.5

Сообщение DbIMok 17 янв 2012, 23:58

VBProgr писал(а):Но я ведь не смогу управлять из другого потока объектами юнити.

не сможете
VBProgr писал(а):я просто хочу, чтобы рендер игнорировал ... что корутина выполняется и делал свою работу.

рендер делает свою работу - рендерит, если есть что рендерить. нечего рендерить - не рендерит
VBProgr писал(а):Остановка потока останавливает основной поток. А рендер должен работать. Он же там теперь в отдельном потоке.

он и раньше был в отдельном (от managed кода), имхо. просто теперь он "отдельнее" от (native) движка. но когда нечего делать (нет Update) он ничего не делает.

я не знаю чего вам действительно нужно. возможно Low-level Native Plugin Interface. скачайте бету, посмотрите. у вас будет отдельный поток с доступом к ренедеру (в смысле вызовам ф-ий DX, OpenGL), но не к юнити объектам, конечно. правда вызывать его придется все равно из managed кода )
Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;

public class UseRenderingPlugin : MonoBehaviour {
       
        // Native plugin rendering events are only called if a plugin is used
        // by some script. This means we have to DllImport at least
        // one function in some active script.
        // For this example, we'll call into plugin's SetTimeFromUnity
        // function and pass the current time so the plugin can animate.
        [DllImport ("RenderingPlugin")]
        private static extern void SetTimeFromUnity (float t);

        IEnumerator Start () {
                yield return StartCoroutine("CallPluginAtEndOfFrames");
        }
       
        private IEnumerator CallPluginAtEndOfFrames ()
        {
                while (true) {
                        // Wait until all frame rendering is done
                        yield return new WaitForEndOfFrame();
                       
                        // Set time for the plugin
                        SetTimeFromUnity (Time.timeSinceLevelLoad);
                       
                        // Issue a plugin event with arbitrary integer identifier.
                        // The plugin can distinguish between different
                        // things it needs to do based on this ID.
                        // For our simple plugin, it does not matter which ID we pass here.
                        GL.IssuePluginEvent (1);
                }
        }
}
правильный вопрос - половина ответа. учитесь формулировать вопросы понятно.
Новости > _Telegram чат @unity3d_ru (11.6k/4.8k online) > _Telegram канал @unity_news (4.7k подписчиков) > Телеграм тема > "Спасибо"
Аватара пользователя
DbIMok
Адепт
 
Сообщения: 6372
Зарегистрирован: 31 июл 2009, 14:05


Вернуться в Оптимизация

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1