Skip to content

Commit

Permalink
Fixed some cases where render proxy wasn't recreated.
Browse files Browse the repository at this point in the history
Added back ray tracing support.
  • Loading branch information
Koderz committed Feb 27, 2023
1 parent 090faf4 commit b4fb2cf
Show file tree
Hide file tree
Showing 17 changed files with 301 additions and 189 deletions.
16 changes: 16 additions & 0 deletions Source/RealtimeMeshComponent/Private/Data/RealtimeMeshLOD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ namespace RealtimeMesh
});

ConfigUpdatedEvent.Broadcast(this->AsShared());

MarkRenderStateDirty(true);
}

FRealtimeMeshSectionGroupKey FRealtimeMeshLODData::CreateSectionGroup()
Expand All @@ -82,6 +84,8 @@ namespace RealtimeMesh
});

SectionGroupAddedEvent.Broadcast(this->AsShared(), SectionGroupKey);

MarkRenderStateDirty(true);
return SectionGroupKey;
}

Expand All @@ -100,6 +104,8 @@ namespace RealtimeMesh
});

SectionGroupRemovedEvent.Broadcast(this->AsShared(), SectionGroupKey);

MarkRenderStateDirty(true);
}
else
{
Expand Down Expand Up @@ -130,6 +136,16 @@ namespace RealtimeMesh
{
SectionGroupRemovedEvent.Broadcast(this->AsShared(), SectionGroup);
}

MarkRenderStateDirty(true);
}

void FRealtimeMeshLODData::MarkRenderStateDirty(bool bShouldRecreateProxies)
{
if (const auto Mesh = MeshWeak.Pin())
{
Mesh->MarkRenderStateDirty(bShouldRecreateProxies);
}
}

FRealtimeMeshLODProxyInitializationParametersRef FRealtimeMeshLODData::GetInitializationParams() const
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ namespace RealtimeMesh
FWriteScopeLock ScopeLock(Lock);
Config = InConfig;
StreamRange = InStreamRange;

MarkRenderStateDirty(true);
}

void FRealtimeMeshSectionData::UpdateBounds(const FBoxSphereBounds3f& InBounds)
Expand All @@ -86,6 +88,8 @@ namespace RealtimeMesh
});

ConfigUpdatedEvent.Broadcast(this->AsShared());

MarkRenderStateDirty(true);
}

void FRealtimeMeshSectionData::UpdateStreamRange(const FRealtimeMeshStreamRange& InRange)
Expand All @@ -100,6 +104,8 @@ namespace RealtimeMesh
});

StreamRangeUpdatedEvent.Broadcast(this->AsShared());

MarkRenderStateDirty(true);
}

bool FRealtimeMeshSectionData::IsVisible() const
Expand All @@ -122,6 +128,8 @@ namespace RealtimeMesh
});

ConfigUpdatedEvent.Broadcast(this->AsShared());

MarkRenderStateDirty(true);
}

bool FRealtimeMeshSectionData::IsCastingShadow() const
Expand All @@ -144,10 +152,20 @@ namespace RealtimeMesh
});

ConfigUpdatedEvent.Broadcast(this->AsShared());

MarkRenderStateDirty(true);
}

void FRealtimeMeshSectionData::MarkRenderStateDirty(bool bShouldRecreateProxies)
{
if (const auto Mesh = MeshWeak.Pin())
{
Mesh->MarkRenderStateDirty(bShouldRecreateProxies);
}
}

void FRealtimeMeshSectionData::OnStreamsChanged(const TArray<FRealtimeMeshStreamKey>& AddedOrUpdatedStreams,
const TArray<FRealtimeMeshStreamKey>& RemovedStreams)
const TArray<FRealtimeMeshStreamKey>& RemovedStreams)
{
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ namespace RealtimeMesh

// Broadcast stream updated event
BroadcastStreamsChanged({ StreamKey }, {});

MarkRenderStateDirty(true);
}

void FRealtimeMeshSectionGroup::ClearStream(FRealtimeMeshStreamKey StreamKey)
Expand All @@ -85,6 +87,8 @@ namespace RealtimeMesh

// Broadcast stream updated event
BroadcastStreamsChanged({ StreamKey }, {});

MarkRenderStateDirty(true);
}

void FRealtimeMeshSectionGroup::RemoveStream(FRealtimeMeshStreamKey StreamKey)
Expand All @@ -96,6 +100,8 @@ namespace RealtimeMesh

// Broadcast stream removed event
BroadcastStreamsChanged({}, { StreamKey });

MarkRenderStateDirty(true);
}

