正常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. windows下安装SASS

    window下安装ruby与sass(附ruby) webstorm设置sass自动编译,及参数配置 安装sass以及如何在sublime里使用 sublime text 3 配置sass环境 sub ...

  2. OpenHarmony轻量设备Hi3861芯片开发板启动流程分析

    引言 OpenHarmony作为一款万物互联的操作系统,覆盖了从嵌入式实时物联网操作系统到移动操作系统的全覆盖,其中内核包括LiteOS-M,LiteOS-A和Linux.LiteOS-M内核是面向I ...

  3. Numpy数组变形和轴变换

    数组变形(reshape)或轴转换(Transposing Arrays and Swapping Axes)后返回的是非副本视图,对于非副本视图的修改会使原来的数组也同时改变. In [1]: im ...

  4. 2、androidStudio调用Unity方法

    1.导入Unity的Classes.jar文件 (1).首先找到这个包在哪 Unity版本为5.0之前时,classes.jar的路径: unity的安装路径\Editor\Data\Playback ...

  5. Linux下安装配置OpenResty服务器

    OpenResty是一款基于Nginx和Lua的高性能Web平台,在nginx基础之上集成了大量的lua库,第三方模块等,以便搭建各种处理高并发.可扩展的Web应用.服务或网关,并且OpenResty ...

  6. PyQt 快速使用

    1.安装 PyQt:使用 pip 命令在终端或命令提示符中运行以下命令: pip install pyqt5 2.创建 PyQt 应用程序:导入 PyQt5 模块并创建一个 QApplication ...

  7. Linux下的常见基本指令

    pwd //显示当前用户所在的路径 ls //显示当前路径下的文件名或者目录名称 ls-l //显示当前路径下的文件或者目录的更详细的属性信息 cd 一个目录路径 //进入一个目录,进去后,可以用pw ...

  8. RocketMQ 之 IoT 消息解析:物联网需要什么样的消息技术?

    前言: 从初代开源消息队列崛起,到 PC 互联网.移动互联网爆发式发展,再到如今 IoT.云计算.云原生引领了新的技术趋势,消息中间件的发展已经走过了 30 多个年头. 目前,消息中间件在国内许多行业 ...

  9. Go原生插件使用问题全解析

    简介: 本人在设计和落地基于Go原生插件机制的扩展开发产品时踩到了很多坑,由于这方面相关资料很少,因而借此机会做一个非常粗浅的总结,希望能对大家有所帮助.本文只说问题和解决方案,不读代码. 作者 | ...

  10. 让微服务开源更普惠,阿里云微服务引擎MSE全球开服

    ​简介:MSE 于2020年10月在国内开启商业化服务,目前已吸引近万客户使用,用于在云上更低成本构建.更稳定运行微服务架构.此次,MSE 向阿里云国际站开放服务,旨在帮助更多客户享受到更加普惠的微服 ...