在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).自动白平衡:根据光源条件调整图片颜色的保真程度. 网上时常有类似招聘如下的招聘信息: ---- ...
随机推荐
- Python - 字典2
Python - 访问字典项 您可以通过在方括号内引用其键名来访问字典的项: 示例,获取 "model" 键的值: thisdict = { "brand": ...
- 【FAQ】HarmonyOS SDK 闭源开放能力 —Push Kit(2)
1.问题描述: 开发服务端推送,客户端能收到离线推送,但是推送收到的通知只能从手机顶部下拉看到,无法收到一个顶部的弹框.请问是什么原因? 解决方案: 可能原因一: 消息提醒的方式与消息类别有关,比如: ...
- openGauss/MogDB 学习笔记之 -- PITR恢复
openGauss/MogDB 学习笔记之 -- PITR 恢复 概念描述 背景信息 当数据库崩溃或希望回退到数据库之前的某一状态时,MogDB 的即时恢复功能(Point-In-Time Recov ...
- Triton部署mmdeploy导出的TensorRT模型失败篇
记录一下历程,最终没有部署成功,应该是Ubantu系统版本的问题.现在没有时间搞了,先记录一下,后续用到再填坑. Triton demo git clone -b r22.06 https://git ...
- 使用纯c#在本地部署多模态模型,让本地模型也可以理解图像
之前曾经分享过纯c#运行开源本地大模型Mixtral-8x7B 当时使用的是llamasharp这个库和Mixtral的模型在本地部署和推理,前段时间我看到llamasharp更新到了0.11.1版本 ...
- 剑指 Offer II 018(Java). 有效的回文(简单)
题目: 给定一个字符串 s ,验证 s 是否是 回文串 ,只考虑字母和数字字符,可以忽略字母的大小写. 本题中,将空字符串定义为有效的 回文串 . 示例 1: 输入: s = "A man, ...
- 面试题45(Java)-把数组排成最小的数(中等)
题目: 输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个. 示例 1: 输入: [10,2] 输出: "102" 示例 2: 输入: [ ...
- 力扣27(java&python)-移除元素(简单)
题目: 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度. 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入 ...
- 力扣1773(java&python)-统计匹配检索规则的物品数量(简单)
题目: 给你一个数组 items ,其中 items[i] = [typei, colori, namei] ,描述第 i 件物品的类型.颜色以及名称. 另给你一条由两个字符串 ruleKey 和 r ...
- 力扣304(java)-二维区域和检索-矩阵不可变(中等)
题目: 给定一个二维矩阵 matrix,以下类型的多个请求: 计算其子矩形范围内元素的总和,该子矩阵的 左上角 为 (row1, col1) ,右下角 为 (row2, col2) .实现 NumMa ...