signed

QiShunwang

“诚信为本、客户至上”

【读书笔记】游戏开发原理

2021/6/3 15:31:37   来源:

游戏开发原理读书笔记

游戏开发原理

Contents

  • 游戏开发原理读书笔记
  • 一、游戏与游戏设计
    • 1 游戏类型与平台
      • 1.1 类型和子类型
      • 1.2 出品类型
      • 1.3 平台
      • 1.4 图形类型
      • 1.5 交付方式
      • 1.6 视角
    • 2 video game剖析
      • 2.1 引擎
      • 2.2 资产
      • 2.3 规则
    • 3 游戏开发阶段
      • 3.1 基本设计与头脑风暴
      • 3.2 原型设计
      • 3.3 完善设计
      • 3.4 引擎开发
      • 3.5 资产创建
      • 3.6 脚本制作
      • 3.7 测试与调试
      • 3.8 营销与分销
    • 4 游戏设计
      • 4.1 游戏设计目的
      • 4.2 游戏设计文档
      • 4.3 游戏名称、平台和受众
      • 4.4 总结与故事
      • 4.5 人物、设备和地点
  • 二、游戏软件开发
    • 1 项目管理及依据
    • 2 通过RAMS创建一个计划
      • 2.1 可复用性
      • 2.2 抽象性
      • 2.3 模块化
      • 2.4 简单性
    • 3 开发方法
      • 3.1 瀑布模型:线性开发
      • 3.2 瀑布模型:优点和缺点
      • 3.3 敏捷模型:迭代开发
      • 3.4 敏捷开发:优点和缺点
      • 3.5 开发方法选择
    • 4 发布周期
      • 4.1 技术预览版本
      • 4.2 预览版本
      • 4.3 用户测试版本
      • 4.4 候选发布版本
      • 4.5 最终版本
  • 三、游戏编程
    • 1 深度型程序开发
      • 1.1 编码
      • 1.2 脚本
      • 1.3 可视化脚本
    • 2 开发游戏:关于DIY引擎和第三方引擎
    • 3 游戏开发范例
      • 3.1 面向对象
      • 3.2 深入了解面向对象
      • 3.3 面向部分设计方法论
      • 3.4 OO与CBD
    • 4 时间、事件和动作
      • 4.1 时间
      • 4.2 事件和动作
    • 5 错误、测试和调试
  • 四、游戏数学
    • 1 数字的语言
    • 2 坐标系
    • 3 坐标系基础
    • 4 全局与局部坐标系
    • 5 位置、方位和尺寸
    • 6 变换
      • 6.1 位移
      • 6.2 旋转
      • 6.3 缩放
      • 6.4 矩阵变换
          • 6.4.1 矩阵乘法
    • 7 向量:方向和位移
      • 7.1 Vector,什么是向量
      • 7.2 向量加法和乘法
      • 7.3 向量归一化
      • 7.4 向量点积
    • 8 解决速度、距离和时间的问题
  • 五、图形、像素和色彩
    • 1 像素:图形的最小单位
      • 1.1 分辨率
      • 1.2 屏幕宽高比
      • 1.3 分辨率与宽高比带来的难题
      • 1.4 分辨率的差异
      • 1.5 宽高比的差异
      • 1.6 关于游戏像素的总结
    • 2 色彩:图片的品质
      • 2.1 RGB:颜色根本不存在
        • 2.1.1 归一化量值
      • 2.2 色相、饱和度和色彩值:色温调节、阴影调节和色调调节
        • 2.2.1 色相
        • 2.2.2 饱和度
        • 2.2.3 值
        • 2.2.4 色调、阴影和基调
      • 2.3 位深度
      • 2.4 Alpha通道和遮罩
      • 2.5 图片格式:无损与有损
      • 2.6 伽马与伽马校正
      • 2.7 颜色混合:颜色运算
      • 2.8 图片重采样
    • 3 矢量图片:矢量与栅格图
    • 4 图片纹理:纹理与UV映射
  • 六、网格、操纵和动画
    • 1 网格:四个信息通道
    • 2 几何通道
    • 3 UV映射通道
    • 4 操控通道
    • 5 动画通道
    • 6 使用网格:性能优化
      • 6.1 尽量少用多边形
      • 6.2 优化拓扑
      • 6.3 减少UV映射接缝
      • 6.4 回收纹理空间
      • 6.5 特克塞尔密度
      • 6.6 一致的像素密度
      • 6.7 校准像素密度
      • 6.8 优化模型选择和遮挡
      • 6.9 模块化创建网络
      • 6.10 优化模块化构建
      • 6.11 易扩展的模块化构建
      • 6.12 减少动画关键帧
  • 七、照明与补光
    • 1 阴影的组件
      • 1.1 形式:形状、轮廓和结构
      • 1.2 材质与纹理
      • 1.3 照明
    • 2 照明:直接与间接照明
      • 2.1 直接照明
      • 2.2 间接照明
      • 2.3 照明规则
    • 3 光源
    • 4 计算直接照明与间接照明强度
    • 5 光照绘图:通过纹理照明
    • 6 实时照明:基于顶点与基于像素
    • 7 法向映射
    • 8 渲染方法:正向与延迟
      • 8.1 正向渲染
      • 8.2 延迟渲染
    • 9 学习照明和渲染
  • 八、声音与音乐
    • 1 声音、音乐和音频
      • 1.1 声音
      • 1.2 音乐
      • 1.3 音频
    • 2 文件格式及音频工作流
    • 3 加载和码流
      • 3.1 加载
      • 3.2 码流
    • 4 2D音频对应3D音频
      • 4.1 2D声音
      • 4.2 3D声音
    • 5 音频技巧和诀窍
      • 5.1 谨防过度混合
      • 5.2 图画的替代品
      • 5.3 侵入的音乐
      • 5.4 语音和定位
  • 九、特殊效果和后期处理
    • 1 在游戏中创造特殊效果
    • 2 粒子系统
      • 2.1 粒子
      • 2.2 发射器
      • 2.3 行为
    • 3 粒子性质
      • 3.1 粒子规模
      • 3.2 粒子透明度
      • 3.3 粒子颜色
    • 4 粒子系统摘要
    • 5 手翻书纹理方法
    • 6 程序的几何学
    • 7 带状轨迹
    • 8 后处理
      • 8.1 模糊
      • 8.2 景深
      • 8.3 泛光
      • 8.4 渐淡与渐晕
      • 8.5 染色效果
      • 8.6 动画单帧阴影
      • 8.7 镜头闪光

一、游戏与游戏设计

1 游戏类型与平台

1.1 类型和子类型

video game的类型包括:

  • 射击游戏(FPS)
  • 角色扮演游戏(RPG)
  • 即时战略游戏(RTS)
  • 智力游戏(PUZ)
  • 模拟游戏(EG)
  • 冒险游戏(AG)

子类型指类型中的分类别,用于进一步区分指代所讨论游戏的类型。如即时战略游戏回合制战略游戏都属于战略游戏的子类型。另一种子类型游戏包括第一人称射击游戏第三人称射击游戏2D冒险游戏3D冒险游戏单人角色扮演游戏大型多人网络角色扮演游戏(MMORPG)。

1.2 出品类型

主要涉及制作游戏的开发人员类型。

  • AAA:3A级一流品质游戏。经常制作这类游戏的公司(AAA工作室)有Electronic Arts、Ubisoft、Blizzard、Bethesda、Microsoft Game Studios和Bioware。
  • 独立制作:开发人员自行出资制作游戏,并通过小的发行方或自己出售游戏。

1.3 平台

包括游戏机(如Xbox和PlayStation),计算机(PC和Mac)和移动平台(iPad、iPhone、Android、Windows Phone和Microsoft Surface)。

1.4 图形类型

一种极端的现实派表现是写真图形,其主要目的是尽可能使游戏区别于视频或照片。

与写真图形不同的是绘图,许多游戏都属于这一类型。开发人员旨在通过特定的艺术形式绘制类似于真实世界的图形。

另一种类型是寓意图形,属于这一类型的包括像素画和卡通画。

所有这些类型都是脱离真实世界而绘制的图形,尽管如此,也都是从真实世界捕捉的一些元素。

1.5 交付方式

  • 数字下载:玩家购买游戏后,可立即在开发商网站、发行商网站、应用商店或游戏门户网站在线下载,并在本地电脑安装运行。
  • 基于浏览器:玩家可通过Web浏览器,例如Internet Explorer、Firefox或Google Chome,在线玩游戏,无需将游戏下载到自己的操作系统上运行,直接打开网页即可进入游戏。这类游戏包括大多数Adobe Flash游戏和所有HTML5游戏。

1.6 视角

  • 第一人称视角(FPP):一种将虚拟摄像头与主角眼睛同步的视图同步的视图配置。该虚拟摄像头会随着主要人物在游戏中的移动地点和时间进行相应定位和定向,与眼睛保持一致。常用于射击游戏,形成了一种混合名称即“第一人称射击游戏(FPS)”。
  • 第三人称视角:通常是通过摄像头追逐视角展示世界,其中第三人称摄像头会追随主角,从其顶部、后侧或边侧进行定位。
  • 俯视视角:通常用于GOD游戏或战略游戏中。
  • 自由视角:通常用于识别传统上无人物、世界或空间的益智游戏或纸牌游戏。玩家无需控制游戏视角,只需移动组块、旋转图形、打牌或操控屏幕元素即可。

2 video game剖析

资产
引擎
规则
游戏

上图是视频游戏剖析图。

2.1 引擎

引擎是游戏生命力之所在,是游戏得以运行的根本。是视频游戏最重要的部分,就像心脏之于人,不仅不可或缺,而且是最基本的组成部分。通用性与抽象性是引擎的两个基本特征。

  • 第三方引擎:对于开发商来说,尤其是小型开发商,有充分的资金和技术方面的理由采用他人开发的引擎。首先,这样做可以避免开发人员做重复性工作——即自己开发一个通用的引擎框架,而将精力用在其游戏内容的开发上。其次,许多第三方引擎已经做了bug测试,并受到庞大社区开大人员的支持,可大大节省开发商花在测试与质量保证方面的时间与资源。

2.2 资产

引擎因其通用性和高度抽象性而与游戏中许多其他内容存在很大区别。相反,资产指的是特定性内容,通常指代的是开发人员完成一款游戏需要制作的所有内容。资产是建立在引擎之上的。

包括:

  • 图形
  • 声音
  • 故事
  • 设计
  • 动画
  • 脚本
  • 视频
  • 过场动画
  • 界面构件
  • 乐谱
  • 画外音轨道

另外,资产还包括所有其他特定于每款游戏的内容。鉴于资产的特异性和引擎的通用性,将一些可重复用于多款游戏的资产称为通用资产。

另外,资产是静态的、没有生命力的。它们自己本身无法发挥任何作用,既无智力也无主动性。其中任一组都无法在游戏中独立发挥功效。引擎的一个作用就是智慧地协调这些资产,完成一场合奏,即游戏。

2.3 规则

在游戏开发中“规则”一词是“游戏逻辑”或“核心设计”的同义词,且视频游戏的规则实质等同于棋盘游戏规则。规则是游戏独立且抽象的组成部分,既不属于引擎也不属于资产。

多数游戏都会有如下的规则集:

  • 取胜条件
  • 失败条件
  • 达到取胜条件或失败条件的可接受方法

3 游戏开发阶段

视频游戏通常主要由以下三部分组成:

  • 引擎
  • 资产
  • 规则集

确切地说,开发工作可被视为八个不同阶段(可将每个阶段或模块视为一个处理单元分为输入与输出):

基本设计和头脑风暴
原型设计
完善设计
引擎开发
资产创建
脚本制作
测试与调试
营销与分销

3.1 基本设计与头脑风暴

基本设计和头脑风暴阶段的目的是将具有潜力的初步想法作为输入,然后转化提炼为结构完善的游戏计划,形成输出。这一阶段的关键是回答一个问题“这个游戏是关于什么的?”并用游戏语言给出答案(即类型和子类型、视角、目标受众、平台、图像类型等)。

开发人员将观点转为设计的方法与步骤有很多。设计阶段应用最早的显著方法之一是头脑风暴,一个出现、探索和出现想法的过程,并试图理清这些连接想法可能的走向。开发人员通常会采用蛛网图或思维导图记录下头脑风暴的结果。

除头脑风暴外,开发人员还需利用现有游戏类别(类型、平台等)构建思路,并将其视为需要全面回答的具体设计问题。这些问题包括“该款游戏属于什么类型”、“该游戏的支持平台有哪些”,等等。

设计阶段的目的是编制设计文档,即详细记录开发人员成功制作一款游戏涉及的所有内容。文件的编写应使任何一位技术人员都可理解并想象出和设计人员一样的游戏情景。

3.2 原型设计

原型设计阶段在很大程度上是设计阶段的延伸,是开发人员验证自己想法并测试其是否有问题的阶段。

制作模型的目的在于:

  • 作为可行性研究,使开发人员确定该设计的实施在技术上是否可行,以及经济上是否有回报。
  • 作为故障排查或诊断措施,使开发人员和工程师能够通过实际操作,发现设计阶段未能避免的问题并提出解决方案。

3.3 完善设计

之前的阶段是将设计文档作为制作模型游戏的基础。这一阶段的目的是使程序员和技术人员发现游戏中的潜在技术问题。这一阶段的输出经过编辑的最终设计文档,尽管在某些情况下,需进一步修订而重复这一阶段和之前的阶段。

3.4 引擎开发

引擎开发阶段是最终设计完成后的首个实施阶段。所有纯技术化阶段的目的是将书面设计文字转化为最终可玩的游戏。

引擎开发工作,通常由较大游戏工作室的程序员或被称为“引擎开发人员”的引擎专员来完成。这些开发人员会根据针对引擎的设计文件采用各种技术、工具和算法开发引擎。这一开发阶段会和其他实施阶段同时展开,包括资产创建阶段和脚本制作阶段。

3.5 资产创建

游戏内容包括的资产有图形、声音、视频、脚本、音乐及玩家在玩游戏过程中所体验到的所有其他内容。所以,资产创建阶段是一个创建内容的过程,由美术师、程序员、音乐制作人、导演、配音演员和摄影师等共同参与完成。对于任何团队来说,资产创建阶段是整个游戏开发阶段中持续时间最长的阶段,主要因为游戏有很多资产且资产的创建需要很长时间才能完成。这一阶段与引擎开发和脚本制作阶段同时展开。其最终输出是游戏中包含的最终符合质量要求的所有资产。

3.6 脚本制作

尽管引擎开发需要制作脚本并编写代码,但脚本制作阶段是独立于引擎开发阶段的。而且即使是由相同的程序员完成,脚本制作也是一个被单独分开的阶段。程序员制作引擎可以说是在写引擎代码,其制作引起所用的指令统称为“源代码”。引擎的制作如同在建造基础设施,通常独立于游戏。同样引擎代码也独立于单款游戏,这与资产特定于某款游戏有所不同。与之相反,在脚本制作阶段,程序员写的是整个游戏的代码,用程序设计语言编写特定的游戏规则。将这些规则运用到此前已存在的引擎中,用于游戏过程中的游戏资产调度和控制。这些指令赋予了资产与引擎生命力。这种高级别的代码通常被称为“脚本”,而制作脚本的行为被称为“脚本制作”。这一阶段连同引擎开发和资产创建阶段输出,即可能完成的可玩版视频游戏。“可能完成”是因为这一阶段输出的视频游戏还需要接受后续的测试与调试。

3.7 测试与调试

测试与调试是由程序员和游戏测试员完成的质疑阶段。该阶段将可能完成的游戏输入,并质疑其是否制作完好,即进行一系列预先确定的测试,以观察游戏运行情况。为从技术上检查游戏是否如设计文件中描述的一样,这些测试的设计通常具有很强的针对性。

测试阶段的重点在于尽各种可能寻找游戏缺点——毫无保留地以各种无法预料的方式引起错误或故障。有些失败并不会被视为问题,但有些失败是不可接受的。

这类不可接受的问题被称为bug的问题是需要进行修复的。这些修复工作是由程序员在调试阶段完成的。调试的过程就是发现软件缺陷的过程,同时需要找出原因并进行修复,以避免引起其他问题。测试和调试阶段的输出是可供出售给终端玩家的成品游戏。

3.8 营销与分销

开发的最后阶段是由完全不同的人群完成的,且该阶段需要将成品游戏作为输入。该阶段先由营销人员让玩家对游戏充满渴求,继而由分销人员为其提供游戏满足这种渴求。

4 游戏设计

4.1 游戏设计目的

大多数充满热情的玩家和有戏开发人员都希望对自己所玩的游戏做出审美判断。当他们说“这款游戏真是太棒了!”或“这款游戏真没劲!”时,都希望别人认为其所说的是客观事实,以便有好坏之分。然而,反对者则会说这种说法根本不符合事实,仅代表个人意见而已。对于该反对者来说,设计人员永远不会创作出一款好游戏,因为任何游戏都没有好坏之分。

因此,许多人对游戏设计人员的目的持有更加温和的态度。更多地将其目的视为创作自认为好的游戏,即数据表明多数人喜欢的游戏,可能会吸引许多玩家的游戏或是对于开发商来说具有市场的游戏。

4.2 游戏设计文档

无论游戏设计人员创作游戏的动机是什么,其最基本的任务是编制游戏设计文档(GDD)。GDD的核心目的是以清晰简明、技术上独立的方式充分展现出游戏内容,以供其他游戏开发人员阅读理解。对于开发人员来说,清晰简明的GDD必须包括游戏名称、平台、目标受众及其他需要更加详细的内容。

进一步来说,GDD的编写具有技术独立性,即并非直接进行规范性叙述或提出游戏开发的具体需求。文档需要说明该游戏是什么,而不是如何制作该游戏。

游戏不同,GDD内容必然也不尽相同,但通常都包含文字、图表和插图,以尽可能地将游戏形象化。

4.3 游戏名称、平台和受众

GDD首先要有一个名称——最终游戏名称或为开发过程中指代该游戏而使用的临时名称。

“平台”属于游戏常用术语,指的是可供该游戏成功运行的电脑类型,如PC、Mac、Xbox等。

受众指的是游戏锁定的玩家类型。为了成功开发并营销游戏,开发商和广告商通常会基于统计学将全球玩家分为不同的组别。

4.4 总结与故事

设计文档中第一部分的详细讨论为总结、故事梗概或摘要。其中,设计人员会综述游戏的基本概念及其故事,明确游戏中的基本前提、情景、角色及玩家在游戏中的目标。总结部分通常不超过500字,需涵盖玩家在游戏中的角色,进行互动的时间与地点,以及为成功完成游戏所需要达成的目标。

写完总结部分后,则需要以更加正式全面的方式详述故事及游戏规则,即对总结部分展开论述。如果故事有分支剧情供玩家选择,则需要在该部分给出。设计人员通常会借助图标进行解释说明,以帮助读者更加形象地理解故事情节。更加全面的讨论旨在使读者充分了解游戏故事、目的和规则。

4.5 人物、设备和地点

GDD概述和详述部分旨在适当的采用文字、图像和图表给出清晰的游戏画面。游戏的总体描述包括前提、故事、主要人物、主题和规则。

在精心编制的后续部分,会因游戏不同而存在很大差异,但都会详细列出人物、设备和地点。通常这些元素都会配有相应的彩色黑白概念草图和说明,即“概念创作图”,作为GDD的一部分帮助读者,尤其是美术师则应更好地将讨论细节形象化。

二、游戏软件开发

1 项目管理及依据

游戏开发属于一种软件开发项目,这种项目一般包含一些抽象元素:

项目
专业人士
工具
概念
时间
财务
  • 专业人士(Professionals):拥有游戏开发技能并签约参加全部或部分游戏开发过程中的工作人员。包括程序员、美工、设计师、音效工程师和配音演员等。
  • 工具(Tools):专业人士用来开发游戏的软硬件。包括编程语言(如C++或Java)和资源生成软件(如Photoshop、Illustrator、Maya、3dsMax、Blender等)。
  • 概念和想法(Concepts and ideas):包括游戏设计和游戏创作的宏观愿景。这些帮助专业人士更专注地使用工具,明确地告诉他们将要用工具创作出什么。
  • 时间(Time):项目中地开发者用来实现宏观愿景而被分配的以日、周或月为单位的时间。
  • 财务(Finance):为项目分配的总预算——在规定时间里,为支持项目里全部专业人士使用特定的工具实现设计和想法而花的钱的总数。

