正常uGUI使用正交相机的话,旋转是没有透视效果的,但如果能实现较简单的透视,

对一些效果表现来说还是不错的;见下图(左为透视效果):

正常思路感觉各种麻烦。

因为uGUI使用unity的x和y方向表示宽高,z方向自然就是纵深,我们可以直接拿z值作为系数进行缩放处理,

达到伪透视的效果(美中不足,细看会有弧度感)。

但是,直接对z轴进行缩放会出现扭曲问题:

这种情况可以通过顶点细分来解决,一般细分一次即可。顶点越多,UV插值产生的扭曲影响就越小:

再扩展一下可支持Text组件:

最后上代码:

namespace Hont
{
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; [ExecuteInEditMode]
public class UiPerspectiveFx : BaseMeshEffect
{
[Header("Only Image")]
public int subdivision = 2;//有的材质细分2次,有的需3-4次。
public float perspectiveScale = 1.0f;
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)
{
RectTransform rectTransform = transform as RectTransform; if (graphic is Image)
{
vh.Clear(); Vector2 begin = -rectTransform.sizeDelta * 0.5f;
Vector2 cell = rectTransform.sizeDelta / subdivision;
float uvCell = 1f / subdivision;
for (int x = 0; x < subdivision; x++)//TODO:可进一步做缓存优化
{
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=graphic.color, uv0=uv0},
new UIVertex(){position=p1, color=graphic.color, uv0=uv1},
new UIVertex(){position=p2, color=graphic.color, uv0=uv2},
new UIVertex(){position=p3, color=graphic.color, uv0=uv3}
});
}
}
}
else if (graphic is Text)
{
for (int i = 0, iMax = vh.currentVertCount; i < iMax; i++)
{
UIVertex vertex = default;
vh.PopulateUIVertex(ref vertex, i);
CalcPerspectiveScale(ref vertex.position);
vh.SetUIVertex(vertex, i);
}
}
}
}
}

挂载到Image/Text组件下即可:

在uGUI正交相机中实现旋转透视效果的更多相关文章

  1. 子坐标系C在父坐标系W中的旋转问题

    关键词:空间旋转.旋转轴.刚体旋转 用途:相机位姿估计.无人机位姿估计 文章类型:概念.公式总结(本文不带推倒过程,若想了解公式是如何推出来的请自习搜索文献),C++函数展示 @Author:VSha ...

  2. ios中从相册:相机中获取图片信息

    ios中从相册/相机中获取图片信息 从相册中获取图片的信息 UIImagePickerController *imgPickView = [[UIImagePickerController alloc ...

  3. Unity正交相机智能包围物体(组)方案

    Unity正交相机智能包围物体(组)方案 目录 Unity正交相机智能包围物体(组)方案 一.技术背景 二.相关概念 2.1 正交摄像机 2.2 正交相机的Size 2.3 相机的Aspect 2.4 ...

  4. Unity 3D 正交相机(Orthographic)

    1. Camera.aspect 表示摄像机显示区域的纵横比.宽高比,摄像机初始化的时候会默认设置成当前屏幕的宽高比,可以更改,也可以通过 Camera.ResetAspect 来重置. 2. Cam ...

  5. 矩阵中的旋转(Rotation)

    参考的是<游戏和图形学的3D数学入门教程>,算是读书笔记吧. 目录 [隐藏] 1.2D中的旋转 2.3D中的旋转 2.1绕x轴旋转: 2.2绕Y轴旋转 2.3绕Z轴旋转 1.2D中的旋转 ...

  6. OpenGL中的旋转是可以叠加的?

    OpenGL中的旋转是可以叠加的? 1. opengl中的旋转 如:glrogtate(45.0f, 0, 0, 1),是将当前坐标系顺时针旋转45度,然后绘制, 程序如下: ; float line ...

  7. Android中图片旋转

    Activity_main.xml文件配置 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/androi ...

  8. WPF中3D旋转的实现

    原文:WPF中3D旋转的实现 关于3D旋转的原理,请看Daniel Lehenbauer的文章 <Rotating the Camera with the Mouse> http://vi ...

  9. vue实现点击图标,图标在2s中完成旋转

    <!-- 点击 vue实现点击图标,图标在2s中完成旋转 1==>如何让它在2s内完成旋转 使用动画 transform: rotate(-180deg); 动画的运动状态 transit ...

  10. 【VS开发】【图像处理】相机中白平衡的算法模拟实现

    相机主要技术点为3A算法. 而3A算法主要指的是自动对焦(AF).自动曝光(AE)及自动白平衡(AWB).自动白平衡:根据光源条件调整图片颜色的保真程度. 网上时常有类似招聘如下的招聘信息: ---- ...

随机推荐

  1. #线段树#洛谷 4588 [TJOI2018]数学计算

    题目传送门 分析 由于曾经做过原题 所以就直接说了,因为每个数最多被除掉一次 所以可以用线段树维护区间乘,也就很简单了,删除就单点修改就行了 代码 #include <cstdio> #i ...

  2. #状压dp#JZOJ 3853 帮助Bsny

    题目 一共有\(n\)本书,混乱值是连续相同高度书本的段数. 可以取出\(k\)本书随意放回,问最小混乱值,高度\([25\sim 32]\) 分析 设\(f[i][j][k][mask]\)表示前\ ...

  3. SQL 数据操作技巧:SELECT INTO、INSERT INTO SELECT 和 CASE 语句详解

    SQL SELECT INTO 语句 SELECT INTO 语句将数据从一个表复制到一个新表中. SELECT INTO 语法 将所有列复制到新表中: SELECT * INTO newtable ...

  4. 【FAQ】运动健康服务端侧数据常见问题及解答

    目录 Q1:Health Kit开放的API是否支持同时获取多个华为手环的健康数据? Q2:当前通过Health Kit获取运动健康数据的功能是否免费? Q3:在联盟平台申请Health Kit权限, ...

  5. openGauss支持国密SM3和SM4算法

    国密算法介绍 国密即国家密码局认定的国产密码算法,主要有 SM1,SM2,SM3,SM4.密钥长度和分组长度均为 128 位.针对银行客户对数据库安全能力的诉求以及提高产品安全竞争力的要求,进行数据库 ...

  6. 《深入理解Java虚拟机》读书笔记:HotSpot的算法实现

    HotSpot的算法实现 HotSpot的算法实现概要 1.枚举根节点 由于目前的主流Java虚拟机使用的都是准确式GC(这个概念在第1章介绍Exact VM对Classic VM的改进时讲过),所以 ...

  7. Mongoose介绍

    官网 Mongoose.js中文网 (mongoosejs.net) 基本使用 安装 最新的是mongoose8.0.0版本,基于Promise,以前的版本是基于回调函数. npm npm i mon ...

  8. Native Drawing开发指导,实现HarmonyOS基本图形和字体的绘制

      场景介绍 Native Drawing模块提供了一系列的接口用于基本图形和字体的绘制.常见的应用场景举例: ● 2D图形绘制. ● 文本绘制. 接口说明 接口名 描述 OH_Drawing_Bit ...

  9. SSH的密码qsnctfwp

    开启 kali,在终端输入ssh root@challenge.qsnctf.com -p [port]可以访问远程 SSH 系统 根据提供的 passlist.txt 文件内容进行密码爆破 编写 S ...

  10. 实战指南:使用 xUnit.DependencyInjection 在单元测试中实现依赖注入【完整教程】

    引言 上一篇我们创建了一个Sample.Api项目和Sample.Repository,并且带大家熟悉了一下Moq的概念,这一章我们来实战一下在xUnit项目使用依赖注入. Xunit.Depende ...