1. 程式人生 > 其它 >在uGUI正交相機中實現旋轉透視效果

在uGUI正交相機中實現旋轉透視效果

正常uGUI使用正交相機的話,旋轉是沒有透視效果的,但如果能比較簡單的實現透視,

對一些效果表現來說還是會有不錯的增益。見下圖(左為透視效果):

正常思路是在Image的shader裡做一次投影矩陣的逆操作然後替換,但想了想比較麻煩。

因為uGUI使用unity的x和y方向表示寬高,z方向自然就是縱深,我們可以直接拿z值進行縮放處理,

達到偽透視的效果。

但是,直接對z軸進行縮放會出現扭曲問題:

這種情況可以通過頂點細分來解決,一般細分一次即可:

最後上程式碼:

namespace Hont
{
    using UnityEngine;
    using UnityEngine.UI;

    [ExecuteInEditMode]
    
public class UiPerspectiveFx : BaseMeshEffect { public int subdivision = 2;//有的材質細分2次即可,有的材質要細分3-4次。 public float perspectiveScale = 0.01f; public bool alwaysRefresh = true; private void Update() { if (alwaysRefresh) graphic.SetVerticesDirty(); }
private void CalcPerspectiveScale(ref Vector3 point) { Vector3 wPos = transform.localToWorldMatrix.MultiplyPoint(point); float fixValue = wPos.z * perspectiveScale; point *= 1f + fixValue; } public override void ModifyMesh(VertexHelper vh) { vh.Clear(); RectTransform rectTransform
= transform as RectTransform; Vector2 begin = -rectTransform.sizeDelta * 0.5f; Vector2 cell = rectTransform.sizeDelta / subdivision; float uvCell = 1f / subdivision; for (int x = 0; x < subdivision; x++) { for (int y = 0; y < subdivision; y++) { Vector3 p0 = new Vector3(begin.x + cell.x * x, begin.y + cell.y * y); Vector3 p1 = new Vector3(begin.x + cell.x * x, begin.y + cell.y * (y + 1)); Vector3 p2 = new Vector3(begin.x + cell.x * (x + 1), begin.y + cell.y * (y + 1)); Vector3 p3 = new Vector3(begin.x + cell.x * (x + 1), begin.y + cell.y * y); Vector3 uv0 = new Vector3(x * uvCell, y * uvCell); Vector3 uv1 = new Vector3(x * uvCell, (y + 1) * uvCell); Vector3 uv2 = new Vector3((x + 1) * uvCell, (y + 1) * uvCell); Vector3 uv3 = new Vector3((x + 1) * uvCell, y * uvCell); CalcPerspectiveScale(ref p0); CalcPerspectiveScale(ref p1); CalcPerspectiveScale(ref p2); CalcPerspectiveScale(ref p3); vh.AddUIVertexQuad(new UIVertex[] { new UIVertex(){position=p0, color=Color.white, uv0=uv0}, new UIVertex(){position=p1, color=Color.white, uv0=uv1}, new UIVertex(){position=p2, color=Color.white, uv0=uv2}, new UIVertex(){position=p3, color=Color.white, uv0=uv3} }); } } } } }

掛載到Image元件下即可: