Game
2025-11-21
UE5 C++ 创建 2D/3D 纹理资源
UE5 C++ 创建 2D 或 3D 纹理资源
最近在项目里需要在运行时生成体素数据并转换为 3D 纹理资源,过程中踩到不少坑,这里把关键步骤和一份 3D 纹理伪代码整理下来,方便以后查阅。思路同样适用于 2D 纹理,只需把尺寸与 UTexture2D 调整即可。
核心步骤
- 创建唯一的包名与资源名:通常用关卡名与 Actor 名组合,避免命名冲突。
- 准备像素数据:
uint8* Data指向已经排布好的 BGRA 像素缓冲。 - 实例化纹理对象:2D 用
UTexture2D,3D 用UVolumeTexture。 - 填写
Source数据并锁定/解锁 Mip:确保字节数与尺寸匹配。 - 配置
FTexturePlatformData与像素格式:例如PF_B8G8R8A8。 - 更新资源并标记为脏:调用
UpdateResource、PostEditChange、MarkPackageDirty。 - 注册到资产库(可选保存为 .uasset):
FAssetRegistryModule::AssetCreated与UPackage::SavePackage。
3D 纹理伪代码
FString Filename = GetWorld()->GetMapName()+"_"+GetOwner()->GetActorLabel();
const FString PackagePath = FString("/Game/") + Filename;
UPackage* Package = CreatePackage(*PackagePath);
Package->FullyLoad();
uint8* Texture ;
Texture = Data;//Data是要存入的像素数据 uint8指针
//3D纹理
UVolumeTexture* NewTexture3D = NewObject<UVolumeTexture>(Package, *Filename, RF_Public|RF_Standalone|RF_MarkAsRootSet);
// 设置纹理属性
NewTexture3D->Source.Init(SizeX, SizeY, SizeZ, 1, TSF_BGRA8);
NewTexture3D->SRGB = false;
NewTexture3D->Filter = TF_Nearest;
NewTexture3D->CompressionSettings = TC_BC7;
//或者其他自己要设置的属性
uint8* SourceData = NewTexture3D->Source.LockMip(0);
FMemory::Memcpy(SourceData, Texture, ByteSize);//ByteSize是算好的大小,字节数
NewTexture3D->Source.UnlockMip(0);
FTexturePlatformData * TexturePlatformData3D = new FTexturePlatformData();
// 设置贴图大小以及格式
TexturePlatformData3D->SizeX = SizeX;
TexturePlatformData3D->SizeY = SizeY;
TexturePlatformData3D->SetNumSlices(SizeZ);
TexturePlatformData3D->PixelFormat = PF_B8G8R8A8;
NewTexture3D->SetPlatformData(TexturePlatformData3D);
NewTexture3D->AddToRoot();
NewTexture3D->UpdateResource();
NewTexture3D->PostEditChange();
NewTexture3D->MarkPackageDirty();
Package->MarkPackageDirty();
FAssetRegistryModule::AssetCreated(NewTexture3D);
//下面两行是参考的别的人写的,应该可以不写
const FString PackageFileName = FPackageName::LongPackageNameToFilename(PackagePath, FPackageName::GetAssetPackageExtension());
bool bSaved = UPackage::SavePackage(Package, NewTexture3D, EObjectFlags::RF_Public |
EObjectFlags::RF_Standalone, *PackageFileName, GError, nullptr, true, true, SAVE_NoError);
ByteSize需根据SizeX * SizeY * SizeZ * 每像素字节数计算。若填写错误,LockMip后的内存拷贝会导致越界或花屏。
注意事项
- 3D 纹理的
SetNumSlices(SizeZ)必须与Source.Init的 Z 保持一致。 - 若要生成 2D 纹理,则改用
UTexture2D并移除SetNumSlices,同时注意SizeZ设为 1。 - 纹理压缩格式会影响最终效果,
TC_BC7适合高质量 RGBA 数据,若需要线性空间可保持SRGB = false。 - 若运行时只需内存中的纹理,可跳过
UPackage::SavePackage,但别忘记调用AddToRoot以避免 GC。
总结
流程的本质就是:准备好字节数据 → 创建纹理对象 → 写入 Source → 配置 PlatformData → 注册并保存。以上伪代码覆盖了关键 API,按需微调即可快速在 UE5 中生成 2D 或 3D 纹理资源。