3.9 KiB
3.9 KiB
项目1,北京市科委研发项目
需要在虚幻里访问api获得模型文件(fbx模型 png贴图)和场景描述(json) 在runtime下加载后,用于扣绿虚拍系统
项目2,国家数字资产平台
根据访问需求,接通云游戏(使用蔚领云游戏SDK),然后收到前端的资产uuid,加载资产渲染。
第一阶段
用户访问一个web平台,点击某个资产(模型or场景) 会弹出一个页面,页面类似虚幻metahuman编辑器一样,是视频流的形式
在视频流中,是一个runtime窗口,可以渲染目标资产
第二阶段
可以在前端点击资产添加,runtime窗口里会添加资产,然后runtime窗口里有简单编辑器可以摆镜头,可以简单摆放资产
Default材质
标准pbr(半透明) 提供参数
- base color (tex)
- basecolor tilt (v3) 乘basevolor
- opacity(tex linear)
- opacity power(scale)乘到opacity
- roughness(tex linear color)
- roughness tilt(scale) 乘roughness
- metalic (tex linear color)
- metalic tilt(scale)
- ao (tex linear color)
- emisive(tex)
- emisive power(scale) 乘emisive
- normal(tex)
FaceSet
b4ed874081/projects/FBX/FBXSDK.cpp (L477)
int mat_count = 0;
if (pMesh->GetElementMaterialCount() > 0) {
for (auto i = 0; i < numPolygons; ++i) {
faceset[i] = pMesh->GetElementMaterial()->GetIndexArray().GetAt(i);
}
mat_count = pNode->GetMaterialCount();
for (auto i = 0; i < mat_count; i++) {
FbxSurfaceMaterial* material = pNode->GetMaterial(i);
ud.set2(format("faceset_{}", i), material->GetName());
}
}
UE中相关逻辑位于FbxMesh.cpp
void ExtractMeshMaterials(FFbxParser& Parser, FbxMesh* Mesh, FbxNode* MeshNode, TFunction<void(const FString& MaterialName, const FString& MaterialUid, const int32 MeshMaterialIndex)> CollectMaterial)
{
if (!Mesh || !MeshNode)
{
return;
}
//Grab all Material indexes use by the mesh
TArray<int32> MaterialIndexes;
int32 PolygonCount = Mesh->GetPolygonCount();
if (FbxGeometryElementMaterial* GeometryElementMaterial = Mesh->GetElementMaterial())
{
FbxLayerElementArrayTemplate<int32>& IndexArray = GeometryElementMaterial->GetIndexArray();
switch (GeometryElementMaterial->GetMappingMode())
{
case FbxGeometryElement::eByPolygon:
{
if (IndexArray.GetCount() == PolygonCount)
{
for (int32 PolygonIndex = 0; PolygonIndex < PolygonCount; ++PolygonIndex)
{
MaterialIndexes.AddUnique(IndexArray.GetAt(PolygonIndex));
}
}
}
break;
case FbxGeometryElement::eAllSame:
{
if (IndexArray.GetCount() > 0)
{
MaterialIndexes.AddUnique(IndexArray.GetAt(0));
}
}
break;
}
}
const int32 MaterialCount = MeshNode->GetMaterialCount();
TMap<FbxSurfaceMaterial*, int32> UniqueSlotNames;
UniqueSlotNames.Reserve(MaterialCount);
bool bAddAllNodeMaterials = (MaterialIndexes.Num() == 0);
for (int32 MaterialIndex = 0; MaterialIndex < MaterialCount; ++MaterialIndex)
{
if (FbxSurfaceMaterial* FbxMaterial = MeshNode->GetMaterial(MaterialIndex))
{
int32& SlotMaterialCount = UniqueSlotNames.FindOrAdd(FbxMaterial);
FString MaterialName = Parser.GetFbxHelper()->GetFbxObjectName(FbxMaterial);
FString MaterialUid = TEXT("\\Material\\") + MaterialName;
if (bAddAllNodeMaterials || MaterialIndexes.Contains(MaterialIndex))
{
if (SlotMaterialCount > 0)
{
MaterialName += TEXT("_Section") + FString::FromInt(SlotMaterialCount);
}
SlotMaterialCount++;
CollectMaterial(MaterialName, MaterialUid, MaterialIndex);
}
}
}
}
AFBXMeshActor::AddMesh
UFBXSceneImporter::ImportFBX() => UFBXSceneImporter::ProcessNode() => UFBXSceneImporter::ProcessMesh() => UFBXSceneImporter::CreateNodeMaterials() => FBXImportSettings->GetMaterialProperties(FbxMaterial, Node->GetName());
FaceSet
FbxGeometryElementMaterial* GetElementMaterial
FbxGeometryElementMaterial(FbxLayerElementMaterial),