具体来说,项目经理的核心目标是保证游戏的实现尽量忠诚于游戏设计,同时最优化地使用资源。

2 通过RAMS创建一个计划

游戏开发项目中的项目经理,最主要的目标之一就是创建一个如何将纸面的游戏设计变为一个可以玩的游戏——最终产品的计划或时间表。这份行动计划通常包括游戏设计文档,每个人在项目中负责工作的细节,他们需要的工具以及可用的时间和预算。此外,计划中会注明工作(全部的编程、图像、音效、声音和其他游戏开发工作)的时间表。

日程表的角色是明确工作执行的顺序和开始结束的时间。通常情况下,时间表是在将总工作量分解成较小的组成模块的过程中产生的(有时被称为块);最终的游戏是由这些模块组成的。每一个模块都会被分配给一个特定的项目组成员,并且该成员应该在一个预定的时间点完成该模块。

如何将工作分解成模块,模块的完成顺序和模块需要提前规划的程度,在不同的开发者和不同的项目间有所不同,帮助开发者做出这种决定的策略被称为“开发方式”。软件行业中游戏开发最流行的两种方式是敏捷模式和瀑布模式。

在分解成模块需考虑的四种通用的抽象原则:(RAMS)

RAWS
可复用性Recyclability
抽象性Abstrantness
简单性Simplicity
模块化Modularity

2.1 可复用性

提高生产效率的一种方式是通过循环利用。更频繁的使用,意味着更强的可复用性。

2.2 抽象性

抽象性,本质上是对特定的对象进行概括,仅仅是程度的不同。对特定场景没有依赖可以自然地视为完全的抽象。

2.3 模块化

模块化原则是解决几乎所有问题的根本。它首先将一个实体作为一个整体考虑,之后根据不同的目的、功能、抽象性和可复用性细分成离散的组成模块。它可以将一个已完成的游戏看成一系列小型任务的结果——将游戏作为设计、图形、编程和音效的总和。

采用模块化原理,各模块的工作可以看作是独立的和可替换的。独立意味着可以通过功能的不同,区别于其他模块。

模块化使一个游戏可以被分成模块,并进一步使每个模块在保持与整体的关系时隐匿实现细节。模块通过专注于达成单一目标而实现这一点。

2.4 简单性

简单性原则提醒模块化过程必须以简单为基础——也就是以化繁为简为目的。

简单性原则,首先应视为一个不让已经复杂的工作变得更加复杂的合理建议;并且应用于保证游戏预期质量的基础上。其次,当复杂解决方案和简单解决方案产出相同结果并且都可以被项目中的成员完成,很难说复杂的那个更好。

3 开发方法

3.1 瀑布模型:线性开发

瀑布模型一直是主流游戏开发中最主要的设计方法。这种模型的名字来源于一个瀑布图,一个传达一种线性的、顺序的、工作按部就班进行的图,如下:
在这里插入图片描述

在开始实现一个游戏之前,开发者要求做出一个全局的设计——一个不可变的、全面描述了游戏中所有需要开发细节的文档。包括受众、摘要、详细细节、人物履历、关卡设计、敌人、武器列表及其他一些有关细节。最好情况下,文档会把所有重要细节都包括进来。这份文档可以被一个团队中的开发者从开始一直使用到结束,以完整地了解最终产品是什么样的。

总体设计完成,在几周甚至几个月的头脑风暴和原型设计讨论之后,项目中的工作就可以计划和执行了。瀑布模型建议:因为设计是最终且不可变的,开发工作应该根据RAMS原则分解成一系列有限的模块。每个模块应该预先指定和声明;并且每一个都应该建立在前一个基础上。

根据这一模型,一个游戏是所有模块的总和,所有的模块都应该被相应的负责人在规定的时间内线性地完成,就像水机械性地、可预测地级联下降,一步步下降到瀑布的底端。每个模块的完成都表示一个新的组件可以加入到一个逐渐被组装起来的更大的整体,但只有到开发末期这个整体才能具体化,开发者才能实际看到他们的工作成果。

瀑布模型的主要特点如下:

  • 前期总体设计
  • 不可改变的设计
  • 机械
  • 可预测
  • 线性
  • 连续

3.2 瀑布模型:优点和缺点

瀑布模型为开发者提供很多优势

  • 当开发按照计划进行时,它为开发者提供提前知道开发什么样软件的舒适和安全感。
  • 它使得开发者可以将工作量化,并且为整个项目和每个相关联的模块估算合理的截止时间。
  • 它将开发工作设想并组织为一种模块化的、顺序的、直观的方式——让开发者预见和理解他们的工作对整体工作的重要性。
  • 它让开发者能够在设计阶段就对开发阶段可能产生的难解决的问题有所预期和准备。

由于瀑布模型不变的天性,相对于软件总在变化的天性产生了一个严重的问题:由于游戏市场中普遍存在的易变性,开发者总是致力于为他们的游戏提供更新更好的内容和功能。他们的目标是提供使用最新技术创新的内容,或者实现竞争对手提供的功能。玩家也期望开发者尽量提供更好的游戏——提供新功能或扩展或者通过改变现有功能以满足已知的需求。

瀑布模型,就如同所看到的,将开发工作视为一条由模块连接而成的链子。链子的第一个环节是基础性的设计,后续的模块随之成为一条顺序的链路。作废、改变或削弱瀑布模型的第一个环节将对后续工作产生灾难性后果。

在最好的情况下,对设计和模块较少的低成本改动可以加入到总体设计,尤其是工程中还没有开始的模块。在不那么好的情况下,更多的时间和资源必须被投入到修改设计中,后果是会让有些之前的工作被废弃,有些模块会被调整,总体来说,项目会比之前预期的更晚完成。在最坏的情况下,也许整个设计需要推倒重来;全部或大部分工作将被废弃;项目也许会从头开始或者被取消。

3.3 敏捷模型:迭代开发

敏捷开发方法是当代游戏开发中比较新颖的一种。“敏捷”这个词强调这种模式使开发者可以敏捷地调整和适应变化的市场、需求和科技。当前形式的敏捷模型常被视为解决瀑布模型所存在的问题——不可变的设计和死板的开发结构的方案。对比被视为线性和有序的瀑布模型,敏捷模型被视为增量,迭代和周期性的。如下:
在这里插入图片描述
敏捷模型总体上将软件开发视为一个进化的过程——游戏作为整体被视为一个经常在增量中完善的半成品。敏捷通过向前看而不是向后看的方式,认为游戏必须不断地调整和扩展以满足不断变化的设计,就如同一个自动制导导弹经常性地变轨以追踪一个移动的目标。每一个循环的目的都是创造一个新的,相比之前所有版本都更加接近于最终设计的版本。

像瀑布模型一样,敏捷模型开始于关于游戏的一个基础想法。但敏捷模型不要求开始就提出一个游戏的总体设计。相较而言,敏捷允许改变和重新审视。它仅仅要求游戏被充分地设计以满足为每一次增量而创造一个可以工作的游戏。在一个为期5周或6周的周期之后,“可以工作的”意味着可以被玩起来或者被测试。敏捷并不视游戏为一个在某个开发时间点,当所有的模块都到位之后被拼凑起来的大型实体,而将其视为某种只要有可能就被拼凑起来的东西,即便这种东西是非常基本的或仅仅是一个原型。敏捷的每个阶段或增量(循环)开发的产出不仅仅是拼图的一部分,而是整个拼图本身,只不过更加细化和扩展,并在后续版本中持续细化和扩展。从这种特定角度看,软件是在开发周期中逐渐演进的。

如上所述,开发开始于第一个增量并持续5~6周,一个增量中的工作通常按照一种模块化的方式完成——一个小型化的瀑布模式。最终,一个可以使用的框架根据设计被创造出来。这个最初的游戏或者原型很有可能和预期的最终产品想去甚远,因为游戏通常选哟5 ~ 6周甚至更长时间并经过很多个增量才能开发完成。但这些对于敏捷模型都不是问题,因为整个过程不停重复并持续循环。在下一次循环中,更多的设计细节即存模型并在合适的情况下添加更多的新功能。之后开发将会持续几周并根据细化的设计产生一个可以使用的软件,之后此过程会又一次被重复,建立在之前基础上的另一个设计周期,更多的开发工作,更加的细化,之后再重复。实际上,开发周期的迭代一直持续,每一个周期都会产生一个更新、更细化的软件的增量或“种类”。直到最后,经过一次次地递进,目标达成,项目完成。者即是敏捷开发地本质。

3.4 敏捷开发:优点和缺点

灵活的增量和迭代特性是开发人员和开发过程具有瀑布模型不可能达到的灵活性和空间。避免一个大而不变的总体设计,意味着开发者可以让软件适应一个需要根据不断变化的市场环境。

敏捷本身的主要缺点与它的短视和开放性直接有关——设计被减少到最低限度,以便开发者能够在短时间内,在需要的情况下对软件做出改动。

首先,针对短期目标而不是长期目标进行开发,容易使开发者对长期目标缺乏合理认识,导致项目没有实质性进展。也就是说,开发者总是疲于应对市场环境变化和竞争对手,而没有在实际上使项目由任何显著的进展。

其次,没有总体计划中可以给出的明确的行动计划和方向,容易使项目在不停或过早演变中偏离方向,并且由于这些都不可量化也就难估算其代价。没有一个明确的预计截止时间,开发者可能会一直在循环中添加新功能,优化现有功能和对竞争对手产品做出反应,从来也不能达到一个明确的结束点。另外,也有可能在某些理想或最优的时间点被停止。为此类项目做预算是一件很难的事情

3.5 开发方法选择

通过公平地考虑某种方法和项目有关地基于技术、经济、逻辑因素的优点和缺点来选择一种开发方法。

  • 所有固定不变或者可以预先知道内容的游戏使用瀑布模型(或它的变种),此其他模型更加合理和适用。这样的游戏通常包括单人游戏,叙事游戏,如冒险游戏或者第一人称射击游戏;横向滚屏游戏;休闲游戏,例如隐藏物品游戏;益智游戏,例如俄罗斯方块或宝石迷阵。

  • 在线游戏、多人游戏、社交游戏、脸书游戏使用敏捷模型(或它的变种),一般来说,对于所有基于用户需求或市场环境内容经常变化,功能经常添加的游戏使用敏捷模型。这种游戏包括在线RPG游戏、多人战略游戏和多人游戏。对用户能够使用地图编辑器或修改工具创造内容的游戏,例如模拟游戏、第一人称或第三人称动作游戏也使用敏捷模型或者它的变种。

  • 不要惧怕标新立异

    可以在合适的情况下合并敏捷和瀑布方法,合并或修改其他方法或发明全新的开发方法。开发方法被发明主要目的是让软件开发更简单,安全和高效。在使用各种变种或替代品时无需犹豫,只要让它们可能产生更好地结果就可以放心使用。

4 发布周期

当一个游戏逐渐完成,被开发者常遇到的一些特征:

  • 游戏将会完成到虽未经优化、修饰、打磨但仍可玩的体验程度。
  • 游戏很有可能包含错误、过失、疏忽、不一致、不工作或让人感到不对的地方。不是因为计算机、工具、软件或开发方法中的问题,而仅仅是因为操作人员总体上容易犯错。
  • 游戏将会被审查、试玩、检查、调试和通过质量保证过程检查错误。
  • 游戏将会基于这些测试、检查和观察结果被调整、修正、修复和改动。

这些开发后期的行动和细节可以被更仔细地考虑,并总结为一系列离散且通用的开发阶段,称为“发布周期”。

软件发布周期:

Pre-Alpha版
Alpha版
Beta版
发行版
最终版

4.1 技术预览版本

技术预览版本是一个代表发布周期前所有开发阶段的版本总称,包括除错,测试,发布阶段前的所有版本。因此,技术预览版本代表了设计,编码,图像音频资源生成,甚至更早期程序员在编码时进行的非正式测试。所以,技术预览版本通常用来描述开发过程中耗时最长,工作量最大,人员参与最多的部分。开发的各个阶段通常不会如此精确地标定,以至于可以明确地识别出何时一个阶段结束,另一个开始,特别是在敏捷模型中。总体来讲,当游戏已经处于一个基本完成地状态,技术预览版本阶段即认为已经完成。

4.2 预览版本

在这个开发阶段,第一次有了可以在实际意义上用来测试的游戏。也就是说,游戏将从总体上看成一个接近最终形态的完整游戏,并真实地反应最终产品。在这一阶段中,程序员和其他一些内部开发人员将主要通过白盒测试辅以黑盒测试方法对软件进行测试

白盒测试需要测试人员不以游戏玩家而是以开发者的角度,不将游戏看成一个内容和功能全部不可见的黑盒子,而是从一个懂得内部工作原理的开发者角度看问题。

而黑盒测试是与白盒测试相对的,黑盒测试可以被开发者之外的其他人执行。这种测试不需要对软件代码有深入的了解用户测试通常是一种常见的黑盒测试。

4.3 用户测试版本

用户测试版本的开发过程标志着软件可以对普通测试人员开放,这些人包括项目上的非开发人员。他们的目标就是将游戏的极致发挥出来,测试所有功能,尽其所能通过合理的手段将游戏玩出问题。目标不仅仅是找到问题,并且还包括识别和记录所有问题产生的条件。理想情况下,对每个问题,测试人员将提供一组清楚并精确的指令,让任何在同样条件下的用户可以在自己的系统中按部就搬地复现问题。这样一个包含细节和复现步骤的问题列表会交给程序员和其他项目中的开发者,在不引入新问题的前提下问题解决掉。在此之后会发布新版本或软件补丁用来更新游戏程序。

4.4 候选发布版本

候选发布版本是一个包含了所有问题被修复和已解决的软件版本,是开发者推荐的用于最终测试的产品。候选发布版本阶段标志着测试的最后一个阶段,也是开发者消除任何可能问题和错误的最后一个机会。候选发布版本阶段与用户测试阶段类似

4.5 最终版本

一个完成的游戏仅仅表示该游戏的开发进入了最终版本阶段。最终版本阶段描述了一个开发中游戏可以认为已经完成的阶段。游戏在这一阶段已经离开了开发者进入到发行者、制作人、市场开拓人员,以及任何参与将游戏送到客户中的人手中。

三、游戏编程

1 深度型程序开发

程序的功能是创造各种动作以使各种元素的集合赋予生命,而非静态的、相互毫无关系的元素集合。

如下图所示(基于可运行的程序的游戏集合):

基础:引擎.代码.脚本
元素:图片.声音.数据库等
游戏:程序+元素

程序在很大程度上是通过程序语言来定义视频游戏如何运作的。程序员的作用就是用程序设计语言编写这些指令,计算机的作用就是不用思考地读取和执行这些指令。

在游戏编程中,主要有3种程序语言。

  • 编码
  • 脚本
  • 可视化脚本

1.1 编码

编码是这3种中最主要和最直接的,也正因如此,才创建游戏引擎。术语“编码”通常认为是使用可编译语言进行的编码,而不是使用解释语言或者脚本语言进行的编码。所以编码通常指程序员编写的文本格式的指令,这些指令是使用单词或者数学表达式来控制程序的运行。编译器会把这些表达式(代码或者源代码)转换成简单的电脑可执行语言。如下图所示(代码被编译成可执行的形式),一旦代码被编译,电脑就会以尽可能快的速度运行并执行这些表达式。

编程
编译
可执行程序

使用可编译语言来编码的一个主要优点是高效。可编译语言会产生可以在电脑上运行的简单高效的代码。所以游戏开发者通常会开发出游戏引擎和其他基本函数库,以保证游戏所用的基础函数库能够尽可能简洁高效地运行。

在游戏开发过程中,语言通常使用C++、汇编、C#、OCC和Java等。用这些语言编写代码通常都使用集成开发环境(IDE)软件,例如Microsoft Visual Statio、Apple Xcode或者Eclipse IDE

1.2 脚本

编码主要和编译语言有关。为提高游戏的运行速度和性能,程序员可以选择不同程序语言用于开发游戏引擎或者基础函数库。通常,这些语言用于开发游戏中重要的部分和体系结构类型相关的部分,包括:

  • 渲染器:负责在屏幕上绘制图形。
  • 语音基础框架:负责声音可以输出到扬声器上。
  • 错误处理系统:如果发生错误,这些错误会被记录下来并打印到人类可读的文本文件中。

从抽象和总体上看,在使用可编译语言开发的游戏引擎中,包含很多潜在特征中的3种主要特征。除了几乎所有游戏都需要的一些基本原则,还要创建很多游戏指定的逻辑

  • 特定敌人的智力水平。
  • 赢得游戏或者在游戏中失败的条件。
  • 搜集的特定动作和武器,以及使用它们的特定说明。

通常用脚本而不是编码来定义逻辑。

编写脚本可以从各种角度在Microsoft Word里编写宏或者在Microsoft Excel里写公式,尽管Word和Excel本身也是由程序员用可编译语言写的,相比之下,宏是使用这些程序的用户在之后写的。用户不需要了解这些程序是如何被编写出来的,就可以创建和运行宏。程序代码是闭源的,但这不妨碍创建用于控制这些程序的宏(脚本),如下图示。这就让开发者在不开源或用户也没必要知道技术细节的情况下,可以创建这些游戏,并且也使其他人可以定制这些游戏。

可执行程序
脚本编程

基于脚本的游戏,和代码游戏、宏一样,也是由文本形式书写的指令组成,也使用了数学表达式和编码中使用的一样的编程语言。

编程游戏和脚本指令的本质区别是计算机如何理解和处理这些被写下的指令。可编译的代码是可以被编译器优化和提高运行效率的,相反,脚本代码在通常意义上无需编译和优化,是直接在电脑上运行的,就像word或excel的宏编写完成后直接运行一样。归根结底,脚本程序让开发者也能和编码一样灵活,不过,脚本由于无法优化,所以在性能上不如可编译程序。因此,脚本语言运行通常会比可编译语言在机器处理周期和时间上要慢。

但是,脚本在描述程序的独有逻辑上要比可编译语言有明显独特的优势。首先,它可以让非引擎开发人员编写程序独有的逻辑,并且不需要知道引擎是如何实现和工作的情况下,就可以实现对引擎的控制。这意味着,逻辑程序员不必由引擎开发人员担任。而且,开发工作可以分为几个部分,然后由不同的人进行协同开发。这通常是很有用的,其中一点就是它允许第三方的开发者,例如Unity Technologies或者Epic Games,来开发并进行市场运作可以供其他开发者使用的、在代码上相近的引擎,通常这样的引擎做成了产品,被称为中间件产品。开发者可以购买这些产品,然后基于这些引擎开发自己的游戏,并且这些游戏可以通过脚本控制和定制。脚本的第二个优势是方便性。因为开发人员可以通过修改脚本达到修改游戏逻辑的目的。他们不需要等待漫长的测试过程,因为脚本不需要编译和优化。所以程序逻辑可以通过脚本很快实现及测试、交付程序。

通常脚本语言使用在包括C#、JavaScript、Lua、Python和Ruby等语言的开发游戏中。

1.3 可视化脚本

编码通常指使用可编程语言进行游戏引擎的基础开发。相反,脚本是一种不依赖于具体引擎的以宏形式呈现的高级形式的编码,通常用来定义程序的逻辑或指定程序的规则。可视化脚本是在简化程序开发过程或让非程序员也参与开发的过程中越来越受欢迎的开发方式。和脚本类似,可视化脚本用于定义程序的逻辑。在某种情况下它用于实现和使脚本标准化;在某些情况下,可视化脚本可以用来整个地替代脚本

可视化脚本通过可视化地或是图表的方式,通过拖拽编辑器来进行。可视化编辑器通常看上去就像创建图表的工具箱,通过它,程序员可以在图表中添加、链接和排列模块组装宏或脚本。其目的就是通过可视化编辑模块的方式来编写程序,以保证程序按照预定的设想运行。

一些比较著名的游戏引擎以支持可视化脚本编辑器而出名,包括CryEngine、Unreal Engine、Unity Engine和其他一些引擎,例如Construct2和Stencyl。在以内容敏感为主导的游戏开发过程中,可视化脚本得到了广泛的使用。

