renderthread是什么_Game Thread与Render Thread数据传输

按照惯例,先自淫一下,宣传下自己的书。

本节Unreal渲染流程架构的最后一节,这节结束后,就继续Skeletal Mesh Dynamic Instance讲解,这样你就会很好理解如何,实现Skeletal Mesh Dynamic Instance。

Light、Primitive、Material等数据在Game Thread发生了变化,Render Thread对应的数据也要发生变化,Unreal使用了3种方式让Game Thread通知Render Thread。

1. bRenderTransformDirty——Transform更新,例如:动态物体位置变化

2. bRenderDynamicDataDirty——动态数据更新,例如:骨骼数据

3. bRenderStateDirty——RenderState更新,除以上情况外的变化。

基本流程需要主动调用MarkRenderStateDirty、MarkRenderTransformDirty、MarkRenderDynamicDataDirty三个函数(还有其他函数,读者自己可以查询,需要添加Dirty变量和重载DoDeferredRenderUpdates_Concurrent函数)。然后通知World是帧末多线程执行、帧末GameThread执行、还是马上执行。无论哪种都会触发DoDeferredRenderUpdates_Concurrent函数。

void UActorComponent::DoDeferredRenderUpdates_Concurrent()

{

if(bRenderStateDirty)

{

RecreateRenderState_Concurrent();

}

else

{

if(bRenderTransformDirty)

{

SendRenderTransform_Concurrent();

}

if(bRenderDynamicDataDirty)

{

SendRenderDynamicData_Concurrent();

}

}

}

其中RecreateRenderState_Concurrent包括销毁DestroyRenderState_Concurrent和重建CreateRenderState_Concurrent两个函数。

CreateRenderState_Concurrent、DestroyRenderState_Concurrent、SendRenderTransform_Concurrent、SendRenderDynamicData_Concurrent都为虚函数,子类可以重载。

下面是UPrimitiveComponent和USkinnedMeshComponent的重载函数。

void UPrimitiveComponent::CreateRenderState_Concurrent()

{

Super::CreateRenderState_Concurrent();

// If the primitive isn't hidden and the detail mode setting allows it, add it to the scene. if (ShouldComponentAddToScene())

{

GetWorld()->Scene->AddPrimitive(this);

}

}

void UPrimitiveComponent::DestroyRenderState_Concurrent()

{

// Remove the primitive from the scene. UWorld* World = GetWorld();

if(World && World->Scene)

{

World->Scene->RemovePrimitive(this);

}

Super::DestroyRenderState_Concurrent();

}

void UPrimitiveComponent::SendRenderTransform_Concurrent()

{

// If the primitive isn't hidden update its transform. const bool bDetailModeAllowsRendering = DetailMode <= GetCachedScalabilityCVars().DetailMode;

if( bDetailModeAllowsRendering && (ShouldRender() || bCastHiddenShadow))

{

// Update the scene info's transform for this primitive. GetWorld()->Scene->UpdatePrimitiveTransform(this);

}

Super::SendRenderTransform_Concurrent();

}

void USkinnedMeshComponent::SendRenderDynamicData_Concurrent()

{

Super::SendRenderDynamicData_Concurrent();

}

根据目前UE4代码,UPrimitiveComponent以及子类不频繁调用MarkRenderStateDirty,这会导致UPrimitiveComponent从Scene移除并加入,是一个很昂贵的操作。同理ULightComponent也是。

如果真的有频繁的操作,希望用MarkRenderTransformDirty或者MarkRenderDynamicDataDirty方式,不需要移除再加入Component两个操作就可以更改Component属性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值