procedural mesh的源碼
UnrealEngine/ProceduralMeshComponent.cpp at c3caf7b6bf12ae4c8e09b606f10a09776b4d1f38 · EpicGames/UnrealEngine (github.com)
問題在于procedural建立的時候實際是對資料進行了拷貝,如果這些代碼都在主線程執行,必然會影響遊戲的流暢性。
void UProceduralMeshComponent::CreateMeshSection(int32 SectionIndex, const TArray<FVector>& Vertices, const TArray<int32>& Triangles, const TArray<FVector>& Normals, const TArray<FVector2D>& UV0, const TArray<FVector2D>& UV1, const TArray<FVector2D>& UV2, const TArray<FVector2D>& UV3, const TArray<FColor>& VertexColors, const TArray<FProcMeshTangent>& Tangents, bool bCreateCollision)
{
SCOPE_CYCLE_COUNTER(STAT_ProcMesh_CreateMeshSection);
// Ensure sections array is long enough
if (SectionIndex >= ProcMeshSections.Num())
{
ProcMeshSections.SetNum(SectionIndex + 1, false);
}
// Reset this section (in case it already existed)
FProcMeshSection& NewSection = ProcMeshSections[SectionIndex];
NewSection.Reset();
// Copy data to vertex buffer
const int32 NumVerts = Vertices.Num();
NewSection.ProcVertexBuffer.Reset();
NewSection.ProcVertexBuffer.AddUninitialized(NumVerts);
for (int32 VertIdx = 0; VertIdx < NumVerts; VertIdx++)
{
FProcMeshVertex& Vertex = NewSection.ProcVertexBuffer[VertIdx];
Vertex.Position = Vertices[VertIdx];
Vertex.Normal = (Normals.Num() == NumVerts) ? Normals[VertIdx] : FVector(0.f, 0.f, 1.f);
Vertex.UV0 = (UV0.Num() == NumVerts) ? UV0[VertIdx] : FVector2D(0.f, 0.f);
Vertex.UV1 = (UV1.Num() == NumVerts) ? UV1[VertIdx] : FVector2D(0.f, 0.f);
Vertex.UV2 = (UV2.Num() == NumVerts) ? UV2[VertIdx] : FVector2D(0.f, 0.f);
Vertex.UV3 = (UV3.Num() == NumVerts) ? UV3[VertIdx] : FVector2D(0.f, 0.f);
Vertex.Color = (VertexColors.Num() == NumVerts) ? VertexColors[VertIdx] : FColor(255, 255, 255);
Vertex.Tangent = (Tangents.Num() == NumVerts) ? Tangents[VertIdx] : FProcMeshTangent();
// Update bounding box
NewSection.SectionLocalBox += Vertex.Position;
}
// Copy index buffer (clamping to vertex range)
int32 NumTriIndices = Triangles.Num();
NumTriIndices = (NumTriIndices/3) * 3; // Ensure we have exact number of triangles (array is multiple of 3 long)
NewSection.ProcIndexBuffer.Reset();
NewSection.ProcIndexBuffer.AddUninitialized(NumTriIndices);
for (int32 IndexIdx = 0; IndexIdx < NumTriIndices; IndexIdx++)
{
NewSection.ProcIndexBuffer[IndexIdx] = FMath::Min(Triangles[IndexIdx], NumVerts - 1);
}
NewSection.bEnableCollision = bCreateCollision;
UpdateLocalBounds(); // Update overall bounds
UpdateCollision(); // Mark collision as dirty
MarkRenderStateDirty(); // New section requires recreating scene proxy
}
不過光看代碼感覺沒什麼問題,不過我還是懷疑拷貝過程造成的問題
後來測量了建立網格(CreateMeshSection函數)花費時間,果然跟網格數量成正比,是以我果斷嘗試了一個mesh comp隻對應一個網格,
成功解決。目前流暢的60fps
項目位址:
ActivePeter/VoxelFrame_UE4: Planning to implement my VoxelFrame project on ue4, which is a minecraft like game. (github.com)