2 开发游戏:关于DIY引擎和第三方引擎

DIY引擎的优缺点:

  • 市场化。一个新生的适合市场的引擎不仅仅能在内部开发游戏使用,也可以作为潜在的产品提供给其他开发者使用。
  • 灵活性。开发者也许会创造新的、带有实验性质的游戏,这些游戏也许带有特定的不通用特征,通常市面上的引擎不能很好地支持这些特征。
  • 版权。每一台安装了引擎的工作站都要购买版权,某种情况下DIY引擎是更经济的选择。
  • 平台支持。游戏引擎支持一系列的平台,包含PC、MAC、控制台、移动平台等。开发人员在开发一款游戏的时候通常会有一个或者多个目标平台。通常,开发者所设想的目标平台会和引擎支持的平台出现不匹配的情况,这种不匹配会使开发者丰富DIY引擎的种类,以使游戏能支持全系列的目标平台。

第三方引擎的优缺点:

  • 开发速度。使用第三方引擎通常会节省开发DIY引擎的时间和资源,而引擎又是开发者所必备的基础和前提。

  • 稳定性。口碑好的引擎是经过很长时间由很多开发者共同开发出来的,并且通常会由大批的社区用户群在继续使用,同时也在不断地测试完善。会使这些引擎变得很稳定。

  • 可行性。第三方引擎让小团队找到了可以开发出推向市场的游戏的方法。

  • 文档及支持。很多引擎在发布的时候,也同时发布对应的文档及帮助文件,用来解释引擎如何作为一个游戏开发工具来使用,文档虽然不是一种很方便的方式,但是对于追求DIY路径的开发者来说,足够便宜。

3 游戏开发范例

开发一款游戏的目的创造一个虚拟世界,这项工作可以细分为3个主要步骤

  • 定义所有出现和即将出现在游戏世界中的任何东西
  • 在游戏时间中创建一个时间流
  • 定义所有存在的东西是如何随着时间而改变的

游戏开发主要的工作就是通过编程语言控制游戏如何执行。通常,开发就是控制事件、对象、人物角色和游戏里所有成员协同工作完成游戏所规定的任务

编程语言是由各种指令组成的,编程语言的局限性决定了它能做的事情的局限性。对于程序员来说,选择了适合自己的编程语言才能更好地控制游戏中的对象,程序语言提供了让游戏更容易理解的语法手段,例如声明、定义和描述对象的方式

在编程开发中,描述客观存在的事物的思维成为程序设计论。在游戏开发中,有这种程序设计论,面向对象和面向过程的程序设计论。这些程序设计论并非是在计算机程序中唯一的或者指定的。

3.1 面向对象

面向对象认为世界是由各种离散的、清晰的、每一个彼此相互独立的对象组成的集合。为了描述这些特殊的对象,人们定义了抽象对象的集合或者对象的类,称之为模板,这些模板适用于具有相似特征的一类对象。因此使用类和类的实例化来这个世界,类实例化后用来描述不同特征的术语称为属性,每一种特征都定义为一个不同的属性,类可以有一个或多个属性,而类在方法上也有区别。

3.2 深入了解面向对象

面向对象理论把事物分解为类、对象、属性和方法的观点类看待世界。但是,这个模型忽略了——事物间的关系。为了反应这种关系,面向对象模型引入了继承、父类、子类等概念。

3.3 面向部分设计方法论

面向对象理论是一种解决方案、用类、对象、属性、方法以及描述它们之间的关系的继承的概念等术语来描述、分类实体。面对组件(CBD)方法论,很大程度上依赖于类,属性,方法和继承等经典的想法。所以,看作是和面向对象截然不同的解决方案,也有些人看作是面向对象的补充

面向组件鼓励人们不用静态的和具体的,相反,它鼓励人们把这些都当作是运动的,在不停地变化着,运动、过程和做某件事地状态等来认识和思考事物。它认为每一个独立的具有自己独特功能的部分共同组成了一个网络,而这些不同的部分又是不可分割地互相连接在一起地一个完整的工作集的一部分

就像人一样,有自己的智力,有自己的意识,也可以思考和推理。值得一提的是,它有种特殊的、只有它才具有的功能,演绎魅力的能力,有了这种能力,它能够演绎出各种迷人的效果,再配合其他的部分,会创造出令人叹为观止的惊人效果,这称为基于组件的设计方法

基于组件的设计方法在描述世界上的事物变化的时候特别方便。也许有一天它会丧失这种产生魅力的能力,该组件也会从它的组成网络中去掉。推测以后它会失去自己的智力和头脑,甚至会语无伦次,在这种情况下它会失去智力部分,最后也许会死掉。在那一天,它的所有部分都会离开它,它什么也没剩下,网络的部分解体也就意味着该网络将不复存在。同时,死亡也意味着新的开始,这就称为组件论。在基于组件的设计方法中,什么都是由部分组成的。

3.4 OO与CBD

和面向对象设计方法论相比,面向组件的设计方法论提供了吸引力和直观感很强的解决方案,让人觉得容易上手及会产生立竿见影的效果。在游戏里的对象相关的根本和本质上的改变被认为是相关部分的种类发生了改变,通常这些部分一起组成了对象。基于组件的改变其实就是事物存在方式的改变。

因此,正是基于组件的设计方法有着自己的特性,所以在游戏开发过程中更有用和更重要,对象和实体经常变化的游戏更是如此。但是并不意味着面向部分的设计方法论可以完全替代基于面向对象的设计方法论。问题依旧在于部分还是作为基础存在的。在面向对象术语中,经常这么说,带有自己属性和方法的类。类似地,部分也通常被认为可以像类一样,通过其各种部分的有机解决组成更高级和更复杂的对象。

在游戏开发过程中,通常在这些方面会同时使用面向对象和面向组件两种方法论,面向对象方法论通常用在开发基础类或者对象上,因为相对基于部分的更容易实现。这种方式被首先用在构建部分生存环境上。如果部分确定后,相对于面向对象方法论,由于在描述时间的推移而发生的过程方面的优势,面向组件的方法论就会用来构建和定义游戏中存在的所有剩余的对象和元素。

4 时间、事件和动作

面向对象和面向组件的方法论都依赖于时间这个概念,也就是说不需要参考时间,使用OO或者CBD也是可以定义事物的。这并不是说,这两种方法在关于时间问题上都是无能为力的,相反,在任何时候,它们都能用来描述在任何时候的任何事物。在面向对象设计方法里,事物的任何时间的状态都能通过属性和方法来描述。在面向组件的设计方法论里,这被称为组件。

4.1 时间

基于时间的对象改变称为“动画”,没有时间的概念,就不会有动画。

对于一个开发者来说,需要以一致性和系统性的方式来优先考虑,在视频游戏开发过程中时间是如何展现和流逝的。

以系统的方式展现时间可以通过在数字上面做一下显示和算术上的操作。目标是让开发者在游戏中可以精确地计算时间,例如从某一特定的时间包括游戏开始的时间,到现在已经过去了多久,在选中的两个时间点上有何不同。这些使开发者在一个清晰的框架下,游戏开始的时候就可以发起和结束一个事件。而且,以延续的方式来展示时间,建立起一个基础的计算时间的方式,可以在数字上计算时间,以便于在基础单位改变的时候也能进行比较。描述时间的方式通常是跨系统和跨平台的。这通常认为是保证不同系统的玩家都能享受到事件的体验和发生的重要因素。为了达到此目的,时间通常用秒或者毫秒来计算,而不是用帧的方式。

基于帧的解决方案会错误地假设在所有的系统下帧率(每秒的帧数)都是一致的,甚至在同样的系统下每一秒的帧率也是一致的。其实,帧率在不同的系统下是不同的,即使在一样的系统下,由于硬件和软件性能的变动,也会产生不一致。基于帧的游戏,在高性能的PC上播放完3000帧所需要的时间,比在只有性能一半的机器上运行完所需要的时间要少一半,其他时间也是如此。这会导致不同系统下的玩家即便在同一时刻开始玩游戏,所感受到的游戏体验也是完全不同的。

系统时钟的秒或者毫秒来计量时间,是独立于硬件存在的,因为秒相对于其他的方式是绝对不变的。在所有系统中,针对所有的人、在所有的时间,一秒都是一样长的,所以大多数的游戏开发者都是从游戏开始使用秒或者秒以下的单位来计量时间的。

注意:除了时间的计量之外,开发者会在引擎中通过编码来合理控制FBS(Frame Per Second,每秒所运行的帧数)的性能,至少在FPS比期望高的情况下是这样的。这通常通过丢帧的方式来实现,所谓丢帧就是数一下每秒的帧数,在超过希望的FPS到达的帧数后,会舍弃后面的帧,然后等着下一秒开始处理下一帧。

4.2 事件和动作

对象的状态是时刻改变着的,不见得是以一种方式或者在某一特定的时间里。在时间和对象之间有一种特殊的关系,所以对象总是在特定的时间以特定的方式在改变着。

时间和对象的这种关系引起了对象在特定时间的特定改变,通常这种都有通用的结构或者模式。这种形式就是它们区别于其他事物的本质特性。一般会这样描述:如果发生了X,那么就做Y。描述的前半部分通常认为是“事件”,描述的后半部分通常认为是“动作”。事件通常是游戏世界里重要的事情发生时候的一个通知或者一个时刻。与此同时,动作就是由于事件的发生引起的特定游戏世界里的改变。

由于涉及事件和动作,这类编程有时候称为“事件驱动编程 ”。主要目标就是让这个世界发生点什么。这是游戏编码或者编写脚本中的重要方法,是驱动游戏前进的动力。应用于游戏开发的事件驱动编码,主要任务就是识别不仅仅是简单的事件和动作,而且能识别所有可能的动作和所有可能的事件,无论这些事件根据玩家的选择在游戏里是否发生。开发者的任务就是实现所有动作的时间内,无论任何可能的事件发生,游戏都会作出反应。

5 错误、测试和调试

开发游戏或者游戏编码的工作包含3个主要步骤:

  • 首先,开发者必须定义虚拟世界里存在的所有事物。
  • 其次,开发者必须建立起来一个一致的时间系统。
  • 最后,开发者必须建立一套时间规则或者一套对象和时间的关系,该关系决定了某一特定的对象会经历特定改变的时间和环境。

成功认识到这3步是一个程序员的工作内容,然后使用一种语言和逻辑的规则作为唯一的工具去实现。但是,在执行这个工作时,肯定是会犯错误的,这些错误会是下列两类中的一类:

  • 语法错误。程序员在写程序时发生输入错误、弗洛伊德错误、或者是混淆了标点符号,就会发生语法错误。错误会被计算机判定为无意义的表达式。这些错误大致有拼写错误、标点符号错误、丢单词或者缺少语句计算机通常会自动检测并提示语法错误。
  • 逻辑错误。逻辑错误比语法错误更麻烦,更难解决。程序在语法上是正确的,但是在因果关系或者逻辑上是错误的时候,就会发生逻辑错误。逻辑错误会引起很多问题,这些问题通常都不易发现。不像语法错误,逻辑错误会隐藏自己,到游戏最终发现,或者在最终用户(玩家)那里发现。

从逻辑角度考虑,游戏里是可能存在问题的,所以开发人员进行了严格的测试,发现问题是保证质量的一部分,称之为“调试”,调试的目的就是发现问题,然后找出它们出现的原因。基于这样的观点,程序员在不断地解决问题。调试过程中也伴随着没有发现问题的潜在风险。

四、游戏数学

现实世界和虚拟世界共同点

  • 两个世界中充满了不同的存在于时间和空间中的元素,如人物、武器、交通工具和国家等。这些元素有各种属性,包括颜色、大小、位置、方向和其他属性。
  • 两个世界中的各种元素互相关联。这些关联被一些可以解释的规则所制约,包括重力、惯性和因果关系。

1 数字的语言

经得起数学考验的名词:

  • 位置
  • 大小
  • 规模
  • 颜色
  • 方位
  • 旋转
  • 方向
  • 速度

游戏开发者主要的工作之一就是将这些常识性语句翻译成由这些元素构成的准确的数学语言。

2 坐标系

当坐标系用于视频游戏时,是一个使开发者可以将数字赋予每个物体位置和大小的数学结构或系统。坐标系有两类,2D(二维)和3D(三维),取决于游戏是二维还是三维。

3 坐标系基础

2D坐标系由贯穿整个游戏世界的两条相交直线组成(3D坐标系是3条),从一头到另一头。这些线被称为世界的轴。标注在相交的位置称为原点。原点表示坐标系中所有丈量距离的起始位置。每个轴都从原点分成同样长度的小段来创造一个有单位的系统,统称为世界单位。

丈量单位建立之后,坐标系中任何一点都能明确地定位。任何空间中的点都可以用(X,Y)或者(X,Y,Z)来表示相对于原点的偏移。

4 全局与局部坐标系

坐标系提供一种通过坐标描述的相对于原点的偏移,明确并系统地确定物体在游戏世界中的位置。物体的高度和宽度(3D中的深度)可以通过坐标数学计算或估计。基于这一理念,游戏开发者依赖两种不同的坐标系确定物体的大小和位置:全局和局部坐标系。这并不是两种互斥的系统,仅仅是在不同的情况下,以不同的术语确定位置和大小。两者的不同点是原点位置的不同。

全局坐标系中,坐标通过全局原点,作为游戏世界中心的点来测量。通过这一点测量的位置可以存在于游戏世界中的任何一点。全局坐标系的作用是标明某个物体或事件在世界中的绝对位置。

局部空间的原点有时称为物体中心、锚点或中枢。

游戏开发者在描述一个关卡中的物体位置时,既用全局又用局部空间坐标系。

5 位置、方位和尺寸

一个物体的位置和它在游戏世界中的外观,从根本上可以视为三个关键且独立的有关于该物体的属性。

  • 位置。物体的位置是它在游戏世界中,全局空间中的绝对位置或局部空间中的相对位置的坐标。物体的位置是该物体的中心或中枢的绝对坐标。
  • 方向。物体的方位是在游戏世界中其所朝向的方向。它明确了物体是朝上还是朝下,是在这里还是在那里。方位独立于位置,这两种属性中的任何一种可以在不影响另外一个的情况下改变。方向可以从数学上通过一些不同的数字表达,包括欧拉角,矩阵,弧度和四元数。
  • 尺寸。物体的尺寸影响其以宽度、高度、深度为单位的大小或密度。它在数学上以十进制数的形式出现,并作为一个乘数——一个通过物体的高度、宽度、深度乘以缩放物体的因子。

所有这3种属性,位置,方向和尺寸,确定了物体在游戏世界中的放置方式,并影响其如何对游戏用户展现。

6 变换

在视频游戏中,变换指随着时间推移,物体的位置、方向、尺寸的任意组合的改变。典型的视频游戏在每一帧里都会出现几十、几百、甚至几千次的变换。

变换由3个细分过程构成。

  • 位移。指移动某个物体,或改变其位置的过程。
  • 旋转。指转动某个物体,或改变其方向的过程。
  • 缩放。指拉伸或收缩某个物体,或改变其尺寸的过程。

在游戏中对某个物体应用这3个过程中的其中1个或多个,便形成了变换(或单一变换)。

变换可以用数学方式来表达,也就是,使很多不同方式组成一种数据结构。一种方式是通过跟踪3类不同的数字,来表达位移,旋转或缩放。另一种是将所有的变换数据编码,并保存在一种称为矩阵的新的混合型数字里面。

6.1 位移

位移可以表示为一个标明物体相对于当前位置的移动。

6.2 旋转

旋转可以在2D中表示为欧拉角或角度。360°表示一个完整的旋转或一圈;180°是半圈;90°是四分之一圈;0°是完全没有旋转。在3D空间,旋转需要用3个数字表示角度,因为一个物体可以像很多方向旋转。物体可以根据X轴旋转(俯仰),可以根据Y轴旋转(偏航),也可以根据Z轴旋转(翻滚)

6.3 缩放

如之前提到的,缩放可以用十进制数表达。因子为1时使物体保持不变;因子为2时,大小将翻倍;因子为0.5时,大小将减半。2D空间中,两个不同的十进制数用来表示尺寸中的高和宽(X,Y)3D空间中,3个十进制数用来表示物体相对于其每一个局部轴尺寸的高度,宽度和深度(X,Y,Z)

缩放是基于每个轴定义的。对于物体的每一个轴都有一个独特的缩放因子。可以分别在每个轴上拉伸或收缩物体。也就是说,任何缩放行为都可以是下面两种形式中的一种:

  • 一致性缩放。最常见的缩放形式,确保物体在所有轴上都使用同一个因子被拉伸或收缩
  • **非一致性缩放。**指所有其他形式的缩放。至少有一个轴上的因子是不同的。

一致性缩放总是使物体在保持原有比例前提下放大或缩小,非一致性缩放在使物体在一个维度上明显变大或变小的前提下不会保持原有的比例。

6.4 矩阵变换

矩阵结构可以用来编码变换数据

变换矩阵,本质上是由4×4网格构成的十进制数字表示的数据结构。这些数字被系统性地放进行和列中,整个结构被大括号环绕。这些数字可以编码一个物体所有的变换(位移,旋转,缩放),如同普通的坐标和十进制数可以分别表示一样。

矩阵相对于标准的方法有两个优势

  • 单一的结构而非多重结构。它是一种将相关变换信息合并为一个独立结构的方法。
  • 矩阵经过巧妙地配置可以适用于各种运算,它可以被另外一个矩阵相乘,也可以乘以一个小数或一个标量。
6.4.1 矩阵乘法

矩阵相乘是指将两个或多个变换叠加在一起。例如,加入一个游戏角色,比如索尼克或者马里奥做出一个奔跑和跳跃的合并动作来越过两个移动平台中间的深渊。奔跑和跳跃的合并和两种主要的变换有关:一个在X轴上,当角色向前跑时;另一个在Y轴上,当角色跳跃的时候。矩阵乘法可以通过将这两个变换合并成一个结构来解决这个问题。矩阵A可以将奔跑编码;矩阵B可以将跳跃编码;这两个矩阵通过相乘合并后产生矩阵C——奔跑和跳跃的编码。

简单来讲,标量矩阵乘法用来缩放矩阵。矩阵A可以编码一个180°的旋转,通过将此矩阵和0.5这个小数相乘产生一个新的一半变换的矩阵B,也就是90°旋转。

7 向量:方向和位移

7.1 Vector,什么是向量

向量是一种用来表示方向的数学结构。如果在一张纸上画一条任意方向,任意长度的直线,再在任何一端画一个箭头,使其指出那个方向,就成功地画出了一个向量。方向从本质上来讲,可以通过向量来尝试用数学方法来捕获。向量的表示方法和坐标完全一致,并且有2D和3D版本。

向量和坐标不同,虽然它们以同样的基本形式或结构出现。坐标总是标明坐标空间中点和原点之间的距离。相比之下,向量并不表示坐标系中任何特定的点或位置,向量编码一个方向。向量总是假设开始于原点,其X、Y、Z分量总是标明从原点出发的箭头指向的那个点

在这个方向之外,向量有一个量级。向量的量级是以单位标明的斜线的长度——那条可以画出的从原点直接到箭头指出的点的线。这条线相当于直角三角形的斜边,表示了在特定的方向上需要移动的距离。然而,向量的量级通常可以忽略——通常在仅仅关心方向的情况下。

7.2 向量加法和乘法

如同矩阵和其他数学结构,向量可以通过数学运算合并(加、减、乘、除)并产生新的相对于原有向量有意义的向量。

向量的加法是将两个向量(S序列)相加,将所有X分量、Y分量和Z分量相加。相加的结果是一个新的表示从原点到S序列中最后一个向量的最短路径的向量。向量相加相当于将所有向量都平铺在一起,前一个向量的头连接下一个向量的尾。它将序列S中的所有向量都视为一系列的必须从头到尾被执行的前行或绕行标志。达到序列中最后一个向量后,一条笔直的斜线可以连接到起始点。这条线表示输出向量相加后的结果

