3D游戏开发关键术语

3D图形和音频

OpenGL是一个开放式图形库,是一个用来渲染二维或三维计算机图形的跨平台的专业图形程序接口。对于Java来说,有两种基于OpenGL实现的渲染器。

  1. 轻量级Java游戏库 (LWJGL)
  2. Java开放图形库 (JOGL)

OpenAL是一个开放式音频库,是一个跨平台的3D音频程序接口。

上下文(Context)、显示(Display)、输入系统(Input System)、渲染器(Renderer)、染色器(Shader)

Context: 直接翻译为“上下文”,在开发中我们也常称之为上下文。上下文(Context)可以简单理解为当前对象在程序中所处的一个环境。JME3上下文(Context)为JME3游戏提供了所需的一切,包括:配置管理、渲染器、计时器、输入监听器、事件监听器和显示系统等。

Display: JME3显示系统 替代了Java Swing组件,用于绘制jME自定义窗口。 Input System: JME3输入系统 可以让你对用户输入做出反应,包括:鼠标点击、鼠标滑动、键盘输入、手柄操作等。 Renderer: JME3渲染器,用于处理将3D场景图绘制到2D屏幕上的所有计算工作。 Shader: 染色器是整个渲染管线的编程部分,jME3游戏引擎用它制作高级自定义材质。

几何(Geometry)

多边形,网格,顶点

多边形,网格,顶点

3D场景里大部分的可见物体都是由多边形网格组成的——角色、地形、建筑等等。网格(Mesh)是一种可以表达复杂形状的网状结构。网格的优点是,从数学角度讲足够简单,可以实时处理形状变化,细节上也足够辨认该物体。

每个形状都可以简化成一定数量相互连接的多边形(通常是三角形)。即便是圆形表面,比如球体,也可以简化成由许多三角形组成的网格形状。

多边形的拐角称作顶点,每个顶点都可以用坐标定位,所有顶点一起就可以标绘出该物体的大致轮廓。

你可以使用3D建模工具来创建3D网格,比如用Blender、3D Max、Maya、ZBrush等。jME可以加载3D网格模型,并把它们布置到场景里,但是引擎自己不能编辑网格。

材质:颜色、光照/着色

我们所说的“颜色”仅仅是物体光线反射的一部分。观察者大脑用明暗对比和反射光推断物体的形状和材质。这些因素共同作用,使观察者能够区别粉笔与牛奶,皮肤与纸张,水与塑料等不同的物体。

颜色

  1. 环境颜色
  • 网格物体的基色 - 就是当物体不受任何光源影响时显现出的颜色。
  • 通常类似漫反射颜色。
  • 是使该物体肉眼可见所需最少的颜色。
  1. 漫反射颜色
  • 网格物体的基色加上受光源影响发出的碎光和阴影。
  • 通常类似环境颜色。

光源

发射色

  • 由光源或发光材质散发出的光的颜色。
  • 只有发光材质,比如光源,才有发光色,普通物体不具备此特性。
  • 一般是白色的光(太阳光)。

反射光

  1. 反光度
  • 物体表面的反光程度(1~128)。
  • 有光泽的物体可以发出小面积的、轮廓清晰的反射光。(例如:玻璃、水、银器等)
  • 普通物体的反射光通常是大面积的、模糊的。(例如:塑料、石头、抛光材质等)
  • 凹凸不平的物体表面没有光泽。(例如:衣服、纸张、木头)反射颜色通常设置为ColorRGBA.Black(黑色)。
  1. 高光颜色
  • 如果材质是有光泽的,那么高光颜色就是反射光的颜色。
  • 通常和光源的发光颜色相同(例如白色)。
  • 你可以使用不同的颜色来实现特殊的高光效果,比如金属光泽或彩虹反射。
  • 非发光物体的高光颜色是黑色的。
高光颜色

材质:纹理

纹理是材质的一部分。在最简单的情况下,一个对象可能只有一个纹理,即从一个图像文件加载的颜色贴图(Color Map)。当你回想起旧的电脑游戏时,你会记得这看起来相当普通。

你(游戏设计者)把颜色贴图(Color Map)做得越详细,细节度和真实度就越高。无论你想做到像拍照一样的真实感,还是像卡通片一样的赛璐珞风格(Cel Shading),这完全取决于你的材质和纹理的质量。最新的3D图形技术使用多个图层来描述一份材质,每个图层就是一张纹理。

