Работа с виртуальным миром
There is a number of optimization techniques and practices relating to world management. They are used to decrease the rendering load without losing much of the image quality.При создании виртуального мира не обойтись без оптимизации. Различные способы оптимизации помогают разгрузить процесс отрисовки без существенного влияния на качество изображения.
Levels of DetailsУровни детализации#
Smooth alpha-blended levels of details (LODs) are used to decrease geometry complexity of 3D objects, when these objects move away from the camera, making it possible to lighten the load on the renderer.Чем проще геометрия 3D-объектов, тем меньше нагрузка на рендер. Поэтому при увеличении расстояния между камерой и объектами имеет смысл плавно переключаться между уровнями их детализации (LOD-ами) в режиме прозрачности Alpha Blend.
UNIGINE offers two mechanisms of LODs switching:В UNIGINE предусмотрено два механизма смены LOD-ов:
-
Disable one LOD and enable another at the specified distance defined by two values: maximum visibility distance of the first LOD (Max Visibility) and minimum visibility distance of the second LOD (Min Visibility). Выключение одного LOD-а и включение другого на определенном расстоянии, которое задается двумя значениями: конец видимости первого LOD-а (Max Visibility) и начало видимости второго LOD-а (Min Visibility).
-
Smoothly fade one LOD into another at the specified interval defined by two values: minimum fade distance of the first LOD (Min Fade) and maximum fade distance of the first LOD/minimum fade distance of the second LOD (Max Fade). Плавный переход (fade) между LOD-ами в указанном интервале, который задается двумя значениями: расстояние плавного появления первого LOD-а (Min Fade) и расстояние плавного исчезновения первого LOD-а / расстояние плавного появления второго LOD-а (Max Fade).
Surface LODs are adjusted in the LOD section of the Node tab of the Parameters window. It provides the following parameters:Настройки LOD-ов поверхностей находятся в секции LOD вкладки Node в окне Parameters. Доступны следующие параметры:
Visibility Distances Границы видимости |
The LODs visibility parameters are defined by the visibility range. It is set by two parameters: the minimum visibility and maximum visibility distances measured from the camera. If the surface is within the range specified by these bounds, it is displayed, otherwise, it is hidden.Видимость LOD-ов определяется диапазоном видимости. Он задается двумя параметрами: начало и конец видимости, которые определяются по расстоянию от камеры. Поверхность отображается только в том случае, если она находится в пределах этого диапазона.
Ranges for surfaces that represent different LODs of the same object should not overlap.У поверхностей, которые представляют собой разные LOD-ы одного и того же объекта, диапазоны видимости не должны совпадать даже частично. |
Fade DistancesРасстояния перехода между LOD-ами |
Discrete LODs are likely to have one noticeable and quite distracting artifact - "popping", when one LOD is switched to another. Rather than abruptly switching the LODs, they can be smoothly blended into each other over a fade distance making the transition imperceptible.При переключении между LOD-ами может обнаружиться один заметный визуальный дефект — резкая смена изображения. Плавное превращение одного LOD-а в другой делает смену LOD-ов менее заметной. Smooth LODs with alpha-blend fading are available only when render_alpha_fade is set to 1 (which is set by default).Плавный переход между LOD-ами в режиме Alpha Blend возможен, только когда для render_alpha_fade установлено значение 1 (задано по умолчанию). Just like visibility distances, the range of the fading region is defined by the minimum fade and maximum fade distances:Интервал плавного перехода задается аналогично диапазону видимости при помощи значений Min Fade и Max Fade:
Although alpha blending between the LODs looks by far better, it also means that within the fade region two versions of the same object are rendered at the same time. For this reason, the fade region should be kept as short as necessary.Несмотря на то что переход между LOD-ами в режиме Alpha Blend визуально улучшает изображение, нужно помнить и о том, что в диапазоне плавного перехода одновременно отрисовываются обе версии одного и того же объекта. Поэтому диапазон плавного перехода следует делать по возможности минимальным. |
Within distance of surface visibilityПоверхность в пределах видимости
|
Within fade distanceРасстояние плавного перехода
|
Suppose, we have two LODs: high-poly surface_lod_0 and low-poly surface_lod_1, and we need to organize smooth transition between these two LODs.Например, у нас есть два LOD-а: высокополигональный surface_lod_0 и низкополигональный surface_lod_1, и нам нужно сделать плавный переход между этими двумя LOD-ами.
-
We want the switching distance at 50 units. For that, we need to "dock" visibility distances of surfaces to each other:Мы хотим, чтобы смена LOD-ов происходила на расстоянии 50 единиц. Для этого нужно состыковать друг с другом их границы видимости:
- Our first LOD surface surface_lod_0 should be always presented when the camera is close to the object. So, the minimum visibility distance is set to -inf. And 50 units from the camera will be the maximum visibility distance for it.Поверхность первого LOD-а surface_lod_0 должна отображаться, когда камера находится вблизи объекта. Поэтому задаем значение -inf для начала видимости (Min Visibility). А для конца видимости (Max Visibility) выставляем значение 50 единиц от камеры.
- Directly following it, comes the second LOD surface surface_lod_1. It is visible from 50 units (which is the minimum visibility distance) - and up to infinity (the maximum visibility distance = inf).На большем расстоянии сразу же включается поверхность второго LOD-а surface_lod_1. Она видна на расстоянии от 50 единиц (которое указано в Min Visibility) — и до бесконечности (Max Visibility = inf).
-
Now the LOds are switched but sharply rather then smoothly. To be smoothly blended, the symmetrical fade-out (for the 1st LOD) and fade-in (for the 2nd LOD) distances are set. Let's say, the fading region should be 5 units.Переключение между LOD-ами происходит довольно резко. Для плавного исчезновения (для первого LOD-а) и появления (для второго LOD-а) указываются симметричные расстояния. К примеру, установим диапазон плавного перехода равный 5 единицам.
- For the 1st LOD to fade-out, its maximum fade distance is set to 5.Для плавного исчезновения первого LOD-а указываем значение Max Fade равное 5.
- For the 2nd LOD to fade-in, its minimum fade distance is also set to 5.Для плавного появления второго LOD-а, указываем значение Min Fade равное 5.
In the result, the LODs will be changed in the following manner:В результате для LOD-ов будут применяться следующие значения:
From the BB of the object
to 50 units От ограничивающего контура объекта до расстояния 50 единиц |
Only the 1st LOD surface surface_lod_0 is completely visible Полностью видна только поверхность первого LOD-а surface_lod_0 |
50 - 55 units50 — 55 единиц | The 1st LOD fades out, while the 2nd LOD fades inПервый LOD плавно исчезает, а второй LOD плавно появляется |
From 55 units and furtherОт 55 единиц и дальше | Only the 2nd LOD surface surface_lod_1 is completely visibleПолностью видна только поверхность второго LOD-а surface_lod_1 |
Reference ObjectОпорный объект#
There is one more LOD-related parameter: reference object to measure the distance to switch LODs. It specifies whether the distances should be measured to the surface itself or to any of the surfaces or nodes up the hierarchy branch. There are two reference objects for each surface: Система уровней детализации включает еще один параметр — опорный объект. Этот параметр задает границы, от которых отмеряется расстояние перехода между LOD-ами. Можно отмерять расстояние от самой поверхности или от какой-либо из поверхностей или нод выше по иерархии в этой ветке. Для каждой поверхности указываются два опорных объекта:
Min Parent |
Minimum parent is a reference object to measure the minimum visibility distance from: Опорный объект, от которого определяется расстояние до начала видимости (Min Visibility):
|
Max Parent | Maximum parent is a reference object to measure the maximum visibility distance from. The same principle is used to count it.Опорный объект, от которого определяется расстояние до конца видимости (Max Visibility). Задается в соответствии с тем же самым подходом. |
Let's take a model of the house, for example. When the camera is close by, the high-poly detail surfaces are seen, such as the door arch, stone corners, round window and roof tiles. When we move away, all these surfaces should be simultaneously changed by one united low-poly LOD surface.Для примера возьмем модель дома. Когда камера находится рядом, видны высокополигональные детализированные поверхности, такие как арка над дверью, каменная кладка углов дома, объем круглого окна и черепицы. При увеличении расстояния между камерой и объектом все эти поверхности должны одновременно заменяться на одну-единственную низкополигональную и менее детализированную поверхность.
High-poly modelВысокополигональная модель
|
Low-poly model to be used as distant LODНизкополигональная модель, используемая
в качестве менее детализированной поверхности |
The problem is, all these detailed surfaces have different bounding boxes. So if their distances are checked for themselves (0 as min and max parents), we can have a situation when LODs of different parts of the house are turned on (or off) unequally, because their bounding boxes will be closer to the camera. This may cause z-fighting artifacts. Here the distant corner has not yet switched to a more detailed LOD, while the close one is drawn twice: as a high-poly corner LOD and at the same time the united low-poly house LOD.Проблема заключается в том, что у всех этих детализированных поверхностей разные ограничивающие контуры (bounding box). Поэтому если границы видимости измеряются от самих поверхностей (установлено значение 0 для Min Parent и Max Parent), может произойти ситуация, когда смена LOD-ов различных частей дома происходит неравномерно, так как их границы находятся на разном расстоянии от камеры. Это может спровоцировать визуальный дефект под названием z-fighting, когда одна поверхность проглядывает сквозь другую. В нашем примере на рисунке ниже дальний угол еще не переключился на более детализированную поверхность, а ближний отрисован дважды: высокополигональный угол дома одновременно с низкополигональной поверхностью, представляющей весь дом целиком.
If we set a bounding box of the whole house to be a reference object (min and max parent to 1), all surfaces will switch on simultaneously no matter what side we approach the house from.Если мы выставим в качестве опорного объекта ограничивающий контур всего дома (значение 1 для Min Parent и Max Parent), то все поверхности будут переключаться одновременно независимо от того, с какой стороны мы приближаемся к дому.
One more option is to use different reference objects when check. For example, the lower bound (minimum distance) is checked for the surface itself, and the upper bound (maximum distance) is checked for the parent. This may sound complicated, so take a look at the pictures below. The first picture shows a ring, which is split into surfaces according to levels of details.Еще один вариант — использовать при проверке разные опорные объекты для различных поверхностей. Например, начало видимости (Min Visibility) проверяется относительно самой поверхности, а конец видимости (Max Visibility) — относительно родительской ноды. Разберем на примере кольца, разбитого на поверхности в зависимости от уровня детализации.
Here, surfaces from the rightmost column will be displayed, when the camera is very close to them. The leftmost surfaces will be displayed, when the camera is very far from them. Merging of several surfaces into one reduces the number of objects to draw, hence, reduces the number of DIP requests and speeds up rendering.Итак, поверхности из крайнего правого столбца будут отображаться, когда камера находится очень близко к объекту. Поверхность из крайнего левого столбца будет отображаться, когда камера находится очень далеко от кольца. Совмещение нескольких поверхностей в одну снижает количество отрисовываемых объектов, тем самым сокращая число вызовов DIP и увеличивая скорость рендеринга.
Note that all of the minimum distances here are measured to the surface itself, but almost all of the maximum distances are measured to another reference object, a parent. One more picture will help you to understand, why it is so.Обратите внимание, что все точки начала видимости (Min Visibility) здесь измеряются от самой поверхности, а точки конца видимости (Max Visibility) — от другого опорного объекта, родителя. Следующая иллюстрация поможет вам понять, зачем это сделано.
A star is the camera; it doesn't matter now what exactly the camera will be looking at. On both images, required surfaces are drawn according to the camera position and distances from the camera to the corresponding reference objects. For example, on the left image, the upper left part of the ring is a single surface, the upper right part is split in two separate surfaces, and the bottom part is also a single surface. On the right image, the whole upper part is divided into the smallest possible sectors.Звездой обозначено место расположения камеры. По сути, не важно, куда будет направлена камера. На обоих изображениях сегменты кольца выбираются в зависимости от положения камеры и расстояния от камеры до соответствующих опорных объектов. Например, на изображении слева верхняя левая часть кольца представляет собой цельную поверхность, правая часть разбита на две отдельные поверхности, нижняя часть также представляет собой цельную поверхность. На изображении справа вся верхняя часть разделена на минимально возможные сектора.
Here, distances are measured to different reference objects to properly "turn off" smaller single sectors and display a larger sector instead. The maximum distance is calculated to the parent sector, because the distances to the neighboring subsectors may differ too much. The minimum distance is calculated to the current sector, because we need to show it, if the camera is too close to it.Расстояния измеряются от различных опорных объектов, чтобы правильно "выключать" самые маленькие сектора и отображать вместо них более крупный сектор. Конец видимости (Max Visibility) рассчитывается от родительского сектора, поскольку расстояния до смежных подсекторов могут существенно различаться. Начало видимости (Min Visibility) рассчитывается от текущего сектора, поскольку нам нужно его показать, если камера находится слишком близко к нему.
Outdoor SpaceОткрытое пространство#
The techniques that are appropriate for indoor scenes, are not efficient when it comes to managing the vast landscapes. Rendering speed directly depends on the number of entities and polygons drawn in the scene, as well as physics computed for the objects, the count of which is usually very high in the outdoor scenes. So the main goal of managing is to render only the regions that are seen while culling all the rest. If the world cannot be narrowed down to a set of closed areas, the approach called space partitioning becomes relevant.Методы, которые подходят для сцен в замкнутом пространстве, неэффективны, когда дело доходит до масштабных ландшафтов. Скорость отрисовки напрямую зависит от количества рисуемых сущностей и полигонов, а также физических расчетов, которых в сценах с открытым пространством, как правило, тоже очень много. Поэтому основная задача при настройке таких сцен — обеспечить отрисовку только тех участков, которые видны, и отсечь все остальное. Если мир невозможно сузить до набора замкнутых пространств, то имеет смысл применить подход, который называется разбиение пространства (space partitioning).
Space partitioning in Unigine is implemented using adaptive axis-aligned BSP trees.В Unigine разбиение пространства реализуется при помощи адаптивных BSP-деревьев с привязкой к осям координат.
Binary Space PartitioningДвоичное разбиение пространства#
Binary space partitioning is a method for dividing the scene along the axes into the regions that are dealt with individually and thus are easier to manage. BSP tree is a hierarchical structure obtained by division and organizing all the scene data. The adaptive behavior allows to optimize the BSP algorithm by adjusting sizes of the regions to the processed geometry and distribution of objects in the world.Двоичное разбиение пространства — это метод разбиения сцены вдоль осей на участки, каждый из которых обрабатывается индивидуально, что упрощает работу со сценой. BSP-дерево представляет собой иерархическую структуру, которая создается посредством разделения и группирования всех данных сцены. Адаптивное поведение оптимизирует алгоритм двоичного разбиения пространства: размеры участков определяются пропорционально обрабатываемой геометрии и распределению объектов в мире.
The BSP tree is built in the following way:BSP-дерево строится следующим образом:
- The root node is created. It is done by simply spanning an axis-aligned bounding box over the whole scene.Сначала создается корневой узел: ограничивающий контур с привязкой к осям (AABB), который охватывает всю сцену.
- The space of the bounding box is recursively subdivided into two regions by a partitioning plane that is perpendicular to one of the three major axes. As a result, two nodes of the tree are created. Each of these nodes is again enclosed in an axis-aligned bounding box and this step is repeated for each of them until the whole scene geometry is represented.Затем пространство ограничивающего контура рекурсивно делится на два участка разбивающей плоскостью, которая перпендикулярна одной из трех основных осей. В итоге создается два узла дерева, каждый из которых заключается в ограничивающий контур с привязкой к осям. Этот шаг повторяется для каждого из этих узлов до тех пор, пока не будет представлена вся геометрия сцены.
-
The subdivision is stopped when the level with required number of editor nodes is reached. Процесс деления останавливается, когда достигается уровень с необходимым количеством нод.
If the partitioning plane at a certain level splits an object, such object stays at the previous level and does not slide down the tree. It often happens with big and extensive objects, like sky or huge buildings.Если разбивающая плоскость на определенном этапе разбивает объект, то этот объект остается на предыдущем уровне и не спускается дальше по дереву. Такое часто происходит с масштабными объектами, такими как небо или большие здания.
During rendering, the engine loops through the BSP nodes to determine whether their bounding boxes are intersected by the viewing frustum. If a node passes this test, the same action is repeated for its children until a leaf node or a node that is outside the viewing frustum is reached. All necessary calculations are performed for visible regions, while the rest of the scene (i.e. objects and their lighting ) is discarded.Во время рендеринга движок проходит по всем узлам BSP-дерева и определяет, какие из ограничивающих контуров находятся в пределах пирамиды видимости. Если узел попадает в эти пределы, то проверка повторяется для его потомков до тех пор, пока не будет достигнут дочерний узел, который находится за пределами пирамиды видимости. Для видимых участков производятся все необходимые расчеты, а остальная часть сцены (т. е. объекты и их освещение) игнорируется.
The tree is regenerated on the fly each time an object is added or removed from the world as well as when the object changes its status to collider or clutter object. If there were no changes, the tree remains the same. This quality makes adaptive BSP efficient not only when rendering static geometry, but also for handling dynamic objects.Каждый раз при добавлении объекта в сцену, его удалении или изменении его статуса на коллизионный или clutter дерево автоматически пересоздается. Если изменений не вносилось, дерево остается прежним. Благодаря этому адаптивное двоичное разбиение пространства эффективно не только при отрисовке статичной геометрии, но и при работе с динамическими объектами.
To provide effective management of the scene on the one hand and good tree balancing on the other, separate trees are created for different node types:Чтобы работа со сценой была эффективной, а дерево сбалансированным, для каждого типа нод создается свое дерево:
- World tree handles all sectors, portals, occluders, triggers and clusters.Глобальное дерево охватывает все сектора, порталы, загораживающие объекты, триггеры и кластеры.
- Objects tree includes all objects except for collider objects and the ones with the Immovable flag enabled.Дерево объектов включает все объекты кроме тех, у которых включено состояние коллизионный или clutter.
- Collider objects form a separate tree to facilitate collision detection and avoid the worst case scenario of testing all the objects against all other objects. This tree contains collider objects. It is clear, that objects can intersect only if they are situated and overlap in the same region of the scene. This tree allows to drastically reduce the number of pair-wise tests and accelerate the calculation.Коллизионные объекты формируют свое дерево, чтобы было проще обнаружить коллизии и не проверять каждый объект на предмет столкновения со всеми остальными объектами в сцене. Очевидно, что объекты могут пересекаться, только если они расположены в одном и том же участке сцены. Такое дерево позволяет существенно снизить число попарных проверок и ускорить расчеты.
-
Clutter objects are also separated as they are intended to be used in great numbers, which can disturb the balance of the main object tree.Объекты clutter также выделяются в отдельное дерево, поскольку содержат большое количество элементов, включение которых в дерево объектов может нарушить его баланс.
- Light tree handles all light sources.Дерево освещения обрабатывает все источники освещения.
- Decal tree handles decals.Дерево декалей обрабатывает декали.
- Player tree handles all types of players.Дерево камер обрабатывает все виды камер.
- Physical node tree handles all physical forces.Дерево физических нод обрабатывает все физические силы.
- Sound tree handles all sound sources.Дерево звуков обрабатывает все источники звука.
Mesh PartitioningРазбиение мешей#
After the editor node level is reached, there still exists the need for further partitioning of the mesh. Division is based on the same principles: the tree must be binary and axis aligned. The only difference is that these trees are precomputed (they are generated at the time of world loading), because a mesh is a baked object and there is no need for the related trees to change dynamically. The mesh is divided into the following trees:После того как достигнут уровень нода, есть необходимость продолжить разбиение — на уровне меша. Разбивка происходит по тому же принципу: дерево должно быть бинарным и с привязкой к осям. Единственное различие в том, что эти деревья рассчитываются заранее (они генерируются при загрузке мира), поскольку меш является запеченным объектом, и необходимости в динамическом изменении соответствующих деревьев нет. Меш разбивается на следующие деревья:
- Surfaces treeдерево поверхностей;
- Polygon treeдерево полигонов.
These two mesh-based trees provide the basis for fast intersection and collision calculations with the mesh.Эти два дерева обеспечивают основу для быстрых расчетов пересечений и коллизий с мешем.
Perspective ProjectionПерспективная проекция#
When the human eye views a scene, objects in the distance appear smaller than objects close by - this is known as perspective. While orthographic projection ignores this effect to allow accurate measurements, perspective definition shows distant objects as smaller to provide additional realism.Для наблюдателя отдаленные объекты кажутся меньше, чем расположенные близко — это называется перспектива. В отличие от ортографической проекции, которая игнорирует этот эффект и позволяет производить точные измерения, в перспективной картинке чем дальше объект, тем он меньше размером, что добавляет реалистичности.
A viewing frustum (or a view frustum) is a field of view of the virtual camera for the perspective projection; in other words, it is the part of the world space that is seen on the screen. Its exact shape depends on the camera being simulated, but often it is simply a frustum of a rectangular pyramid. The planes of the viewing frustum that are parallel to the screen are called the near plane and the far plane.Пирамида видимости — это угол обзора виртуальной камеры для перспективной проекции. Иными словами, это часть пространства мира, которая видна на экране. Ее точная форма зависит от симулируемой камеры, но зачастую это просто усеченная прямоугольная пирамида. Параллельные экрану плоскости пирамиды называются ближняя и дальняя плоскости отсечения.
As the field of view of the camera is not infinite, there are objects that do not get inside it. For example, objects that are closer to the viewer than the near plane will not be visible. The same is true for the objects beyond the far plane, if it is not placed at infinity, or for the objects cut off by the side faces. As such objects are invisible anyway, one can skip their drawing. The process of discarding unseen objects is called viewing frustum culling.Поскольку угол обзора камеры не бесконечен, внутрь него попадут не все объекты. Например, объекты, которые находятся к зрителю ближе, чем ближняя плоскость отсечения, не будут видны. Точно так же и с объектами, которые находятся за дальней плоскостью отсечения, если она не выставлена на бесконечность (inf), или объектами, которые отсекаются боковыми поверхностями пирамиды. Все эти объекты в любом случае невидимы, поэтому можно пропустить их отрисовку. Процесс исключения объектов, которые не видны, называется отсечение по пирамиде видимости.
Orthographic ProjectionОртографическая проекция#
When the human eye looks at a scene, objects in the distance appear smaller than objects close by. Orthographic projection ignores this effect to allow the creation of to-scale drawings for construction and engineering.Для наблюдателя отдаленные объекты кажутся меньше, чем расположенные близко. Ортографическая проекция игнорирует этот эффект, позволяя создавать проектировочные и строительные чертежи в масштабе.
With an orthographic projection, the viewing volume is a rectangular parallelepiped, or more informally, a box. Unlike perspective projection, the size of the viewing volume doesn't change from one end to the other, so distance from the camera doesn't affect how large an object appears.В ортографической проекции поле видимости представляет собой прямоугольный параллелепипед, проще говоря, прямоугольник. В отличие от перспективной проекции, размер видимого объема не меняется на всем его протяжении, поэтому расстояние от камеры до объекта не влияет на размер изображения этого объекта.
Occlusion CullingОтсечение невидимых объектов#
Another popular practice is to remove objects that are completely hidden by other objects. For example, there is no need to draw a room behind a blank wall or flowers behind an entirely opaque fence. This technique is called occlusion culling. The particular cases of occlusion culling are the following:Еще один популярный способ оптимизации — исключение объектов, которые полностью скрыты за другими объектами, то есть зритель их не видит. Например, нет смысла рисовать комнату, которая находится за стеной, или цветы, скрытые сплошным забором. Эта техника называется отсечение загороженных объектов (occlusion culling). Частные случаи отсечения загороженных объектов:
- Occludersзагораживающие объекты (occluder);
- Potentially visible sets that divide the space in a bunch of regions, with each region containing a set of polygons that can be visible from anywhere inside this region. Then, in real-time, the renderer simply looks up the pre-computed set given the view position. This technique is usually used to speed up binary space partitioning.потенциально видимые части пространства. Пространство делится на участки, в каждом из которых находится набор полигонов, видимых из любой точки внутри этого участка. В режиме реального времени программа рендеринга просто использует заранее рассчитанный участок с учетом положения камеры. Этот подход обычно используется для ускорения процесса двоичного разбиения пространства.
OccludersЗагораживающие объекты#
In large and complex environments with a lot of objects that occlude each other, culling of the occluded geometry allows significantly increase performance. The most appropriate decision, in this case, is to use occluders. They allow culling geometry that isn't visible behind them.В больших и сложных сценах со множеством загораживающих друг друга объектов исключение загороженной геометрии позволяет значительно повысить производительность. Наиболее подходящим решением в данном случае будет использовать загораживающие объекты (occluder). Эти объекты позволяют отсекать геометрию, которая находится полностью позади них и поэтому не видна.
Существует два типа загораживающих объектов: загораживающий контур и загораживающий меш. Тип загораживающего объекта выбирается в зависимости от геометрии, которую необходимо отсечь.
However, using occluders to cull large objects with a few surfaces may cause additional performance loss. Moreover, occluders aren't effective in scenes with flat objects, or when a camera looks down on the scene from above. So, when using the occluders, you should take into account peculiarities of objects to be culled.Однако использование загораживающих объектов для отсечения больших объектов с малым количеством поверхностей может только ухудшить производительность. Также загораживающие объекты неэффективны в сценах с плоскими объектами или когда камера смотрит сверху. Поэтому следует учитывать размеры загороженных объектов и их поверхностей, а также их расположение и позицию наблюдателя при использовании загораживающих объектов.
Hardware Occlusion QueriesАппаратная проверка видимости#
Another way to cull geometry that is not visible in the camera viewport is to use a hardware occlusion query. It allows reducing the number of the rendered polygons therefore increasing performance. To run the hardware occlusion test for the scene before sending data to the GPU, set the Rendering ->Features -> Occlusion query flag. In this case, culling will be performed for all objects with the Culled by occlusion query flag set in the Node tab of the Parameters window.Еще один способ отсечь геометрию, которая не видна, — использование аппаратной проверки видимости (hardware occlusion query). Такая проверка позволяет снизить число отрисовываемых полигонов, тем самым увеличивая производительность. Для запуска аппаратной проверки видимости в сцене включите флаг Rendering -> Features -> Occlusion query перед отправкой данных на графический процессор. Тогда будут отсекаться все объекты, у которых включен флаг Culled by occlusion query во вкладке Node окна Parameters.
When culling is enabled for the object, an occlusion query box is rendered for it. Its size coincides with the size of the object's bounding box. If the occlusion query box is in the camera viewport, the object will be rendered; otherwise, it is not.При включении флага отсечения для объекта создается контур проверки видимости. Его размер совпадает с размером ограничивающего контура объекта. Объект будет отрисован только в том случае, если его контур проверки видимости попадает в обзор камеры (окно просмотра).
The hardware occlusion queries should be used only for a few objects that use heavy shaders. Otherwise, performance will decrease instead of increasing. It is recommended to enable queries for water or objects with reflections.Аппаратную проверку видимости следует использовать только для тех объектов, у которых тяжелые шейдеры. В противном случае производительность только снизится. Рекомендуется включать проверку для воды или объектов с отражениями.
Asynchronous Data StreamingАсинхронный стриминг данных#
Data streaming is an optimization technique intended to reduce spikes caused by loading of graphic resources. It supposes that not all the data is loaded into random access memory (RAM) at once. Instead, only the required data is loaded and transferred to the GPU in separate asynchronous threads, and all the rest is loaded progressively, on demand.Стриминг данных — это прием оптимизации, призванный снизить просадку по производительности, которая связана с загрузкой графических ресурсов. Для этого данные подгружаются в оперативную память не все сразу, а по необходимости, и передаются в графический процессор отдельными асинхронными потоками, а все остальное загружается постепенно по запросу.
Streaming system provides asynchronous loading of the following data to RAM:Система стриминга асинхронно загружает в оперативную память следующие данные:
- All textures, including cubemaps, voxel probe maps and shadow maps of baked shadows.все текстуры, включая кубические, запеченные воксельные и запеченные тени;
- ObjectMeshStatic, ObjectMeshClutter и ObjectMeshCluster.
Streaming system uses texture cache composed of minimized copies generated for all textures with user-defined resolution and stored in the data/.cache_textures folder. These copies are used instead of the originals while they are loaded.Система стриминга использует текстурный кэш, который состоит из минимизированных копий. Эти копии генерируются для всех текстур с пользовательским разрешением и хранятся в папке data/.cache_textures, чтобы использоваться вместо оригиналов, пока те загружаются.
For more information on streaming configuration please refer to the Asynchronous Data Streaming article.Более подробно о настройке стриминга написано в статье Асинхронный стриминг данных.
Multi-threaded Update of NodesМногопоточное обновление нод#
Nodes are updated in the multi-threaded mode, which can substantially increase performance. For example, this can be very handy when a big number of particle systems or dynamic meshes are rendered in the world.Многопоточное обновление нод может существенно повысить производительность в таких случаях как, например, отрисовка большого количества систем частиц и динамических мешей.
Asynchronous update of nodes in the world depends on their type and hierarchy. It's important to take this into consideration for the most performance-demanding projects.Асинхронное обновление нод в мире зависит от их типа и иерархии. Это важно учитывать для проектов, в которых производительность является одним из основных критериев.
There are three modes for different types of nodes:Для различных типов нод существует три режима:
- no update - for nodes that do not change and don’t have to be updated (Mesh Static, NodeDummy, Decals, PlayerDummy, etc.), these nodes are skipped.без обновления — для нод, которые не изменяются и не нуждаются в обновлении (Mesh Static, NodeDummy, Decal, PlayerDummy и т.д.), эти ноды пропускаются.
-
independent update - for nodes that are guaranteed not to have any hierarchy-based logic, such nodes are put to separate threads automatically, when needed:независимое обновление — для нод, которые гарантированно не имеют никакой иерархической логики, такие ноды автоматически помещаются в отдельные потоки, когда это необходимо:
- ObjectLandscapeTerrain
- LandscapeLayerMap
- ObjectGrass
- MeshDynamic, (только с назначенным телом типа rope, a cloth или water)
- WaterMesh
- PlayerPersecutor
- SoundSource
-
dependent update (hierarchy based) - such nodes can be influenced by similar nodes (a child Particle System is updated in accordance with the update of the parent and so on...), such nodes are grouped and updated in the same threads.зависимое обновление (на основе иерархии) — на такие ноды могут оказывать влияние аналогичные ноды (дочерняя система частиц обновляется в соответствии с обновлением родительской и т.д.), такие ноды группируются и обновляются в одном потоке.
Groups of dependent nodes are built automatically based on the hierarchy. The only thing to take care of is to avoid breaking hierarchies of dependent nodes by inserting an independent or non-updated node between them. E.g. if you have a hierarchy of particle systems that should be updated together in one thread, inserting a NodeDummy between them will break this hierarchy and put them to separate threads.Группы зависимых нод строятся автоматически на основе иерархии. Единственное, о чем нужно позаботиться, это не ломать иерархию зависимых нод, вставляя между ними независимые или необновляемые ноды. Например, если у вас есть иерархия систем частиц, которые должны обновляться вместе в одном потоке, вставка NodeDummy между ними нарушит эту иерархию и разнесет их по разным потокам.
The following node types are hierarchy dependent:Следующие типы нод являются зависимыми от иерархии:
- PlayerSpectator
- PlayerActor
- ObjectParticles
- ObjectMeshSkinned
- ObjectExtern
- WorldExtern
- WorldTransformPath
- Объекты которые имеют физическое тело
Nodes can change their update mode at run time, for example, assigning a physical body to an ObjectDummy switches its update mode to dependent. Visibility of an object (be it a particle system or a skinned mesh with animation played) has an impact on how often it is updated.Ноды могут изменять свой режим обновления во время выполнения, например, при назначении физического тела ObjectDummy переключает свой режим обновления на зависимый. Видимость объекта (будь то система частиц или скелетный меш с анимацией) влияет на частоту его обновления.
Extended use of multithreading in combination with an internal task system ensures that load is distributed evenly between all available threads.Расширенное использование многопоточности в сочетании с внутренней системой задач обеспечивает равномерное распределение нагрузки между всеми доступными потоками.
Node CachingКэширование нод#
Caching of nodes is used to speed up loading process: a hidden copy of the loaded node (or a hierarchy of nodes) is added to the list of world nodes, thus enabling to simply get clones of cached nodes, instead of parsing the .node file and retrieving data once again.Кэширование нод используется для ускорения процесса загрузки: скрытая копия загруженной ноды (или иерархии нод) добавляется в иерархию мира, что позволяет просто получить клоны закешированных нод , вместо повторного анализа файла .node и получения данных из него.
When the node is cached and you try to access it, take into account the following:При попытке доступа к кэшированной ноде, важно помнить, что:
- If the node is loaded by the name — the node gets stored in the cache by its name.Если нода загружается по имени — нода и сохраняется в кэше по своему имени.
- If the node is loaded from the parent Node Reference — the node is stored in the cache by its GUID.Если нода загружается из родительской Node Reference — нода сохраняется в кеше по ее GUID.