向量的乘法有两种形态:向量-向量乘法向量-标量乘法,后者将在这里讨论。可以将向量-标量乘法想象成缩放向量的过程。如同十进制数可以用来在局部空间轴上缩放物体的大小一样。标量1(向量×1)保持向量的量级和方向。标量0.5(向量×0.5)将向量的量级减半,但保持方向。标量2(向量×2)将向量的量级翻倍,同时保持方向。标量-1(向量×-1)保持向量的量级,同时将方向取反。

7.3 向量归一化

到目前为止,讨论过的向量都有一个方向和量级或长度。如果预先知道方向和距离,毫无疑问这是一个非常有用的结构。然而,在游戏中的一些情况,例如玩家沿着一个走廊跑动时,仅仅关心方向,而不是距离。在这种情况下,希望一个物体按照特定的速度和方向移动一个未知的距离。这个距离是“将要确定的”,或者保持运动状态直到决定让该物体停止。

在这些情况下,希望从向量中去除量级,或者改变该向量,使其量级无意义,就必须要执行归一化过程。归一化是将一个标准的有方向和量级的向量转换成一个新的拥有同样方向,但量级总是1的向量的运算过程。这个称为**“单位向量”**的向量很特殊,因为它仅仅代表方向。单位向量可以很容易通过向量-标量乘法赋予量级。

7.4 向量点积

在处理向量时,开发者经常需要知道两个向量的夹角或需要旋转的角度

两个向量间的角度可以基于一个称为**“点积”的数字计算。点积也可称为标量积或内积**,点积是可以通过两个向量进行一系列数学运算得出的标量(一个十进制数)。这个数字并不给出两个向量间的角度,但它可以表示某种相对于该角度的关系。一旦点积生成,可以将这个数字代入反三角函数acos(反余弦)并最终得出两个向量间的角度。

8 解决速度、距离和时间的问题

给出物体O的位置、方向和速度,一个通用的计算在时间T时刻,物体O的位置的方程可描述为:
新 位 置 = 当 前 位 置 + ( 归 一 化 方 向 × 速 度 × 时 间 ) 新位置 = 当前位置 + (归一化方向×速度×时间) =+(××)

五、图形、像素和色彩

1 像素:图形的最小单位

图形是指游戏中所有可见的事物:图片、动画和视频。它们经过PC,游戏机或移动设备的处理和操作,然后显示在屏幕上被游戏玩家看到。

电脑通过一个系统把视觉信息转化为数字数据。这种系统的基本单元就是像素,是图片元素的简称

注:像素有各种各样的形状和大小,而在视频游戏中最常见的是方形像素

电脑把显示屏幕的长和宽划分成相等大小的正方形小格儿,每一个正方形小格就定义为像素。因而,显示屏平面呈现出网格状的像素点。网格中的每一个像素都有着一个单独的纯色。通过这种基本的方法,复杂的图片可以通过网格中大量的像素点组建出来,就像马赛克瓷砖。这种方法奏效是因为图片可以看成是五颜六色的正方形小格儿通过有规律地排列而形成的。

1.1 分辨率

一般用屏幕的长度和宽度的像素个数来表示像素网格的尺寸大小,更习惯称它为分辨率。分辨率用来表示像素网格的大小,因此,大量的细节信息可以显示在屏幕上或图片里,像素点越多,图像细节越清晰。

视频游戏中采用了很多常用的分辨率大小,包括1024×768。许多经典的台式机老游戏,iPad和很多手机设备都采用这种分辨率。也有其他分辨率,例如800×480、640×960、1280×720和1920×1080,最后两种分辨率属于HD(高清)。

1.2 屏幕宽高比

屏幕宽度和高度的关系可以用它们包含的像素点个数的比例来显示,称它为屏幕的宽高比。可以这样得到宽高比,用宽度比上高度得到一个分数,然后通过化简得到分数的最简形式

例如,屏幕分辨率是1024×768,那么宽高比(AR)就为4:3,分辨率为1920×1080,屏幕的宽高比就为16:9。后一种分辨率就是大众熟知的宽屏,每16个像素点的单位宽度,必定对应9个像素点的高度。

1.3 分辨率与宽高比带来的难题

由于游戏开发的目标设备的差异,不可避免地存在着两个基本的小问题:分辨率不同和宽高比不同

1.4 分辨率的差异

当出现分辨率的差异时,比较受欢迎的做法是,降低游戏的尺寸,或调整图形的大小,以适应较低分辨率的设备。

只有分辨率不同的情况下,降低游戏尺寸通常不是问题。尽管它们在规模大小上不同,但它们有相同的宽高比例。因而,图形可以以相同的比例缩小,并且和原始图像在宽度和高度上保持着相同的比例,这样图像就可以像在预期分辨率屏幕上显示一样。

1.5 宽高比的差异

但如果用户和预期的设备在分辨率和宽高比上都不一样

如何保持不同分辨率下的宽高比,有两种主要的解决方案。第一种是宽荧幕模式,这种方式以相同的比例缩小图像(宽度和高度上缩小一样的比例)直到宽度或高度有一个量与用户分辨率一致为止。由于图片是按一个比例压缩的,所以宽高比没有改变。这样,调整后的图形保持着原来的宽高比,只能在一个方向上铺满整个屏幕,在屏幕的上方或者两侧留有黑条或者空间。这种方法为了保持宽高比,不能在另一个方向上铺满整个空间。第二种解决方法,就是针对不同的配置,裁剪游戏的大小,开发多个游戏版本,让它能在不同宽高比的设备上运行。

1.6 关于游戏像素的总结

关于游戏像素简单总结出以下几点建议。

  • 所有的游戏图形都可以转化为像素。
  • 像素是带有某种颜色的小方块儿。
  • 若干像素点在像素网格中排列组合形成图像。
  • 像素网格的尺寸规模用图片的分辨率表示。
  • 图片的宽度和高度的比例称为图片的宽高比。
  • 图形可以在有相同宽高比的不同分辨率间放大缩小而不产生形变。
  • 图片无法不失真。
  • 可以采用宽荧幕模式或者多种游戏配置来支持多种宽高比。
  • **开发游戏之前决定好游戏所支持的分辨率和宽高比。**基于像素组成的某种宽高比的图形,无法不失真地转化到其他宽高比,不论是通过放大缩小还是宽荧幕模式。

2 色彩:图片的品质

现实世界中通过混合油画材料来调制颜色,与游戏世界的开发有着强烈的相似性,只不过游戏世界是通过混合数字来绘制颜色。具体来说,通过建立一套规则,约定色彩空间、数字用来创建颜色。色彩空间数字上等价于绘画材料的颜色集。这是一个富有创造性的,令人兴奋的系统规则。凭借它在监控器和显示器中的运用,特定的像素数字可以在显示屏上显示出对应的颜色。

颜色空间可以让开发者能成功地办到两种事情:

  • 确保每一个独一无二的颜色都对应有独一无二的数字
  • 颜色数字间的算术运算(加、减、乘、除)好比颜色绘画材料的混合

当今有两种主流的色彩空间运用到计算机图形中。一种是RGB彩色空间(红、绿、蓝)几乎所有游戏和电影都采用RGB彩色空间。另一种是CMYK彩色空间(青、洋红、黄、黑)几乎所有印刷和文档设计都采用CMYK彩色空间。(因为字母B表示RGB中的蓝色,所以用字母K表示CMYK中的黑色。)这种机制以色彩空间中的原色命名,就是那些可以通过混合得到任何其他颜色的原色。

2.1 RGB:颜色根本不存在

RGB彩色空间是一个数字的空间系统,在RGB空间里,每一个数字都代表着一种唯一的颜色。每一种颜色都写成3个数字的形式(R,G,B)。如红色(255,0,0)、绿色(0,255,0)、蓝色(0,0,255)。数字中每一个成分都称为色彩通道。它表达出了某种原色同其他原色强度上的关系,0代表一点都没有,255代表满格。

2.1.1 归一化量值

颜色可以用它们独一无二的RGB值表示,每个值取值0~255区间。在游戏开发过程中,游戏开发者必须处理从最小到最大范围的许多数字。通常情况下,处理这些数字时,开发者需要指定范围中的特定位置或特定取值。对于颜色,可能希望指明是中值颜色、阴影或者高亮。这些表达式的值是取值范围中的特定值,最大和最小间的某个特定值。

可以用具体的数值表示:中值是128,暗色取值低于100,高亮在200以上。然而,所有这些值只对这个取值范围有意义,只要知道最小和最大值是多少。如果取值范围改变——可能有更多的颜色添加进来——最大值就会突然大于255。这样带来的后果就是之前特殊指定的暗色或高亮就会出现在取值范围中的不同位置,不得不回到原来的位置去修正先前的颜色值。

游戏开发者试图避免这种设定绝对数值带来的麻烦,通常采用一种相对计量形式,称为归一化量值。不论是什么样的取值范围,这种方法都适用。简单来说,它把绝对范围值映射到0~1之间,对于颜色值,0 ~ 255对应0~1。RGB色彩空间,0值对应于归一化的0值,255对应归一化的1值。中值就是0.5所在的位置,暗色对应0.39,高亮对应0.78。

那么,RGB数值和通道的讨论学习与颜色不存在这种基本观点有什么关系呢?

在RGB空间里,一张照片有3个独立的通道,红色通道、绿色通道和蓝色通道。这些通道中的每一个像素都是0(黑色或暗色)到255(白色或高亮)间的一个单独的灰度值,中间值就是128(灰色或者是中间色调)。因此,只有当所有通道覆盖到其他通道,每个通道中每个像素的取值结合到一起,形成以像素为基础的完整RGB值,图片完整的RGB值才得以形成。

虽然最后的RGB颜色值是以3个分量的数字形式产生的,它仍然能有效地编码,只需对3个通道地灰度值或者量大小编码,每个通道的取值范围在0~255。在这种意义上,RGB色彩空间反映出颜色并不存在。颜色并不存在于数字本身、计算机本身或者是数字图片本身,因为数字表达的仅仅是3个通道,图片实际上只是3个灰色通道。更进一步说,颜色在硬件层面上是通过监视屏或显示屏反映出来的,是经过工艺制造,使一些特殊的发光二极管以某种特殊频率闪烁、激活,人眼和大脑把它识别为相应的颜色。

这带来的后果就是数字图片的颜色从来都不是恒定不变的,反而经常与设备相关。也就是,某个RGB颜色值的像素常常在不同设备上看起来有点不一样,这取决于设备的制作工艺。这样的差异性最初看来绝对是一个糟糕的现象,特别是对那些完美主义者,希望确保图片在所有设备上都能显示得完全一样。有幸的是,有大量得确保措施来使得不同的显示设备能够最大可能地显示一致的颜色,但目前为止,这种微小的差异仍然存在。有时候,这些色彩差异可以通过图像调整过程来降到最低,例如通过伽马校正。但是有些时候,有一些无法避免的差异,现在除了忍受之外别无他法。

2.2 色相、饱和度和色彩值:色温调节、阴影调节和色调调节

2.2.1 色相

“色相”这个词就是生活中常用的“颜色”,蓝色就是色相(0,0,255),绿色就是色相(0,255,0),红色就是色相(255,0,0)。以此类推,黄色色相是(255,255,0),品红色色相是(255,0,255),灰白色色相就是(170,170,255),其他的颜色色相也类似。在所有能用颜色的地方,用色相去替换它,基本上都是可行的。一个RGB颜色的色相是由所有3个颜色通道的值决定的,它的产生来源于3个颜色通道值之间的平衡。只要RGB的3个值不全相等,那么像素点就有一个色相。如果3个通道全相等,那么这个像素就是一个灰度值,术语称为中性值、非彩色,因为每个通道的值等量,它在颜色上就有一种消除效果。因此,RGB形式的“理想灰度”对应值是(128,128,128)。

2.2.2 饱和度

饱和度是描述色相密度或强烈程度的值。霓虹灯信号或粗体、明亮游戏室的色相是完全饱和。色调越接近中性灰度值,色调的饱和度就变得越淡。例如,大红色(255,0,0)就是完全饱和的,而略淡的红色(255,100,100)就是低饱和的。不够鲜活、强度很弱的颜色认为是低饱和度的色调

RGB3个颜色通道越接近相等,像素的饱和度越低,因为中性的灰度像素的3个RGB颜色通道相等。3个通道差异越大,饱和度越高。在游戏设计图形过程中,图像艺术家通常选用一些柔和的色调,因为柔和的色调是现实世界中最容易见到的。

2.2.3 值

值经常用明度来代替,用来指代一个像素与全黑色的接近程度。明度大小是用RGB像素中最高或最大的通道值来衡量的。因此,(255,0,0)的红色的明度就是255,褐色(170,170,255)的明度也是255。明度值为210或者更高的像素点通常被划分为高亮——一幅图像中最亮的颜色。明度值低于100的像素点划分为暗色——一幅图像中最暗的颜色。这两者之间的明度称为中间色调。

2.2.4 色调、阴影和基调

与色相、饱和度、值有联系的名词。有时候,这些名词用来表示一幅图片或图像中各种各样的颜色,它们用得很宽泛,大多时候可以互换。而在一些特定的场景下,色调指的是白化了的像素点或是用白色混合过的像素点。总之,它指的是经过稀释饱和度处理而得到的像素。暗色指的是任何混合了黑色的像素点,或是加暗、取值减小的像素点。暗红色指的是暗化处理的红色——最强的RGB通道被减弱。最后,色调指的是同时被暗化和稀释饱和度的颜色。

2.3 位深度

RGB图片以RGB的格式指定颜色——一个3通道的数字(R,G,B)。每一个通道得知取值在0~255之间,这样就产生了总共256个不同的亮度级,或者色调(包括0,0代表黑色)。也就是说,一幅图像可以最多显示16,777,216种不同的颜色(256×256×256=16,777,216),这种颜色集称为真彩色。

颜色值的所有数字可以用一个颜色通道(红,绿或者蓝色) 表示,取决于这个通道的位深度。位是一个缩写,它更完整的表述是二进制数字(0或者1)。因此,位深度指的是二进制数字的集合。一个取值范围为0~256的通道的位深度是8个比特。因为一个8位二进制数字组合在一起可以产生共256个唯一的排列(28=256)。视频游戏中一幅标准的RGB图像(通常是JPG和PNG格式的图像)具有这样的特点,它的每个通道位深度都是8bits。这意味着,这幅图像是24位的图像,每个像素点都有24bits,因为8×3=24(图像有3个8bits的通道)。所以,每个单一的像素点的颜色都可能是16,777,216种颜色范围中的一种,因为2(8×3)=16,777,216。

但是,通常艺术家们更多的时候选择每个通道16位的深度去创作图像,这样在运用特效和展示颜色操作时,可以获得更高的精确度和准确度。

2.4 Alpha通道和遮罩

RGB图像除了3个基本的红、绿、蓝颜色通道外,还包含其他可供选择的通道。这些可供选择的通道称为Alpha通道或者遮罩。它们对于选取图片中的区域非常有用,特别在视频游戏制作中选取需要透明或者隐藏的区域时

和标准的RGB通道一样,Alpha通道的像素以1:1的比例直接映射到其他通道的像素点。更进一步来说,Alpha通道的像素也是有灰度的,但它们的值对图像颜色没有直接影响。相反,它们使得选择区域凸显出来。也就是说,像素点的Alpha通道值反映出图像中这个位置的像素点是否被选中,两者之间的取值从黑色(最弱)到白色(最强)。总之,图像中全部选中的像素点能够在视频游戏画面中看见,未被选中的像素点会从画面中隐藏掉,处于半选择状态的像素点会以某种透明度显示出来,它们的值与整个选择区相匹配。

2.5 图片格式:无损与有损

保存一个基于像素的图像需要在硬盘上把所有的像素信息记录成永久性文件,即使在电脑关掉的情况下,这个文件仍保持不变,一段时间以后可以恢复和编辑。文件的格式是像素数据以什么样的方式在文件内部进行构建、排序和存放。保存格式上,有非常多的种类供选择来保存工作成果,例如BMP、JPG、GIF、PNG、TGA和TIFF等不同的保存格式对应着不同的存放方式,不同的存放方式适合于不同的用途。实际应用中常用的格式包括TIFF、PNG、JPG。这些存储方式都采用了压缩的形式,能使图像数据减少,从而只存取最小量的数据。这种方式节约了磁盘空间的占用,也使得图片文件在网络连接中更容易传输。

数据的压缩形式有两种类型。

  • 无损压缩:把图形数据量压缩减少,存放在文件中,它保留了原始数据图像的质量和细节信息。无损压缩格式,能够从保存的压缩形式中重建原始图像,并且没有数据的丢失。以无损压缩格式保存的图像,在图形编辑软件中重新打开时,可以得到压缩前的原始数据。无损压缩格式包括BMP、PSD、TGA和PNG。
  • 有损压缩:把图形数据压缩保存在一个文件大小的硬盘空间中,但是牺牲了图像的质量和保真度。因此,只有一部分原始图像信息可以从压缩的数据中恢复出来。如果以有损压缩格式保存的图片,当在图形编辑软件中再次打开它时,只能得到与原始图像近似的恢复,一个稍低质量的视觉版本。这个问题在每一次的保存中得以放大,因为每一次的保存,压缩算法都会产生另一个近似。最开始的有损图像格式是JPG。

2.6 伽马与伽马校正

显示屏本质上是通过把RGB像素值转化成一系列0到1的电压值,然后传到屏幕上显示出来,被人眼看起来像是颜色。因此,黑色直接转化成0,白色会转化成0。

颜色转化过程中,图像中的RGB值与显示屏上颜色间的关系并不是线性的,而是服从伽马分布,或者叫伽马曲线。

结果是直接送到显示设备的像素看起来总是比希望的颜色更深一点。这是伽马曲线的原因,当今大多数显示设备上伽马曲线都把所有的值提高到自身的2.2次方。因此,从图像中得到的像素值0.9,经过伽马曲线后,最后变成显示屏上一个暗得多的值,大约为0.793,因为0.92.2=0.793。同样,0.5这个中间值会变成暗色的0.218,因为0.52.2=0.281。

在像素值传到显示设备之前,硬件设备通过人为提高图像的像素值,补偿伽马曲线带来的误差,这个过程称为伽马矫正。目的是尽可能地保证图像的亮度和它们在显示屏上的显示保持一种线性的对应关系。另外一个目的就是图像中的中间值色调在显示器中也显示为中间值的色调,同样,图像中的高亮和阴影部分在显示其中也显示出高亮和阴影。
在这里插入图片描述

2.7 颜色混合:颜色运算

颜色的混合本质上是颜色的数学运算。是把两个颜色的RGB值通过算术运算(加、减、乘、除)结合到一起来产生新的颜色,这种颜色是原始两种颜色的混合产物。

这些颜色混合过程可以使游戏中的敌方单位变成红色,当他们受到攻击或者愤怒时,也可以让防御的激光束变成透明,或者让GUI按钮不能使用的时候变成灰色。

以下是两种混合模式:

  • 相乘。黑色的颜色值是0,因此RGB(0,0,0)是黑色。当任何数字乘以0,结果都是0。白色的颜色值是255或1(当用它来表示乘数)。当任何数字乘以1,结果还是它本身。这种模式遵循的就是这种规律。相乘的混合模式(乘以颜色值)是一个调暗颜色的过程。颜色x乘以白色(1)得到颜色x;颜色x乘以黑色(0)得到黑色;如果乘以一个黑白之间的灰度值会使最后的结果变暗。

    相乘模式在游戏开发过程中特别有用。例如,可以为游戏中的主要人物穿上一件白色的T恤。然后把它乘以一个红色,这样摆T恤就变成了红T恤。或者乘以一幅图像Alpha通道的值,随着时间的推移减少阴影的灰色值,从白色变成黑色。这样的结果就是图像会慢慢变成透明。

  • 扫描。扫描混合模式在很多方面都与相乘的混合模式相对,至少从结果的角度来看。扫描混合模式除法常常看作是乘法模式的逆变换,但是扫描混合模式并没有涉及除法。在结果上与乘法模式正好相反:图像在两个颜色的基础上变得更亮而不是更暗。它是这样运作的,先对所有的值取反,然后相乘,最后把结果再取反。这样的结果是,颜色x乘以黑色(0)得到颜色x;颜色x乘以白色(1)得到白色。

    扫描混合模式在实际系统中对于鬼魂产生特效,明亮的光粒子特别有用,也很适用于其他场合,例如颜色需要变亮或变鲜艳的时候。