没有纹理? 你可以从 opengameart 下载免费的纹理。记得把版权声明和纹理放在一起!

纹理映射

  1. 颜色贴图/漫反射贴图

    颜色贴图/漫反射贴图
    • 是一个纯图片文件或程序纹理,用来描述物体可见的表面外观。
    • 该图片可以有Alpha透明通道。
    • 一张颜色贴图是最少的纹理。你可以做多个纹理映射,以改善画面质量。
    • 颜色贴图(Color Map)是没有经过渲染的。在Phong照明材质里这被称作漫反射贴图(Diffuse Map),因为纹理决定了物体漫反射光的基本色。
  2. 凹凸贴图

    凹凸贴图用于描述在网格编辑器中造型过于困难或效率太低的详细形状。凹凸贴图有两种可用的类型:

    • 您可以使用“法线贴图”(Normal Maps)对墙上的裂缝、锈迹、皮肤纹理或帆布织物等微小细节建模(更多关于凹凸贴图的相关资料)。
    • 您可以使用高度图来模拟有山谷和山脉的大地形。
  3. 高度图

    高度图

    您可以使用高度图来模拟有山谷和山脉的大地形。

    • 高度图是一种类似于地形图的灰度图像。较亮的灰色代表较高的区域,较暗的灰色代表较低的区域。
    • 高度图可以表示256个高度层,大多用于粗略的轮廓地形。
    • 你可以在任何图像编辑器中手工绘制高度图。
  4. 法线贴图

    法线贴图
    • 一个完美的法线贴图可以使一个形状更加详细,而不需要在网格中添加昂贵的多边形。它包含阴影信息,使物体显得更光滑和纹理更细粒度。
    • 在图像编辑器中打开“法线贴图”时,它看起来就像上错色的颜色贴图。然而,法线图不是用来上色的,相反,它里面的颜色是用来计算表面凸凹程度和裂缝的编码位移数据的。位移数据用斜面的表面法线表示,因此得名。
    • 你不能手动绘制或者手工编辑法线贴图,专业设计师用专用软件在高质量3D模型上通过运算的方法获得法线贴图。你可以花钱买专业的纹理图集,或者找那种包括法线贴图的免费图集
  5. 高光贴图

    高光贴图
    • 高光贴图进一步提高了物体表面的真实感: 它包含了关于光亮度的额外信息,使得物体的形状看起来更真实。
    • 从一张中灰色的漫反射贴图开始,这张贴图对应的是这种材质的平均亮度/暗度。然后添加更轻的灰色平滑,光亮,更多的反光区; 和更暗灰色的暗,粗糙,磨损的地区。生成的图像文件看起来类似于漫反射贴图的灰度版本。
    • 你可以在高光贴图中使用颜色来创建特定的反射效果(假彩虹色,金属效果)。
  6. 无缝贴图纹理

    无缝贴图纹理

    无缝纹理是一种非常简单、常用的纹理类型。当你在一个很大的区域(比如墙壁,地板)贴图时,你不需要创建一个巨大的纹理,相反你是做一小片纹理然后不断拼接直到填满整个区域。 无缝纹理是一个经过设计或修改的图像文件,它可以用作贴片: 右边缘匹配左边缘,顶边缘匹配底边缘。观众无法轻易分辨出一个纹理的起点和终点,因此产生了一种巨大纹理的错觉。不利的一面是,当从远处观察该区域时,瓷砖会痛苦地变得明显。此外,您不能将它用于更复杂的模型,比如角色。

  7. UV贴图 / 纹理贴图集

    UV贴图 / 纹理贴图集

    给立方体形状贴纹理是很容易的,但是如果是一个有脸和四肢的角色呢?对于更复杂的物体,您可以参照平面缝纫模式用相同的方式设计纹理: 即一个图像文件包含物体的前面、后面和侧面的轮廓信息,并排放在一起。将平面纹理的指定区域(UV 坐标)映射到3D模型的指定区域(XYZ坐标),这种方式称为UV贴图(也叫纹理图集)。使用UV贴图,一个模型的每一个面都可以有不同的纹理。你可以为每个纹理创建一个相应的UV贴图。 精确地找到接缝然后正确拼接显得十分重要: 你必须使用某个图形工具,如 Blender 来创建 UV 贴图(纹理图集)和正确地存储坐标。

值得一试---- UV贴图模型看起来更专业。

  1. 反照率贴图 反照率贴图类似于漫反射贴图,只是没有阴影和高光。它们被用作 PBR 材料的基色。

