关于Unity中Camera的Aspect

【Unity】相机 Cameras 主要介绍官方文档中相机模块的内容。 阅读详情

 一直以来对Camera的Aspect和Game窗口的Aspect都是一知半解,某天从一本书中看到了对Camera的API讲解,但是总觉得对Aspect讲解的有问题。于是就认真的思考起了这个问题,还发现设置完Cmera.aspect之后,Scene窗口的视椎体竟然不同步, 也不知其原因。苦恼了很久。经过一番研究并与同事讨论有所收获,便写下此文。一方面为了强化自己的理解,一方面也为了分享给更多人。

  言归正传,大家都知道我们在场景中放置的物体最终渲染到屏幕上都是离不开我们的摄像机。对于透视摄像机(Perspective Projection)来说,在Unity中你会在Scene场景中看到一个白色边框的锥形体,也就是常说的视椎体,在整个渲染流程中这个视椎体是非常重要的,它会参与到透视投影矩阵的计算以及裁剪等处。

  如下图:

  

  视椎体有4个非常重要的参数,一个是Field of View,他是表示的相机在Y方向上上顶面和下底面的夹角的一半;另外一个是相机的Aspect,他代表的是相机视椎的宽高比.在最终的投影矩阵中,还有两个是近平面和远平面。这4个参数是很重要的。

  Unity中的摄像机有个Camera组件,上面是直接可以调节FieldofView,单位是度。但你在上面是找不到Aspect属性的。可能有人会去拖动Scene中相机远平面上的四个白点去改变视椎体的形状,你可以观察一下Camera组件的变化,你发现变化的启示是Fieldofview,无论你去调整宽还是高,Unity都会按照Aspect去相应的调整高或者宽。以保证你的调整不会影响相机的Aspect.

  那么相机的Aspect是怎么设置的呢?你当然可以再代码里用camera.aspect = x这种方式去改变他的值.但是为什么我们每次即使没有去自己写代码为aspect赋值也没感觉有什么不便呢?那是因为Unity会根据Game窗口的设置去自动设置它。(如下图)

  

  可以看到Game窗口也有个Aspect的东西,但是这个Aspect可并不是指相机的Aspect,而是指最终游戏屏幕的宽高比.可以看到大体上这些可选的设置中可以分为三大类,一类是Free Aspect,一类是给出宽高比,另一类是指定分辨率.分别说明一下。

  1.选择Free Aspect时候(默认选项):

    屏幕的宽高比实际上就是你Game窗口的宽高比,你可以手动去拖动来调节他,而这时候Unity也会实时的去修改场景中对应摄像机的Aspect值,使它和Game窗口的Aspect保持一致。你可以一遍改变Game窗口大小,一边看Scene窗口中相机视椎体的变化。

  2.选择X:Y的时候:

    屏幕的宽高比被固定在X:Y这个大小上,而Camera的Aspect也会被设置成X:Y,这时候无论你怎么去改变Game窗口的大小,Camera的Aspect都是不会改变的.Scene中视椎体不会变。

  3.选择指定分辨率(XXXX:YYYY):

    第二钟情况的另一种表现方式类似,Camera的Aspect也会被设置成XXXX:YYYY,同样无论你怎么改变Game窗口大小,Camera的Aspect都是不会变的。Scene中视椎体也不会变。

  很多人也许就奇怪了为什么我无论怎么去改变Game窗口的Aspect选项,我在屏幕上看到的渲染后的画面并没有发生太大变化(比如被拉伸或者缩小).这就是因为Game的Aspect一直和Camera的Aspect保持一直所导致的。这其中涉及到投影变换,透视除法以及最终投影到屏幕空间。说起来很乱,我也怕自己说错。大家如果发现不对的地方欢迎指正,首先为了裁剪的方便,最终需要把物体的坐标从相机空间转换到一个长方体裁剪空间,这一步是通过投影变换来完成的,一般会引擎会在这一步之后进行空间裁剪(也有的会选择在透视除法之后进行裁剪)。然后再经过透视除法,对坐标进行归一,变换到所谓的规范化设备空间,坐标的大小被限定在一个[-1~1]的空间内,可以看成一个长方体被压缩成了一个正方体(也可能不是正方体,DX和OpenGL是不同的)。想要详细了解的同学不妨参看Twinsen前辈blog中相关文章。

  那我们就可以想象,加入我在摄像机的视椎体内放置了了一个宽高比2:1的平面(如下图).在透视变换后的裁剪空间中我们看到的应该依然还是一个(2:1)的平面,但是经过透视除法的规范化之后,大家想象一下视椎体从一个2:1(相机的Aspect)的长方体被压缩成(1:1)正方体的过程.在规范化设备空间中我们的长方形平面应该是被压成了1:1的正方形平面了(实际上不是图形在变,只是顶点的坐标变了而已)。如果直接把这样的结果投影到平面显然不是我们想要的结果。这时候就需要Game窗口的Aspect出马了。

  

  在透视除法把坐标归一化之后,还要在规范化设备空间上进行一次视口变换才把物体真正的映射到屏幕空间,而这一步中实际上主要是解决之前投影变换和透视除法造成的失真(就像我们的长方行被压扁了),具体做法就是把规范化后的x,y坐标按照屏幕的Aspect来进行一次调节,那么如果屏幕的Aspect和摄像机的Aspect保持一致也是2:1,我们被压扁的长方形就又被拉回到了原来的2:1了。最后再经过光栅化处理,也就得到了我们在屏幕中最终看到的结果了。

  所以说之所以屏幕的Aspect和Camera的Aspect始终保持一致,就是为了保证透视投影的正确。那么如果我们强行让两者不一致的话,那么在透视变换和透视除法造成的图像失真就无法得到修正,也就会使我们最终渲染的屏幕的图像是错的。比如说你在Camera上挂个脚本在它的Start方法中写上camera.aspect = 2(也就是2:1).而设置Game视口的Aspect是1:1那么你会看到屏幕上是个正方形.如果设置Game视口的Aspect是1:2,你会发现原来屏幕上的长方形宽高比从原来的2:1变成了1:2了。这正验证了我们刚才所说的。

  我在做这个例子的时候还发现了一个问题,就是说你在代码里去修改相机的Aspect之后,你会发现Scene窗口里的相机视椎体并不会同步到你设置的值.而且如果这时候去修改Game窗口的Aspect,Scene中的视椎体竟然会跟着变化,但是你在Camera刚才的脚本里Update输出camera.aspect发现还是我们刚才设置的值。并且从渲染效果上观察也确实使用的是我们设置的值。所以我觉得一旦你在代码里设置了camera.aspect之后,Scene窗口中的相机视椎体不会同步到新值,而且也失去了参考价值。不知道这是不是Unity的一个Bug.或者也许这个白色椎体并不是代表的视椎体而是有着其它的含义?如果有知道的同学,请一定告诉我。

  在最后还有两个地方需要提及:

  1.当我们把摄像机的内容渲染到的是RenderTexture上而不是屏幕上时,那么相机的Aspect默认会设置成和RenderTexture的分辨率一样.不过最终如果把RenderTexture作为贴图贴到模型上去的时候还是会被由于被UV拉伸和缩小的。

  2.对于Camera组件的的Viewport Rect属性也就是所谓的视口,他会影响实际上最终渲染的屏幕窗口大小,最终渲染窗口的Aspect实际上是由Game窗口的Aspect和Viewport Rect的Aspect相乘得到的结果。这点要注意。 

  以上就是我对Camera.aspect的一些见解。由于本人数学功底不高,很多理论性的东西无法讲的很透彻,甚至可能理解错误。所以希望大家只做参考。如果发现我哪里写的有问题,请务必指出。

   尊重他人智慧成果,欢迎转载,请注明作者esfog,原文址 http://www.cnblogs.com/Esfog/p/4172896.html 

Unity Camera深度指南——全面解析实例对象的属性及其应用 Camera实例对象的属性涵盖了从基本视图和投影设置到高级性能和渲染选项。每个属性都有其特定的用途和配置场景,允许开发者在Unity中精细地控制摄像机的行为。 阅读详情

相关推荐

【Unity】入门学习笔记180516——API(3)Camera类实例方法

二、Camera类——B、实例方法B、实例方法1、RenderToCubemappublic bool RenderToCubemap(Cubemap cubemap);    //参数为Cubemap静态贴图(RenderTexture cubemap);    //    参数为RenderTexture静态贴图(Cubemap cubemap, int faceMask);    //fac...

Dylan_Day的博客 548

UnityAPI的学习——Camera类

set;功能:此属性的功能是设置摄像机的自定义投影矩阵。此属性常在一些特效场景喜爱用到,在切换变化矩阵时通常需要先用camera.ResetProjectMatrix()重置camera的变化矩阵。

ht_game的博客 1824

Unity常用类camera类-控制游戏中虚拟场景的展示(附带练习代码)(未更新完)

camera以左下角为屏幕的(0,0)点坐标,以右上角为屏幕的(camer.pixelWidth,camera.pixelHeight)点坐标,如果用单位化方式显示,则左下角为(0,0)点,右上角为(1,1)点 实例属性 aspect 设置摄像机视口比例 cameratoworldmatrix cullingMask eventMask layerCullDistances layerCullSpherical orthographi

yanyufeichengxu的博客 2575

unity camera aspect