2.8 图片重采样

图片重采样是关于改变图片大小规模的。简单来说,不论图像放大还是缩小,图片都进行了重采样。

图片重采样的过程对图片的质量影响重大。事实上,不可能放大一个基于像素的图片而没有图片质量的损失。例如,把一个100×100像素图片放大成7000×7000的像素图片,并没有重新检索原图片中的额外细节信息,因为100×100个像素点是原始图片包含的全部信息。相反,现在图片延伸扩展到新的规模,电脑采用平均技术填充新增的像素点,这也是重采样过程的一部分。

建议是永远不要向上重采样,除非这样做是迫不得已,或者想得到一个模糊不清,低质量的图片。在画一幅图像之前,先问自己“这幅图片以后需要的大小会比现在的设计大吗?”如果这个问题的答案是肯定的,那么便以更大的尺寸画这幅图片,使得这幅图的大小会在以后适用。

3 矢量图片:矢量与栅格图

所有的数码图片,不论它们的组成或是来源,都可以无一例外地减少像素,因为是像素点传到显示设备和显示器上。即便这样,数码图片还是可以分为两大类。

  • 栅格图片:是标准的以像素为基础的图片,也是Ps和其他图片编辑软件打开和编辑的标准类型。对于这类图片,绘画者直接对像素点本身操作、低级别控制、使用笔刷工具、选择工具、颜色调整、过滤等能控制每一个像素点如何显示。
  • 矢量图片:这类图片是在类似Adobe Illustrator,Flash,Inkscape里画出来的。它们可以减少像素,但是不能供绘画家在像素级别进行操作。换言之,画家不是通过绘画每个像素来绘制或编辑图像。相反,画家画出矢量图,是通过控制一组可以绘画和链接的像素点来勾画出图形形状的区域。通过绘制一些点来勾画图形形状的边界,矢量图中两种不同的属性出现了,分别是描边和填充。描边指的是用一系列可供链接起来的向量点描出来图形的边框和边界。填充定义的是外形内部填充的模式或颜色。

矢量图数学上的天然属性让矢量图较之栅格图有两个显著的优势

  • 可以无限地向上重采样,并且没有失真。画一个比较小的矢量图形,然后把它放大到任何规模,这过程中不会丢失任何原本质量。因为图形是由一系列的数学锚点组成的,这些数字在任何大小下都保持原样。矢量图很容易再一次来适应大的规模。
  • 编辑矢量图非常容易,不用非得去选择像素选择区,因为编辑一幅矢量图是改变它原始数学属性的过程。

对于游戏开发者,矢量图形最主要的不足在于,它们不能非常方便地得到逼真的数据、图形信息,这些信息必须在像素基础上经常变化。矢量图特别适合制作GUI小工具(按钮、箭头和其他元素),也适合制作图标、便于、卡通人物和场景。绘画家通常会把矢量图转化成栅格图的形式(也就是把矢量图变成以像素为基础的图片),然后再把图片导入游戏引擎中,因为大多数游戏引擎不识别矢量图

4 图片纹理:纹理与UV映射

纹理基于像素的图片投影或者包裹到一个3D模型的表面,就好比用包装纸去包裹一个礼物。尽管纹理是基于像素的图片,它的像素点称为纹理像素点。这是由于纹理用到3D模型的表面时,会显示为透明的,它的像素点不再与显示屏上的像素点有1:1的对应关系。显示屏上的像素点仍称作像素点,纹理点保留作为纹理像素点的简称。

显示屏的像素点以X和Y度量,纹理的像素点以U和V度量。这样(0,0)指的就是纹理中左上角的像素点,(1,1)指的就是右下角的像素点。纹理中心的像素点,一般在(0.5,0.5)的位置。

注:当投影到3D模型时,纹理世界中会出现宽高比和重采样的问题。因此,必须确认纹理图大小比例都适合要运用的场景,这样才能避免图片中的质量丢失。

把纹理图映射或包裹到模型表面的技术称作UV映射。一个3D模型在表面标记若干个点,每个点都有一个UV值,它对应于或者映射到纹理图上的一个位置信息。然后把纹理图包裹到模型的表面,以便同模型特定的UV值保持一致。

有一些行业标准指南适用于创建纹理图像:

  • 纹理图规模大小应该是2的指数倍,这样可以保证纹理图能够在大多数硬件设备上很好地展示。也就是说,纹理图像素点的宽度和高度应该在以下大小中选择:22=4,23=8,24=16,25=32,26=64,27=128,28=256,29=512,210=1024,211=2048,212=4096。由于纹理图不一定是正方形,因此可行的大小包括512×256,1024×1024,等等。
  • 尽管纹理图大小不一定是正方形,正方形的尺寸通常是低功率硬件,例如移动设备的首选尺寸。因此,应该尽可能地选择正方形地尺寸大小。
  • 纹理图应该保存为无失真的格式,如PNG、TIFF、TGA、PSD等,而不是JPG。

六、网格、操纵和动画

网格是指在游戏中的多个三维模型所组成的网络结构。

1 网格:四个信息通道

网格是一组游戏的集合,在某种意义上说,它是艺术家通过使用建模软件(如Maya、3ds Max或Blender等)创建和经过数字化雕刻形成的模型,然后导入到最终游戏使用的游戏引擎中。

艺术家和高级设计师在创建和使用网格的一般工作流程如下:

(1)在建模软件中建立网格。

(2)将网格导出到一个文件。

(3)将网格从文件导入到游戏引擎。

(4)把网格设定为某个级别。

通常步骤(1)和(2)由艺术家进行,步骤(3)和(4)由高级设计师或程序员完成。

从此工作流程可以看出,网格被创建,然后导出到一个文件中。这就是对网格进行编码。如果文件检查无误,并且可以打开,这将视为该文件包含所有一切需要重构网格的信息,就像作为一个图像文件,例如JPG或PNG文件,包含了所有重建图像所需的数据一样。和一个图像文件一样,网格文件具有几个不同的包含特定信息的通道或轨道。具体有四个,所有这些通道完整地定义了网络。不像图像文件有业界公认的RGB颜色通道,网格通道没有类似的规范名称或明确说明的术语。

网格包含4个信息通道:几何、UV映射、操纵和动画。

  • 几何:几何通道是网格的唯一强制性通道。它定义了网格的结构。
  • UV映射:模型结构通道描述了材料和纹理是怎么被包裹起来的,贴覆在几何通道定义的网格表面上。
  • 操纵:操纵信道与动画相关。它规定了节点、铰链和表面看不到的网格的基本骨架。对于理解网格的不同部分是怎么移动的很有用。
  • 动画:动画通道介绍了根据操纵通道的规则在网格中实际使用的动作和动画。

2 几何通道

几何通道与UV通道一起,回答了网格是什么样子的问题。几何通道定义了网格的形式、质地或结构。它描述了网格是如何被构建的。但是几何通道并没有明确定义网面如何出现或光影如何响应,也没有定义材料或质地如何包裹或横跨网状表面形成图案。这些是材料和UV映射索要解决的细节问题。

几何通道使用各种数学结构体或构造体定义的网格组成,即顶点、边和多边形。因此网格有时被认为是多边形网格及为这些多边形建模的过程。

3 UV映射通道

当需要用到平面、二维形状,例如三角形、正方形、长方形和圆圈时,可以直接把它们画在纸上或显示在屏幕上,也可以直接给它们加上阴影效果或涂上颜色。例如,可以直接把摄影的纹理覆盖在它们上面改变其颜色和外观,因为该形状本身已存在于二维空间。但是,使用现在网格的过程中,艺术家在三维视角上遇到了如何对物体表面绘制阴影的技术问题。这个问题的存在是因为不同坐标系空间之间的差别,具体是指模型的三维空间和基于平面造影的二维空间之间的差异。

以合理的方式把二维空间的问题映射到三维空间上,需要额外的信息来实现这两种空间之间的映射。这些信息包含在网格的UV映射通道里。为了说明UV的概念,可以想象儿童创意手工艺品的制作过程,儿童被要求在纸张上画出六个面的正方形,把它剪下来并且折叠成一个正方体。实际上,这就是将一个二维平面图转换成三维模型的过程。

理论上,这个过程可以把任何三维空间对象逆向转换映射到二维空间里。也就是说,如果对象在足够的空间里被切割成小块,它就可以展开到平面里。本质上,UV映射就是把网格的每处表面实现三维空间到二维空间的映射,或者直接通过图片材质实现其转换或映射。它通过使用UV坐标达到这样的结果,UV坐标通常简写为UVs。UV坐标系是一种特殊的坐标系统,使用U和V而不是X和Y,以避免命名上的混乱。

UV坐标用0和1来定义平面的二维空间,左上角的位置用UV(0,0)表示,右下角的位置用UV(1,1)来表示。因此,中心纹理像素(纹理元素)坐标为(0.5,0.5)。当三维网格分割和平铺到UV空间的时候,每个顶点都有自己独特的UV坐标。用这种方式,每一个顶点都分配一个CV值,使用该值,每一处纹理都可以映射到网格的多边形上。

注:UV通道常常编码成两个子通道第1个(UV映射通道0)定义纹理如何投射到网格上(2D转3D)。第2个(UV映射通道1或光映射的UV)定义了照明信息。例如,阴影投射到平面的信息是如何从网格映射、展开到2D纹理上(3D到2D)。

4 操控通道

操控通道与动画通道一起,回答了网格是怎么运动的这个问题。

类似于几何和UV映射通道,操控和动画是相关但截然不同的。操控通道是艺术家使用建模软件创建的。它并非定义了每一秒的动作或者动画,而是定义了网格在需要动的时候的运动规则。它规定了基本框架或铰链和各种组件的结合方式,以及在动画动的时候网格所有组成部分是如何动的。操控人或类似人能用双腿走路、有骨架和关节的游戏对象,使其能够在一定的方向上以一定的幅度移动和旋转,禁止在其他方向上旋转或移。也就是说,手臂不能向后弯曲,头不能转动360度。

事实上,操控通道独立并和其他通道不同,尤其是与动画通道相比。这意味着对于特定的网格,如对于类似于人的对象网络,其操控信息可以单独抽出并循环用于具有类似结构对象的网格。

5 动画通道

第4个和最后1个网格通道是动画通道,同样是艺术家或是动画师通过三维建模和动画软件创建出来的。这条通道负责网格如何随时间变化而变化的。因此,它对两个时间点的动画联系关系进行了编码。对两种基本的属性进行了动画编码:第1种是变化的种类和程度;第2种是变化的时间点。如果网格对象行走、奔跑、跳跃、爆炸、发生变异、翻滚、移动或随时间变化,那么它很可能从它的动画通道生成动画数据。

主要有两种类型应用到网格的动画,可以在其对游戏的运行性能和实现效果的影响方面加以区分。

这些动画的类型如下:

  • 刚体动画(RBA):也称为骨骼动画,**包括网格对象随着时间转变、转动、攀爬的一系列动作和改变。RBA用于走、跑、跳、飞等各类动画,这些动画网格的部分必须移动或变化。RBA直接操控转变骨骼和关节。由于是背后操控,所以网格几何动画的操控不那么直接。RBA容易实现对网格的操控,并且运行起来占用计算机的资源比较少,所以很多游戏中的主流动画都采用RBA。**通常情况下,开发人员通过动作捕捉的硬件和软件来记录RBA,然后导入网状,实现操控动画。
  • 变形动画:也称为基于顶点的动画,**可独立地操控网格,并且直接作用于网格地顶点,也就是直接作用于网格几何物体上,等同于直接作用于网格操控。用于有机体类的动画或不依赖于基于骨头或刚性结构类的动画。**例如,面部表情、嘴的动作、眨眼等等。基于变形的动画记录从关键时刻的网格顶点的位置或关键帧开始,然后通过改变不同时间点的顶点状态来回放动画。

6 使用网格:性能优化

通常中游戏中每秒钟硬件处理的数据(图像数据、声音数据、动画数据)量是巨大和惊人的。由于计算机硬件计算能力有限,所以计算机处理数据的能力也存在瓶颈或者有限制,虽然这个限制根据硬件和环境的不同而不同。当这个瓶颈到达后,游戏会停顿或滞后。假死,甚至完全崩溃,因为目标硬件无法持续维持如此高的性能。

实现性能和效果的微妙平衡称为性能优化,这是游戏开发者的职责之一。这种方式中,程序员会调节游戏的复杂性和细节,精心安排和优化,使整个游戏以可以接受的效果运行在目标平台上。由于游戏中网格是如此通用和丰富,也由于网格是如此复杂和数量巨大(数以千计的多边形),所以它们在性能优化方面发挥着关键作用。事实上,有一系列的指导原则或工作总结,供开发人员采用来创建网格,以确保游戏渲染过程中网格处于最佳工作状态。

6.1 尽量少用多边形

讨论网格时,经常会用到拓扑这个词。如何实现拓扑结构对游戏运行时的性能有重要影响。拓扑是关于网格的所有多边形和整个模型结构化管理索引的总括。关于拓扑的问题集中在三角形如何组成网状或更确切地说,它们组成网格的镶嵌方式。

拓扑结构比其他任何方面更应该优先被考虑,很大程度上是因为有序化与简单化。

在不影响原来设计的情况下,创建尽量简单化的网格意味着创建网格时要尽量少使用多边形一个网格多边形总数称为网格的分辨率或详细度,术语为多边形数包含更多的多边形网状被认为有更高的分辨率,因为它可以包含更多的潜在信息。高分辨率网格有时称为高聚网格,低分辨率网格有时称为低聚网格。高聚网格会消耗更多的计算机资源,因为它们包含更多的多边形,边和顶点数据。

区别低分辨率和高分辨率网格的确切数字并没有明确规定,而且这一数字在不同时间点不同平台上也是不同的。但是,在大多数平台上有500个多边形的流行网格,按照大多数游戏开发者的标准,是一个低聚网格。

6.2 优化拓扑

简单化的原则并不是要求创建一个用尽可能少的多边形(因为这只是得到一个三角形)的网格,而是要求在满足需求设计的前提下用尽可能少的多边形来实现网格。然而,简单化的原则并不是孤立地在工作。

有序化的原则要求设计师应注意组成网格的多边形的排列和镶嵌方式,特别是在网格会变形、移动或会随时间改变的情况下。总之,顶点和边应该尽可能地合理安排,使多边形在行和列上有序,从而使得网格的结构清晰合理。

注:实时游戏的网格通常只有3个或4个边的多边形,也就是三角形和四边形。也就是说,没有网格会包含有4条边以上的多边形。具有4条边的多边形通常称为n边形,大多数游戏引擎暂时或者永久不支持n边形。为确保最佳性能和最大兼容性的网格文件,请使用只有3、4条边的多边形。

6.3 减少UV映射接缝

UV映射,是把3D模型扁平化到2D空间的一个过程,所以它的表面可以直接映射到标准的纹理材质上。UV映射过程要求被映射的模型可以分割成几部分或可以从某些地方“撕开”,以便它可以被一些数学算法展开并平铺到二维空间。如,如果不沿着球形物体的横向或者纵向切开,就无法把它平铺到一个平面上。该模型沿切口的线或边缘称为接缝,一个模型的接缝越多,那么这个模型就越容易展开到平面上,并且越不容易变形。

然而,焊缝的使用也带了两个主要问题,一个是针对艺术家产生的,另一个是针对程序员。

对于艺术家,接缝必然在材质上留下一条裂缝,该裂缝破坏了材质的连续性,同时该裂缝相邻的两个多边形也把材质划分到了两个空间里,处于这两个空间的材质纹理为了能连接在一起必然会产生一定的形变。如果两个空间的像素差异很大,将必然导致接缝处很明显。艺术家可以使用特殊方法解决这个问题,其中包括编辑纹理最小化接缝(使用小碎块纹理),通过这样的方式达到隐藏接缝的目的,并设法在实现UV映射的过程尽量少使用接缝。

针对程序员接缝的主要问题是接缝对计算机系统资源的开销。对于游戏引擎,例如Unity引擎,网格的每一处接缝都有一笔开销。其结果是,针对目前的硬件处理器和3D渲染模型,在接缝外经常有两个或者多个定点。因此,接缝增加了游戏中显示的网格的定点数量。解决这一问题最主要的方法是把网格UV接缝的数量减少到最少以及谨慎使用纹理空间。

6.4 回收纹理空间

UV接缝在纹理空间也是可以优化系统性能的。纹理空间以MB为单位来计量,在视频或者系统存储器里保持或存储着所有的游戏正在运行时用到的纹理。当游戏使用更多或更大的纹理时,纹理空间或者纹理使用量在增加。接缝之所以能优化系统性能是因为接缝可以减少存储纹理数据空间的使用量,同时也使用了更少的系统资源就实现所需要的纹理,所以说接缝可以优化系统性能。总之,UV接缝通过纹理回收来减少纹理空间。如果额外的接缝或切口插入网格,以使网格得以映射成若干个独立的和分开的纹理岛(称为UV壳),这些纹理岛就可以在纹理空间中重复使用纹理相同的部分。也就是说,纹理岛可以以共用相同的纹理材质相互覆盖。这在实际应用中大大减少了网格中所用的到的纹理材质的数量

总之,使用UV接缝有好处也有坏处,应谨慎使用。使用它没有带来明显的性能提升时要尽量少用;在需要节省材质空间的时候,使用它可以大大节省材质空间。

6.5 特克塞尔密度

特克塞尔密度是纹理像素密度的简称,表示在三维空间的网格或表面的尺寸和通过UV映射应用到该表面的纹理像素数目之间的比率关系。总之,场景的特克塞尔密度或者水平有助于判断纹理填充到所有3D模型表面的像素数量,无论模型或网格是否被玩家看到都能对纹理像素的数量有个大概的估计。

特克塞尔密度很重要,因为图形硬件要处理的每一帧像素数据的数量对游戏的运行性能有很大的影响,更多的像素数据意味着更大的复杂性和更大的计算开销。重要的是网格的大小和纹理是独特变化的。一个改变不见得是由其他相关的改变引起的。网格纹理,无论其大小,在3D模型的表面进行UV映射的时候,总是在一定程度上会出现拉伸或者收缩的情况。因此,特克塞尔密度对于游戏开发者来说是个问题。考虑一个3D带纹理的矩形对象(或正方形),对象的尺寸不变,但是像素空间的纹理增加的时候,相应的特克塞尔密度就会减少。特克塞尔密度的增加意味着更多的像素要一起挤到像素的表面,而特克塞尔密度的降低意味着更少的像素分散在模型的表面。

太低或过高的密度都会给游戏带来问题。太低的密度(太少的像素)会使游戏的纹理看起来模糊、虚化,因为较少的像素被放大以适应较大的网格。过高的密度(过多的像素)会导致像素集中及性能问题,例如卡机或滞后。

因此,游戏的正确像素密度值需要在实际应用中根据具体情况而定。根据游戏和目标硬件的情况,经过反复测试和检查才能确定合理的像素密度。

通常有两步要做:

①确定所有对象的一致像素密度;

②测试一个对象在目标硬件上的像素密度,以确定什么像素密度效果好和什么像素密度不好。

6.6 一致的像素密度

步骤①中,艺术家使用由开发者确定的以一定的单位(如米、厘米)来描述的大小和比例把所有的网格进行映射和模型化。通过这种方式,间接地保证所有对象共用一个一致的像素密度。

按照一定的比例关系映射游戏中的所有模型,开发人员可以确保游戏中所有模型像素密度一致,此解决方案本身并未回答某种情况下的正确像素密度值的问题,但它使回答这个问题简单化了。因为当一个级别的所有对象共用像素密度,如果想知道哪个像素密度是正确的,只需要确定一个对象的像素密度即可,因为所有的对象共用一个像素密度,找到了一个对象的像素密度也就找到了所有对象的像素密度。

6.7 校准像素密度