环境映射

环境映射

环境映像,或者说反射映像,用来模拟实时反射和折射效果。这种方法比离线渲染程序中使用的射线追踪方法速度快,但是精确度低。 你可以创建一个立方体来表示周围环境;也可以创建球体映射,但是看起来会变形失真。总的来说,就是把周围环境当成环境贴图,设计一整套图片来表现背景场景的360°视图,类似一个天空盒的表现形式。然后用渲染器做环境映射,做出反射表面的纹理,最后得到可以接收的"玻璃、镜面、水"效果。就像天空盒,反射贴图是静止的,移动的物体(比如行走的人)不属于反射效果的一部分。

MIP多对一贴图

多对一贴图(MIP Map)意味着在一个文件中提供两个或三个不同分辨率的纹理图像。根据摄像机距离的远近,引擎会自动为物体呈现更多(或更少)的纹理细节。这样物体近看很细致,远看效果也很不错。这种办法还不错,但需要更多的时间来制作纹理,也需要更多的额外空间来存储纹理文件。如果自己不想做,jMonkeyEngine 可以自动创建基本的 MIP 贴图,用于性能优化。

程序纹理

程序纹理

程序纹理是由一个小图像不断地重复,外加上一些伪随机和梯度变化(称为柏林噪声)。程序纹理看起来比静态矩形纹理更加自然,他们看起来球面失真度小。对于大型网格物体,这种重复纹理看起来比无缝纹理更加自然。程序纹理若用于不规则大面积结构物体,效果更为立项,比如草地,土壤,石块,锈迹,还有围墙。可用jMonkeyEngine的 Neo Texture插件 来制作程序纹理。 还可以参考Blender: Every Material Known to Man

基于物理的渲染纹理(PBR)

基于物理的渲染是计算机图形学的一种方法,它寻求以一种更精确地模拟现实世界中光流的方式来渲染图形 - Wikipedia(维基百科)

为了简化,PBR 尝试基于材质的纹理和光线如何变得更具反射性的角度来提供照片般逼真的纹理。换句话说,它是基于真实的物理学。所有的东西都有一个反射,但是在视频图形中准确地表示这个反射,在引入 PBR 之前,大部分都是通过技巧来实现的。使用不同的照明图像(高光贴图)叠加彩色图像(漫反射贴图)来模拟亮度的技巧。 使用 PBR 时,一种材料的“金属性”(导电性)或“介电性”(绝缘性)和“粗糙性”或缺乏这些将决定光是如何被反射的。例如,金属(金属性)比灰尘(电介质)更光滑,因此反射更强,而灰尘会吸收光线,就像在现实世界中一样。 上述技术被称为“金属化工作流程”。决定纹理是金属的还是电介质的,决定纹理的粗糙程度。 还有另外一种工作流叫做“高光工作流”。在金属工作流程的反照率映射是用于两个漫反射颜色和高光颜色。“高光工作流”改为使用镜面彩色贴图。在这个工作流程中,反照率贴图是漫反射颜色,高光贴图是高光颜色,你有一个与粗糙度贴图相同的灰度光泽贴图。工作流程非常类似于用于制作材料的旧技术。 本节简要介绍了 PBR。实际上,它需要大量的学习来正确实现。阅读名为物理基础渲染的三部分系列文章,可以在“材质、光线、阴影”主题下找到,从而对 PBR 纹理有更深入的解释。这是任何 jME 开发人员都必须阅读的内容。

参考: 理解金属性

动画

在3D游戏中,骨骼动画是用于制作动画角色的,但是原则上骨骼方法可以扩展到任何一中3D网格物体(例如,一个开口板条箱的铰链可以被认为是原始的关节)。

除非你制作过3D卡通动画,否则难以体会,动画角色如何实现往往是十分棘手的问题: 角色动作可能看起来像外星人一样呆板、机械或破碎,角色形象看起来很空洞,或者像是漂浮的。专业的游戏设计师投入了大量的精力使动画角色以自然的方式生动起来,包括动作捕捉技术

装配和蒙皮

装配和蒙皮

动画角色是有一个支架的: 一个内部骨骼(骨头)和一个外部表面(皮肤)。皮肤是动画角色可见的外表,它包括衣服。骨骼(骨头)是不可见的,是用来对皮肤的图像渐变做插值(计算)的。