void FRealtimeMeshSectionGroup::SetAllStreams(const TArray<FRealtimeMeshStreamKey>& UpdatedStreamKeys, const TArray<FRealtimeMeshStreamKey>& RemovedStreamKeys,
Expand All @@ -109,6 +115,8 @@ namespace RealtimeMesh

// Broadcast all stream added/removed events
BroadcastStreamsChanged(UpdatedStreamKeys, RemovedStreamKeys);

MarkRenderStateDirty(true);
}

FRealtimeMeshSectionKey FRealtimeMeshSectionGroup::CreateSection(const FRealtimeMeshSectionConfig& InConfig, const FRealtimeMeshStreamRange& InStreamRange)
Expand All @@ -134,6 +142,8 @@ namespace RealtimeMesh

BroadcastSectionsChanged({SectionKey}, {});

MarkRenderStateDirty(true);

return SectionKey;
}

Expand All @@ -151,6 +161,8 @@ namespace RealtimeMesh
});

BroadcastSectionsChanged({}, {SectionKey});

MarkRenderStateDirty(true);
}
else
{
Expand All @@ -177,6 +189,16 @@ namespace RealtimeMesh

// Broadcast all stream removed events
BroadcastSectionsChanged({}, RemovedSections);

MarkRenderStateDirty(true);
}

void FRealtimeMeshSectionGroup::MarkRenderStateDirty(bool bShouldRecreateProxies)
{
if (const auto Mesh = MeshWeak.Pin())
{
Mesh->MarkRenderStateDirty(bShouldRecreateProxies);
}
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,26 @@ namespace RealtimeMesh
const auto LODScreenSizes = RealtimeMeshProxy->GetScreenSizeLimits(LODIndex);

FMeshBatch MeshBatch;
RealtimeMeshProxy->PopulateSectionMeshBatches(ERealtimeMeshSectionDrawType::Static, false, LODIndex, LODMask, LODScreenSizes,
IsMovable(), IsLocalToWorldDeterminantNegative(), bCastRayTracedShadow, nullptr, GetUniformBuffer(), Materials,
[&MeshBatch]()-> FMeshBatch& { MeshBatch = FMeshBatch(); return MeshBatch; },
[&PDI](const FMeshBatch& Batch, float MinScreenSize) { PDI->DrawMesh(Batch, MinScreenSize); },
[this](const TSharedRef<FRenderResource>& Resource) { InUseBuffers.Add(Resource); });
FRealtimeMeshBatchCreationParams Params
{
[this](const TSharedRef<FRenderResource>& Resource) { InUseBuffers.Add(Resource); },
[&MeshBatch]()-> FMeshBatch& { MeshBatch = FMeshBatch(); return MeshBatch; },
#if RHI_RAYTRACING
[&PDI](const FMeshBatch& Batch, float MinScreenSize, const FRayTracingGeometry*) { PDI->DrawMesh(Batch, MinScreenSize); },
#else
[&PDI](const FMeshBatch& Batch, float MinScreenSize) { PDI->DrawMesh(Batch, MinScreenSize); },
#endif
GetUniformBuffer(),
LODScreenSizes,
LODMask,
IsMovable(),
IsLocalToWorldDeterminantNegative(),
bCastRayTracedShadow
};

RealtimeMeshProxy->CreateMeshBatches(LODIndex, Params, Materials, nullptr, ERealtimeMeshSectionDrawType::Static, false);


}
}
}
Expand Down Expand Up @@ -189,11 +204,24 @@ namespace RealtimeMesh

const auto LODScreenSizes = RealtimeMeshProxy->GetScreenSizeLimits(LODIndex);

RealtimeMeshProxy->PopulateSectionMeshBatches(ERealtimeMeshSectionDrawType::Dynamic, bForceDynamicPath, LODIndex, LODMask, LODScreenSizes,
IsMovable(), IsLocalToWorldDeterminantNegative(), bCastRayTracedShadow, WireframeMaterialInstance, GetUniformBuffer(), Materials,
[&Collector]()-> FMeshBatch& { return Collector.AllocateMesh(); },
FRealtimeMeshBatchCreationParams Params
{
[](const TSharedRef<FRenderResource>&) { },
[&Collector]()-> FMeshBatch& { return Collector.AllocateMesh(); },
#if RHI_RAYTRACING
[&Collector, ViewIndex](FMeshBatch& Batch, float, const FRayTracingGeometry*) { Collector.AddMesh(ViewIndex, Batch); },
#else
[&Collector, ViewIndex](FMeshBatch& Batch, float) { Collector.AddMesh(ViewIndex, Batch); },
[](const TSharedRef<FRenderResource>&) { });
#endif
GetUniformBuffer(),
LODScreenSizes,
LODMask,
IsMovable(),
IsLocalToWorldDeterminantNegative(),
bCastRayTracedShadow
};

