Our team are developing a multiplayer online battle royale game. We use both World Origin Shift and Distance Field Ambient Occlusion.When we use SetWorldOriginLocation function to shift the world, the Actor and physics both work correctly, but the DFAO is very weird as shown in the following image.
The right AO texture shoud be the following:
After eject, I found the Distance Field Ambient Occlusion Texture is not correct, not match the world’s primitives.
After some further investigation, I have found that the UStaticMeshComponent’s Distance Field not be updated in the Global Distance Field. The Global Distance Field does nothing when the world origin be shifted.
I fix it by modify some Rendering files below.
in the class FSceneInterface of SceneInterface.h :
add: virtual void UpdatePrimitiveDistanceFieldSceneData_GameThread(UPrimitiveComponent* Primitive) {};
in the class FScene of ScenePrivate.h:
add:
virtual void UpdatePrimitiveDistanceFieldSceneData_GameThread(UPrimitiveComponent* Primitive) override;
void UpdatePrimitiveDistanceField_RenderThread(FPrimitiveSceneProxy* PrimitiveSceneProxy);
in the RenderScene.cpp:
add :
void FScene::UpdatePrimitiveDistanceFieldSceneData_GameThread(UPrimitiveComponent* Primitive)
{
if(Primitive->SceneProxy)
{
FScene* Scene = this;
ENQUEUE_RENDER_COMMAND(UpdateDistanceFieldCommand)(
[Scene, Primitive](FRHICommandListImmediate& RHICmdList)
{
FScopeCycleCounter Context(Primitive->SceneProxy->GetStatId());
Scene->UpdatePrimitiveDistanceField_RenderThread(Primitive->SceneProxy);
});
}
}
void FScene::UpdatePrimitiveDistanceField_RenderThread(FPrimitiveSceneProxy* PrimitiveSceneProxy)
{
DistanceFieldSceneData.UpdatePrimitive(PrimitiveSceneProxy->GetPrimitiveSceneInfo());
}
in the class UPrimitiveComponent of PrimitiveComponent.h:
add: virtual void ApplyWorldOffset(const FVector& InOffset, bool bWorldShift) override;
in the PrimitiveComponent.cpp
add:
void UPrimitiveComponent::ApplyWorldOffset(const FVector& InOffset, bool bWorldShift)
{
Super::ApplyWorldOffset(InOffset, bWorldShift);
if (SceneProxy)
{
GetWorld()->Scene->UpdatePrimitiveDistanceFieldSceneData_GameThread(this);
}
}
That fix the problem.
Though I fix by myself, but I think offset the Global Distance Field Volume Texture in
FScene::ApplyWorldOffset_RenderThread(FVector InOffset) function must be elegant and efficient.
Our game website : http://en.zogame.com.cn/