JME3游戏引擎只能加载、显示录制好的动画,因此,你必须使用其他工具(比如Blender)创建角色(包括装配、蒙皮、制作动画的过程)。

  1. 装配 为动画角色构造骨架。

    • 创建尽可能少的骨头,以减少复杂性。
    • 骨骼在父子层次结构中相互连接: 移动一块骨头可以拉动另一块骨头(例如运动胳膊会带动手掌)。
    • 骨骼遵循特定的命名方案,所以3D引擎知道什么是什么。
  2. 蒙皮 个别骨骼与相应皮肤部位的关联。

    • 每块骨头都与皮肤的一部分相连。(看不见的)骨头拽着(看得见的)皮肤跟它一起动。比如:大腿骨与大腿上部皮肤的连接。
    • 一部分皮肤可以受到一个以上的骨骼影响。(如膝盖,肘部)。
    • 骨骼和皮肤部分之间的联系是渐进的: 你给每个皮肤多边形的权重分配受任何骨骼运动影响的程度。例如,当大腿骨移动时,腿部完全受影响,髋关节受影响较小,头部则完全不受影响。
    • jMonkeyEngine 支持硬件蒙皮(在 GPU 上,而不是 CPU 上)。
  3. 关键帧动画 一个关键帧是一个运动序列的记录快照。

    • 一系列的关键帧组成了一个动画。
    • 每个模型都可以有几个动画,每个动画都有一个名字来标识它(例如“走”,“攻击”,“跳”)。
    • 您可以在游戏代码中指定要加载哪个关键帧动画,以及何时播放它。

动画制作(装配、蒙皮、关键帧)与动作变换(旋转、缩放、移动、插值)有何区别?

  • 动作变换比动画制作简单。有时候,做个几何图形变换,看起来似乎就是动画了。比如,旋转的风车,脉动的能量球,机器拉杆的移动。用JME3实现动作变换非常容易。
  • 然而,动画制作就复杂多了,它以一种特别的编码形式保存(关键帧)。动画制作会扭曲网格皮肤,而且,它有复杂的动作系列,需要借用外部工具记录,再用JME3显示。

运动学

  • 正向运动学: 给定已知角色所有关节的角度,求改角色手部位置在哪里?
  • 逆运动学: 根据角色手部的位置,求该角色其他关节的角度是多少?

控制器及频道

在 jme3应用程序中,您可以向动画控制器(Animation Controller)注册动画模型。动画控制器使您能够访问可用的动画序列。控制器有几个通道,每个通道可以运行一个动画序列的时间。要运行多个序列,您需要创建多个通道,并且并行运行它们。

AI人工智能

非玩家(计算机控制)角色(npc)只有当他们没有愚蠢地撞到墙上,或者盲目地冲进火线中时,才会在游戏中变得有趣。你需要让 npc“意识到”他们周围的环境,让他们根据游戏状态做出决定——否则玩家就可以忽略他们。最常见的用例是,你想让敌人以一种方式互动,这样他们就能为玩家提供一个更有趣的挑战。

使游戏变聪明的游戏设计元素,称为人工智能(AI )。人工智能可以用来实现敌人的NPC以及训练有素的宠物; 你也可以用它们来创建自动警报系统,在玩家触发入侵者警报后锁上门并“呼叫”守卫。

人工智能的领域,包括但不限于:

  • 知识——知识是人工智能可以访问的数据,AI能的决策也基于这些数据。现实的AI只“知道”他们“看到和听到”的东西。这意味着信息可以隐藏的AI,以保持游戏的公平。你可以拥有一个无所不知的AI,或者你可以只让一些AI分享信息,或者你只让那些非常接近的AI知道当前状态。例如: 当玩家绊倒电线后,只有少数带有双向收音机的 AI NPC开始朝玩家的位置移动,而许多其他守卫还没有怀疑任何事情。
  • 目标规划——所谓目标规划就是AI如何“采取行动”。每个AI都有优先权达成某项具体目标,目的是为达到未来某种状态。编程的时候,你把AI的目标分解成几个小目标。AI求助于它的知识获取当前状态,从储备的战术/战略中甄选,同时做优先排序。AI不停地考察当前状态是否更接近目标。如果不是,AI舍弃当前战术/战略,选择另一个进行尝试。举例:AI在一个不断变化的环境里所搜到达玩家基地的最佳路径,同时还要避开陷阱。AI追踪玩家,目标是消灭他。AI藏起来不让玩家看到,目标是谋杀VIP。
  • 解决问题——问题解决是AI如何_对干扰做出反应_,就是摆在自己和目标之间的障碍。AI依据一套假定的事实和规则推算自己的状态——基于类似轻微疼痛、剧痛、厌倦或者陷入困境的觉知作出选择。在每个状态里,只有选择具体的反应子集才有意义。实际的反应还取决于该AI的目标,因为AI的行动不一定能阻碍自己的目标!举例:如果玩家接近自己,AI是选择攻击还是隐藏自己,亦或是给出警告?AI空闲的时候,他是布置陷阱呢,还是给自己疗伤,亦或是给魔法符文充能?如果有生命危险,AI是选择逃跑还是与对方同归于尽?

