uvSetIndex | 要返回 UV 分布指标的 UV 集索引。0 表示第一个。 |
float 三角形面积/UV 面积的平均值。
UV 分布指标可用于根据摄像机的位置计算所需的 Mipmap 级别。
示例代码显示了如何将此值与某些摄像机属性一起使用来计算所需的 Mipmap 级别。
using UnityEngine;
public class MyMipmapClass : MonoBehaviour { private Vector3 m_CameraPosition; private float m_CameraEyeToScreenDistanceSquared;
private float m_MeshUVDistributionMetric; private float m_TexelCount; private Texture2D m_Texture;
public void SetView(Vector3 cameraPosition, float cameraHalfAngle, float screenHalfHeight) { m_CameraPosition = cameraPosition; m_CameraEyeToScreenDistanceSquared = Mathf.Pow(screenHalfHeight / Mathf.Tan(cameraHalfAngle), 2.0f); }
public void SetView(Camera camera) { float cameraHA = Mathf.Deg2Rad * camera.fieldOfView * 0.5f; float screenHH = (float)camera.pixelHeight * 0.5f; SetView(camera.transform.position, cameraHA, screenHH); }
private int CalculateMipmapLevel(Bounds bounds, float uvDistributionMetric, float texelCount) { // based on http://web.cse.ohio-state.edu/~crawfis.3/cse781/Readings/MipMapLevels-Blog.html // screenArea = worldArea * (ScreenPixels/(D*tan(FOV)))^2 // mip = 0.5 * log2 (uvArea / screenArea) float dSq = bounds.SqrDistance(m_CameraPosition); if (dSq < 1e-06) return 0;
// uvDistributionMetric is the average of triangle area / uv area (a ratio from world space triangle area to normalised uv area) // - triangle area is in world space // - uv area is in normalised units (0->1 rather than 0->texture size)
// m_CameraEyeToScreenDistanceSquared / dSq is the ratio of screen area to world space area
float v = (texelCount * dSq) / (uvDistributionMetric * m_CameraEyeToScreenDistanceSquared); float desiredMipLevel = 0.5f * Mathf.Log(v, 2);
return (int)desiredMipLevel; }
public void Start() { Mesh mesh = GetComponent<MeshFilter>().sharedMesh; m_MeshUVDistributionMetric = mesh.GetUVDistributionMetric(0);
// If the mesh has a transform scale or uvscale it would need to be applied here Vector3 scale = transform.lossyScale; float vertexScale = scale.x * scale.y * scale.z; m_MeshUVDistributionMetric *= vertexScale;
m_TexelCount = m_Texture.width * m_Texture.height; }
public void Update() { SetView(Camera.main);
m_Texture.requestedMipmapLevel = CalculateMipmapLevel(GetComponent<Renderer>().bounds, m_MeshUVDistributionMetric, m_TexelCount); } }