RealtimeMeshProxy->CreateMeshBatches(LODIndex, Params, Materials, WireframeMaterialInstance, ERealtimeMeshSectionDrawType::Dynamic, bForceDynamicPath);
}
}
}
Expand Down Expand Up @@ -226,51 +254,59 @@ namespace RealtimeMesh
#if RHI_RAYTRACING
void FRealtimeMeshComponentSceneProxy::GetDynamicRayTracingInstances(struct FRayTracingMaterialGatheringContext& Context, TArray<struct FRayTracingInstance>& OutRayTracingInstances)
{
//this->RayTracingGeometries
//SCOPE_CYCLE_COUNTER(STAT_RealtimeMeshComponentSceneProxy_GetDynamicRayTracingInstances);
SCOPE_CYCLE_COUNTER(STAT_RealtimeMeshComponentSceneProxy_GetDynamicRayTracingInstances);

//// TODO: Should this use any LOD determination logic? Or always use a specific LOD?
//int32 LODIndex = 0;
//
//if (RealtimeMeshProxy->HasValidLODs())
//{
// auto& LOD = RealtimeMeshProxy->GetLOD(LODIndex);

// for (const auto& SectionEntry : LOD.Sections)
// {
// int32 SectionId = SectionEntry.Key;
// auto& Section = SectionEntry.Value;

// if (Section.ShouldRenderDynamicPathRayTracing())
// {
// UMaterialInterface* SectionMat = GetMaterialSlot(Section.MaterialSlot);
// check(SectionMat);

// FRayTracingGeometry* SectionRayTracingGeometry = &Section.Buffers->RayTracingGeometry;

// if (SectionRayTracingGeometry->RayTracingGeometryRHI->IsValid())
// {
// check(SectionRayTracingGeometry->Initializer.TotalPrimitiveCount > 0);
// check(SectionRayTracingGeometry->Initializer.IndexBuffer.IsValid());

// FRayTracingInstance RayTracingInstance;
// RayTracingInstance.Geometry = SectionRayTracingGeometry;
// RayTracingInstance.InstanceTransforms.Add(GetLocalToWorld());

// FMeshBatch MeshBatch;
// CreateMeshBatch(MeshBatch, Section, LODIndex, SectionId, SectionMat, nullptr, true);
// Make sure all pending changes have been processed
RealtimeMeshProxy->HandleUpdates(false);

// TODO: Should this use any LOD determination logic? Or always use a specific LOD?
const int32 LODIndex = 0;


// MeshBatch.CastRayTracedShadow = IsShadowCast(Context.ReferenceView);

if (RealtimeMeshProxy->GetDrawMask().HasAnyFlags())
{
if (auto LOD = RealtimeMeshProxy->GetLOD(LODIndex))
{
if (LOD.IsValid() && LOD->GetDrawMask().IsAnySet(ERealtimeMeshDrawMask::DrawDynamic | ERealtimeMeshDrawMask::DrawStatic))
{
FLODMask LODMask;
LODMask.SetLOD(LODIndex);

const auto LODScreenSizes = RealtimeMeshProxy->GetScreenSizeLimits(LODIndex);

FMeshBatch MeshBatch;
FRealtimeMeshBatchCreationParams Params
{
[](const TSharedRef<FRenderResource>&) { },
[MeshBatch = &MeshBatch]()-> FMeshBatch& { *MeshBatch = FMeshBatch(); return *MeshBatch; },
[&OutRayTracingInstances, LocalToWorld = GetLocalToWorld(), FeatureLevel = GetScene().GetFeatureLevel()](const FMeshBatch& Batch, float MinScreenSize, const FRayTracingGeometry* RayTracingGeometry)
{
check(RayTracingGeometry->Initializer.TotalPrimitiveCount > 0);
check(RayTracingGeometry->Initializer.IndexBuffer.IsValid());
checkf(RayTracingGeometry->RayTracingGeometryRHI, TEXT("Ray tracing instance must have a valid geometry."));
FRayTracingInstance RayTracingInstance;
RayTracingInstance.Geometry = RayTracingGeometry;
RayTracingInstance.InstanceTransforms.Add(LocalToWorld);

RayTracingInstance.Materials.Add(Batch);
RayTracingInstance.BuildInstanceMaskAndFlags(FeatureLevel);
OutRayTracingInstances.Add(RayTracingInstance);
},
GetUniformBuffer(),
LODScreenSizes,
LODMask,
IsMovable(),
IsLocalToWorldDeterminantNegative(),
IsShadowCast(Context.ReferenceView)
};

RealtimeMeshProxy->CreateMeshBatches(LODIndex, Params, Materials, nullptr, ERealtimeMeshSectionDrawType::Dynamic, true /* bForceDynamicPath */);
}
}
}

// RayTracingInstance.Materials.Add(MeshBatch);
// RayTracingInstance.BuildInstanceMaskAndFlags();
// OutRayTracingInstances.Add(RayTracingInstance);
// }
// }
// }
//}
check(true);
}
#endif // RHI_RAYTRACING

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,8 @@ namespace RealtimeMesh
MarkStateDirty();
}

