在uGUI正交相机中实现旋转透视效果
正常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正交相机中实现旋转透视效果的更多相关文章
- 子坐标系C在父坐标系W中的旋转问题
关键词:空间旋转.旋转轴.刚体旋转 用途:相机位姿估计.无人机位姿估计 文章类型:概念.公式总结(本文不带推倒过程,若想了解公式是如何推出来的请自习搜索文献),C++函数展示 @Author:VSha ...
- ios中从相册:相机中获取图片信息
ios中从相册/相机中获取图片信息 从相册中获取图片的信息 UIImagePickerController *imgPickView = [[UIImagePickerController alloc ...
- Unity正交相机智能包围物体(组)方案
Unity正交相机智能包围物体(组)方案 目录 Unity正交相机智能包围物体(组)方案 一.技术背景 二.相关概念 2.1 正交摄像机 2.2 正交相机的Size 2.3 相机的Aspect 2.4 ...
- Unity 3D 正交相机(Orthographic)
1. Camera.aspect 表示摄像机显示区域的纵横比.宽高比,摄像机初始化的时候会默认设置成当前屏幕的宽高比,可以更改,也可以通过 Camera.ResetAspect 来重置. 2. Cam ...
- 矩阵中的旋转(Rotation)
参考的是<游戏和图形学的3D数学入门教程>,算是读书笔记吧. 目录 [隐藏] 1.2D中的旋转 2.3D中的旋转 2.1绕x轴旋转: 2.2绕Y轴旋转 2.3绕Z轴旋转 1.2D中的旋转 ...
- OpenGL中的旋转是可以叠加的?
OpenGL中的旋转是可以叠加的? 1. opengl中的旋转 如:glrogtate(45.0f, 0, 0, 1),是将当前坐标系顺时针旋转45度,然后绘制, 程序如下: ; float line ...
- Android中图片旋转
Activity_main.xml文件配置 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/androi ...
- WPF中3D旋转的实现
原文:WPF中3D旋转的实现 关于3D旋转的原理,请看Daniel Lehenbauer的文章 <Rotating the Camera with the Mouse> http://vi ...
- vue实现点击图标,图标在2s中完成旋转
<!-- 点击 vue实现点击图标,图标在2s中完成旋转 1==>如何让它在2s内完成旋转 使用动画 transform: rotate(-180deg); 动画的运动状态 transit ...
- 【VS开发】【图像处理】相机中白平衡的算法模拟实现
相机主要技术点为3A算法. 而3A算法主要指的是自动对焦(AF).自动曝光(AE)及自动白平衡(AWB).自动白平衡:根据光源条件调整图片颜色的保真程度. 网上时常有类似招聘如下的招聘信息: ---- ...
随机推荐
- [AHOI2014/JSOI2014/一本通1722]骑士游戏 题解 (spfa做dp)
题目描述 在游戏中,JYY一共有两种攻击方式,一种是普通攻击,一种是法术攻击.两种攻击方式都会消耗JYY一些体力.采用普通攻击进攻怪兽并不能把怪兽彻底杀死,怪兽的尸体可以变出其他一些新的怪兽,注意一个 ...
- 一文告诉你如何使用java调用http接口
程序如下: 添加apache相关maven依赖: 1 <dependency> 2 <groupId>org.apache.commons</groupId> 3 ...
- 【Java面试指北】单例模式
单线程下的单例模式: public class Singleton { private static Singleton instance; private Singleton() {} public ...
- CSS 布局专题
0x01 浮动布局 (1)常见网页布局 顶部商标栏(Logo):展示网站的标志.名称以及具有代表性的图片 导航栏(Navigation):展示网站大概的分类 左侧边栏(Left-side Bar):展 ...
- leetcode插件问题
1.使用一段时间后,提交答案一直返回undefind 原因为插件缓存token有效期已过,需要重新登录 2. 重新登录
- 【Oracle】Oracle数据库,第N大数据取值
Oracle数据库,第N大数据取值 没想到力扣还有数据库的练习,正好本菜鸡跑过来练手 要显示第二大的数据可以使用order by进行排序,然后用limit对显示的数据进行限制,limit1,1,以此来 ...
- 宏杉科技加入阿里云PolarDB开源数据库社区
简介: 宏杉科技签署阿里巴巴开源CLA(Contribution License Agreement, 贡献许可协议), 正式与阿里云PolarDB 开源数据库社区牵手. 宏杉科技签署阿里巴巴开源CL ...
- IPv6时代,中小企业该如何布局?
简介:IPv6要为全世界的每一粒沙子都分配一个IP,你的企业跟上了吗? 11月中旬,中央网信办等部门联合印发了<关于开展IPv6技术创新和融合应用试点工作的通知>,联合组织开展IPv6技 ...
- [Contract] 测试 Solidity 合约代码的两种方式 与 优缺点
第一种,使用 Truffle 这类继承了测试工具的框架,只要编写 js 脚本就可以测试 web3 与合约的逻辑. 优点是完全可控,粒度够细,便于集成测试:缺点是需要花费一些时间编写测试脚本,不过值得. ...
- WPF 已知问题 开启 IsManipulationEnabled 之后触摸长按 RepeatButton 不会触发连续的 Click 事件
本文记录 WPF 的一个已知问题,在 RepeatButton 上开启 IsManipulationEnabled 漫游支持之后,将会导致触摸长按到 RepeatButton 之上时,不会收到源源不断 ...