相机和视口
本节我们介绍相机 (Camera) 和视口 (Viewport) 。
相机节点就是我们在3D场景中部署的虚拟拍摄机位,视口相当于一块画布,用于绘制相机拍摄到的游戏画面.
相机
简介
相机是一个特殊节点,用于显示从其当前位置可见的内容。 相机会与在最近的视口(Viewport)节点绑定。 每个视口(Viewport)只能激活一个相机。 如果在场景树中没有可用的视口(Viewport)节点,相机将自动关联在全局视口中。 换句话说,相机只是为视口(Viewport)提供3D显示能力,如果没有,则无法显示该视口(Viewport)中的内容。
无论在场景中中放置了多少物体、对象,除非将相机也添加到场景中,否则运行项目将不会显示任何内容!
我们已经预先为您在场景中预置了一个相机节点 MainCamera , 它是我们运行项目后的主相机。当然,您也可以添加新的相机。
相机属性
请先选中我们场景树中的 MainCamera 节点,然后将目光移至下方的属性栏窗口。我们相机的属性就呈现在我们眼前。
- 剔除遮罩 剔除遮罩是决定我们场景中哪个3D渲染层会被此相机渲染的属性,即我们的相机会看见哪个场景中的物体。 我们可以试着取消勾选层1(或点击第一个方块),然后使用快捷键 F6 运行我们正在编辑的场景,您就会发现我们原本场景有的对象就不能被相机看到了。这是因为我们的物体默认都是置于渲染层1的。
- 环境 环境属性就是设置相机视角下的能实现的环境球效果。其中 环境 属性下 新建环境 后的各个参数与 环境节点 中所包含的属性是相同的。
试着在我们相机节点的环境属性中,新建一个环境,然后试着更改 背景 → 模式 。
运行我们的场景,看看各个模式下,相机渲染实现的效果吧!
- 水平偏移:设置相机视口的垂直偏移分量
- 垂直偏移:设置相机视口的水平偏移分量 我们可以尝试着改变这两个属性值,然后我们运行场景,可以看到相机的位置会有所改变。
修改前相机视角效果
修改后相机视角效果
- 多普勒跟踪 此相机将针对在特定的方法中更改的对象模拟多普勒效应。
- 当前的 此属性用于判断,视口是否使用当前的相机。如果我们场景中使用了多个位置的相机,那么我们就可以通过个这个属性的启用与否知道,当前视口在运行后使用的是哪个相机。
- 视场 相机的视场角(以度为单位)。此属性可以用于调整相机所能看到的视角的大小。默认值为70。
- 近截面与远截面
- 近截面 :相机视口所能看到的最近物体的距离。
- 远截面 :相机视口所能看到的最远物体的距离。
- 投影 : 透视 :相机视口中的物体的大小,会随着它们距离相机中的距离变化。它们距离相机越远,它们在相机视口中的大小就会越小。 正交 :相机视口中的物体的大小不随它们距离相机的距离变化。 锥台 :相机的锥台投影。 此模式下允许调整锥台偏移来创建“倾斜的视锥”效果。
快速创建(相机)
在编辑器顶部菜单栏中单击 快速创建 按钮,如下图
- 空相机 : 一个普通的相机节点。常用于相机动画节点操作。
- 飞行相机 : 支持前后左右(W A S D)控制移动相机,在空间中可以任意方向的移动。
- 第一人称相机 : 模拟第一人称视角漫游的相机,支持前后左右(W A S D)控制移动相机, 空格实现弹跳,鼠标右键实现相机视角移动。只能作用于某一个平面或连续的、凹凸不平的平面(地面)移动。
- 第三人称相机 : 模拟第三人称视角漫游的相机,与第一人称相机不同的是,多了一个人物模型,支持前后左右(W A S D)控制移动相机, 空格实现弹跳,鼠标右键实现相机视角移动。只能作用于某一个平面或连续的、凹凸不平的平面(地面)移动。
导入人物模型,放在在第三人称相机下,
选中 第三人称相机 节点,在属性栏中 点击 指定人物,
弹出选择节点页面,选择医生节点,然后点击确认即可。
相机预览
当我们在编辑器中摆放好了相机的位置,同时想要预览从相机视角下看到的场景是什么样子的时候,就会用到我们 相机预览 的功能。 IdeaXR提供2处切换 相机预览 的入口:
- 选择相机节点或其父节点(场景中的选择与节点树的选择是绑定的),选中后,窗口右下角会出现一个小窗口来预览当前选中相机的显示效果。
- 我们可以在视口左上角中进行相机视角的切换。
视口
简介
视口(Viewport)相当于一块画布,你可以在上面任意的布局,变换大小等。 将 Viewport 想成投影游戏的荧幕. 为了看到游戏, 我们需要有一个表面来绘制它, 这个表面是作为根节点的 Viewport。 视口也可以添加到场景中, 以便绘制多个区域。 当我们绘制到一个不是根节点的 Viewport 时。 我们将该视区称为渲染目标。我们可以通过访问它对应的 texture 属性来访问渲染目标的内容。 将任一 Viewport 作为渲染目标时, 我们要么可以同时渲染多个场景, 要么可以渲染到场景中某个对象的 texture 上, 例如渲染到动态天空盒的材质上。
Viewport 有多种使用情况, 包括:
- 在2D游戏中渲染3D物体
- 在3D游戏中渲染2D元素
- 渲染动态纹理
- 在运行时生成程序式纹理
- 在同一场景中渲染多个摄像机
所有这些用例的共同点是, 你被赋予了在纹理上绘制物体的能力, 就好像它是另一个屏幕一样, 然后可以选择如何处理产生的纹理。
视口的创建和使用
视口是否显示的必要设置 :
- 视口需要绑定相机节点;
- 视口需要设置大小;
- 需要渲染到 视口容器 或者 视口纹理图 上;
视口创建
添加 视口 节点
视口 节点需要绑定 相机节点,否则看不到视口内的效果,一片黑幕。
绑定相机
将相机节点置于视口节点下,如下:
设置视口大小
必须手动设置视口的大小,否则会警告提示!
视口容器
视口容器(ViewportContainer)是2D节点,如果 Viewport 是 ViewportContainer 的子节点, 它将变为活动状态并显示其内部的任何内容, 布局看起来像这样:
如果 ViewportContainer 的 拉伸 属性设置为 启用 状态,那么 Viewport 就会完全覆盖这个父亲节点 ViewportContainer。
启动项目后,Viewport 的内容就会显示在 视口容器 中。
该 ViewportContainer 的大小不能小于 Viewport 的大小。
视口纹理
Viewport作用于纹理图(TextureRect),纹理图也是2D节点。添加 纹理图 节点后,选择纹理图,属性栏中点击 纹理 创建 ViewportTexture
弹出选择 视口 的界面,选择其中任意视口后确认,
该纹理图就与选中的 视口 绑定在一起,在启动项目后,viewport的内容就会显示在 纹理图 中,但是顺序是上下颠倒的。
需要启用属性栏中的 垂直翻转,
专业知识点
场景
在 3D 中,Viewport 会包含一个 World,简单而言就是连接物理和渲染的宇宙。基于 Spatial 的节点会绑定到距离最近的 Viewport 的 World 中。新建的 Viewport 默认不包含 World,会使用其父亲节点 Viewport 的值(根 Viewport 始终包含 World,对象默认渲染到此处)。可以通过 Viewport 的“world”属性设置 World,设置完成后,就会切断该 Viewport 所有子节点与父 Viewport 中 World 的交互。特定情况下这是非常有用的,例如,你可能会想要在游戏之上单独显示一个 3D 角色(类似星际争霸)。
作为您想要创建的情况的帮助 Viewport 显示单个对象而不想创建 World, Viewport 可以选择使用自己的 World. 当您想要在2D World 中实例化3D角色或对象时, 这非常有用.
对于 2D,每个 Viewport 总是包含它自己的 World2D。这在大多数情况下都足够了,但是如果需要共享,可以手动设置 Viewport 的 World2D。
渲染
由于以下事实 Viewport 是进入另一个渲染表面的入口, 它会暴露一些可能与项目设置不同的渲染属性. 第一个是MSAA, 您可以选择为每个使用不同级别的MSAA Viewport, 默认行为是DISABLED. 您还可以设置 Viewport 以使用HDR, 当您想要在纹理中存储超出0.0 - 1.0范围的值时,HDR非常有用.
如果你知道 Viewport 将被如何使用,可以把它的用法设置为 3D 或 2D。这样 IdeaXR 就会根据选择限制 Viewport 的绘制方式;默认是 3D。与 3D 使用模式相比,2D使用模式的速度稍快,占用的内存也少。如果视窗没有在 3D 中渲染任何东西,将 Viewport 的使用属性设置为 2D 是一个好主意。
如果需要在视图中渲染3D阴影, 请确保将视图的 Shadow Atlas Size阴影贴图集大小 属性设置为大于0的值. 否则, 阴影将不会被渲染. 作为参考, 项目设置默认定义为4096。
渲染目标
渲染到一个 Viewport 时, 里面的东西在场景编辑器中是看不到的. 为了显示内容, 你必须在某个地方绘制 Viewport's ViewportTexture. 这可以通过代码使用, 例如:
var rtt = viewport.get_texture()
prite.texture = rtt
每一帧, Viewport 的纹理都会被清除, 并使用默认的透明色(或者如果 Transparent Bg 被设置为 true ). 这可以通过设置 清理模式 为 从不 或 下一帧 来改变. 顾名思义,从不 意味着纹理将永远不会被清除, 而 下一帧 将在下一帧清除纹理, 然后将自己设置为Never.
默认情况下,Viewport 的重新渲染会发生在 Viewport 的 ViewportTexture 在一帧中被绘制时。可见是会渲染;不可见时则不会。这个行为可以改为手动渲染(单次)或者无论是否可见总是渲染。这种灵活性使用户可以渲染一次图像,然后使用纹理,而不需要承担每一帧渲染的消耗。