132 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			132 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
# 项目1,北京市科委研发项目
 | 
						||
需要在虚幻里访问api获得模型文件(fbx模型 png贴图)和场景描述(json) 在runtime下加载后,用于扣绿虚拍系统
 | 
						||
 | 
						||
# 项目2,国家数字资产平台
 | 
						||
根据访问需求,接通云游戏(使用蔚领云游戏SDK),然后收到前端的资产uuid,加载资产渲染。
 | 
						||
 | 
						||
## 第一阶段
 | 
						||
用户访问一个web平台,点击某个资产(模型or场景)
 | 
						||
会弹出一个页面,页面类似虚幻metahuman编辑器一样,是视频流的形式
 | 
						||
 | 
						||
在视频流中,是一个runtime窗口,可以渲染目标资产
 | 
						||
 | 
						||
## 第二阶段
 | 
						||
可以在前端点击资产添加,runtime窗口里会添加资产,然后runtime窗口里有简单编辑器可以摆镜头,可以简单摆放资产
 | 
						||
 | 
						||
# Default材质
 | 
						||
标准pbr(半透明)
 | 
						||
提供参数
 | 
						||
1. base color (tex)
 | 
						||
2. basecolor tilt (v3) 乘basevolor
 | 
						||
4. opacity(tex linear)
 | 
						||
5. opacity power(scale)乘到opacity
 | 
						||
6. roughness(tex linear color)
 | 
						||
7. roughness tilt(scale) 乘roughness
 | 
						||
8. metalic (tex linear color)
 | 
						||
9. metalic tilt(scale)
 | 
						||
10. ao (tex linear color)
 | 
						||
11. emisive(tex)
 | 
						||
12. emisive power(scale) 乘emisive
 | 
						||
13. normal(tex)
 | 
						||
 | 
						||
 | 
						||
# FaceSet
 | 
						||
https://github.com/zenustech/zeno/blob/b4ed8740810f20cf0612d615d9505468b2d2a4d1/projects/FBX/FBXSDK.cpp#L477
 | 
						||
 | 
						||
```c++
 | 
						||
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
 | 
						||
```c++
 | 
						||
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), |