您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

116 行
3.6 KiB

using Unity.Mathematics;
using UnityEngine;
public static class LODGroupExtensions
{
public struct LODParams
{
public float lodBias;
public float3 cameraPos;
public float screenRelativeMetric;
public bool isOrtho;
public float orthosize;
}
public static LODParams CalculateLODParams(Camera camera)
{
LODParams lodParams;
lodParams.cameraPos = camera.transform.position;
lodParams.isOrtho = camera.orthographic;
lodParams.orthosize= camera.orthographicSize;
lodParams.lodBias = QualitySettings.lodBias;
var halfAngle = math.tan(math.radians(camera.fieldOfView * 0.5F));
float screenRelativeMetric;
if (lodParams.isOrtho)
{
screenRelativeMetric = 2.0F * lodParams.orthosize;
}
else
{
// Half angle at 90 degrees is 1.0 (So we skip halfAngle / 1.0 calculation)
screenRelativeMetric = (2.0f * halfAngle) / lodParams.lodBias;
screenRelativeMetric = screenRelativeMetric * screenRelativeMetric;
}
lodParams.screenRelativeMetric = screenRelativeMetric;
return lodParams;
}
public static float GetWorldSpaceSize(LODGroup lodGroup)
{
return GetWorldSpaceScale(lodGroup.transform) * lodGroup.size;
}
static float GetWorldSpaceScale(Transform t)
{
var scale = t.lossyScale;
float largestAxis = Mathf.Abs(scale.x);
largestAxis = Mathf.Max(largestAxis, Mathf.Abs(scale.y));
largestAxis = Mathf.Max(largestAxis, Mathf.Abs(scale.z));
return largestAxis;
}
public static int CalculateCurrentLODIndex(float4 lodDistances, float3 worldReferencePoint, ref LODParams lodParams)
{
var distanceSqr = CalculateDistanceSqr(worldReferencePoint, ref lodParams);
var lodIndex = CalculateCurrentLODIndex(lodDistances, distanceSqr);
return lodIndex;
}
public static int CalculateCurrentLODMask(float4 lodDistances, float3 worldReferencePoint, ref LODParams lodParams)
{
var distanceSqr = CalculateDistanceSqr(worldReferencePoint, ref lodParams);
return CalculateCurrentLODMask(lodDistances, distanceSqr);
}
static int CalculateCurrentLODIndex(float4 lodDistances, float measuredDistanceSqr)
{
var lodResult = measuredDistanceSqr < (lodDistances * lodDistances);
if (lodResult.x)
return 0;
else if (lodResult.y)
return 1;
else if (lodResult.z)
return 2;
else if (lodResult.w)
return 3;
else
// Can return 0 or 16. Doesn't matter...
return -1;
}
static int CalculateCurrentLODMask(float4 lodDistances, float measuredDistanceSqr)
{
var lodResult = measuredDistanceSqr < (lodDistances * lodDistances);
if (lodResult.x)
return 1;
else if (lodResult.y)
return 2;
else if (lodResult.z)
return 4;
else if (lodResult.w)
return 8;
else
// Can return 0 or 16. Doesn't matter...
return 16;
}
static float CalculateDistanceSqr(float3 worldReferencePoint, ref LODParams lodParams)
{
if (lodParams.isOrtho)
{
//return worldSpaceSize * lodParams.screenRelativeMetric;
//@TODO:
throw new System.NotImplementedException();
}
else
{
return math.lengthSquared(lodParams.cameraPos - worldReferencePoint) * lodParams.screenRelativeMetric;
}
}
}