第 7 章 摄像机:游戏里的”眼睛”
上一章我们把”光怎么算出明暗”讲透了。现在有个新问题摆上来:
光算好了、物体摆好了、场景里该亮的亮了该暗的暗了——然后呢?这些三维的东西,是怎么”进到你眼睛里”、变成你屏幕上那张二维画面的?
答案就是这一章的主角:摄像机(Camera)。
你可能觉得”摄像机不就是个视角吗,有什么好讲的”。别急。我先丢一个会颠覆直觉的事实:
你玩游戏时看到的每一帧画面,不是”世界本来的样子”,而是”某一台摄像机看到的样子”。 世界是三维的、无限的;你屏幕是二维的、方形的、有边界的。从”无限三维”到”你眼前这块方屏”,中间全靠摄像机这一道转换。而这套转换里,藏着”近大远小”这种你以为天生如此、其实是人类硬设计的约定。
本章我们就把摄像机从”一个视角”拆成”一台决定你看见什么、怎么看的虚拟仪器”。
7.1 摄像机就是一台虚拟相机
先确立一个最根本的认知:游戏里的摄像机,和现实里你举的相机/手机,是同一个东西的虚拟版。
现实相机干四件事:
- 它有个位置(架在哪)。
- 它有个朝向(镜头冲哪)。
- 它有个取景范围(广角还是长焦,能看到多大一片)。
- 它把三维世界压成二维照片存下来。
游戏摄像机一字不差地干这四件事,只是”照片”变成了”你这一帧看到的屏幕画面”。Unity 里每个场景至少有一个 Camera 物体,它身上就挂着 Position(位置)、Rotation(朝向),以及一组决定”看多大、怎么压”的参数。
最关键的一句,请刻进脑子:
你看到的 = 摄像机看到的。没有摄像机,就没有画面。 摄像机被你转一下,整个世界在你眼里就转一下;摄像机往前推,世界就朝你涌过来。玩家操作角色时,本质常常是”挪动那台跟着角色的摄像机”。
这引出第 2 章我们埋的伏笔——世界坐标和屏幕坐标之间,隔着”摄像机”这道转换。现在揭晓:这道转换,就是摄像机把三维世界**投影(Projection)**成二维屏幕的过程。投影是本章的心脏,7.2、7.3 专门拆。
生活化类比:把游戏世界想成一座巨型舞台,摄像机是台始终开着的直播相机。观众(你)只能看到这台相机拍到的画面。你想让观众看主角特写,就把相机推近主角;想看全景,就拉远、调广角。整个”玩家体验”,很大程度是”相机怎么摆、怎么动”的艺术——电影里叫”镜头语言”,游戏里也一样。
我再补一层,帮你把”摄像机”和”坐标”(第 2 章)彻底焊死:你调角色的 transform.position,改的是它在世界坐标里的位置;但角色”在屏幕的哪个像素”,不由世界坐标决定,而由”那台摄像机的世界坐标 + 朝向 + 投影”决定。同一辆车停在世界 (10,0,0),摄像机在它正前方拍,它在屏幕中间;摄像机绕到它背后拍,它在屏幕里就”转了向”——车没动,动的是相机。所以第 2 章那句”同一物体在不同眼里位置不同”,到这里就完全坐实了:不同的”眼”= 不同的摄像机,屏幕坐标随之而变。你以后做”小地图(正交俯视)、主画面(透视跟随)、过场(导演机)“,本质就是在同一世界里架了好几双不同的”眼”,各看各的。
还有个容易被忽略的点:摄像机本身也是场景里的一个物体(GameObject),它也有 Position、Rotation,也能被代码移动旋转。所以它不是什么神秘全局设置,就是”一个你能随便摆弄的虚拟相机节点”。你写 camera.transform.position = ...,就是在挪这台相机。把它想成一个”可程序控制的相机道具”,恐惧感立刻消失。
7.2 透视投影:近大远小是自然规律
现在进核心。先问你一个天天见、却从没质疑过的事:
一条笔直的马路,远处的路越变越窄,最后汇成一个点;两排路灯,近的粗大、远的细小,远到天边几乎重合。为什么”远的看起来小”?这是世界本来如此,还是眼睛/相机在骗你?
7.2.1 现实里:远的东西”张角”小
原因在几何,不在物体。一个路灯,它本身大小没变。但它在你眼睛里占多大,取决于它对你眼睛所张的角(视角 / 张角)。
你伸一根手指在眼前 10 厘米,它挡住你半边视野,张角大;同样的手指举到两米外,只占一小条,张角小。物体越远,对我们眼睛的张角越小,于是”看起来越小”。这叫透视(Perspective),是光学和几何的铁律,不是错觉。
相机的底片(或你视网膜)上,一个物体成像的大小,近似正比于”它真实大小 ÷ 它到相机的距离”。距离翻倍,成像减半——这就是”近大远小”的数学根。
7.2.2 为什么 3D 游戏用透视投影
既然现实世界是透视的(近大远小),而游戏想”像真的”,那最自然的选择就是:让摄像机也按透视来压画面。这叫透视投影(Perspective Projection)。
好处一望便知:用了透视,远处的山自然变小、马路自然汇成一点,画面立刻有”真实的空间纵深”。你第 8 章学的雾,也是靠这种纵深感才显得合理——远处又小又糊,正好。
连回第 2 章:世界坐标里的点,要经过”摄像机投影”才能变屏幕坐标。透视投影干的具体事就是——把每个三维点,按”它离摄像机多远”,往中心压缩,得到屏幕上的二维位置。离得近,压得少(显得大);离得远,压得多(显得小)。
这里补一个你写程序能懂的细节,但不深究:透视投影在数学上是一个**4x4 矩阵(projectionMatrix)**的乘法。第 2 章我埋过钩子”变换 = 矩阵搬运坐标”,这里兑现一半——摄像机把”世界坐标”乘上这个投影矩阵,再除以一个叫 w 的分量(透视除法),就得到”屏幕坐标”。你看,矩阵不是吓人的概念,它就是”把三维压成二维的那道搬运公式”。等以后你深入 shader,会再回来。现在你只需记住:透视 = 按距离压缩 = 近大远小。
7.2.3 一个能动手体会的投影示例
还是算一次,你就不虚了。设想摄像机在原点朝 +z 看,FOV 合适。世界里有根柱子,高 2 米,底部在 z = 10 米处、顶部在 z = 10 米处只是 y 从 0 到 2。
透视投影做啥?它把每个点的 y 除以”到相机的距离 z”,再乘一个缩放系数(由 FOV 定)。底部:屏幕y = 2系数 × (0 / 10) = 0。顶部:屏幕y = 系数 × (2 / 10) = 0.2 × 系数。
现在柱子被你走近到 z = 5 米(还是高 2 米)。底部还是 0;顶部:系数 × (2 / 5) = 0.4 × 系数。同样一根 2 米柱子,离你 10 米时屏幕高 0.2 系数,离你 5 米时变成 0.4 系数——近了一倍,看起来大一倍。 这就是”距离翻倍、成像减半”的活演算。除以 z 那一步,就是”近大远小”的数学心脏。
你写程序会心一笑:这不就是 screenPos = worldPos / z 嘛。对,透视投影的”压缩”,核心就是这一道除法。正交投影呢?它不除以 z,直接 screenPos = worldPos(再平移缩放到屏幕),所以远近一样大。一个除、一个不除,就是透视和正交的全部差别——简单到有点好笑,却是整个 3D 画面的分水岭。
7.2.4 一个关键直觉:透视投影”保不住平行”
透视有个反直觉但重要的性质:现实中平行的线,在透视画面里不一定平行。最经典的例子:火车两条铁轨,现实绝对平行,可在你照片里它们在远处”汇合”了。这是因为透视按距离压缩,远处两点被压得靠拢,平行线就”相交”于灭点(vanishing point)。
这对游戏意味着什么?意味着你做场景时,别指望”屏幕上看齐”就等于”世界里平行”。很多新手摆建筑,发现”地上两条线在画面里歪了”,慌了——其实没歪,是透视的正常表现。理解这点,你就不会被画面骗。
7.3 正交投影:为什么工程图 / 小地图不要近大远小
透视这么”真实”,那是不是永远该用它?不一定。我先问:
你看过建筑图纸吗?一张房子的平面图,近处的墙和远处的墙一样长、一样粗,绝不”近大远小”。工地工程师拿它量尺寸,要是远处墙画小了,他算材料就错。还有游戏里那种”从上往下俯视”的小地图,远处的敌人和近处的敌人一样大。这些为什么故意不用近大远小?
这就是另一种投影:正交投影(Orthographic Projection)。
7.3.1 正交:没有透视缩短
正交投影的思想极简单:不管物体离摄像机多远,成像大小一律不变。 它不做”按距离压缩”那一步。
几何上,透视是”从相机这个点发射视线、像锥子一样收拢”(透视投影也叫”针孔/锥体投影”);正交是”视线全部平行射出,像一堵平板把世界拍扁”——远近物体在平板上投影大小相同。
生活类比:透视像你用一只眼睛瞄远处(越远越小);正交像你拿一块玻璃垂直贴着世界、把每个点平行地拓到玻璃上(远近一样大)。第二种不真实,但量得准。
7.3.2 它对付什么问题:等距、可量、清爽
正交投影解决的是”我要准确、不要真实”的场景:
- 工程图 / CAD:尺寸必须 1:1 可读,远小近大会误导。建筑、机械用正交。
- 2D 游戏:很多 2D 游戏(横版、俯视)本质是世界是平的或固定视角,用正交相机最干净——角色远近一样大,不会忽大忽小,布局和碰撞好算。
- 俯视小地图 / 战术视图:小地图上敌人离你远还是近,要靠”位置”判断,不能靠”大小”,否则远处敌人缩成点你看不见。正交保证远近一样大,信息不丢。
- 等距(Isometric)视角:很多策略游戏(如模拟城市类)用正交做出”伪 3D”的等距感——有立体样子,又不变形,方便排布。
7.3.3 等距(Isometric):正交造出的”伪 3D 立体感”
正交里有个特别常用的变体叫等距视角(Isometric),值得单拎出来说,因为你一定见过。
纯正交如果正对着拍,世界是”正面平板”(像看一张海报)。但工程师把正交相机转一个固定角度(比如俯 30 度、侧 45 度)去拍一个盒子世界,出来的画面就有”能看见顶面+正面+侧面”的立体样子——可因为是正交,盒子远近一样大、平行线不汇合,于是它既有立体感、又不畸变。这种”看起来是 3D、量起来是 2D”的调调,就是等距。
经典游戏:模拟经营(模拟城市类)、很多像素风 RPG(如早期《暗黑破坏神》《星级争霸》的斜 45 度)、《纪念碑谷》式的空间解谜。它们的魅力正来自”正交的清爽 + 立体的好看”。你做这类游戏,选正交相机 + 固定角度即可,不用操心透视变形,排布建筑也直观(一格就是一格,不会近大远小导致对齐难题)。
为什么等距比透视”好排布”?因为透视下远处一格会被压缩,你想铺整齐的棋盘格会越往远越挤;正交下每格等大,棋盘永远整齐。这就是为什么策略游戏爱用正交/等距——信息密度均匀,玩家读图不吃力。
7.3.4 透视 vs 正交:一张对照
| 维度 | 透视投影 | 正交投影 |
|---|---|---|
| 近大远小 | 有(真实) | 无(等大) |
| 平行线远处 | 汇成灭点 | 始终平行 |
| 真实感 | 强 | 弱 |
| 可量性 | 差(远小) | 强(等大) |
| 典型用途 | 绝大多数 3D 游戏主画面 | 2D 游戏、小地图、工程图、等距策略 |
| 摄像机参数 | 有 FOV、近/远裁剪面 | 有 Size(正交视野大小)、近/远裁剪面 |
你看,选透视还是正交,不是”哪个高级”,而是你要真实感还是要准确/清爽。这是工程师按”对付什么问题”做的选择,又是那条主线。
7.4 视野(FOV)、近 / 远裁剪面:屏幕装不下的怎么办
投影类型定了(透视还是正交),摄像机还有几个决定”看多大、看哪段”的参数。这一节讲最实用的三个。
7.4.1 FOV(Field of View,视野角)
透视摄像机有个 FOV,中文”视野”或”视场角”,单位是度。它决定”镜头张多大口”。
生活类比:你睁一只眼,FOV 大概是你余光能罩住的角度(人眼单眼约 100~120 度广角)。你举起双筒望远镜(长焦),FOV 很小,只能看远处一小块,但那小块被放得很大。
游戏里:
- FOV 大(如 90~110 度) = 广角。看得宽,但边缘物体被拉扯变形(广角畸变,类似手机自拍广角脸歪)。第一人称射击游戏常用较大 FOV,让你”眼观六路”。
- FOV 小(如 20~40 度) = 长焦 / 望远镜。看得窄,但远处物体被放大、显得近。过场动画想”把远处主角拉近”,就缩 FOV。电影感运镜常这么玩。
调 FOV 是你做”观感”最直接的旋钮之一:想紧张压抑(狭窄视野)就小,想开阔自由就大。
举几个具体数字帮你建立手感(人眼单眼约 100~120 度,但游戏几乎不用这么大,因为边缘畸变太重、且屏幕没那么宽):
- 第一人称射击(FPS):常用 75~90 度。开大(如 103)显得”速度快、开阔”,但枪和手会被拉扯变形;调小(如 70)画面更”长焦”、稳定,但周边余光少、易眩晕。很多玩家调试感,就在这几度之间反复拧。
- 第三人称动作:常用 40~60 度,像”隔着一段距离拿长焦看主角”,主体突出、背景压缩。
- 过场特写:可临时拉到 20~35 度,把远处主角”放大拉近”,电影感强。
- 赛车游戏座舱视角:贴近人眼,约 60~80 度,兼顾仪表和路感。
一个重要的”沉浸感”陷阱:FOV 太大会让画面边缘疯狂畸变,玩久了头晕(眩晕感多源于”视野信息和内耳平衡感冲突”);太小则像透过管子看世界,压抑。所以 FOV 不是越大越爽,而是”匹配你预期的距离感”。VR 游戏对 FOV 极敏感,因为头显要贴合人眼真实视野才不晕——这是另一个深坑,你以后做 VR 会撞上。
还有件反直觉的事值得点破:FOV 不影响”物体真实大小”,只影响”它占屏幕多大比例”和”远近物体的相对压缩”。 很多新手以为”调大 FOV 角色就变小”,其实角色世界尺寸没变,只是广角把周围撑开、显得角色占比小了。这点和焦距(相机镜头)的关系一模一样,你拍照换广角镜头,人没变小,是背景被拉远了。
7.4.2 近裁剪面(Near Clip Plane)与远裁剪面(Far Clip Plane)
这是两个距离值,决定”摄像机拍多近、拍多远”。
现实相机拍不了”贴着镜头”的东西(镜头前有玻璃),也拍不到无限远。游戏摄像机同理,设两道”围墙”:
- Near(近裁剪面):比这更近的物体,不画。比如你设 Near = 0.3 米,那么镜头前 30 厘米内的东西被裁掉,不显示。
- 为什么要裁?数学上投影要把”近大远小”算准,距离不能太接近 0(否则除零/精度崩)。而且贴脸的东西多半是你不需要看的(比如你自己的枪管根部)。
- 坑预警:Near 设太小,会导致”远近精度”变差,远处物体闪烁(深度冲突 z-fighting)——这是老手的经典踩坑。一般 Near 设个合理小值(0.01~0.3)即可,别设成 0。
- Far(远裁剪面):比这更远的物体,不画。设 Far = 1000 米,那么 1 公里外的东西直接不渲染。
为什么要有 Far?两个原因:
- 性能:远处看不见的东西白画浪费算力(呼应第 1 章餐厅、第 8 章偷工)。不画远处,省下的就是帧率。
- 边界:世界有尽头,Far 就是”可视距离”的硬边界。
7.4.4 一组具体数字,帮你建立手感与避坑
参数不是抽象名词,给几个真实取值你就懂怎么拧了:
- Near 设 0.3,Far 设 1000:这是很多第三人称游戏的默认档。Near 0.3 避免贴脸穿模、又不过小伤精度;Far 1000 米覆盖大多数开放场景。
- Near 设 0.01(太小)的坑:Near 越接近 0,相机”前后精度”跨度越大(从 0.01 到 1000),深度缓冲(depth buffer,记录每个像素离相机多远的缓冲区)精度被摊薄,远处两个物体会”打架”闪烁,叫 z-fighting(深度冲突)。常见症状:远处地面和贴在其上的纹理不停闪、交错。解法:把 Near 提到 0.1~0.3,别贪小。
- Far 设太小(如 200)的穿帮:你站高处看,200 米外全没了,像世界被刀切。这时要么拉 Far,要么用第 8 章的雾把 200 米处糊成天色,伪装成”远处有雾”。
- Near/Far 比例别太悬殊:经验上 Far ÷ Near 别超过几千倍。要既看近又看远,优先抬 Near(而非猛抬 Far),或用对数深度缓冲(高级话题)。
一句话:Near 和 Far 是你给”世界切片”的两刀——中间这段才进画面。 它们既是性能开关(切掉不画的),也是精度旋钮(比例影响 z-fighting),还是和第 8 章雾配合的边界帘。调它们时心里同时装着这三件事,就不会乱。
7.4.5 宽高比(Aspect Ratio):屏幕不是方的怎么办
FOV 只管”上下张多大口”,但屏幕还有个”宽窄”问题——宽高比(Aspect Ratio)= 画面宽 ÷ 高。
现实里:老电视 4:3(接近方),今显示器/手机 16:9(宽屏),超宽屏 21:9,竖屏手机 9:16。相机投影时,FOV 通常管”垂直方向”,水平方向由宽高比撑开。所以同一个 FOV,屏幕越宽,你左右看到越多(水平 FOV 越大);屏幕越竖,左右看到越少。
这带来一个真实坑:你在宽屏上调好的构图,到竖屏手机上左右被砍,重要东西可能跑出画面。 移动端游戏常要按设备动态适配——要么锁死宽高比加黑边(信箱模式),要么让相机 FOV 随宽高比自动扩(保证关键信息总在屏内)。
你写程序会联想到:投影矩阵里就藏着宽高比这个因子(乘到 x 上)。调竖屏就是把那个因子压扁。本质还是”世界→屏幕”这道压缩里,多了一个”按屏幕形状拉伸”的步骤。记住它,你做跨平台发布时就不会被”手机上怎么构图怪了”搞懵。
一个设计直觉:横屏适合”看远方、看战场”(水平 FOV 大,视野开阔);竖屏适合”看正前方、看角色特写”(垂直信息重要)。很多手游横竖屏切换,背后就是重算这套投影。这也说明:摄像机参数不是”设一次就忘”,而是要跟着”玩家用什么设备看”走。
7.4.3 连回第 8 章:雾用来藏远裁剪边界
这里把第 8 章的伏笔接上——远裁剪面以外不画,可玩家会看见”边界突然没东西”的穿帮。怎么办?用雾。
经典做法:把 Far 设在比如 500 米,然后在 300~500 米这段加浓雾(雾色 = 天色)。于是”500 米外不画”和”500 米外被雾吞没”在视觉上无法区分——玩家以为远处是雾,其实是世界尽头被裁了。雾,又一次成了”偷工不穿帮”的窗帘。
你看,摄像机(Far)和雾(Fog)是搭档:Far 决定”算到哪停”,雾决定”停的地方看起来自然”。两个参数一起调,才既省算力又不露馅。这条线你串起来,就懂了为什么教程顺序是坐标→……→雾→光→摄像机——它们彼此咬合。
7.5 多个摄像机:小地图、过场、画中画
最后一节说一个你肯定会用到的能力:一个场景可以有不止一台摄像机。
7.5.1 多台摄像机叠在一起
现实里你想同时看两路画面,得架两台相机。游戏里同理——场景里放两个 Camera,它们各自拍各自的角度,然后叠到同一块屏幕上(靠一个叫 Depth / 渲染顺序的属性决定谁盖谁)。
常见用法:
- 小地图:主摄像机拍正常第一/三人称视角;再放一台正交摄像机吊在场景正上方俯拍,把它渲染到屏幕右上角一小块(用 Viewport / 图层遮罩限定区域)。于是你主画面正常玩,角落有个俯视小地图——这正是 7.3 说的正交用途。
- 过场动画(Cutscene):剧情时刻,切到一台专门摆好的”导演机”,从好看的角度播演出,播完切回玩家机。
- 画中画(PiP):双人分屏、监控画面、后视镜,本质都是多台摄像机各拍各的、各占屏幕一块。
- 第一人称枪械 / 特效层:主画面之外,单独一台机只拍”枪和手”,叠加在最前,避免枪被墙挡住(穿墙枪的经典解法)。
7.5.2 它们怎么不打架:图层与深度
多台机叠一起,怎么保证”小地图只在角落、主画面占满”?两个机制:
- Culling Mask(剔除遮罩 / 图层):每台机指定”我只拍哪些层(Layer)的物体”。比如小地图机只拍”地形层”,不拍 UI;主角机拍”角色层 + 地形层”。
- Depth(深度):决定渲染先后。Depth 大的后画、盖在上面。小地图机 Depth 高,所以画在主画面之上;主画面 Depth 低,先画打底。
你写程序的话,这就像”多个图层(layer)分别渲染,再按 z-order 合成”。游戏引擎的渲染管线,底层就是”依次让每台摄像机把它的世界画到帧缓冲,后画的覆盖先画的”。
一个直觉收尾:摄像机不是”一个全局视角”,而是”可任意增删、各自取景、叠加合成的多个取景器”。你以后做 UI、做特效、做过场,都会回来指挥这些摄像机。理解了它,你就从”被动看画面的人”变成”安排画面的人”。
7.5.3 更多多机实例:分屏与后视镜
再给两个你一定会碰的用法,巩固”Culling Mask + Depth + Viewport”这套组合拳:
- 分屏对战(Split-screen):两个人同屏玩,每人一台主摄像机。两台机都用满屏 Viewport,但一台占左半(x:0
0.5)、一台占右半(x:0.51),各自跟一个玩家。两台机 Culling Mask 可以相同(都拍全部),靠 Viewport 把屏幕劈成两半。经典如《马里奥赛车》本地双人。 - 载具后视镜:赛车游戏里后视镜那块小画面,其实是一台放在车尾、朝后拍的摄像机,渲染到后视镜那个 UI 区域。它和主摄像机(车头朝前)方向相反,但同属一个场景。原理和小地图一样,只是朝向不同。
- 特效/UI 独立层:有些游戏把”全屏泛光、血迹边框”放到一台额外的高 Depth 摄像机,只拍特效 Layer,叠在最前。这样特效永远不被场景遮挡。
你会发现,这些花样万变不离其宗:多台机 = 多路取景,Viewport 定占屏哪块,Depth 定谁盖谁,Culling Mask 定拍什么。 你写过程序,就把每台机当成”一个独立渲染通道”,合成时按 Depth 叠加——思路清晰得很。
7.5.4 第一人称与第三人称:两种”眼”的哲学
顺着”多机”的思路,聊一个你会反复做选择的题:主摄像机到底架在哪? 这决定了整个游戏的”体感”。
- 第一人称(FPS):摄像机直接架在”角色眼睛”上,Position = 角色头部,朝向 = 角色视线。你看到的就是角色看到的,看不到自己身体(只看到枪和手,那是用另一台机/特效层做的,见 7.5)。优点是沉浸感强——你就是角色;代价是空间感弱,容易晕、容易判断不好距离(因为全是透视、没有”自己身体”当参照)。
- 第三人称:摄像机在角色”后上方”悬浮,看向角色(就是 7.6 跟随的那套)。你能看到角色全身、看到它和环境的关系,空间感好、操作友好;代价是”屏幕中心不一定是准星”,射击类要额外算”镜头到目标的延长线”当瞄准线。
你发现没有,这根本不是”哪个更好”,而是”你要玩家代入角色,还是观察角色”。代入→第一人称;观察→第三人称。而无论哪种,底层都只是”摄像机 Position/Rotation 绑在角色的哪个局部坐标上”——第一人称绑头部、第三人称绑身后偏移。又是第 2 章”局部坐标”的用武之地:那台机是角色的”子物体”,跟着角色的局部系走。
进阶玩法:很多游戏在两者间无缝切换——平时第三人称看角色,举枪瞄准时切第一人称(相机瞬移头部)。实现上就是”同一台机在两套局部偏移间插值”,或干脆两台机切换 Depth。你理解原理后,这种花活不过是”挪相机 + 切图层”的组合拳。
7.6 摄像机跟随:它怎么”黏”着主角
多摄像机讲完,有个你几乎每个游戏都要写的功能必须单独说:主摄像机怎么跟着玩家走? 这是”摄像机”从”静态取景器”变成”活的角色伙伴”的关键。
最朴素的做法:每帧把摄像机位置 = 玩家位置 + 一个固定偏移(比如”玩家头顶后方 5 米”)。玩家挪,摄像机跟着挪;玩家转,偏移也跟着转,于是摄像机始终在玩家”后上方”盯着他。这就是绝大多数第三人称游戏的基础。
但你会立刻撞见两个真实问题:
- 太硬:摄像机严格贴着玩家,玩家一抖摄像机就抖,看得人晕。工程师的解法:平滑跟随(Lerp / 阻尼)——摄像机不直接瞬移到目标位置,而是每帧”朝目标挪一点点”(当前位置 = lerp(当前, 目标, 系数))。像摄像机吊在一条有弹性的绳上,玩家急停它缓缓追上。系数小=懒洋洋跟,系数大=紧贴。这又是”用近似换体验”的老套路。
- 穿墙:玩家走到墙后,摄像机如果还按偏移摆,会卡进墙里,看到墙的背面(穿帮)。解法:碰撞规避——摄像机朝玩家连线如果戳到墙,就把摄像机往前拉到墙前;或者给摄像机也加碰撞体,让它被墙挡住时自动贴墙。很多引擎的 Cinemachine(摄像机工具)把这些全打包好了。
为什么提这个?因为跟随的本质,还是”每帧重新算摄像机的位置和朝向”——也就是第 2 章的变换(平移+旋转)每帧作用在摄像机上。 你调摄像机,本质是在调”它相对玩家这个父物体的局部坐标(偏移)“。这又把第 2 章的坐标、第 6 章的”玩家体验靠镜头”全串起来了:玩家看到的世界,永远是”一台被代码实时摆弄的虚拟相机”看到的。
一个能直接上手的小实验:你建个 Cube 当玩家,建个摄像机,写三行伪代码——“摄像机位置 = Cube位置 + (0,3,-5);摄像机看向 Cube;每帧执行”——跑起来,Cube 一动摄像机就跟着。再把它改成 lerp 平滑,感受”硬跟”和”软跟”的区别。这几行代码,就是你理解所有第三人称镜头语言的起点。
7.7 收个尾,连回主线
把摄像机扣回全书那句话:游戏把贵/复杂的事,用约定和预计算换成可控的体验。
- 自然现象:现实相机有位置、朝向、取景范围;近大远小是几何铁律(远物张角小)。
- 现实问题:无限三维世界,装不进有限二维屏幕;有时要真实(透视),有时要准确(正交);太近太远的东西不能画(性能/精度/边界)。
- 工程师方案落进引擎:
- 投影(Projection):透视按距离压缩(近大远小,用 projectionMatrix),正交不压缩(等大)。连回第 2 章”世界→屏幕隔投影”。
- FOV:广角 vs 长焦观感。
- Near / Far 裁剪面:只画一段距离。连回第 8 章”雾藏 Far 边界”。
- 多摄像机 + Culling Mask + Depth:小地图、过场、画中画。
- 你能做的:挪摄像机改体验,调 FOV 改观感,用正交做小地图,用多机做画中画。
到这,坐标(第 2 章)、材质(第 5 章)、光照(第 6 章)、雾化(第 8 章)、摄像机(本章)这条”空间与画面”的主线,你已经能串成一张图了:物体在坐标里摆好 → 材质定表面 → 光照算出明暗 → 摄像机投影成二维 → 雾藏住远处边界。 下一阶段我们进”声音”,你会看到声音”存进计算机”也是从自然现象(波)出发、为解决问题才发明采样与压缩,思路一模一样。
【思考题】
- 现实里”远处的路灯看起来小”,到底是路灯真变小了,还是另有原因?用”张角”解释。为什么 3D 游戏主画面几乎都用透视投影?
- 正交投影和透视投影最核心的区别是什么?举两个”必须用正交、不能用透视”的游戏场景,并说明为什么。
- 近裁剪面(Near)和远裁剪面(Far)分别裁掉什么?为什么要有 Far?它和第 8 章的雾是怎么配合的?
- 一个场景里放两台摄像机(主视角 + 右上角小地图),它们怎么做到”主画面占满、小地图只在角落不打架”?需要哪两个机制配合?
【参考答案】
- 路灯没真变小,是它对你眼睛的张角随距离变小了——物体越远张角越小,成像(看起来)越小,这是几何铁律不是错觉。3D 游戏主画面用透视投影,正是因为现实世界是透视的(近大远小),用透视画面才有真实的纵深感;而且第 8 章的雾也依赖这种”远处又小又糊”的纵深才显得合理。所以透视 = 按距离压缩 = 近大远小,是”像真”的自然选择。
- 核心区别:透视按距离压缩(近大远小),正交不压缩(远近等大)。 必须用正交的场景:(a) 俯视小地图——远处敌人若被透视缩小就看不见/误判远近,正交保证远近一样大,信息不丢;(b) 2D 游戏 / 工程图——2D 游戏世界是平的或固定视角,正交最干净不变形,布局碰撞好算;工程图要 1:1 可读尺寸,远小近大会误导算料。本质都是”要准确/清爽,不要真实感”时选正交。你能否想到第三个该用正交的场景?
- Near 裁掉”比它更近”的物体(不画),Far 裁掉”比它更远”的物体(不画)。要有 Far 因为:一是性能(远处看不见的画了白费算力),二是边界(世界有尽头,Far 是可视距离硬限)。配合第 8 章雾:把 Far 设在一定距离(如 500 米),在接近 Far 的区段加浓雾(雾色=天色),于是”Far 外不画”被伪装成”远处被雾吞没”,玩家看不出世界尽头。雾再一次当”偷工不穿帮”的窗帘。
- 靠两个机制配合:(a) Culling Mask(图层遮罩)——每台机指定只拍哪些 Layer,小地图机只拍地形层、主機拍角色+地形;(b) Depth(深度/渲染顺序)——决定谁后画盖谁上,小地图机 Depth 高,画在主画面之上,且用 Viewport 限定它只占屏幕右上角一小块。两者一限”拍什么”、二限”画在哪层”,就不打架。这本质就是”多图层按 z-order 合成”,和写程序的图层叠加一个道理。