版本:Unity 6 (6000.0)
语言英语
  • C#

Mesh.GetUVDistributionMetric

建议修改

成功!

感谢您帮助我们提高 Unity 文档的质量。虽然我们无法接受所有提交内容,但我们确实会阅读用户提出的每个建议更改,并在适用情况下进行更新。

关闭

提交失败

由于某些原因,您的建议更改无法提交。请<a>稍后再试</a>。感谢您抽出时间帮助我们提高 Unity 文档的质量。

关闭

取消

切换到手册

声明

public float GetUVDistributionMetric(int uvSetIndex);

参数

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, float aspectRatio) { m_CameraPosition = cameraPosition; m_CameraEyeToScreenDistanceSquared = Mathf.Pow(screenHalfHeight / Mathf.Tan(cameraHalfAngle), 2.0f);

// Switch to using the horizontal dimension if larger if (aspectRatio > 1.0f) // Width is larger than height m_CameraEyeToScreenDistanceSquared *= aspectRatio; }

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, camera.aspect); }

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; }

// Pick the larger two scales of the 3 components and multiply together float GetLargestAreaScale(float x, float y, float z) { if (x > y) { if (y > z) return x * y; else return x * z; } else // x <= y { if (x < z) return y * z; else return x * y; } }

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

// Transform scale: // Use two scale values as we need an 'area' scale. // Use the two largest component to usa a more conservative selection and pick the higher resolution mip m_MeshUVDistributionMetric *= GetLargestAreaScale(transform.lossyScale.x, transform.lossyScale.y, transform.lossyScale.z);

// To determine uv scale for a material use Material.GetTextureScale // If there is a uv scale to apply then divide the m_MeshUVDistributionMetric by (uvScale.x * uvScale.y)

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); } }