camera的aspect默认是与screen保持一致,可以通过脚本将其设为指定值,如下: usingUnityEngine;usingSystem.Collections;publicclassmakeCameraViewWequalsH:MonoBehaviour{//UsethisforinitializationvoidStart(){...

weixin_30315723的博客 127

Unity3d Camera 讲解

1. 摄像机组件 照相机是玩家观察世界的装置,屏幕空间点按像素定义,屏幕的左下为(0,0);右上是(pixelwidth,pixelHeight),z位置在照相机的世界单位中。 相机组件 Clear Flags : 清除标识:确定了屏幕哪些部分将被清除,方便多个摄像机画不同的游戏元素 Background:背景色 Culling Mask:包含或省略要由相机呈现的对象层。在检查器...

leoysq的博客 3871

java modbus通讯协议_Modbus通 讯 协 议

电磁流量计Modbus通 讯 协 议(版本号:9000-K V9.1.1)2020年01月01日通讯协议针对KFD电磁流量计工业应用设计,版本:9000-K V9.1.1,该版本主要用于实时数据采集、流量测量、流量累计控制及部分参数的修改。一、主机系统通讯部件要求1.国际标准RS-485通讯接口部件,不小于11Bytes 的通信缓冲区(FIFO),支持1200、2400、4800、96...

weixin_39956612的博客 1010

android camera viewport rect,Unity学习笔记:Camera视口、aspect、pixelRect与rect

1.Camera视口:用来记录当前摄像机能看到场景中的哪些内容,其大小及位置是可以改变的。而屏幕视口是指当前硬件的屏幕,对于一个固定的硬件(例手机),它的屏幕视口大小(即分辨率)是固定的。Camera视口的内容不一定可以完全显示在屏幕上,屏幕可能只显示了一部分视口内容,也可能对视口内容进行了放缩。可以简单理解为,Camera视口是一张二维图片,而屏幕是用来显示这张图片的,图片可能被裁减、也可能被压...

weixin_42394656的博客 602

论文阅读笔记---Deep HDR Video from Sequences with Alternating Exposures

Kalantari N K, Ramamoorthi R. Deep HDR Video from Sequences with Alternating Exposures[C]//Computer Graphics Forum. 2019, 38(2): 193-205. 摘要: 在本文中,提出了一种基于学习的方法来,我们使用两个顺序卷积神经网络(CNN)对整个HDR视频重建过程进...

qq_25283239的博客 1446

Unity3d中Camera类的aspect属性解析

2.1.1 aspect属性:设置摄像机视口比例 基本语法:public float aspect{ get; set; } 功能说明:此属性用于获取或设置Camera视口的宽高比例值。例如,设camera.aspect=2.0f,则camera视口的宽度/高度=2.0f,但是当硬件显示器屏幕的宽度与高度比例不为2.0时视图的显示将会发生变形。aspect只处理摄像机Camera可以看到的视图

宏哥的博客 9008

【虚拟化生态平台】虚拟化平台esxi挂载USB硬盘

虚拟化平台安装好之后,一般情况下,只有一个硬盘在工作,其他的外接硬盘(我的只有一个ssd硬盘,其他的均是usb外接,SATA接口的硬盘是否这样我暂时不清楚哈)没有在工作,但是一个硬盘明显不够我们使用的,所以我们需要去挂载外接的硬盘来扩容。...

Rubik Blog 4834

万达电影 com.wandafilm.app headers check

万达电影 安卓逆向 抓包 逆向 check

weixin_43786514的博客 1436

Unity Aspect

Unity封装的东西太多,所以在很多情况下回忽略这些基本的事情。游戏窗口的中Aspect是通过Game窗口中进行选择,但对于相机的Aspect Unity并没有暴露接口在设置界面中,至少在编辑器下进行的任何视口调整都会马上看到正确的效果。 Camera.ResetAspect 会自动计算。OK, 实际在代码运行中呢? 如果要修改视口大小 就需要显式的设置Aspect并调用 Camera.Rese...

weixin_33910385的博客 172

Tessent ATPG Flow 流程 (代码和注释)

**摘要:Tessent ATPG流程分为五个阶段:1) 环境初始化(加载设计文件、库和扫描链配置);2) DRC规则检查(验证设计可测试性并修复违例);3) ATPG向量生成(设置故障模型并运行引擎优化覆盖率);4) 向量验证与后处理(仿真验证并生成ATE格式文件);5) 进阶操作(多电压域和存储器测试)。流程输出包括测试向量、覆盖率报告和验证日志,支持stuck-at和transition故障模型,使用Tcl脚本控制。关键步骤包含扫描链配置、EDT压缩和覆盖率优化。

QQ_778132974的博客 929

Unity Gizmos 绘制 Camera 的 视口、视锥和 FOV

