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),