步骤②中,假设所有对象具有一致的像素密度,开发人员根据游戏的情况确定正确的像素密度。他们主要通过试验和错误来实现确定的正确的像素密度。总之,只关注场景中的一个独立对象,如门、游戏人物、武器或其他玩家能移动的对象。他们把这个对象放入游戏,然后在目标硬件中玩这个游戏,以观察该对象在游戏中的显示效果,在当前分辨率下是虚化还是像素密度过高。他们通常以比设计要求高的大纹理、高像素密度开始,然后逐步减小纹理的大小,直至在目标平台和分辨率下取得合适的像素密度为止。

6.8 优化模型选择和遮挡

视频游戏开发中,选择和遮挡有非常特殊的含义,但两者都和一条原则有关,即“保持简单”。游戏的大多场景都是复杂和广阔的世界,玩家可以探索,这些都需要计算机处理和渲染数据来实现。很多角色扮演游戏中,允许玩家爬过隧道,发现秘密通道,前往海滩,探索森林,进入森严的堡垒等。这些地方通常都需要耗费计算资源的图形效果:树叶沙沙作响的森林,会动的阴影,飞溅的水波纹,燃烧的火把,以及各种材质、反射、高亮和闪光,更不提所有模型和网格本身了。

无论是游戏世界还是现实世界,有一件事是一样的,即游戏玩家无论站在哪里,基于游戏摄像头前方都有个有限的视野区域。正是通过这些限制,从最早的游戏和游戏开发引擎以来就是一个最重要的优化技巧,并用于减少计算机的计算量、渲染和绘制游戏画面,使复杂的游戏世界得以实现。总之,游戏引擎将忽视或不处理不能被玩家直接看到的任何对象。如果玩家看不到某个对象,那么游戏引擎绘制它到屏幕上或计算应该如何运行。如果一个对象被隐藏或遮挡,那么它将被剔除,或者从必须计算和绘制的对象列表中删除。这种优化的技巧通常会影响艺术家怎么建模或创建网格。总之,艺术家必须确保在游戏中远处的一个接一个的对象是作为单独的网格或文件导入到游戏引擎中的。也即是说,它们不能群组化创建远处的对象网格。由于每个对象都有独立的网格,这将使引擎更加容易检测到它是什么,以及是否应该把它从列表中删除。

6.9 模块化创建网络

游戏开发人员像砖或块排列组合组成更大的结构,构建网格时也同样可以这样做。这种构建网格的方法称为模块化构建方法。

至少有两种方法供艺术家进行环境建模

  • 传统的方法是把整个环境作为一个整体的网格全部雕刻出来,然后作为一个整体导入游戏引擎中。
  • 另一种方法是在环境中确定所有可重复使用的部分,然后分解出来。

在游戏开发中使用后一种方法,有两个主要优点。

  • 优化了模块化构建。
  • 使模块化构建易扩展

6.10 优化模块化构建

模块化构建方法要求图形艺术家把场景分解为基本组成部分,并且重点关注基本组成部分的独立性

该方法在两方面有显著的优点

①对开发人员来说,模块化不必重复工作

②对游戏本身来说,不必把整个环境作为一个巨大的纹理来进行维护和保持。相反,每一个单独的组件都有自己的纹理材质,而且这些纹理也可以被重复使用。

6.11 易扩展的模块化构建

模块化建造方法可以扩展,这是因为环境被分成了可重复使用的独立部分。如果需要把环境的组成部分进行线性排列或者降低,以提高游戏的难度,设计者需要改变组成部分的排列方式,这是没问题的;调整布局只需要简单地重新排列组成部分即可。如果测试人员或游戏玩家需要扩展包或下载新的环境,这些需求可以通过重复使用和重新安排组件模块来实现。

6.12 减少动画关键帧

许多动画数据都包含被称之为关键帧的编码数据。关键帧是指动画在特定时间(关键时刻)网格状态的记录或者快照动画可以包含一个或多个关键帧。

根据关键帧里记录的基本信息,计算机可以自动计算生成其他所有帧。这个过程使用了数学方面的技术,计算图的关键帧的值,绘制一条连续的曲线连接它们,然后使用曲线读出关键帧之间的其他帧的值。用这种方式,通过计算从第一帧开始到最后一帧的每一帧的数据值就可以产生一个流畅和连续的动画效果。

由于有更多的用户自定义关键帧,所以关键帧越多,计算出来的帧就越少,对整个动画过程控制的就越好。但是,对动画控制的好,意味着需要耗费的计算机资源就越多:更多的关键帧意味着更多的数据,更多的数据意味着更大的计算性能损失。因此动画开发者也需要像权衡优化网格和多边形的数量、纹理和像素之间的关系一样权衡动画和关键帧之间的关系

七、照明与补光

玩家看到的最终的3D场景,称为“渲染场景”。因此,为了实时三维视频游戏,渲染通常每一帧发生一次。

1 阴影的组件

要渲染图像,需要图像中所有对象的下列成分:

  • 形态
  • 材料和纹理
  • 照明

总之,这3个组件部分确定物体的底纹。因为渲染是一个共享的过程,因此,这些组件有助于渲染。

1.1 形式:形状、轮廓和结构

二维世界中,一个物体的形式或结构,可通过形状和轮廓来定义。3D世界里,可以通过一个网状定义,由顶点、边和多边形建立。网格的几何信道定义了形式,即对象本身的状态、空间占用、质量、形状数量和结构。

1.2 材质与纹理

一个对象的材料和质地定义其表面的属性,也就是说,表面是否粗糙、光滑、坚硬、柔软、有光泽、沉闷、透明或者不透明。它们的定义改变了表面的细微差别或影响如何响应,使其显示为照明或补明,以及几乎所有对人眼可见的东西。材质和纹理问题涉及严格的表面对象,而不是对象结构或照明的性质。

1.3 照明

对象通常不会孤立存在于彼此找不到的地方。相反,它们的坐标空间在世界里并用光源以定向光线的形式照明。光子从光源发出并投射到一个对象。然后光子反弹,并从物体的表面散射后继续前行,直到射入眼睛,大脑决定了某段频率为视线的感官体验;通过它,人们感知颜色、形状和形态。

请注意对象形状和材料的影响,一个对象如何被光照影响。该材料或表面,当它碰到物体时,控制光线如何反射和散射。这种形状决定了所有的光是否阻塞或闭塞接以决定是否显示对象。

2 照明:直接与间接照明

2.1 直接照明

直接照明是指从光源发出的光线(阳光或人造光)到目标的任何对象,且中间没有反射。直接放在聚光灯下的椅子,大部分的照明会是直接照明。也就是,大部分的光从聚光灯源直接打在椅子上。这有两个显著的原因:首先,直接照明强度更大,会更强烈地照亮主体;其次,直接照明有更加强烈的色彩与主题的颜色光。如绿灯将增加绿色色调,蓝灯会增加蓝色色调。

2.2 间接照明

不仅光滑镜面的物体有反射,如镜子、金属、玻璃等。几乎从任何对象都有反射,包括弥漫性物体,如墙壁、床单、地毯、砖、门和人。光从后者反射是所谓的“扩散间反射”,光从前者反射称为“镜面间的反射”光——无论是直接或间接的照射都称为“入射光线”。

间接照明经过每次反射都失去了部分强度,因此其强度在下降。此外,反射光线从它反射的表面继承一个色光。如果从红灯反射砖墙,那么反射光线将继承一个红色的去饱和色调。

2.3 照明规则

总之,直接和间接照明负责创建三维场景的照明。

由这两种光和六个基本规则定义的照明和渲染场景为:

  • 没有直接或间接照明的物体应为黑色。
  • 接收直接和间接照明的物体通常最明亮并且显示出场景的亮点。
  • 只接收间接照明的对象是在阴影处并且通常显得比接收直接照明的对象更暗。
  • 接收间接照明的对象将会受到颜色飞溅。即会染上一些微妙的颜色,因为间接照明继承了表面反射的颜色。
  • 当咖啡杯放在桌子上时,在杯子的底部边缘形成一点银色,在它与桌子结合处形成的光线,营造出进藏黑暗的阴影。这就是所谓的“接触影子”,整体的效果称为“环境光遮挡”。
  • 物体的材质决定了有多少光被吸收。由光泽的材料(如玻璃和镜面材料)加大光的反射,因为它们吸收较少的光线而反射更多的光线。漫反射材料(如砖和布料)减少光的反射,因为它们吸收更多的光线而反射更少的光线。基于材料和对照明场景的色调变化有助于粗糙或光滑的对象的显现。粗糙的物体拥有高层次的对比并且其表面像素的亮度级变化。混乱的亮光和暗光形式显示了物体的粗糙度。平滑的物体拥有连续色调的灯光亮度;可预测的亮暗之间强调了光滑的表面。

3 光源

照明,无论是直接还是间接的照明光,都可以转化成从一个或多个光源照射到一个环境中所形成的光。计算机图形学中,光源在本质上是光线产生的地方。不同于现实世界的是,现实世界中光从灯泡、太阳和其他有形对象产生时本身就可以受到光线的影响。视频游戏中的光源从本质上来说是潜物质的数学结构。视频游戏中,光源是光线产生的地方,它们一般只能产生光线,不能接收光线。现实世界中,太阳是太阳系中最亮的光源。光源还包括灯泡、蜡烛、手电筒、反射、火灾和更多能产生光线的事物。计算机图形学中,能利用的光源类型远远少于现实世界中的光源的类型,但所有这些现实世界中的光源必须通过丰富的想象力的融合有限的光源去模拟现实世界中的光源。

注:“光源”指主光源在一个场景,即光的发起者。不用于间接的光源,如通过墙壁反射的光。

计算机图形学和视频游戏世界里,通过一组预先确定的经过数学精确计算的光源来仿真实现或者产生近似实际世界的真实光源。大多数的游戏引擎和3D建模软件都支持这些光源和其他很多光源的类型。然而,对于不同游戏引擎和3D建模软件所支持的光源都不同。

  • 直接光:从计算复杂度来说,直接光通常是指耗费最小的光。直接光存在的3D场景中,需要耗费的图形处理单元(GPU)和中央处理单元(CPU)相比于其他标准光类是最少的。一条直接光可以定义为数学上的一条列向量D。向量的方向代表了直接光的光源所要照射的方向。直接光一般不限制其照射范围,因此可以被比喻为一面无限大的墙面沿着光照射的方向延伸无限远的距离。视频游戏中,直接光频繁应用于仿真超大超亮的光源,特别是模拟有太阳的白天场景和有月亮的夜间场景。
  • 泛灯光:泛灯光(点光源)在游戏中广泛地应用于仿真各种人工光,包括墙灯、天花板灯、爆炸、耀斑、烟花、火把、神奇的魔幻效果,等等。本质上来讲,泛灯光是在3D场景中从一个单一的无限小的点光源向四面八方投射的光。这个无限小的点通常是用空间中的坐标来表示。泛灯光投射的范围是有限的,受限于两个半径值的影响,内半径和外半径内半径指泛灯光开始淡出的地方,外半径则标志着泛灯光完全终止的地方。游戏场景中,外半径以外的任何地方的对象点都不会受到这个泛灯光的影响。泛灯光可以在数学中表达出来,但是至少要两个完全独立的方面才能描述它,并且不同引擎会根据需求去决定一个或多个方面。因此,泛灯光在计算复杂度上的耗费可以仅次于直接光,但也可能是最复杂的灯光类型,这一切都由泛灯光所采用的方法决定。
  • 聚光灯:通常**用于对直接光的限制或必须指定详细的范围。聚光灯通常用于汽车头灯、手电筒、舞台灯光、各种魔法法术效果和更多的场景中。然而,聚光灯通常是计算复杂度最高的光。因此,在游戏中很少采用,**当没有其他类型的光可以应用时,才会考虑采用聚光灯。

4 计算直接照明与间接照明强度

全局照明(GI)直接照明和间接照明组合在一起所形成的照明影响。总之,全局照明指的是所有照明,让事物更接近于现实的世界,其中包括强光、阴影、反射、环境闭塞、颜色飞溅等等。

从表面上来看,全局照明(GI)的计算复杂度相当高。实际,它也许是视频游戏中计算耗费最高的环节,必须考虑视频游戏中的多个图形,至少要考虑所要耗费的时间。因为计算机必须从每个光源跟踪所有光线,确定它们在场景中接触点的对象,然后根据每个对象材质跟踪它们的反射光线,跟踪反弹光线接触的点,重复这个过程,直到完全计算每一束射线反射的光线。

现实世界中,一束光的反射可以产生无限的反射光线束。但对于游戏的研究开发人员来说,在一个蓬勃发展、竞争激烈的时代,游戏的运行性能很重要,因此必须严格的限制,必须要设置反射光线允许的数量,这样可以在进行照明计算时,防止无限循环和递归。即使有这样的具体限制,计算逼真的3D场景的照明仍然存在太多的实时图形,至少在目前一般的硬件上,运行起来还不能很轻松,几乎每帧的计算(每个渲染)对硬件都有极大的耗费。

:这个限制是一个实际的约束,而不是逻辑上的推理。并不是说GI不能实现实时计算,只是因为一些逻辑上的矛盾或需求方法的局限性,当前硬件的局限性使它不切实际。

有一系列的技巧和技术可供开发人员使用来实现游戏中逼真的照明效果。几乎所有的开发人员都会更改渲染过程,或一些特定的渲染方法。其中之一就是光照绘图,另一个是延迟渲染

5 光照绘图:通过纹理照明

“光照绘图”指的不是一个特定的事物或某个实体,指的是一个过程,或者说是游戏开发者使用的一门技术。光照绘图就是烘焙照明到纹理的过程。它是一次渲染系统的过程和提前计算一个场景的照明,然后保存结果的过程。照明信息以纹理、混合、分层的形式映射到现有的纹理场景,模拟游戏的运行,仿佛真的是通过灯光照亮产生的场景。光照绘图的输出流程是一组纹理,称为“光图”。这些纹理以网格的形式记录所有的照明情况,包括基于网格的现场灯光的位置和形式。阴影呈现为较暗的像素,并强调为轻像素。如果实现了实时计算,这些纹理可以混合到现有的模型来照亮,使他们在特定领域模仿阴影的效果,突出了间接照明。

光照绘图基本包含以下3个阶段过程

  • 计算一个场景中的照明情况

    使用游戏引擎的渲染系统或3D建模软件时发生。根据模型的直接和间接照明,该系统计算物体出现在现场的位置和大小,以及灯光的位置和方向。这些计算在实践中需要花费很长的时间,尤其针对大型场景中存在的多个模型,在较慢的硬件上需要花费几个小时甚至几天。

  • 存储照明计算的结果

    结果存储在基于像素颜色纹理表单中,当存储完成后与游戏中所有其他的纹理一起打包和运行。光照绘图过程生成这些纹理的过程使用了模型结构。计算光遇到表面的平面结构模型和呈现的信息。根据其UV图通过”未处理的“3D模型来构建,这样光图纹理可以投射到正在运行的游戏中,使它看起来像是一个常规的纹理。

  • 游戏运行时将光图纹理投射到每个模型

    通过一般的纹理和材料混合来让模型出现光亮。用这种方法,光照绘图通过减少照明计算纹理内存的占用和纹理混合减少实时计算损耗

总之,不能低估光照绘图技术作为全局照明的潜力,它可以使视频游戏产生惊人的现实效果。但是它有一个重要的缺点,就是局限性。具体来说,光照绘图不能用于动态的照明场景,包括网格动画,改变或随着时间的推移,并且不能在画面中移动。因为光照绘图纹理是由光照图产生的,而光照图是在开发时就已经产生了,不是在运行过程中才产生。照明是由开发人员开发游戏时产生,这样他们可以在游戏运行时应用纹理。如果物体移动或改变,照明也会做出相应的改变作为回应,光线将沿不同的道路,并反弹向不同的方向。但光线绘图从来都不允许改动光照图,光线绘图的根本目的是改善游戏在运行时的性能而提前制作光照图的水平。

6 实时照明:基于顶点与基于像素

游戏引擎渲染系统负责即时绘制的照明场景。因此,绘制照明动态对象的任务渲染系统的工作。为实现这一目的,渲染器依赖于遮光技术,它是一个系统的方法,在每帧的基础上计算阴影表面的算法。它被称为“阴影技术”,因为绘制照明的任务涉及阴影场景中的对象,增亮或调暗它们的表面。

20世纪90年代后期,最显著的遮光技术之一,用于实时照明对象叫做高洛德着色,由其发明者亨利·洛德而得名。这种方法是基于顶点的照明算法通过考虑模型的每个顶点在当前使用的摄像头的视野,决定顶点是否直接暴露于光源,确定亮度的程度。多边形的每个顶点赋予权重或亮度值,该多边形的表面是连续的阴影,就像顶点之间的平滑渐变,这个亮度的渐变是由顶点的亮度控制的。

这种方法经常用于只要求速度而不是准确性的情况。方法的复杂性取决于场景中光源和暴露于视野及光源网格顶点的数目。与大多数渲染方法一样,这种方法没有考虑到不可见的(不在摄像头视野内)物体。因为看不见的物体不需要渲染。

高氏着色和顶点为基础的照明方法的优点主要是速度。它们通常在较旧的硬件上工作良好,并且能够快速产生结果。但通常以牺牲真实感为代价。用这种方式遮蔽表面倾向于看起来更平滑的、线性梯度在顶点之间的渐变。

另一个问题出现了,遮光方法直接关系到的场景,即几何形状,以及其顶点。该结果是,网格必须密集镶嵌与多边形产生效果好的照明。手电筒照耀到墙上方形网格的中心,如果出现手电筒不能直接照射的角落,墙看上去仍然是黑色。

这些问题已经导致了在几乎所有的游戏平台上采用基于顶点的光照减少,除了游戏定位于传统的硬件或移动平台。相反,大多数游戏现在使用基于像素的照明解决方案,因为多数的硬件使得它具有更强烈的真实感。

基于像素的照明是一种替代顶点基于照明该遮蔽网的表面中的场景照明,是在像素的基础上而不是顶点。基于像素的光照,网格可见的摄像头呈现到屏幕上。对于每个像素,呈现系统决定它应该是变亮或变暗,根据照明的场景像素,黑色和光源通常被认为是照明的两个极端值,其他种类的像素在这两个极端之间的某个值。

许多方面,基于像素的照明在计算上比顶点的光照更耗费资源,但它通常会产生更逼真的效果。因为照明在整个表面的强度计算上的逐像素基础上,意味着照明强度可以非线性地变化。基于像素的照明,通常是使用通用的技术映射,进一步增强渲染的真实感。

7 法向映射

选择照明渲染系统中的像素着色技术,为游戏开发商提供了更加真实的世界渲染的可能性。可以使用其他的基于像素的技巧,并结合逐像素光照,以增加场景的真实感,开辟了新的用在优化游戏的运行时性能的可能性。

其中一个技巧是法向映射。该技术主要用于模拟粗糙的外观、凹凸、凹痕、标记和其他更明显的细节,以便用于网格的表面。

使用法向映射既可以节省计算,又不失真实感和细节。该法向映射的目的是让开发人员能够使用地图定义网状表面的粗糙度、锯齿、凹痕、凹口等等,而无需详细设计多边形的详细模型。

法向映射的工作原理是利用一个专门的RGB纹理映射到模型各像素纹理编码法向量,方向箭头指出模型指定的像素,并告诉像素的渲染器相对于场景的灯的方向。指向朝着光的像素获得更多的光照比。像素(其RGB值)的亮度取决于正常朝向光的入射射线向强弱。

法向映射为开发人员提供基于每个像素的控制出现光反射的表面和细节的方式。开发者可以设置一些像素(X)中的正常映射在一个方向上的点,和其他集合(Y),以指向不同的方向。在方向集合X和Y之间的法线差异意味着集合X将获得不同程度的照明,从集合Y设置法线,从而改变每个像素的基础照明,在没有像素的地方创造一个平面多边形的外观和深度表面的细节。因为大部分的照明,表面的细节来源于像素。

每个像素的光线与法向映射的结合可以增强场景实时照明的真实感。法向映射利用每个像素的控制,根据亮度改变像素在一个正常的值映射到表面上产生向反应程度来描述照明。

8 渲染方法:正向与延迟

不同的渲染方法在于它们的性能和效率不同,区别在于命令和渲染的对象方式不同传统或默认的渲染方法被许多游戏称为“正向渲染”,这种方法对于带有许多对象的场景往往引起性能问题。如何推进渲染工作成为它思考的问题,其中还涉及到渲染冗余校验的问题。而在最近,渲染已发展为延迟渲染,结合正向渲染和延迟渲染可以解决以上提到的问题。

