UE4.27中的景观创建

2024-01-15

我正在尝试创造一个风景Python 虚幻 API https://docs.unrealengine.com/4.26/en-US/PythonAPI/ using unreal.EditorLevelLibrary.spawn_actor_from_class()产生一个LandscapeProxy演员然后使用改变其高度图landscape_import_heightmap_from_render_target() of the 景观代理 https://docs.unrealengine.com/4.26/en-US/PythonAPI/class/LandscapeProxy.html?highlight=landscapeproxy#unreal.LandscapeProxy class.

生成的演员是一流的景观占位符 https://docs.unrealengine.com/4.26/en-US/PythonAPI/class/LandscapePlaceholder.html?highlight=landscape#unreal.LandscapePlaceholder它不支持高度图操作。如何转换它还是我应该走其他路?


景观/地形 API

UE4 中的地形是基于“高度图”概念构建的特殊角色。每个地形都是一个组件网格(ULandscapeComponent)。每个组件都映射到保存高度数据的纹理。景观组件概念影响结果的性能和质量。组件是地形的最小渲染单元 (可以从渲染和碰撞的角度剔除的最小几何体)。简要景观成分说明 https://docs.unrealengine.com/latest/INT/Engine/Landscape/TechnicalGuide/#componentsections.

要构建新地形(或 UE4 中的景观),您需要一张高度图。 UE4 API 将根据该高度图生成映射到组件的纹理。高度图是无符号 16 位值的简单数组(0 到 65535,其中 32768 值被视为“海平面”)。在 Python 中(出于性能原因以及与 NumPy 集成)高度图是字节数组的(您最终需要重新转换它们)。

创造新景观

使用随机值创建高度图:

import unreal_engine as ue
import struct
import random

width = 1024
height = 1024
heightmap = []

# fill the heightmap with random values
for y in range(0, height):
    for x in range(0, width):
        heightmap.append(random.randint(0, 65535))

data = struct.pack('{0}H'.format(width * height), *heightmap)

现在我们可以将“数据”用于景观 API。在填充景观之前,我们需要生成它:

from unreal_engine.classes import Landscape

new_landscape = ue.get_editor_world().actor_spawn(Landscape)

不要运行之前的脚本,因为编辑器不喜欢未初始化的地形(它会崩溃)。使用之前创建的高度图数据填充地形。选择我们需要多少个组件(网格分辨率)以及每个组件需要多少个四边形(组件几何体由四边形基元形成)。一旦我们知道地形大小,我们就可以相应地扩展/调整高度图:

unreal_engine.heightmap_expand(data, original_width, original_height, terrain_width, terrain_height)

这将生成具有景观最佳尺寸的高度图。

import unreal_engine as ue
import struct
import random
from unreal_engine.classes import Landscape

width = 1024
height = 1024
heightmap = []

for y in range(0, height):
    for x in range(0, width):
        heightmap.append(random.randint(0, 65535))

data = struct.pack('{0}H'.format(width * height), *heightmap)

quads_per_section = 63
number_of_sections = 1
components_x = 8
components_y = 8

fixed_data = ue.heightmap_expand(data, width, height, quads_per_section * number_of_sections * components_x + 1, quads_per_section * number_of_sections * components_y + 1)

landscape = ue.get_editor_world().actor_spawn(Landscape)
landscape.landscape_import(quads_per_section, number_of_sections, components_x, components_y, fixed_data)
landscape.set_actor_scale(1,1,1)

我们没有指定每个组件的四边形,而是使用“部分”概念。 UE4允许另一个级别的细分 https://docs.unrealengine.com/latest/INT/Engine/Landscape/TechnicalGuide/#componentsections更好地控制优化(LOD 和 mipmapping)。您可以有 1 个部分(1x1 四边形)或 2 个部分(2x2 四边形)。不支持其他值。四边形的数量与纹理大小有关,因此有效值为:7x7、15x15、31x31、63x63、127x127、255x255(请注意相差一的怪异,因为所有地形工具都使用最大值而不是大小)。您需要仔细选择地形的大小 https://docs.unrealengine.com/latest/INT/Engine/Landscape/TechnicalGuide/index.html#calculatingheightmapdimensions以及高度图。

获取/创建 ULandscapeInfo

有关景观/地形的信息存储在名为 ULandscapeInfo 的 uobject 中。要检索它(或者如果您进行奇怪的操作,最终创建一个新的),您有以下两个函数:

landscape_info = landscape.get_landscape_info()

# create a new ULandscapeInfo, required if you do not import an heightmap in a manually spawned landscape
landscape_info = landscape.create_landscape_info()

检索 ULandscapeComponent 的纹理

要访问地形的高度值,请从每个组件中检索它们:

import unreal_engine as ue

for component in landscape.LandscapeComponents:
    heightmap_texture = component.HeightmapTexture
    print('{0}x{1} -> {2}'.format(heightmap_texture.texture_get_width(), heightmap_texture.texture_get_height(), len(heightmap_texture.texture_get_source_data())))

这将打印每个景观组件的纹理宽度、高度和数据大小。

将地形导出到 FRawMesh

FRawMesh 是一个表示网格的特殊结构 https://github.com/20tab/UnrealEnginePython/blob/master/tutorials/SnippetsForStaticAndSkeletalMeshes.md。您可以使用它来生成新的静态网格物体。您可以使用以下命令从景观生成新的 FRawMesh:

# lod is optional, by default it is 0
raw_mesh = landscape.landscape_export_to_raw_mesh([lod])

地形通常面积很大。

高度图 API

公开高度图高级 API 以简化高度图操作。

# expand the heightmap to fit the new size
expanded_data = ue.heightmap_expand(data, data_width, data_height, new_width, new_height)
# import a heightmap file (r16 or grayscale 16bit png) and returns a bytearray
data = ue.heightmap_import(filename[,width, height])

如果未指定宽度和高度,它将尝试从文件中检索它们。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

UE4.27中的景观创建 的相关文章

随机推荐