对于开启skincache的骨架网格体,几乎所有顶点数据计算都是在
计算着色器中完成的。
游戏线程:
FRendererModule::
BeginRenderingViewFamily
World->
SendAllEndOfFrameUpdates();
UActorComponent::
DoDeferredRenderUpdates_Concurrent
USkinnedMeshComponent::
SendRenderDynamicData_Concurrent
FDynamicSkelMeshObjectDataGPUSkin::
InitDynamicSkelMeshObjectDataGPUSkin
UpdateRefToLocalMatrices 计算并存储当前每个骨骼相对该骨骼参考姿势的相对matrix
FSkeletalMeshObjectGPUSkin::
Update
渲染线程
FSkeletalMeshObjectGPUSkin::
UpdateDynamicData_RenderThread
FSkeletalMeshObjectGPUSkin::
ProcessUpdatedDynamicData
if(
bMorph)
SkeletalMeshObjectGPUSkin::
FSkeletalMeshObjectLOD::
UpdateMorphVertexBufferGPU
FGPUMorphUpdateCS,
每个section的每个顶点变相目标都会执行一遍以下步骤:
IMPLEMENT_SHADER_TYPE(,
FGPUMorphUpdateCS,
TEXT(
"/Engine/Private/MorphTargets.usf"),
TEXT(
"GPUMorphUpdateCS"),
SF_Compute);
:
根据
当前顶点索引,获取
MorphDeltas数组中的当前顶点的顶点变形的总偏移量
MorphDelta
乘以顶点变形的幅度weight,获得实际的
偏移量加入
对应顶点在
MorphVertexBuffer的数组元素中
。
FGPUMorphNormalizeCS
if (
bDataPresent) 每个section执行以下操作
FGPUBaseSkinVertexFactory::
FShaderDataType::
UpdateBoneData 更新
每个骨骼相对该骨骼参考姿势的相对matrix
if (
bUseSkinCache)
如果section启用了skincache,则顶点的计算在这里进行,否则在渲染骨架网格体的顶点着色器GpuSkinVertexFactory.ush的GetVertexFactoryIntermediates中进行
FGPUSkinCache::
ProcessEntry
FGPUSkinCache::
DoDispatch(
FRHICommandListImmediate&
RHICmdList,
FGPUSkinCacheEntry*
SkinCacheEntry,
int32
Section,
int32
RevisionNumber)
FGPUSkinCache::
DispatchUpdateSkinning
TGPUSkinCacheCS 根据受影响的多个骨骼的相对位置矩阵,计算顶点的组合变换矩阵(直接按加法计算,因为矩阵a与向c量相乘
+
矩阵b与向量c相乘=矩阵a+b与向量c相乘
), .根据顶点的顶点变形数据或衣服的数据,计算新的未经过矩阵运算的顶点数据(位置以及切线法线数据),然后计算变换后的顶点位置和顶点的切线数据
IMPLEMENT_SHADER_TYPE(
template<>,
TGPUSkinCacheCS<0>,
TEXT(
"/Engine/Private/GpuSkinCacheComputeShader.usf"),
TEXT(
"SkinCacheUpdateBatchCS"),
SF_Compute);
// 16bit_0, BoneInfluenceType_0, SkinType_0
如果section需要重新计算切线的功能
FGPUSkinCache::
DispatchUpdateSkinTangents
FRecomputeTangentsPerTrianglePassCS 根据每个三角面的顶点,重新计算每个顶点的面法线和切线并加入到buffer中指定索引的位置。并加入到顶点的其他重复顶点(重复顶点是指空间中所在位置相同但被作为非相同相同索引的顶点)在buffer中所在的索引的位置。
IMPLEMENT_SHADER_TYPE(
template<>,
FRecomputeTangentsPerTrianglePassCS<0>,
TEXT(
"/Engine/Private/RecomputeTangentsPerTrianglePass.usf"),
TEXT(
"MainCS"),
SF_Compute);
FRecomputeTangentsPerVertexPassCS 对上面计算的每个顶点的切线和法线信息进行归一化处理。(因为每个顶点上的法线和切线信息可能存了好几个面的面法线信息),同时根据
r.SkinCache.BlendUsingVertexColorForRecomputeTangents 所设置的参数计算切线(用顶点颜色的r,
g,b通道进行非重新计算切线的切线和重新计算切线的选择和计算)
IMPLEMENT_SHADER_TYPE(
template<>,
FRecomputeTangentsPerVertexPassCS<0>,
TEXT(
"/Engine/Private/RecomputeTangentsPerVertexPass.usf"),
TEXT(
"MainCS"),
SF_Compute);