你也可以学习更先进的人工智能,例如神经网络。

有很多资源包好了有趣的人工智能算法: - A*寻路理论 - GOAP - 面向目标的行动计划 - Neuroph ー Java 神经网络 - 等等...

数学

坐标

坐标

坐标表示坐标系中的一个位置。坐标相对于(0,0,0)的原点。在3D 空间中,您需要指定三个坐标值来定位一个点: x (右) ,y (上) ,z (朝向您)。同样,-x (左) ,-y (下) ,-z (远离你)。与向量(看起来相似)相反,坐标是一个位置,而不是一个方向。

原点是三维世界中的中心点,也就是三个轴相交的地方。它总是在坐标(0,0,0)处。 例如:

Vector3f origin = new Vector3f( Vector3f.ZERO );

向量

向量有长度和方向,就像三维空间中的箭头一样。向量从坐标(x1、 y1、 z1)或原点开始,到目标坐标(x2、 y2、 z2)结束。向后的方向用负值表示。 示例:

Vector3f v = new Vector3f( 17f , -4f , 0f ); // starts at (0/0/0)
Vector3f v = new Vector3f( 8f , 0f , 33f ).add(new Vector3f( 0f , -2f , -2f )); // starts at (8,-2,31)

单位向量是一个长度为1个世界单位的基本向量。由于它的长度是固定的(因此它只能指向一个位置) ,这个向量唯一有趣的地方就是它的方向。

- Vector3f.UNIT_X = ( 1, 0, 0) = 右
- Vector3f.UNIT_Y = ( 0, 1, 0) = 上
- Vector3f.UNIT_Z = ( 0, 0, 1) = 前方
- Vector3f.UNIT_XYZ = 1 wu diagonal right-up-forewards
- 

对向量的分量求负,可以改变它的方向。例如:对右方向(1, 0, 0)求负得到左方向(-1, 0, 0)。

标准化向量是自定义单位向量。标准化向量与(曲面)法向量不同。当对一个矢量进行正则化时,它仍然具有相同的方向,但是丢失了矢量最初指向的地方的信息。 示例: 在计算角度之前将向量归一化。

曲面法线是与平面垂直(正交)的矢量。通过计算叉积计算曲面法线。 曲面法线

叉乘是用来计算垂直向量(一个正交的,一个90 ° 的“直角”)的计算。在三维空间中,说到正交只有在平面上才有意义。你需要两个向量来唯一地定义一个平面。这两个矢量的叉乘,v1 × v2,是垂直于这个平面的一个新矢量。垂直于平面的向量称为表面法线。 举例: x单位向量和y单位向量合在一起可以定义x/y平面。垂直于该平面的向量就是z轴。JME可以计算出这个方程为真:( Vector3f.UNIT_X.cross( Vector3f.UNIT_Y ) ).equals( Vector3f.UNIT_Z ) == true

动作变换的意思是指在3D场景下,表现物体的旋转、缩放(重新定义大小)或者位移。3D引擎针对这些过程提供简化方法,你写写代码就可以使节点完成动作变换。 举例: 3D俄罗斯方块游戏里面下落并旋转的方块

**球面线性插值(Slerp)**就是球面线性插值的英文单词快读结果,写出来是 Spherical linear interpolation。一个Slerp就是一个插值变换,用来做简化的3D引擎动画。定义初始状态和结束状态,然后slerp插入中间过程,做出从一个状态到另一个状态的等速变换。你可以正常播放、暂停、回放、快进该动作。 JavaDoc: slerp()) 举例: 一个正在燃烧的陨石形状几何体,位置p1,旋转速度r2,缩放比例s1。从天空下坠到地面"p2, r2, s2",对它做球面线性插值。

点击这里了解更多关于3d 数学的知识。

3D图形术语wiki百科