# 摄像机

由挂载渲染器、灯光等组件的节点构成了场景,还需要一个“观察者”来将整个场景展示,这就是摄像机(Camera)。

# 创建

摄像机也是一种组件,所以也可以使用两种方式来创建。

# 在 IDE 中

选中Entity后在 Inspector 里可以添加:

# 使用代码

const camera = entity.addComponent(engine.Camera);

无论是在 IDE 还是代码中创建,里面的参数配置都是等同的,比如在 IDE 中配置depth:0等价于在代码中camera.depth = 0

下面就来详细阐释下各个参数的实际意义和使用。

# 投影方式

首先是投影方式以及其相关的参数,投影方式由projectionType决定,目前可选透视投影Perspective或正交投影Orthographic,关于这两者的区分开发者可以自行查阅。

无论是对于哪种投影类型,以下参数都是通用的:

  1. nearClipPlane:近裁剪平面,决定相机最近能看到多远的物体。
  2. farClipPlane:远裁剪平面,决定相机最远能看到多远的物体。
  3. aspectType:纵横比类型,可选Auto或者Custom,一般是Auto,可自适应当前画布。
  4. aspect:在aspectTypeCustom的情况下,开发者需要自行设置。

在选择了透视投影的模式下,有以下参数可供调整:

  1. fieldOfView:视场角。

在选择了正交投影的情况下则有以下参数:

  1. orthographicSize:相机可视范围大小,是横向的尺寸,纵向会根据aspect换算。

# 自定义矩阵

本质上来讲,投影方式和参数方式决定了投影矩阵,而相机所在节点的变化信息(Transform)则决定了视图矩阵,这里不再赘述这种基本概念,一般来讲都是小游戏框架自动计算的。但在某些高级需求,比如水面折射投影的渲染需求中,确实有可能要自己定制投影方式、甚至是定制视图矩阵的计算。为了解决这种需求,小游戏框架提供了方案。

// 修改投影矩阵
camera.changeProjectMatrix(manual, matrix);

// 修改视图矩阵
camera.changeViewMatrix(manual, matrix);

这两个方法可以用于修改投影或者视图矩阵,第一个参数manual用于控制开启或者关闭手动模式,第二个参数即为要设置的矩阵值。

# 渲染目标和视图

知道了要花那些物体、以及如何讲这些物体投影到平面上,还需要知道将这些东西最终画在什么上面,这就是渲染目标renderTarget

renderTarget,即渲染画布资源,配置一个画布资源到这个参数即可,如果不配置(为空)则会渲染到主屏上,对应在代码里则是:

camera.renderTarget = game.renderSystem.screen;

有了渲染目标还要知道如何渲染到其上,这就是视图。上面提到了视图矩阵,但那个视图和这里的视图完全不同,主要由几个参数决定:

  1. isClearColor/clearColor:设置是否要在绘制前清除渲染目标的颜色,以及要清除为怎样的颜色。
  2. isClearDepth/clearDepth:设置是否要在绘制前清除渲染目标的深度,以及要清除为怎样的深度。
  3. isClearStencil/clearStencil:设置是否要在绘制前清除渲染目标的模板值,以及要清除为怎样的模板值。

# 深度和掩码

除了通过平截体剔除确定哪些物体要被渲染之外,还需要一种直接精确的剔除方案,这就是掩码(cullingMask)。点开 cullingMask 的下拉框:

可以看到有很多个选项,而这些选项和EntityLayer又是一一对应的,这实际上就是一种剔除策略,当二者没有交集的时候,对应的物体就不会再相机的剔除结果中出现。

除了单相机的渲染,很多时候会有很多个相机,它们之间也可能会有一定的顺序,这时候就可以使用depth来调整这个顺序,越大渲染顺序越靠后。

# 阴影

相机还可以配置阴影相关的参数,在场景中有平行光并且平行光开启了阴影的时候,平行光便可以通过开启了shadowCaster的渲染器产生阴影:

  1. shadowMode:阴影渲染类型,小游戏框架采用 CSM 来提升阴影质量,这个方案总共分为三级,None为不开启,之后是一级、二级、四级,级别越高质量越好,但是性能开销越大。
  2. cascadedSplits:用于调节 CSM 每一级分割的依据。
  3. shadowFitMode:暂时无效。
  4. shadowDistance:决定离相机最远的可产生阴影的物体的距离。

# 跟随目标

小游戏框架默认集成了基本的了相机跟随控制能力,配置targetTransform即可:

如图便是将另一个Entity指定为了跟随目标,之后相机在移动时都会朝向这个节点。

# 其他配置

除了以上,还有一些其他配置:

  1. drawSkybox:相机是否要绘制天空盒。
  2. drawGizmo:相机是否要绘制Gizmo。