网格曲面上的LineRenderer

问题描述 投票:0回答:1

目标:渲染基于网格的图元(即球体,立方体等)表面上两点之间的距离线。

Lines drawn on surface of sphere当前解决方案:以某种方式迭代地遍历两个端点之间的距离线和“反向”光线投影。由于距离线直接通过网格连接两个顶点,因此需要网格表面上的相应点。

Ray ray = new Ray();
RaycastHit raycastHit;
ray.origin = posOnDistanceLine;
ray.direction = raycastNormal.normalized;
// Reverse ray since we can't raycast from inside the mesh
ray.origin = ray.GetPoint(1);
ray.direction = -ray.direction;

然后使用Unity的LineRenderer绘制线条,每当识别出法线的变化(对于先前的光线投射)时,该radius * directionFromCenter将填充顶点的位置。

问题:

  • 糟糕的表现(每当终点移动时,会投射100条光线)​​。
  • 解决方案并不总是有效,并产生意外的,锯齿状的线条/点。

问题:有没有更好的方法来实现它?

unity3d 3d mesh
1个回答
1
投票

如果要优化解决方案,可能需要为每个基元创建一个脚本并使用特定于原语的数学。

例如,您可以简单地获取网格的半径并将线顶点放在[RequireComponent(typeof(LineRenderer))] public class SurfaceLine : MonoBehaviour, IPointerClickHandler { [SerializeField] private float pointsPerUnit; [SerializeField] private MeshFilter mesh; private Vector3 start; private Vector3 end; private LineRenderer lineRenderer; void Awake() { this.lineRenderer = this.GetComponent<LineRenderer>(); } public void OnPointerClick(PointerEventData eventData) { if(eventData.button == PointerEventData.InputButton.Left) { this.start = this.transform.InverseTransformPoint(eventData.pointerCurrentRaycast.worldPosition); this.Render(); return; } if(eventData.button == PointerEventData.InputButton.Right) { this.end = this.transform.InverseTransformPoint(eventData.pointerCurrentRaycast.worldPosition); this.Render(); } } private void Render() { var distance = Vector3.Distance(this.end, this.start); var direction = (this.end - this.start).normalized; var numPoints = Mathf.FloorToInt(distance * this.pointsPerUnit); numPoints = Mathf.Max(numPoints, 2); this.lineRenderer.positionCount = numPoints; var positions = new Vector3[numPoints]; var stepInDir = direction * (distance / (float)numPoints); for(int i = 0; i < numPoints; i++) { positions[i] = this.start + i * stepInDir; var dirFromCenter = positions[i] - this.mesh.mesh.bounds.center; positions[i] = this.mesh.mesh.bounds.center + dirFromCenter.normalized * (this.mesh.mesh.bounds.size.x / 2.0f); } positions[positions.Length - 1] = this.end; this.lineRenderer.SetPositions(positions); } } 上,而不是投射光线。

这是一个示例脚本:

pointsPerUnit

这似乎也在更新循环中表现良好。缺点当然是解决方案不是通用的。每个基元都需要一个策略。

或者,您至少可以在脚本中利用enter image description here概念来控制线条的分辨率并坚持使用光线投射。我认为你看到的奇怪的人工制品是由于点密度太高造成的。使每单位距离点数保持一致可能也会有更好的表现。

以下是上述脚本的结果:qazxswpoi

© www.soinside.com 2019 - 2024. All rights reserved.