void FRealtimeMeshLODProxy::PopulateMeshBatches(ERealtimeMeshSectionDrawType DrawType, bool bForceAllDynamic, const FLODMask& LODMask,
const TRange<float>& ScreenSizeLimits, bool bIsMovable, bool bIsLocalToWorldDeterminantNegative, bool bCastRayTracedShadow, FMaterialRenderProxy* WireframeMaterial,
FRHIUniformBuffer* UniformBuffer, const TMap<int32, TTuple<FMaterialRenderProxy*, bool>>& Materials, TFunctionRef<FMeshBatch&()> BatchAllocator,
TFunctionRef<void(FMeshBatch&, float)> BatchSubmitter, TFunctionRef<void(const TSharedRef<FRenderResource>&)> ResourceSubmitter) const
void FRealtimeMeshLODProxy::CreateMeshBatches(const FRealtimeMeshBatchCreationParams& Params, const TMap<int32, TTuple<FMaterialRenderProxy*, bool>>& Materials,
const FMaterialRenderProxy* WireframeMaterial, ERealtimeMeshSectionDrawType DrawType, bool bForceAllDynamic) const
{
const ERealtimeMeshDrawMask DrawTypeMask = bForceAllDynamic ? ERealtimeMeshDrawMask::DrawPassMask :
DrawType == ERealtimeMeshSectionDrawType::Dynamic ? ERealtimeMeshDrawMask::DrawDynamic : ERealtimeMeshDrawMask::DrawStatic;
Expand All @@ -81,8 +79,7 @@ namespace RealtimeMesh
{
if (SectionGroup->GetDrawMask().IsAnySet(DrawTypeMask))
{
SectionGroup->PopulateMeshBatches(DrawType, bForceAllDynamic, LODMask, ScreenSizeLimits, bIsMovable, bIsLocalToWorldDeterminantNegative, bCastRayTracedShadow,
WireframeMaterial, UniformBuffer, Materials, BatchAllocator, BatchSubmitter, ResourceSubmitter);
SectionGroup->CreateMeshBatches(Params, Materials, WireframeMaterial, DrawType, bForceAllDynamic);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,11 @@ namespace RealtimeMesh
MarkStateDirty();
}

void FRealtimeMeshProxy::PopulateSectionMeshBatches(ERealtimeMeshSectionDrawType DrawType, bool bForceAllDynamic, uint8 LODIndex, const FLODMask& LODMask,
const TRange<float>& ScreenSizeLimits, bool bIsMovable, bool bIsLocalToWorldDeterminantNegative, bool bCastRayTracedShadow, FMaterialRenderProxy* WireframeMaterial,
FRHIUniformBuffer* UniformBuffer, const TMap<int32, TTuple<FMaterialRenderProxy*, bool>>& Materials, TFunction<FMeshBatch&()> BatchAllocator,
TFunction<void(FMeshBatch&, float)> BatchSubmitter, TFunction<void(const TSharedRef<FRenderResource>&)> ResourceSubmitter) const
void FRealtimeMeshProxy::CreateMeshBatches(int32 LODIndex, const FRealtimeMeshBatchCreationParams& Params, const TMap<int32, TTuple<FMaterialRenderProxy*, bool>>& Materials,
const FMaterialRenderProxy* WireframeMaterial, ERealtimeMeshSectionDrawType DrawType, bool bForceAllDynamic) const
{
const auto& LOD = LODs[LODIndex];
LOD->PopulateMeshBatches(DrawType, bForceAllDynamic, LODMask, ScreenSizeLimits, bIsMovable, bIsLocalToWorldDeterminantNegative, bCastRayTracedShadow, WireframeMaterial,
UniformBuffer, Materials, BatchAllocator, BatchSubmitter, ResourceSubmitter);
LOD->CreateMeshBatches(Params, Materials, WireframeMaterial, DrawType, bForceAllDynamic);
}

void FRealtimeMeshProxy::EnqueueRenderingCommand(TUniqueFunction<void(const FRealtimeMeshProxyRef&)>&& InCommand)
Expand Down
Loading

0 comments on commit b4fb2cf

Please sign in to comment.