LumenSceneData 初始化 [1]

前置信息:

灯光从World到Scene的流程。

UE4 Lights UWorld to FScene [1]_spawnactor failed because of collision at the spaw_sh15285118586的博客-CSDN博客

mesh从world到Scene流程,与灯光类似

cpp 复制代码
void UStaticMeshComponent::CreateRenderState_Concurrent(FRegisterComponentContext* Context)
{
	LLM_SCOPE(ELLMTag::StaticMesh);
	Super::CreateRenderState_Concurrent(Context);
}
cpp 复制代码
void UPrimitiveComponent::CreateRenderState_Concurrent(FRegisterComponentContext* Context)
{
	// Make sure cached cull distance is up-to-date if its zero and we have an LD cull distance
	if( CachedMaxDrawDistance == 0.f && LDMaxDrawDistance > 0.f )
	{
		bool bNeverCull = bNeverDistanceCull || GetLODParentPrimitive();
		CachedMaxDrawDistance = bNeverCull ? 0.f : LDMaxDrawDistance;
	}

	Super::CreateRenderState_Concurrent(Context);

	UpdateBounds();

	// If the primitive isn't hidden and the detail mode setting allows it, add it to the scene.
	if (ShouldComponentAddToScene())
	{
		if (Context != nullptr)
		{
			Context->AddPrimitive(this);
		}
		else
		{
			GetWorld()->Scene->AddPrimitive(this);
		}
	}

	// Components are either registered as static or dynamic in the streaming manager.
	// Static components are registered in batches the first frame the level becomes visible (or incrementally each frame when loaded but not yet visible). 
	// The level static streaming data is never updated after this, and gets reused whenever the level becomes visible again (after being hidden).
	// Dynamic components, on the other hand, are updated whenever their render states change.
	// The following logic handles all cases where static components should fallback on the dynamic path.
	// It is based on a design where each component must either have bHandledByStreamingManagerAsDynamic or bAttachedToStreamingManagerAsStatic set.
	// If this is not the case, then the component has never been handled before.
	// The bIgnoreStreamingManagerUpdate flag is used to prevent handling component that are already in the update list or that don't have streaming data.
	if (!bIgnoreStreamingManagerUpdate && (Mobility != EComponentMobility::Static || bHandledByStreamingManagerAsDynamic || (!bAttachedToStreamingManagerAsStatic && OwnerLevelHasRegisteredStaticComponentsInStreamingManager(GetOwner()))))
	{
		FStreamingManagerCollection* Collection = IStreamingManager::Get_Concurrent();
		if (Collection)
		{
			Collection->NotifyPrimitiveUpdated_Concurrent(this);
		}
	}
}
cpp 复制代码
void FScene::AddPrimitive(UPrimitiveComponent* Primitive)
{
	SCOPE_CYCLE_COUNTER(STAT_AddScenePrimitiveGT);
	SCOPED_NAMED_EVENT(FScene_AddPrimitive, FColor::Green);

	checkf(!Primitive->IsUnreachable(), TEXT("%s"), *Primitive->GetFullName());

	const float WorldTime = GetWorld()->GetTimeSeconds();
	// Save the world transform for next time the primitive is added to the scene
	float DeltaTime = WorldTime - Primitive->LastSubmitTime;
	if ( DeltaTime < -0.0001f || Primitive->LastSubmitTime < 0.0001f )
	{
		// Time was reset?
		Primitive->LastSubmitTime = WorldTime;
	}
	else if ( DeltaTime > 0.0001f )
	{
		// First call for the new frame?
		Primitive->LastSubmitTime = WorldTime;
	}

	checkf(!Primitive->SceneProxy, TEXT("Primitive has already been added to the scene!"));

	// Create the primitive's scene proxy.
	FPrimitiveSceneProxy* PrimitiveSceneProxy = Primitive->CreateSceneProxy();
	Primitive->SceneProxy = PrimitiveSceneProxy;
	if(!PrimitiveSceneProxy)
	{
		// Primitives which don't have a proxy are irrelevant to the scene manager.
		return;
	}

	// Create the primitive scene info.
	FPrimitiveSceneInfo* PrimitiveSceneInfo = new FPrimitiveSceneInfo(Primitive, this);
	PrimitiveSceneProxy->PrimitiveSceneInfo = PrimitiveSceneInfo;

	// Cache the primitives initial transform.
	FMatrix RenderMatrix = Primitive->GetRenderMatrix();
	FVector AttachmentRootPosition = Primitive->GetActorPositionForRenderer();

	struct FCreateRenderThreadParameters
	{
		FPrimitiveSceneProxy* PrimitiveSceneProxy;
		FMatrix RenderMatrix;
		FBoxSphereBounds WorldBounds;
		FVector AttachmentRootPosition;
		FBoxSphereBounds LocalBounds;
	};
	FCreateRenderThreadParameters Params =
	{
		PrimitiveSceneProxy,
		RenderMatrix,
		Primitive->Bounds,
		AttachmentRootPosition,
		Primitive->GetLocalBounds()
	};

	// Help track down primitive with bad bounds way before the it gets to the Renderer
	ensureMsgf(!Primitive->Bounds.ContainsNaN(),
			TEXT("Nans found on Bounds for Primitive %s: Origin %s, BoxExtent %s, SphereRadius %f"), *Primitive->GetName(), *Primitive->Bounds.Origin.ToString(), *Primitive->Bounds.BoxExtent.ToString(), Primitive->Bounds.SphereRadius);

	INC_DWORD_STAT_BY( STAT_GameToRendererMallocTotal, PrimitiveSceneProxy->GetMemoryFootprint() + PrimitiveSceneInfo->GetMemoryFootprint() );

	// Verify the primitive is valid
	VerifyProperPIEScene(Primitive, World);

	// Increment the attachment counter, the primitive is about to be attached to the scene.
	Primitive->AttachmentCounter.Increment();

	// Create any RenderThreadResources required and send a command to the rendering thread to add the primitive to the scene.
	FScene* Scene = this;

	// If this primitive has a simulated previous transform, ensure that the velocity data for the scene representation is correct
	TOptional<FTransform> PreviousTransform = FMotionVectorSimulation::Get().GetPreviousTransform(Primitive);

	ENQUEUE_RENDER_COMMAND(AddPrimitiveCommand)(
		[Params = MoveTemp(Params), Scene, PrimitiveSceneInfo, PreviousTransform = MoveTemp(PreviousTransform)](FRHICommandListImmediate& RHICmdList)
		{
			FPrimitiveSceneProxy* SceneProxy = Params.PrimitiveSceneProxy;
			FScopeCycleCounter Context(SceneProxy->GetStatId());
			SceneProxy->SetTransform(Params.RenderMatrix, Params.WorldBounds, Params.LocalBounds, Params.AttachmentRootPosition);

			// Create any RenderThreadResources required.
			SceneProxy->CreateRenderThreadResources();

			Scene->AddPrimitiveSceneInfo_RenderThread(PrimitiveSceneInfo, PreviousTransform);
		});

}