Unity Gizmos 绘制 Camera 的 视口、视锥和 FOV 一、目的 由于开发需要,需要绘制出Camera 的 视口、视锥和 FOV 以便于观察游戏物体与camera之间的一些关系,以利于游戏的开发需要。 二、要点 1)OnDrawGizmos() 和 OnDrawGizmosSelected() 中绘制,任选其一即可 注意:OnD...

仙魁XAN 2883

从养虾到退坑:OpenClaw 卸载不留残留,一步到位

文章摘要: 本文提供OpenClaw软件的完整卸载指南,适用于Windows、macOS和Linux系统。内容包含卸载前的数据备份步骤(配置文件、日志、插件列表),以及详细的卸载脚本。Windows版通过批处理文件删除程序文件、注册表项和环境变量;macOS/Linux版则提供shell脚本,涵盖服务停止、软件包卸载、配置清理等步骤。特别强调要删除所有用户数据(包括多用户环境),确保系统无残留。文末建议重启计算机以使更改生效,实现"一步到位"的彻底卸载。

一键难忘的博客 298

【Bluetooth蓝牙开发】一、开篇词 | 打造全网最详细的Bluetooth开发教程

1、开篇词 2、蓝牙开发入门 3、蓝牙协议栈总览 4、蓝牙协议栈——物理层 5、蓝牙协议栈——链路层 6、蓝牙协议栈——传输层 7、蓝牙协议栈——L2CAP协议 8、蓝牙协议栈——ATT协议 9、蓝牙协议栈——GATT协议 10、蓝牙通信流程分析 11、蓝牙协议栈——Bluez交叉编译 12、蓝牙调试工具汇总

Donge's Blog 1万+

Unity API详解——Camera类

Camera类用来控制游戏中虚拟场景的展示,以左下角为屏幕的(0,0)点坐标,以右上角为屏幕的(camera.pixelWidth,camera.pixelHeight)点坐标。如果用单位化方式表示,则左下角为(0,0)点,右上角为(1,1)点。本博客主要介绍了Camera类的一些实例属性和实例方法,最后对摄像机的视口与aspect、pixelRect及rect之间的关系进行了注解。在Camera类中,涉及的实力属性有aspect、cameraToWorldMatrix、cullingMask、eventM

极客园地 2295

Far planner 部署真实小车 & 树莓派部署lego_loam

今天开一贴Far planner的部署,也算是lego loam的部署吧 因为state_estimation用的是lego loam小车底盘: 轮趣的mini差速底盘外加多一层钢板,中间层用来放velodyne的电池(小的电池还没到,大的电池塞不进去目前)和velodyne信号盒子。前面还可以加一个相机。底层用来放小车的电池和马达等设备了,底层不用动。最上面一层用来安装velodyne16线雷达,需要额外钻孔(如果买轮趣的话可以找老板钻个孔?我也不确定,我自己钻的)。 雷达固定螺丝用的是 1/4-20*3

博客 4301

Unity中手动设置纵横比

在Unity中,我们一般不会手动设置屏幕的纵横比,Unity在运行过程中会通过计算自动设置纵横比,但是在一些特殊情况下需要对纵横比进行手动设置,比如我们显示的屏幕被被动压缩时(如在LED屏幕上设置多屏幕显示时,难免会对部分屏幕画面进行压缩显示,在电脑显示器上显示正常,但是在大屏幕上却被压缩),我们可以通过设置纵横比来改善被压缩的情况。 在Camera中有一个属性aspect,用于设置纵横比。 ...

悲欢离合的博客 1767

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

《Unity_API解析》 第二章(下) Camera类实例方法

《Unity_API解析》 第二章(下) Camera类实例方法 RenderToCubemap方法:生成Cubemap静态贴图(专业版有) 1.public bool RenderToCubemap(Cubemap cubemap); 参数为Cubemap静态贴图 2.public bool RenderToCubemap(Render...

weixin_30551947的博客 200

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

【转】Unity3D 浅谈 Camera(摄像机)

今天小编和大家一起学习unity中常用组件Camera,在游戏中Camera就是相当眼睛,通过它来看整个游戏的世界,一切酷炫的景象都需要通过Camera来渲染出来;一个场景需要显示画面,也必须至少有一个Camera

Aries_H的博客 4147

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

Unity中摄像机自适应

unity打包之前Game视图显示的正常,是Scene场景中摄像机的范围区域,但是打包之后,设置分辨率之后,显示就不只是摄像机的显示范围了,分辨率过大会超出去。 using System.Collections; using System.Collections.Generic; using UnityEngine; public class NewBehaviourScript : Mono

一个无聊的人做一些有意思的事 2424
上一篇: Unity3D中世界坐标转换到NGUI坐标
下一篇: 深入探索透视投影变换
cbbbc
博客等级 码龄15年 609粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值