UE3的LOD计算方式

骨骼动画Mesh:

1、计算包围盒中心点在投影空间位置

const FVector4 ScreenPosition( View->WorldToScreen(Bounds.Origin) );

2、计算包围在屏幕的宽度。

注意ScreenPosition.W投影空间的W其实就是View空间的Z,Bounds.SphereRadius / Max(ScreenPosition.W,1.0f);得出投影空间的SphereRadius。

const FLOAT ScreenRadius = Max((FLOAT)View->SizeX / 2.0f * View->ProjectionMatrix.M[0][0],
(FLOAT)View->SizeY / 2.0f * View->ProjectionMatrix.M[1][1]) * Bounds.SphereRadius / Max(ScreenPosition.W,1.0f);
const FLOAT LODFactor = ScreenRadius / 320.0f;

计算屏幕空间的像素距离作为LODFactor的判断。


StaticMesh,普通Mesh:

1、求当前摄像机的位置
const FVector4 ViewOriginForDistance = View->ViewOrigin.W > 0.0f ? View->ViewOrigin : View->OverrideLODViewOrigin;

2、当前Mesh包围盒与摄像机的距离
const FLOAT DistanceSquared = PrimitiveSceneInfo->Bounds.GetBox().ComputeSquaredDistanceToPoint(ViewOriginForDistance);

for(INT LODIndex = LODs.Num() - 1; LODIndex >= 0; LODIndex--)
{
// Use the same distances as FStaticMeshSceneProxy::DrawStaticElements 
// To ensure that LODs change the same way when drawn in a static draw list or when rendered through DrawDynamicElements
const FLOAT MinDist = GetMinLODDist(LODIndex);
const FLOAT MaxDist = GetMaxLODDist(LODIndex);
//求出距离的Squared,会根据View->LODDistanceFactor进行Scale,LODDistanceFactor会根据FOV的大小而变化
const FLOAT LODFactorDistanceSquared = DistanceSquared * Square(View->LODDistanceFactor);
if (LODFactorDistanceSquared >= Square(MinDist) && LODFactorDistanceSquared < Square(MaxDist))
{
return LODIndex;
}
}

根据摄像机距离来求。


FLOAT FStaticMeshSceneProxy::GetMinLODDist(INT CurrentLevel) const 
{
//Scale LODMaxRange by LODDistanceRatio and then split this range up by the number of LOD's
FLOAT MinDist = CurrentLevel * LODMaxRange * StaticMesh->LODDistanceRatio / StaticMesh->LODModels.Num();
return MinDist;
}


/**
 * Returns the maximum distance that the given LOD should be displayed at
 * If the given LOD is the lowest detail LOD, then its maxDist will be FLT_MAX
 *
 * @param CurrentLevel - the LOD to find the max distance for
 */
FLOAT FStaticMeshSceneProxy::GetMaxLODDist(INT CurrentLevel) const 
{
//This level's MaxDist is the next level's MinDist
FLOAT MaxDist = GetMinLODDist(CurrentLevel + 1);


//If the lowest detail LOD was passed in, set MaxDist to FLT_MAX so that it doesn't get culled
if (CurrentLevel + 1 == StaticMesh->LODModels.Num()) 
{
MaxDist = FLT_MAX;

return MaxDist;
}

你可能感兴趣的:(list,UP,float,distance)