AddedPrimitiveSceneInfos 会在后面创建LumenSceneData用到。

cpp 复制代码
void FScene::AddPrimitiveSceneInfo_RenderThread(FPrimitiveSceneInfo* PrimitiveSceneInfo, const TOptional<FTransform>& PreviousTransform)
{
	check(IsInRenderingThread());
	check(PrimitiveSceneInfo->PackedIndex == INDEX_NONE);
	check(AddedPrimitiveSceneInfos.Find(PrimitiveSceneInfo) == nullptr);
	AddedPrimitiveSceneInfos.FindOrAdd(PrimitiveSceneInfo);
	if (PreviousTransform.IsSet())
	{
		OverridenPreviousTransforms.Update(PrimitiveSceneInfo, PreviousTransform.GetValue().ToMatrixWithScale());
	}
}

LumenSceneData创建流程

Engine/Source/Runtime/Renderer/Private/DeferredShadingRenderer.cpp

cpp 复制代码
Scene->UpdateAllPrimitiveSceneInfos(GraphBuilder, true);
cpp 复制代码
void FScene::UpdateAllPrimitiveSceneInfos(FRDGBuilder& GraphBuilder, bool bAsyncCreateLPIs)
{
    TArray<FPrimitiveSceneInfo*> AddedLocalPrimitiveSceneInfos;
	AddedLocalPrimitiveSceneInfos.Reserve(AddedPrimitiveSceneInfos.Num());
	for (FPrimitiveSceneInfo* SceneInfo : AddedPrimitiveSceneInfos)
	{
		AddedLocalPrimitiveSceneInfos.Add(SceneInfo);
	}

	AddedLocalPrimitiveSceneInfos.Sort(FPrimitiveArraySortKey());
    
    while (AddedLocalPrimitiveSceneInfos.Num())
	{
		int32 StartIndex = AddedLocalPrimitiveSceneInfos.Num() - 1;
        for (int AddIndex = StartIndex; AddIndex < AddedLocalPrimitiveSceneInfos.Num(); AddIndex++)
		{
				FPrimitiveSceneInfo* PrimitiveSceneInfo = AddedLocalPrimitiveSceneInfos[AddIndex];
				int32 PrimitiveIndex = PrimitiveSceneInfo->PackedIndex;
				FPrimitiveSceneProxy* SceneProxy = PrimitiveSceneInfo->Proxy;

				if (ShouldPrimitiveOutputVelocity(SceneProxy, GetShaderPlatform()))
				{
					PrimitiveSceneInfo->bRegisteredWithVelocityData = true;
					// We must register the initial LocalToWorld with the velocity state. 
					// In the case of a moving component with MarkRenderStateDirty() called every frame, UpdateTransform will never happen.
					VelocityData.UpdateTransform(PrimitiveSceneInfo, PrimitiveTransforms[PrimitiveIndex], PrimitiveTransforms[PrimitiveIndex]);
				}

				DistanceFieldSceneData.AddPrimitive(PrimitiveSceneInfo);
				LumenAddPrimitive(PrimitiveSceneInfo);
         }

    }
}
cpp 复制代码
// Add function is a member of FScene, because it needs to add the primitive to all FLumenSceneData at once
void FScene::LumenAddPrimitive(FPrimitiveSceneInfo* InPrimitive)
{
	LLM_SCOPE_BYTAG(Lumen);

	if (DefaultLumenSceneData->bTrackAllPrimitives)
	{
		const FPrimitiveSceneProxy* Proxy = InPrimitive->Proxy;
		bool bTrackPrimitveForLumenScene = TrackPrimitiveForLumenScene(Proxy);

		for (FLumenSceneDataIterator LumenSceneData = GetLumenSceneDataIterator(); LumenSceneData; ++LumenSceneData)
		{
			// We copy this flag over when creating per-view lumen scene data, validate that it's still the same
			check(LumenSceneData->bTrackAllPrimitives == DefaultLumenSceneData->bTrackAllPrimitives);

			LumenSceneData->PrimitivesToUpdateMeshCards.Add(InPrimitive->GetIndex());

			if (bTrackPrimitveForLumenScene)
			{
				ensure(!LumenSceneData->PendingAddOperations.Contains(InPrimitive));
				ensure(!LumenSceneData->PendingUpdateOperations.Contains(InPrimitive));
				LumenSceneData->PendingAddOperations.Add(InPrimitive);
			}
		}
	}
}
相关推荐
普世的微光21 天前
UE-- 引入IOS framework 库 真机运行闪退
c++·ios·ue
挨代码1 个月前
UE基础 —— Actors Reference
ue
挨代码2 个月前
UE基础 —— 编辑器界面
ue
海码0072 个月前
【UE 网络】Gameplay框架在DS架构中的扮演的角色
网络·架构·php·ue
闲杂人等121382 个月前
UE/Unity加载倾斜摄影太卡问题-使用局部网格简化重构导出为FBX/OBJ
unity·重构·游戏引擎·ue·倾斜摄影·灵易智模
何去何从28573 个月前
虚幻引擎中增强输入映射中鼠标输入无反应,怎么办?
虚幻引擎·ue
Carpe_yj_Diem5 个月前
UE5 FARFilter筛选器使用方法
ue
JK Chen5 个月前
Unreal 编辑器工具 批量重命名资源
ue
Zhichao_976 个月前
【UE 材质】序列图动画、波动效果、颜色切换效果
材质·ue
海码0076 个月前
【UE 委托】如何利用函数指针理解委托的基本原理
ue·函数指针