OpenGL是一个开放式图形库,是一个用来渲染二维或三维计算机图形的跨平台的专业图形程序接口。对于Java来说,有两种基于OpenGL实现的渲染器。
OpenAL是一个开放式音频库,是一个跨平台的3D音频程序接口。
Context: 直接翻译为“上下文”,在开发中我们也常称之为上下文。上下文(Context)可以简单理解为当前对象在程序中所处的一个环境。JME3上下文(Context)为JME3游戏提供了所需的一切,包括:配置管理、渲染器、计时器、输入监听器、事件监听器和显示系统等。
Display: JME3显示系统 替代了Java Swing组件,用于绘制jME自定义窗口。 Input System: JME3输入系统 可以让你对用户输入做出反应,包括:鼠标点击、鼠标滑动、键盘输入、手柄操作等。 Renderer: JME3渲染器,用于处理将3D场景图绘制到2D屏幕上的所有计算工作。 Shader: 染色器是整个渲染管线的编程部分,jME3游戏引擎用它制作高级自定义材质。
多边形,网格,顶点
3D场景里大部分的可见物体都是由多边形网格组成的——角色、地形、建筑等等。网格(Mesh)是一种可以表达复杂形状的网状结构。网格的优点是,从数学角度讲足够简单,可以实时处理形状变化,细节上也足够辨认该物体。
每个形状都可以简化成一定数量相互连接的多边形(通常是三角形)。即便是圆形表面,比如球体,也可以简化成由许多三角形组成的网格形状。
多边形的拐角称作顶点,每个顶点都可以用坐标定位,所有顶点一起就可以标绘出该物体的大致轮廓。
你可以使用3D建模工具来创建3D网格,比如用Blender、3D Max、Maya、ZBrush等。jME可以加载3D网格模型,并把它们布置到场景里,但是引擎自己不能编辑网格。
我们所说的“颜色”仅仅是物体光线反射的一部分。观察者大脑用明暗对比和反射光推断物体的形状和材质。这些因素共同作用,使观察者能够区别粉笔与牛奶,皮肤与纸张,水与塑料等不同的物体。
- 网格物体的基色 - 就是当物体不受任何光源影响时显现出的颜色。
- 通常类似漫反射颜色。
- 是使该物体肉眼可见所需最少的颜色。
- 网格物体的基色加上受光源影响发出的碎光和阴影。
- 通常类似环境颜色。
发射色
- 由光源或发光材质散发出的光的颜色。
- 只有发光材质,比如光源,才有发光色,普通物体不具备此特性。
- 一般是白色的光(太阳光)。
- 物体表面的反光程度(1~128)。
- 有光泽的物体可以发出小面积的、轮廓清晰的反射光。(例如:玻璃、水、银器等)
- 普通物体的反射光通常是大面积的、模糊的。(例如:塑料、石头、抛光材质等)
- 凹凸不平的物体表面没有光泽。(例如:衣服、纸张、木头)反射颜色通常设置为ColorRGBA.Black(黑色)。
- 如果材质是有光泽的,那么高光颜色就是反射光的颜色。
- 通常和光源的发光颜色相同(例如白色)。
- 你可以使用不同的颜色来实现特殊的高光效果,比如金属光泽或彩虹反射。
- 非发光物体的高光颜色是黑色的。
纹理是材质的一部分。在最简单的情况下,一个对象可能只有一个纹理,即从一个图像文件加载的颜色贴图(Color Map)。当你回想起旧的电脑游戏时,你会记得这看起来相当普通。
你(游戏设计者)把颜色贴图(Color Map)做得越详细,细节度和真实度就越高。无论你想做到像拍照一样的真实感,还是像卡通片一样的赛璐珞风格(Cel Shading),这完全取决于你的材质和纹理的质量。最新的3D图形技术使用多个图层来描述一份材质,每个图层就是一张纹理。
没有纹理? 你可以从 opengameart 下载免费的纹理。记得把版权声明和纹理放在一起!
颜色贴图/漫反射贴图
凹凸贴图
凹凸贴图用于描述在网格编辑器中造型过于困难或效率太低的详细形状。凹凸贴图有两种可用的类型:
高度图
您可以使用高度图来模拟有山谷和山脉的大地形。
法线贴图
高光贴图
无缝贴图纹理
无缝纹理是一种非常简单、常用的纹理类型。当你在一个很大的区域(比如墙壁,地板)贴图时,你不需要创建一个巨大的纹理,相反你是做一小片纹理然后不断拼接直到填满整个区域。 无缝纹理是一个经过设计或修改的图像文件,它可以用作贴片: 右边缘匹配左边缘,顶边缘匹配底边缘。观众无法轻易分辨出一个纹理的起点和终点,因此产生了一种巨大纹理的错觉。不利的一面是,当从远处观察该区域时,瓷砖会痛苦地变得明显。此外,您不能将它用于更复杂的模型,比如角色。
UV贴图 / 纹理贴图集
给立方体形状贴纹理是很容易的,但是如果是一个有脸和四肢的角色呢?对于更复杂的物体,您可以参照平面缝纫模式用相同的方式设计纹理: 即一个图像文件包含物体的前面、后面和侧面的轮廓信息,并排放在一起。将平面纹理的指定区域(UV 坐标)映射到3D模型的指定区域(XYZ坐标),这种方式称为UV贴图(也叫纹理图集)。使用UV贴图,一个模型的每一个面都可以有不同的纹理。你可以为每个纹理创建一个相应的UV贴图。 精确地找到接缝然后正确拼接显得十分重要: 你必须使用某个图形工具,如 Blender 来创建 UV 贴图(纹理图集)和正确地存储坐标。
值得一试---- UV贴图模型看起来更专业。
环境映像,或者说反射映像,用来模拟实时反射和折射效果。这种方法比离线渲染程序中使用的射线追踪方法速度快,但是精确度低。 你可以创建一个立方体来表示周围环境;也可以创建球体映射,但是看起来会变形失真。总的来说,就是把周围环境当成环境贴图,设计一整套图片来表现背景场景的360°视图,类似一个天空盒的表现形式。然后用渲染器做环境映射,做出反射表面的纹理,最后得到可以接收的"玻璃、镜面、水"效果。就像天空盒,反射贴图是静止的,移动的物体(比如行走的人)不属于反射效果的一部分。
多对一贴图(MIP Map)意味着在一个文件中提供两个或三个不同分辨率的纹理图像。根据摄像机距离的远近,引擎会自动为物体呈现更多(或更少)的纹理细节。这样物体近看很细致,远看效果也很不错。这种办法还不错,但需要更多的时间来制作纹理,也需要更多的额外空间来存储纹理文件。如果自己不想做,jMonkeyEngine 可以自动创建基本的 MIP 贴图,用于性能优化。
程序纹理是由一个小图像不断地重复,外加上一些伪随机和梯度变化(称为柏林噪声)。程序纹理看起来比静态矩形纹理更加自然,他们看起来球面失真度小。对于大型网格物体,这种重复纹理看起来比无缝纹理更加自然。程序纹理若用于不规则大面积结构物体,效果更为立项,比如草地,土壤,石块,锈迹,还有围墙。可用jMonkeyEngine的 Neo Texture插件 来制作程序纹理。 还可以参考Blender: Every Material Known to Man
基于物理的渲染是计算机图形学的一种方法,它寻求以一种更精确地模拟现实世界中光流的方式来渲染图形 - Wikipedia(维基百科)
为了简化,PBR 尝试基于材质的纹理和光线如何变得更具反射性的角度来提供照片般逼真的纹理。换句话说,它是基于真实的物理学。所有的东西都有一个反射,但是在视频图形中准确地表示这个反射,在引入 PBR 之前,大部分都是通过技巧来实现的。使用不同的照明图像(高光贴图)叠加彩色图像(漫反射贴图)来模拟亮度的技巧。 使用 PBR 时,一种材料的“金属性”(导电性)或“介电性”(绝缘性)和“粗糙性”或缺乏这些将决定光是如何被反射的。例如,金属(金属性)比灰尘(电介质)更光滑,因此反射更强,而灰尘会吸收光线,就像在现实世界中一样。 上述技术被称为“金属化工作流程”。决定纹理是金属的还是电介质的,决定纹理的粗糙程度。 还有另外一种工作流叫做“高光工作流”。在金属工作流程的反照率映射是用于两个漫反射颜色和高光颜色。“高光工作流”改为使用镜面彩色贴图。在这个工作流程中,反照率贴图是漫反射颜色,高光贴图是高光颜色,你有一个与粗糙度贴图相同的灰度光泽贴图。工作流程非常类似于用于制作材料的旧技术。 本节简要介绍了 PBR。实际上,它需要大量的学习来正确实现。阅读名为物理基础渲染的三部分系列文章,可以在“材质、光线、阴影”主题下找到,从而对 PBR 纹理有更深入的解释。这是任何 jME 开发人员都必须阅读的内容。
参考: 理解金属性
在3D游戏中,骨骼动画是用于制作动画角色的,但是原则上骨骼方法可以扩展到任何一中3D网格物体(例如,一个开口板条箱的铰链可以被认为是原始的关节)。
除非你制作过3D卡通动画,否则难以体会,动画角色如何实现往往是十分棘手的问题: 角色动作可能看起来像外星人一样呆板、机械或破碎,角色形象看起来很空洞,或者像是漂浮的。专业的游戏设计师投入了大量的精力使动画角色以自然的方式生动起来,包括动作捕捉技术。
动画角色是有一个支架的: 一个内部骨骼(骨头)和一个外部表面(皮肤)。皮肤是动画角色可见的外表,它包括衣服。骨骼(骨头)是不可见的,是用来对皮肤的图像渐变做插值(计算)的。
JME3游戏引擎只能加载、显示录制好的动画,因此,你必须使用其他工具(比如Blender)创建角色(包括装配、蒙皮、制作动画的过程)。
装配 为动画角色构造骨架。
蒙皮 个别骨骼与相应皮肤部位的关联。
关键帧动画 一个关键帧是一个运动序列的记录快照。
动画制作(装配、蒙皮、关键帧)与动作变换(旋转、缩放、移动、插值)有何区别?
- 动作变换比动画制作简单。有时候,做个几何图形变换,看起来似乎就是动画了。比如,旋转的风车,脉动的能量球,机器拉杆的移动。用JME3实现动作变换非常容易。
- 然而,动画制作就复杂多了,它以一种特别的编码形式保存(关键帧)。动画制作会扭曲网格皮肤,而且,它有复杂的动作系列,需要借用外部工具记录,再用JME3显示。
在 jme3应用程序中,您可以向动画控制器(Animation Controller)注册动画模型。动画控制器使您能够访问可用的动画序列。控制器有几个通道,每个通道可以运行一个动画序列的时间。要运行多个序列,您需要创建多个通道,并且并行运行它们。
非玩家(计算机控制)角色(npc)只有当他们没有愚蠢地撞到墙上,或者盲目地冲进火线中时,才会在游戏中变得有趣。你需要让 npc“意识到”他们周围的环境,让他们根据游戏状态做出决定——否则玩家就可以忽略他们。最常见的用例是,你想让敌人以一种方式互动,这样他们就能为玩家提供一个更有趣的挑战。
使游戏变聪明的游戏设计元素,称为人工智能(AI )。人工智能可以用来实现敌人的NPC以及训练有素的宠物; 你也可以用它们来创建自动警报系统,在玩家触发入侵者警报后锁上门并“呼叫”守卫。
人工智能的领域,包括但不限于:
你也可以学习更先进的人工智能,例如神经网络。
有很多资源包好了有趣的人工智能算法: - 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",对它做球面线性插值。