虚拟世界的管理
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.UNIGINE引擎使用了大量优化技术和实用方法来管理虚拟世界。 它们可以在不损失较多图像质量的前提下降低渲染负荷。
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.具有平滑的alpha融合特性的细节层次(LOD)用来降低3D对象的几何复杂度;借助该技术,当3D对象远离摄像机时,渲染器的负荷就能减轻。
Visibility Distances 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 Fade Distances(渐隐/渐显距离) |
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间可以彼此平滑融合,而不是做骤然切换,该距离能使LOD在不知不觉间完成过渡。 Smooth LODs with alpha-blend fading are available only when render_alpha_fade is set to 1 (which is set by default).只有当render_alpha_fade设置为1时LOD的衰减才能实现平滑的alpha融合(默认就是该设置)。 Just like visibility distances, the range of the fading region is defined by the minimum fade and maximum fade distances:像能见距离一样,衰减区域的范围由【最小渐隐/渐显】距离和【最大渐隐/渐显】距离定义:
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融合使效果看起来会好很多,但这也意味着在衰减区域内,要在同一时间渲染同一对象的两种版本。 考虑到这一因素,衰减区域则应尽可能的短。 |
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:我们想在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。 而到摄像机的距离为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个单位距离(最小能见距离)开始,一直到无穷远(最大能见距离 = 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来说,它的最大渐隐/渐显距离设置为5。
- For the 2nd LOD to fade-in, its minimum fade distance is also set to 5.对于要渐渐显现的第二个LOD来说,它的最小渐隐/渐显距离也设置为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相关的参数不止一种:其中参照对象就是用来测量切换LOD时所使用的距离。 它指明了应该测量的是到节点表面自身的距离,还是到所处层级分支上级的任意节点表面或节点的距离。 每个节点表面都拥有两类参照对象:
Min Parent(最小父级数) |
Minimum parent is a reference object to measure the minimum visibility distance from: 最小父级数作为参照对象用来测量摄像机到它的最小能见距离:
|
Max Parent(最大父级数) | Maximum parent is a reference object to measure the maximum visibility distance from. The same principle is used to count it.最大父级数作为参照对象用来测量摄像机到它的最大能见距离。 引擎采用相同(同上)原理对其父级数进行计数。 |
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.让我们以房屋模型为例。 当摄像机拉近的时候,我们将会看到高密度多边形的清晰表面,比如拱门,石屋拐角,园窗和屋顶瓦片这些部分的细节。 当摄像机拉远的时候,所有这些表面都应同时切换为一种一致的低密度多边形的LOD表面。
High-poly model高密度多边形模型
|
Low-poly model to be used as distant LOD用于远处的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),又因为清晰表面的边界框会更靠近摄像机,那么房屋不同部分的LOD在被不均匀开启(或关闭)时就很可能会出现状况。 这会造成不自然的深度冲突变化。 此时,远处的拐角还没切换为更加精细的LOD,近处的就已被绘制了两次:作为高密度多边形拐角的LOD被绘制一次,同时作为统一的低密度多边形房屋的LOD又被绘制了一次。
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),那么不管我们从哪一侧拉近摄像机,它的所有表面都会同时切换。
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.在做检测时不止一个选项可用于不同的参照对象。 例如,下限(最小距离)用于检测节点表面自身,上限(最大距离)用于检测父级。 这可能听起来有些复杂,那就让我们看下方的图片。 第一幅图显示的是一个圆环,按照细节层次我们将其划分为了不同的节点表面。
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.注意:此处的所有最小距离都用于节点表面自身的测量,不过几乎所有的最大距离都用于测量其它参照对象,也就是父级。 这里的多张图片会有助于您理解该原理。
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.在上面的图片中,对于不同参照对象的距离测量,我们要正确“关闭”较小的单一扇区,而不是显示较大的扇区。 最大距离由父级扇区计算,这是因为相邻子扇区的距离可能会有很大不同。 最小距离由当前扇区计算,原因是假如摄像机靠它太近的话我们就需要将其显示。
Bounds界限#
A bound object represents a spherical or cubical volume enclosing the whole node, used for describing node's size and location. In UNIGINE, this can be an axis-aligned bounding box or a sphere. Bounds are defined only for the nodes that have visual representation or their own size. The following "abstract" objects do not have bounds at all and therefore are excluded from the spatial tree:绑定对象表示包围整个节点的球形或立方体体积,用于描述节点的大小和位置。 在 UNIGINE 中,这可以是轴对齐的边界框或球体。 边界仅针对具有视觉表示或其自身大小的节点定义。 以下“抽象”对象根本没有边界,因此被排除在空间树之外:
- Dummy Node
- Node Reference
- Node Layer
- World Switcher
- World Transform Path
- World Transform Bone
- World Expression
- Dummy Object (如果它没有分配身体身体)
This approach significantly reduces the size of the tree and improves performance due to saving time on bound recalculation when transforming such nodes.由于在转换此类节点时节省了重新计算边界的时间,因此这种方法显着减小了树的大小并提高了性能。
The following types of bounds are used:使用以下类型的边界:
- Local Bounds - bound objects with local coordinates which do not take into account physics and children: BoundBox and BoundSphere.局部边界 (Local Bounds) - 使用不考虑物理和子级的本地坐标绑定对象:BoundBox 和 BoundSphere。
- World Bounds - same as local ones, but with world coordinates: WorldBoundBox and WorldBoundSphere.世界边界 (World Bounds) - 与本地相同,但具有世界坐标:WorldBoundBox 和 WorldBoundSphere。
- Spatial Bounds - bound objects with world coordinates used by the spatial tree, and therefore taking physics into account (shape bounds, etc.): SpatialBoundBox and SpatialBoundSphere.空间边界 (Spatial Bounds) - 使用空间树使用的世界坐标绑定对象,因此考虑物理(形状边界等):SpatialBoundBox 和 SpatialBoundSphere。
And their hierarchical analogues (taking into account all children) to be used where hierarchical bounds are required (they are slow, but offer correct calculations):并且在需要分层边界的地方使用它们的分层类似物(考虑到所有孩子)(它们很慢,但提供正确的计算):
- Local Hierarchical Bounds - bound objects with local coordinates taking bounds of all node's children into account: HierarchyBoundBox and HierarchyBoundSphere.局部层次界限 (Local Hierarchical Bounds) - 使用本地坐标绑定对象,考虑所有节点的子节点的边界:HierarchyBoundBox 和HierarchyBoundSphere。
- World Hierarchical Bounds - same as local ones, but with world coordinates: HierarchyWorldBoundBox and HierarchyWorldBoundSphere.世界等级界限 (World Hierarchical Bounds) - same as local ones, but with world coordinates: 与本地相同,但具有世界坐标:HierarchyWorldBoundBox 和 HierarchyWorldBoundSphere。
- Spatial Hierarchical Bounds - hierarchical bound objects used by the spatial tree, and therefore taking physics into account (shape bounds, etc.): HierarchySpatialBoundBox and HierarchySpatialBoundSphere.空间层次界限 (Spatial Hierarchical Bounds) - 空间树使用的分层边界对象,因此将物理考虑在内(形状边界等):HierarchySpatialBoundBox 和 HierarchySpatialBoundSphere。
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树是通过对所有场景数据进行划分和组织得到的层次结构。 自适应行为允许通过将区域的大小调整为处理的几何形状和世界中对象的分布来优化 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.创建根节点。 它是通过在整个场景上简单地跨越一个轴对齐的边界框来完成的。
- 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.每次在世界中添加或删除对象时,以及当对象将其状态更改为碰撞对象或杂乱对象时,都会动态地重新生成树。 如果没有变化,树保持不变。 这种质量使自适应 BSP 不仅在渲染静态几何体时高效,而且在处理动态对象时也高效。
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.World(世界)树负责处理所有闭区(Sectors),入口(Portals),遮挡器(Occluders),触发器(Triggers )和对象簇(Clusters)。
- Objects tree includes all objects except for collider objects and the ones with the Immovable flag enabled.Objects(对象)树包含所有对象,但不包含带有【collider(碰撞机)】和【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.Collider(碰撞机)对象构成了单独的类型树以方便碰撞检测和避免出现一组对象全部紧靠另一组对象这样的最坏检测情况 。 很显然,对象间只有在处于场景中的同一区域内并发生重叠时才可以相交。 该类型树可彻底减少成对测试的数量,加速计算。
-
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.Light(灯光)树负责处理所有光源。
- Decal tree handles decals.Decal(贴花)树负责处理贴花。
- Player tree handles all types of players.Player(玩家)树负责处理所有类型的玩家。
- Physical node tree handles all physical forces.Physical node(物理节点)树负责处理所有物理作用力。
- Sound tree handles all sound sources.Sound(音效)树负责处理所有声源。
Mesh PartitioningMesh 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 treeSurfaces(节点表面)树
- Polygon treePolygon(多边形)树
These two mesh-based trees provide the basis for fast intersection and collision calculations with the mesh.这两种基于网格的类型树为网格的快速相交和碰撞计算提供了基础。
Perspective Projection透视投影(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.视锥体(Viewing Frustum或View Frustum)是用于透视投影的虚拟摄像机的视角(Field of View);换句话说,它是我们在屏幕上看到的虚拟世界空间的一部分。 它的具体形状要取决于被模拟的摄像机类型,不过它通常就是一种平截头四棱锥体。 视锥体的平面与屏幕平行,它们分别称为近端剪裁平面(Near Plane)和远端剪裁平面(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.作为虚拟摄像机的视角它不是没范围的,有些对象是不进入视角的。 例如,比近端剪裁平面更靠近观看者的对象将不可见。 如果位于远端剪裁平面后面的对象没在无穷远处,或是有些对象被侧面切断了,那它们也同样是不可见的。 因为这类对象无论如何都是不可见的,所以我们就可以跳过它们的绘图。 丢弃看不见的对象的过程就叫做视锥体剔除。
Orthographic Projection正交投影(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遮挡剔除(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遮挡
- 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.潜在可见集,将空间按成群区域划分空间,每个区域都包含有一系列的多边形,这些多边形在该区域内的任何位置都可见。 之后,渲染器只需实时查询预先计算好的带有视图位置的设置即可。 该技术经常用来加速二叉空间划分(Binary Space Partitioning,简称BSP)。
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.数据流是一种优化技术,它所采用的是不一次将所有数据都加载进随机存储器(RAM)。相反,只有需要的数据被加载,并在独立的异步线程中传输到GPU,其余的都是按需逐步加载。
Streaming system provides asynchronous loading of the following data to RAM:因使用了数据流技术,以下数据将被异步加载进RAM:
- All textures, including cubemaps, voxel probe maps and shadow maps of baked shadows.所有材质的纹理,包括 立方体映射,体素探测映射 和烘烤阴影的阴影映射。
- ObjectMeshStatic, ObjectMeshClutter, ObjectMeshCluster.
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.节点的多线程更新(前提是您通过控制台命令world_threaded启用了多线程)可以大幅提高性能。 例如,当需要在虚拟世界中渲染大量的粒子系统或动态网格时这种技术手段就非常奏效。
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、Decals、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, (only with a rope, a cloth, or a water body assigned)
- 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:以下节点类型取决于层次结构:
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存储在缓存中。