8.1 正向渲染

  • 如何推进渲染?

    需要给出摄像头视野范围内所有对象的列表,包括影响这些对象的光源。

  • 如何做正向渲染?

    通过排序所有渲染对象,开始是贴近摄像机在列表中的对象,接近的对象生成之后,接着是远距离物体。使用排序算法或其他方法,如深度缓冲器。

    最重要的问题是使用任何手段时,要呈现的对象以某种方式排序。其目的是要排序对象,使较近的物体覆盖更远的那些像素。因为近处的物体应该出现在远距离物体的前方。

    但具有正向渲染和每个像素的光照问题对于每个绘制对象的像素,计算其照明数据,而不考虑像素重叠。某些对象会重叠,因为较近的物体出现在远距离物体的前面。因此,大量的像素数据被覆盖,这意味着许多照明计算被浪费。

    正向渲染任何场景的计算复杂性表示如下:

    绘制在视窗中所有对象的像素数×场景中灯光的数量

    正向渲染的渲染性能会受到影响,尤其是有许多灯光和物体的更大场面。

8.2 延迟渲染

对于大功率设备和最新的游戏延迟渲染已经成为默认的渲染方法,例如游戏机和游戏PC。延迟渲染视图解决正向渲染产生的性能问题,以及推出了一系列特殊的方法,可以渲染更加真实的场景。

延迟渲染,就像正向渲染,在视窗中也有一系列的对象排序。它使得这些对象不发光,并将它们的材质加入到临时的几何缓冲区(G缓冲区)。这样做类似向前渲染,但它不为每个对象计算照明。相反,对象绘制光照之后,G缓冲区已经创建,所有的像素合成完成,具有在图像中所有对象的正确深度,并延迟显示,然后进入到一个新的渲染过程。此阶段中,照明在G缓冲区中进行。

因此,照明通常称为“延迟”,像素的照明计算事先在缓冲区进行,但不是马上显示到屏幕

延迟渲染计算照明的复杂性表示如下:

G缓冲区的像素数×场景中灯光的数量

G缓冲区中的每个像素是根据强度到达该表面像素中的每一个场景的光来迭代变亮或变暗。其中一个主要的延迟渲染的优势在于它独立于场景几何的现场照明。即照明的计算复杂度仅仅依赖于屏幕像素的数目和灯的数量,不取决于场景中网格的数目。因此,小而简单的场景和大的场景理论上呈现一样快。

延迟渲染除了解决了正向延迟呈现的复杂性,还实现了用照明和几何解耦,开发独立的访问场景的几何形状和照明的最终效果。这意味着在运行两个几何物体的照明可以对像素进行调整,编辑和独立改变,在每帧的基础上,产生各种实时的特殊效果。

注:延迟渲染最显著的缺陷之一是不能成功地呈现透明,甚至半透明的对象,如玻璃,水晶等等。这种限制的主要原因在于延迟呈现不亮或细化表面的遮光,现场几何不透明地呈现在G缓冲区中。因此,视窗像素中的G缓冲区完全被覆盖,并仅对像素的最近前景的对象进行存储。

9 学习照明和渲染

实时渲染系统中直接和间接照明的实用建议

  • 使用定向灯和点光源,尽可能避免现场灯光。

    通常,点光源灯是最实时,计算昂贵的灯光。因此,建议避免使用实时照明,不使用定向灯和点光源。但这个建议不适用于静态照明的情况,因为光地图是在开发时而不是在运行时生成。它只适用于实时灯光照明的情况,必须计算运行时移动的对象。

  • 尽可能使用映射照明替代实时照明。

    实时照明耗费大量计算资源。

  • 老的硬件一般使用基于顶点灯光渲染。

    一般老的硬件选择延迟渲染系统。

  • 尽量少用透明度和阴影。

    透明度和实时阴影是最耗费资源的计算效果。因此在实时照明时尽量少使用它们。

八、声音与音乐

1 声音、音乐和音频

1.1 声音

声音是有关于任何可以听的数据的集合——任何可以听到的东西,也就是可以用于提升场景的真实性,去强调或完成发生在那个场景里的事件,或者给游戏者提供基于游戏里输入的某种反馈

实际上,声音就是典型的长度少于一分钟的音频文件资产

1.2 音乐

如果声音用于标记的符号,那么音乐就代表了那些标记的内容。游戏中每个音乐通常叫做一个轨道。轨道本身在不同的格式当中,精准地区别于它们各自的使用目的。这里讨论其中的两种轨道。

  • 音乐轨道

    音乐轨道是成熟的作品。常常作为游戏中的一个背景块被无缝地循环播放以传达场景的一种包罗万象的气氛、感受或者情绪。

  • 偶然轨道

    典型的比音乐轨道短的信道以至于可以被引入和混合于现在存在的轨道需求中,以此来创造一种心情的突然过渡或改变

1.3 音频

许多视频游戏以音频的某些或其他形式的表现为特色。音频的一些表现用于游戏中为某些具体的特性添加效果,其音频也可用于增强该效果。也就是说,音频提供玩家发出某种指令用于增强效果。

基于使用目的方面,语音与音乐和声音是完全不同的,它也引进了一些对于游戏的附加技术问题和注意事项。不像声音和音乐,由于前面已经叙述过语音所包含的内容,不是由于它自身的声学性质而产生的情感,语音是一种典型的被包括的形式。语音引进了一个定位的问题,因为口语是一种典型的具体的自然语言。正是因为这个原因,**假设使用不同的语言去制作游戏的许多版本,那么对于游戏中每一个具体的语言版本,口语都必须去适应并替换。**这对于游戏该如何发展给出了重要暗示。

2 文件格式及音频工作流

音频数据在格式方面与声音、音乐及语音是不同的,也由于这些不同影响了音频是如何使用的及音频数据的长度。当开发者们制作游戏时,通常有许多不同的方法来处理这些音频数据。这些方法之间也有很多相似性。其中,一个最显著的相似性就是开发者对于文件格式的通用选择使这些文件格式能够节省音频数据。现在,通常只有一种或两种文件格式用在游戏中。为了节省音频数据资产,现在仍有各种不同的文件格式可供选择。这些文件格式包括WAV、MP3、AAC、OGG等。这些格式在无损及有损压缩方面,还有取得软件专利权方面是有所不同的。这些考虑使得想要在免费及没有法律顾虑情况下得到最好素质的开发者的选择有缩小的趋势。

无损和和有损压缩方法决定了音频保存成音频文件时是否会失真,如果有失真,是对于原始数据有多少失真。无损压缩格式,例如WAV,当数据保存的时候是没有失真的。与此相反,有损压缩格式,例如MP3,保存数据时会丢失数据,因为这种格式只保存原始信号的近似值。

围绕着取得音频文件格式的软件专利权问题,决定了项目是否可以合法地使用特定的文件格式及需要支付多少许可证费用。即使在技术层面有足够能力使用一个具体的音频格式去编码和保存音频数据,这并不意味着可以在现实中合法地这么做,尤其是计划去售卖的游戏,有一系列的法律问题要考虑。现在只有两种音频格式可以在游戏中通用WAV和OGG前者是无损压缩,后者是有损压缩,并且这两种格式都能免费使用。

WAV格式和OGG格式都普遍地被使用,也适用于开发的不同阶段。全心投入于音频数据的录制和编辑阶段的开发者、音乐家和声音工程师使用所选择的软件进行工作,并使用WAV格式或者一些类似的无损格式确保在开发周期中没有音频数据的丢失。当音频资产最终定下来并且准备好放入一个游戏引擎中时,音频通常会从无损的WAV格式转换成有损的OGG格式,这是个在很多方面都与MP3格式类似的格式。首先是为了有利于运行的性能,还有保证数据量较小,因为在百万字节级别,WAV格式比相应的OGG格式文件需要的数据量大很多。

一些已经建立的游戏引擎,例如Unity或者Unreal引擎,是引入音频为WAV格式而不是OGG格式,这仅仅是因为对应引擎会自动把WAV格式压缩成OGG格式或者是其他一些等价的压缩格式。当定制引擎时,使用OGG Vorbis(一种音频压缩格式)框架或者一种相应的技术来实现音频是很有可能的。

3 加载和码流

当音频以OGG格式或者一种等价的格式引进到一个引擎时,开发者面临在游戏过程中引擎如何加载或播放声音资产这个重要的技术选择。从长远来看它非常显著地影响一个游戏的运行时间。任何音频重放将不可避免地引起对于引擎的一种系统开销或者性能负担。

这里列举两个主要的可用选择:

  • 引擎可以把整个声音文件载入系统内存,一旦引擎使用任何一个音频库去装载它时,便把它播放出来。
  • 引擎可以只装载来自音频文件数据的一个子集,当作为回放进程不断地移动横坐标并不断地卸载和载入新数据段时,引擎同时播放这个子集,保证每一次内存中有一个简单的、固定大小的音频数据段。这个方法称为码流法。

加载和码流两种方法都因为不同的原因应用于游戏中。

3.1 加载

加载的方法典型地运用于声音。通常用于文件尺寸小,持续时间短(少于一分钟)及在游戏中频繁播放的音频样本。当这些声音载入时,由于它们的尺寸小,不会占用很多的内存。当完整地载入内存时,这些声音可以被最佳地回放而不需要码流法附加的计算开销。这点使得加载方法成为小的音频文件的首选方法。

3.2 码流

音频码流使大的文件及大量的数据可以被计算机消化为数据序列。当运行一个游戏时,在内存中实际保存的文件只是音频数据的一部分,这时码流的方法尤其有效。码流的方法试图让一个大的音频文件变得很小。通过并行播放和加载音频文件来实现这个目的,特别通过把音频轨道看作数据的一个线性序列来考虑。文件的一个片段是被载入的,然后依次播放。当回放开始时,越来越多的音频数据从内存移除,更进一步为序列中即将播放的声音载入数据创造空间。

对于码流方法的应用引发了一个与加载方法相对应的性能开销。因为码流的方法必须要一直忙碌地卸载和载入数据,同时保证回放进程也处于正轨。但是,码流的方法确实意味着庞大的文件可以在不影响内存的使用上被回放。因为文件本身从来没有完全地载入到内存中。码流的方法更普遍地应用于音乐及语音等更大的文件格式数据的回放方法。

4 2D音频对应3D音频

游戏过程中播放的音频,无论从一个文件完全地加载还是形成码流,可以进一步分类为两种主要类型2D3D。20世纪90年代,3D引擎和游戏出现之前,所有音频都是2D的。3D音频产生于3D游戏。

3D音频的目的在于通过模仿现实世界中音频是如何听到的来提高视频游戏的贴合实际性。在拥有三个维度的现实世界,音频不像一组扬声器的音频那样被简单地听到。相对地,世界上的东西,例如鸟、人、铜管乐队制造噪声,并且那些噪声都在3D空间的某个真实位置。人们在听噪声时也站在3D空间中的一个特定位置,距离声源一定的距离,以及一定的角度和方向。这些空间特性发现于音频发射器中和音频接收者中,分别是制造声音和倾听声音的人,他们对于实际上音频是如何听到的有着巨大的影响,同时还伴随着其他因素,如环境的声学特性的影响。

这些特性不是一个声音设计者建立来使其成为音频资产的一部分的某些东西。它们不是音频文件本身或音频数据本身的固有效果。相对的,3D声音效果作为一个后处理效果被引擎以编程的方式添加进实时的声音中。

4.1 2D声音

2D和3D音频的最根本区别在于它们将某个真实世界中的3D传递给应用场景的能力。但是,一些音频并不受益于3D。音乐就是一个显著的例子。典型地,音乐作为一个场景的情绪伴随物播放,由于它本身在现实世界中不是真实存在的,因此它没有3D位置。音乐是因为有情感的,心理的及现象的特性而存在,不是因为它的存在能够使场景更加逼真。这种类型的音频不经受3D位置效果影响,因为这些效果会损坏音乐本身。当游戏者围绕某个水平面移动时,音乐作为一种情感片段去播放不应该改变音量,因为此时游戏者的位置对于音乐给人的感受是不相干的。音乐是应该按照这种情况去播放的。相同的原则也适用于菜单选项和其他游戏选项的反馈声,如哔哔声和杂音。这些声音也一样并不是典型地位于游戏环境中的任何地方,也不会被一些特定的人或者听者听到。

因此,2D声音没有3D效果应用的声音,这是对游戏很重要的声音。它们典型地包含音乐,菜单声音效果甚至是解说音画外音的声音。总之,在项目里要区分2D和3D声音分别应用前景并恰当地进行使用。

4.2 3D声音

如果音频被认为存在于游戏世界中,那么它成为一个3D音频便是合理的。

成为一个3D声音意味着它应该具备实用的3D效果。3D音频的实现细节在不同游戏引擎之间和不同开发者之间都是不同的,但是实现各种各样3D音频的最基本原理和开发原则是相同的。

3D音频的实现开始于两个基本概念

  • 存在于3D空间的声音(声源
  • 3D空间内能够听到3D声音的某物(听音者

有一个第三要素可以添加进来,声源和听音者均可以在3D环境本身中定位,这个环境应该具备所有的声学特征。

存在着某些东西**既可以作为声源也可以作为声音倾听者。**大多数引擎都能够而且允许游戏中的实体同时成为听音者和声源或同时不成为听音者和声源。也就是说,声源可以制造声音,并且听音者可以听到制造出来的声音。在这个基础上,3D音频的一些性质和特点出现了。

  • 音量和衰减

    3D空间影响了与听音者有关的音频声源的音量和衰减。总之,听音者离音频声源越远,听音者听到的声音音量就会越弱越低。

    听音者听到的音频声源的音量与听音者和音频声源之间的距离有关。一个虚构的包围着声源的球体可以绘制出来形象地表示声源的音量是如何根据听音者与声源的距离而衰减的,音量可以从处于球体中心的满格音量衰减到处于球体圆周上或者更远的静音状态。这个关于音量对于距离的生动表示,描述了音频信号的衰减性质。音量与距离之间的关系可以通过一个二次方程⑩绘制在一张平面曲线图上。总之,3D音频意味着音频声源的音量基于听音者位置的改变而改变,听音者的位置特性正如游戏者的位置特性一样。

  • 平移和方向

    现在大多数玩家在电脑上玩游戏时,都配备多个扬声器制造5.1声道和7.1声道的环绕声,在这些配置下,假设扬声器正确放置,3D声音便可以进一步提高它的真实性及视频游戏的3D效果。它通过非均匀地调整声源在不同扬声器上的音量,并根据玩家在场景中的方位和方向使得某些具体的声音在不同时间、不同扬声器上声音更大来提高效果。

    这个效果可以用来仿真定向。游戏中的3D声音可以提高场景的真实感,根据与周围音频声源相关的游戏者头部的方向去独立地控制扬声器中每一个声音地音量。

  • 混响和音质

    大多数的3D声音系统特性都受环境和音质影响。因为声音在抵达耳朵之前,它必然要跨过那些障碍物和环境,同时还要经过障碍物和环境的反射。这些效应还有回音效应,通常都是3D声音库的一部分,即使对于这些效应的支持和它们的变化及贴近实际性,在不同引擎之间和不同系统之间都是不同的。

5 音频技巧和诀窍

5.1 谨防过度混合

少便是多。如果一个游戏必须以太少或太多的声音效果作为特点,那么通常更少的声音效果会是更好的那个,即使理想的情况应该是处于二者之间的某一种。从只为一个场景添加少量的声音效果开始,停下来并检查那个场景。只有当场景比较乏味、空洞和空旷的时候,才继续添加更多的声音效果。

5.2 图画的替代品

开发过程中很多时候,声音是可以成功地替代图片产生场景中所需要的动作感,活跃感及生命力。这是非常重要的,因为可以减少开发者工作的资金消耗和时间消耗

5.3 侵入的音乐

声乐作品中一遍又一遍重复相同的音乐,可以将注意力吸引到重复中,从而使得游戏者恼怒而删除游戏。因此,建议避免将声乐作品放在音乐轨道中,除非具有一个最重要的高于一切的原因或者是一个例外的需要使用它的方案。

5.4 语音和定位

无论在哪里,试着将语音音频隔离出来并放入单独的文件中,而这些语音音频与游戏的音乐和声音效果是有区别的。目的是使语音数据作为一个能够简单地成为可替换的资产,而不影响诸如音乐和声音效果等其他资产。

语音是用自然语言讲出来的,例如英语或法语,因此它是特定的语言和领域。把游戏放到其他领域和市场,通常会要求地域性,也就是将游戏从一种语言翻译成另一种语言的处理过程,这个过程包括对字幕及语音的翻译。那些市场会期盼听到用当地的语言来发声的语音及用当地的语言写的字幕。对于开发者,本地化会包括大量的工作,但是这其中的许多工作又是可以最小化的,如果那些**资产被很谨慎地计划和制造。**制造孤立的语音资产和可替代的语音文件,意味着那些文件本身是可以由于本地化的目的而被其他语言的替代品所替代。

九、特殊效果和后期处理

1 在游戏中创造特殊效果

特殊效果这个术语通常应用于一个范围更窄的效果包里,开发者使用这些效果包试图仿真自然的或者超自然的现象,这些现象很难用标准工具箱去实现。因此,需要特殊的方法去实现它们。

使用关于顶点、边缘及多边形的标准网格材料去建立一个水滴的模型。然后,在认真仔细地完成一个高度精细的及样貌令人印象深刻的小滴状物体的建模后,会继续用类似水的影像为那个物体添加纹理从而使它看起来像实际中的水滴。最后,一旦建模成功,将会把它放入一个引擎中,在某个场景中复制它成千上万次,然后让那些复制的小滴状物体从天空落到地上从而赋予其生命力,使得一个成功的下雨效果被创造出来,小滴状物体从天空向地面倾泻而下。

这个传统方法可以用来创造下雨效果。但是它给出了值得注意的开发问题,这些问题可以通过更严密地解释这个方法是如何工作的体现出来,基于游戏的性能、时间及预算的问题。

首先,传统的方法应用于下雨效果时,会花费许多时间为那些小滴状物体建模及添加纹理,同时需要花费更多的时间描述让水滴因为重力的作用而落到地面的生动性。第二,可能也是最重要的,场景中成千上万高度精细的小滴网格的存在,例如闪光、亮光及透明度等的水纹理效果可以在它自己身上完成,不需要其他效果或者图像的参与,而如此集中的计算会使系统负担过重,以至于可以击垮当今最强大的硬盘。因此毫无疑问,这个传统的建模、添加纹理、为大多数有形的物体而引进的三步方法,并不是处理创造下雨效果中存在问题的方法。更进一步,它也不能成为创造包含许多小碎片,尤其是雪花、火花、灰尘、鸟的毛絮、蜜蜂群等,任何一种效果的方法。

2 粒子系统

实际上,粒子系统可以解决几乎所有情况下的问题,这些情况中创造的效果包括许多以一个可测的类似群的方式移动的小碎片,这些小碎片包括下雨、下雪、浓雾、火花、灰尘、小鸟、蜜蜂、蚂蚁、瀑布、子弹、火等等。

现在,粒子系统在游戏开发中是被普遍使用的,以至于几乎每一个游戏引擎对于粒子系统都是可用的,无论是免费的还是收费的引擎,并且以对粒子系统某些程度上的支持为特性。实际上,大多数引擎都有广泛支持粒子系统的特点,如Unity引擎、Unreal引擎以及CryEngine。

粒子系统是有关于整体思想和概念的一个打包,这个打包可以应用于使游戏达到各种各样的类似粒子的效果。

粒子系统依赖于以下3个元素一起工作

  • 粒子
  • 发射器
  • 行为

2.1 粒子

粒子系统最中心的概念就是粒子本身。如,可以把一个雨滴考虑成一个粒子.其他系统中,一个单独的火花、一只单独的蜜蜂、一只单独的小鸟,这些东西中的每一种都是一个更大更复杂的系统中的一个唯一分离的粒子。当这些粒子一起出现并和谐运转,它们就形成了一个粒子系统。

一个典型的粒子系统是以不精细的粒子为特点。可以通过使用布告板来实现

之前在水滴的情况下,不是为每一个粒子建模一个复杂的网格,取而代之的是一个粒子是用一个平面网格去表示,也就是由一个只有4个角的矩形网格去代表。这个网格时常与摄像头对齐,从而使摄像头总是可以从一个直观的、正面的角度去看那个粒子。这种更简单的网格叫布告板;每一个粒子对应于一个布告板。这个布告板会被绘制上一个合适的纹理,对应雨滴的一个滴状纹理、对应火花的一个火的纹理、对应蜜蜂的一个蜜蜂的纹理,等等。把那些全部加起来,这样一个布告板和它的纹理便组成了粒子。

2.2 发射器

花园的一支软管是用来喷射水的,典型地,这个是用在花园里,而不是用在好朋友身上。水离开那支软管进入空气中,在空气中又朝着目标落下,那只软管地尖端或者管口可以定义为水进入空气的点,它是水的源点或者起始点。在粒子系统中,这个点称为发射器。发射器是给予粒子生命的地方或者东西。所有的粒子都是在发射器处开始具有生命的。

发射器有着不同的形状和大小。如,下雨粒子系统,发射器可以想象成远远地悬浮在云朵的上方并面对着下面的一个巨大的平面或者平地的表层。雨滴粒子从发射器表面的随机的点中一同发射,在到达地面并终止之前,在重力的作用下以一个变化的速度往下游历。因此,发射器是系统中所有粒子的出生场所。所有的粒子都必须起始于发射器,即使它们不会结束或终止于发射器。

依赖于所需要创建的效果,粒子会从不同形状的发射器发出,也会来自于发射器中不同的点,同时还会以不同的发射速率发出。虽然下雨系统可以被平面形状的发射器所创建,且该发射器是以平稳无变化的速率发出粒子,但从一支魔棒的尖端爆发出火花却需要另外一个不同的配置。这样的一个系统中,粒子会典型地从一个单一的点发出,这个点就是魔棒的尖端,然后进入到一个短时间的爆炸性的几乎在它开始的时候就已经结束的爆发状态。不同粒子系统的发射器形状、大小及发射速率都是不同的,但是所有的粒子系统都基于同样一个概念,那就是不过多强调发射器本身的细节。

2.3 行为

发射器以一个特定的速率将粒子注入系统。然而,一旦粒子已经被发送,它们不会像那些无生命的、自由漂浮的粒子一样。一些起支配作用和控制作用的规则或者力量使那些粒子趋于和谐地移改变或者进行其他行为,从而实现需要的效果。总之,当一个粒子产生时,某些东西就会被需要来确定粒子该阶段的方向。

负责这件事情的东西叫做行为成分。这个成分的职责是去管理每一个粒子在它的生命路线中是怎样改变的,直到它终止了或是死亡了为止。典型地,行为成分依赖于许多数学及物理工作来激活粒子的位置,以使得它们本质上更类似于真实世界中的行为或特性,例如重力、微重力、惯性、风力、飞行轨迹及其他。不同的行为需要大量不同的实现方法,但是不同的实现方法下,它本身仍然是个随时间的变化去统治和管理粒子移动的行为成分。

3 粒子性质

3.1 粒子规模

就像游戏中的图像及网格都会有一个默认的规格一样,粒子系统中的粒子也可以在运行时动态地拉伸和收缩。粒子可以以标准的宽度及高度被绘制,然后收缩到让人察觉不到的的大小或者扩大到让人难以置信的大小。缩放粒子通过移动角的顶点位置来缩放一个四方网格的简单粒子。

粒子的规模及它在时间轴上被改变的方式,对于它可以创建的效果是非常重要的,因此它是一个特性,通常这个特性典型地被行为所激活。一些粒子系统几乎不需要去改变粒子的大小规模,因为它们的粒子在时间推移下保持着大小不变。

自然现象中观察粒子规模的变化,在粒子系统中正确地模仿粒子规模的变化,对于在各种各样的效果中建立可信度而言很重要。

3.2 粒子透明度

如果视频游戏中的粒子是一个真正的有纹理的布告板网格,事实也确实如此,那么它遵循着几乎所有粒子都需要的一些形式的透明度,因为几乎没有一个真实生活中的粒子看起来像一个矩形的布告板。隐藏粒子纹理的区域,对于创建看起来可信性高的粒子非常必要。粒子的纹理会以α的透明度为特性,使图像区域不透光,正如背景当它在游戏中展示于一个粒子上时应该隐藏起来。

然而,这不是粒子透明度的唯一用处。除了使图像中的区域不透光的这个纹理的透明度特性,粒子也控制着一个更普遍和更全面的透明度。透明度决定了粒子的总体可视度及传达关于粒子由哪种材料制作而成的信息。

随着时间的推移透明度的改变可以为某些种类的效果提供凭证。例如,通过反复地在一个循环中连续地加强,然后弱化粒子的透明度,可以为搏动的激光,异常的综合衍射图,力量场,未来主义的电脑控制台及仙女的拂尘等,增加额外的可信度。

3.3 粒子颜色

游戏中的粒子趋向于有一个混合于自己纹理中的整体颜色,从而用一个特定的色彩去染色或者阴影化自己的纹理。像其他粒子的性质一样,颜色也可以在时间轴上被行为激活来模仿各种各样真实世界的效果。像激活大多数粒子性质一样,行为激活通过将它们与粒子的生命关联到一起来实现。

粒子的生命可以表示为0到1的范围,此处0代表粒子从发射器发出的时刻,1代表粒子在系统中终结并且移除的时刻。0和1之间的小数点的值标记了粒子寿命中的点。考虑以上因素,粒子颜色及一个粒子的几乎所有其他数学性质可以制定为与寿命关联的一种关系,并随着生命的推移而改变。这个关于颜色的性质尤其重要,因为在现实世界中有许多这样的效果,在这些效果中粒子的颜色随着时间而变化。

4 粒子系统摘要

  • 最小化粒子

  • 所看非所得

  • 废除不可见粒子

5 手翻书纹理方法

一个平坦的平面需要一个有生命力的纹理在许多情况下都是存在的。它不是指网格或者本身的顶点是要改变和移动,而是指纹理本身要改变和移动。

这种效果可以用电影纹理手翻书纹理两种方法中的一种去创建,而这两种方法都包括对纹理的一个特殊化处理过程。电影纹理概念里,标准的电影文件不是一幅像PNG、JPG或者TGA格式的文件那样静止的画面,而是以一种纹理的形式应用到网格平面上。然而,第二种方法手翻书纹理是更常见的。

手翻书纹理的表现,特别类似于放映给孩子们看的手翻书动画片。这些书中,每一个右手边的页展示卡通片的一个单一的帧,而每一个随后的页显示下一帧。完整的动画片可以通过从头到尾按顺序地翻那本书的所有页而实现从头到尾回放。翻页的速度决定每一帧展示的速度,实现了动画里的动作和移动。

手翻书纹理的概念要求艺术家将一部完整动画片的所有帧都打包到一起并放到一个单独的纹理上面,按行和列将那些帧堆积好。当那些帧都打包进一个单独的纹理之后,那个纹理便可以应用于场景中的一个物体身上。手翻书纹理方法接着会绘制网格的UV坐标。它开始配置UV映射,以至于在任何时间那个网格的表面可以只显示来自于纹理的任何一个需要的帧。由于那些帧是整齐地打包成可预测的行和列的形式,手翻书纹理方法可以通过一帧一帧顺序地激活UV坐标来展示所有的被激活的画面。手翻书纹理提供了一种快速且方便的展示纹理卡通片的方法,而不会因为使用内存较大的电影文件而带来的巨大开销。更进一步,手翻书纹理方法甚至可以与粒子系统结合到一起来创建有生命的粒子纹理!即使手翻书纹理方法的实现细节和性能度量在不同的引擎之间不相同,但是支持它们的基本概念仍保持一致。无论何时需要有生命力的纹理时,推荐考虑手翻书纹理方法。

6 程序的几何学

用于视频游戏中的几何学术语用来表示网格数据,依次有关于顶点、边界及多边性。网格数据典型地被艺术家创造出来用于所精选的建模软件来制作模型,这些软件包括3DSMax,Maya和Blender。这种类型的网格数据,也就是预先被艺术家制作出来的网格数据,有时候是被看成静止的网格数据,要渲染的网格数据甚至是不易被改变的网格数据。这种类型的网格数据的主要特点是在游戏运行之前已经被制作出来。

与此相反,程序几何学中的网格数据是在游戏运行过程中,已经被高效运行的代码产生的网格数据。指的是根据一个具体的公式,一些具体的参数及一些来自于游戏者的具体的输入而在游戏运行时产生的网格顶点,边界及多边性。因此,程序几何学在本质上是一种动态的而非静态的制造网格的方法,由代码或者脚本来产生网格的过程。

程序几何学最明显的运用就是在游戏世界中为游戏者提供具体的定制化服务。如类似于Sim City and Cities XL的游戏使游戏者能够设计和建造城市,提供大量的不仅是对城市税收计划及经济政策的控制,而且是对城镇规划的控制,即哪里是建设道路,哪里是建设建筑物。为了创建道路,游戏者可以用鼠标来绘制点,然后作为对于输入的响应,道路便可以在这些点之间产生。典型地,这些情况下发生的事情便是程序化网格的产生过程,该场景中道路网格的顶点、边界及多边性根据一系列的游戏者定义的参数(道路的点)而实时地产生,去产生一条道路的意图正是与游戏者的设计匹配。然而,程序化几何学并不只限制于这种类型的行为及效果。实际上,这个强有力的并通用的在运行时产生网格的技术,可以产生一个可能无限的效果清单,产生如此多的效果以至于可以用一整本书来专门讲述这一项技术的使用。

由程序化几何而产生的一个显著的效果叫做战争之雾。战争之雾效果虽然时间已经比较长了,但是在今天的大多数策略游戏及这些游戏系列,如Warcraft,Starcraft,以及The Battle for Wesnoth等中存在着并且很好用。战争之雾的基本思想是扮演联盟或者军队还未到达或者被遗留下来的没人出现的战争区域的地形遮蔽物或者深色面纱。目的是在游戏中创建平衡、紧张及公平,来确保作为一个军队的指挥官不能看见没有你的军队存在的世界中所发生的事情。尤其确保了在没有做出努力去事先考察的情况下,没有办法观察到敌人的动态及战术。

为游戏开发者保留的是像这样一个效果是如何创建出来的问题。有许多不同的解决方法,但是几乎所有的解决方法都包括某种程序化几何学。

一种流行的方法是程序化地产生一个镶嵌成棋盘花纹的平面或者一个矩形的平面,也就是一个有许多顶点的平面网格。然后会为战争之雾平面分配一个黑色的、不透明的纹理,然后将这个平面悬浮于地面上的单元及天空中的摄像头之间的空气中,而天空中的摄像头就是游戏者看游戏世界及这个世界中所发生的事件的地方。默认假设游戏者正在目击所发生的一切,因此那个平面是不透明的、朦胧不清的并且整个地面都在它的下方。然而,每一个属于游戏者的在地面上的游戏元素,如一辆坦克或者是一个军人发射一支看不见的箭或者一道光线,这支箭或者这道光线从游戏元素的头部伸出来并继续以一条垂直的线往上射击直到与上面战争之雾的平面相交为止。当与平面的相交被检测到,引擎便可以间接地知道游戏者有一个直接在那个平面下方的友好元素,而这个平面应该对游戏者可见。作为响应,战争之雾平面处于相交上方的周围顶点可以设置为透明,将相应的纹理部分转变成不可见。使得游戏者可以穿过那个平面,看到地面及该平面下面所发生的事件。如果,与之相反,没有发生相交,那么游戏者肯定是在下方没有友好元素,因此那个平面应该继续在那个区域保持为黑色不透明,从而隐藏其下方的事件。

无论使用一个已经制作好的引擎还是自己制作引擎,都推荐尽早使用程序化几何方法。

7 带状轨迹

带状轨迹是一个本质上显著并且常见的游戏中程序化的几何方法的应用。赛跑游戏中,轿车及自行车通常会在轨道附近急速前进,在身后留下一个模糊的带着颜色的轨迹或者是留下一种幽灵般的迹象来传达速度的感觉。虚幻游戏中,当战士带有侵略性地摇晃手中施了魔法地宝剑和斧头,那些武器留下一种带着颜色的幽灵般的轨迹,给人们一种模糊轨迹的印象。弹球游戏中,当球移动时,通常留下一种带着颜色的幽灵般的轨迹来表示动作和路线。所有这些常见的效果都是带状轨迹的结果,这是一种用于强调移动的效果。

实际上,那些移动的物体,无论是一把宝剑,一辆轿车或者一个球在它们后面产生一个暂时的布告板物体的连接链,所有的布告板物体被添加纹理而产生一条长的连续的链。一旦产生了,每一个类似履带车一样的链中的布告板就表现得像一个单独的独立链接,而这个链接是占用了可以被弯曲拧转的链的一定比例。更进一步,链中的所有布告板在时间轴上根据它们被产生来制造冲淡效果的出现顺序而慢慢淡出直到毁灭。

8 后处理

游戏渲染系统负责把像素绘制到屏幕的二维空间上,即一个3D世界的快照,从一个摄像头的角度用光线和物体来完成。特别地,它利用了显卡硬盘(硬盘加速)从一个监控的角度转换一个3D场景并将它作为像素绘制在屏幕上,它在每一帧上都做这个处理。用这样的方法在每一帧去渲染屏幕意味着游戏渲染系统是一个实时的渲染者。因此,屏幕又可能每秒渲染100次,(每秒100帧)。然而,不管帧率是多少,每一个单独的帧构成了那个时间点的屏幕的独一无二的渲染及快照。接下来便处理所有那些应用于每一帧上的完整渲染的像素效果,以及调整的过程。

添加模糊过滤器、创建新的层、以及添加弯曲效果和颜色调整,都是后处理的形式,因为它们都应用于一幅已经存在的在早些时候已经被创建的图像,很有可能是被一个渲染系统,数字摄像头或者扫描仪所创建。在视频游戏中,这些效果不仅仅简单地应用一次或两次,而是应用于每一帧。 这个处理贯穿于整个利用顶点着色器或者像素着色器的过程,运行于显卡硬件本身并且一种诸如Cg或者HLSL的着色器语言写入一种特殊的低级语言程序用这些语言所写的程序包含着各种各样的应用于渲染器的像素效果指令。

8.1 模糊

也许最著名的后处理效果就是模糊及它的各种变化,例如运动模糊及半径模糊。模糊效果本质上是在渲染中复制像素,然后使附近的像素交错到一起,用这样一个方法来创建一种模糊或者污点的效果,使得看起来像是没有聚焦,有时候使用不清晰这个术语来描述。默认的、标准的模糊效果将模糊**不加选择地应用于渲染中的所有像素。**与之相反,部分模糊,如运动模糊,对于应用场景是有选择性的,只模糊那些在渲染时要在场景中移动的物体。有一种非正式的说法,就是模糊效果和丘陵一样老,从70或80年代最早的游乐场游戏出现时,模糊效果就已经以某些形式被广泛使用,这些模糊效果在今天仍被使用来强调动作及移动,还用来仿真醉态、吸毒的效果、瞌睡的效果、近视的状态,以及更多的有显著景深的东西。现在大多数已经建立好的引擎都支持模糊效果及它的许多衍生效果,并且很有可能会在自己的项目中频繁地使用模糊效果。

8.2 景深

景深(DOF)作为一个后处理效果是模糊效果的一个特殊效果目的是提高和增强渲染的3D效果或者深度是通过模仿摄像头或人类的眼睛来达到这个目的。本质上,景深将场景的一个渲染分解成两个主要的部分或者区域,即前景和背景,基于它们对于观察者而言的,由艺术家的意图所决定的重要性。前景主要突出眼睛应该聚焦的主题及事物,而背景突出其他东西,即该图像的负面空间景深模糊并弱化了背景,然而却保持前景突出并对准焦点。用这个方法强调了前景,因此可以帮助去引导眼睛不知不觉地看向图片的前景,并且仍然让你直观地了解到在那个前景之外的场景里的某个地方是存在一个背景的(即使那个背景没有吸引到你的注意力)。

总的来说,景深是一个低调却强大的效果,它普遍地运用于电影,游戏及摄影中,同时还运用于漫画书,在漫画书里背景用较少的线条来绘制。

8.3 泛光

模糊的一个更现代的并且流行的专门化效果是泛光。泛光效果已经在许多游戏中使用,尤其是有着梦幻的仿中世纪设置的RPGs。泛光识别场景中所有高亮的东西(最亮的像素),并且精细地模糊那些区域来增强亮度。这样做的结果是模糊和稀薄的照明的色圈会在最亮的区域出现来包围着物体。色彩沿着它们的轮廓,就好像通过一双睡眼朦胧或者半睁开的眼睛来看这个世界。泛光效果很晚才被大量使用,并且它可以为游戏添加神秘的色彩。然而,使用它的代价昂贵,因此要小心使用。

8.4 渐淡与渐晕

渐淡是关于渐渐变暗的过程或者渐渐减少一幅图像的边界饱和度的过程。已经变暗或者减小了饱和度的区域就用渐淡表示。想象被一个黑色的椭圆形的帧包围的图像,这个帧的边界被模糊化从而能够与那幅图像合并,这就是渐淡。在某种情况下,一个渐淡效果就是对那个世界的回忆,因为看那个世界的时候,你的眼睛是眯着或者是半睁开的。在这种情况下,一个被眼睑及睫毛所创建的弱化了的深色的边界,出现在所看见东西的周围,模糊了那幅图像边界的境界出现在人们面前。渐淡典型地**运用于传达害怕、不确定、困扰、恐慌、紧张、战斗及预感等情绪,有时候与运用于创建一种愁思。**现在,这个效果已经被大量使用,尤其在恐怖电影、惊险小说或者需要悬念及戏剧性的表达紧张情绪的任何情况下被广泛使用。

8.5 染色效果

染色效果在根本上不依赖于模糊效果和后处理效果。染色效果戏剧性地改变或者转化已经渲染了的图片颜色,将它们转变成与原始颜色完全不同的颜色。普遍来讲,染色效果在游戏中是保守使用的。一般被用来渲染喝醉的状态、空想的效果、噩梦的幻觉或者那些作用于精神的毒药的效果。强有力的能够形成鲜明对比的蓝色和绿色的混合在染色效果中是常见的,这个混合也可以用于仿真夜间的幻觉。

8.6 动画单帧阴影

动画单帧阴影是一个特殊的阴影算法及特殊的后处理效果,它用一个简化了的调色板、低对比的灯光及围绕物体的黑体的、用墨水涂染的轮廓将一个看起来规则整齐的3D场景转换成一个卡通场景。被算法所创造出来的结果比手画的卡通和图像看起来更像合成的。但是动画单帧阴影可以并确实为游戏产生了可信的感觉。实际上,动画单帧阴影是一种没有求助于模糊的改变或者染色的改变,便改变了渲染系统亮化、阴影化及色彩化场景的模型方式。总之,如果想要3D游戏有卡通的感觉而又不想改变模型的几何结构,那么动画单帧阴影技术也许可以很好地为你服务。更进一步地,相比于诸如还有动作模糊等效果,动画单帧阴影相对而言在计算开销方面更加经济。

8.7 镜头闪光

镜头闪光是明亮的,像星星一样的光晕,典型地出现于当摄像头面对着太阳并且光线在摄像头地镜头装置附近散射和折射的情况。该效果本身起初是一个明亮的到处渗透的光线是如何与摄像头交互的问题的一个无意识的副产品。但是许多人都认为这个效果漂亮、忧郁及迷人,因此,人们便努力地在视频游戏中人工地重建它。镜头闪光可以用于强调宁静、自然奇迹、浪漫主义、阳光充足的日子及青翠美丽的风景等。

注:技术上,镜头闪光效果不总是作为一个后处理效果来实现。有时候它是一个在渲染之前添加到场景里的基于纹理的效果。然而,它还是在后处理中实现。

你的注意力)。

总的来说,景深是一个低调却强大的效果,它普遍地运用于电影,游戏及摄影中,同时还运用于漫画书,在漫画书里背景用较少的线条来绘制。