Cocos2d-x程序员手册(ProgrammersGuide)v3.3 第9章:3D

Cocos2d-x程序员手册(ProgrammersGuide)v3.3 翻译——第9章:3D

原著是英文,本文只是一个个人的简单理解的中文的非正式翻译,供自己学习使用,参考需谨慎。
向原著的作者SlackMoehrle, Ricardo, Justin, Nite , Kai, Minggo, Wenhai, Tony, Yingtao, Rao 致敬


第9章:3D

你应该已经对Cocos2d-x已经有所熟悉,并且知道它2D游戏引擎。实际上从版本3开始,我们增加了3D特性并从新定义了Cocos2d-x。3D游戏是一个巨大的市场。Cocos2d-x已经增加了所有3D开发所需的特性。你可能刚开始接触3D开发并且会碰到一些你不太熟悉的术语。而且还有一些你需要熟悉的软件。不多说,直接开始吧

初识3D

3D精灵

和2D游戏一样,3D游戏也有精灵。是的,精灵是一切有些的核心基础。3D精灵有z轴坐标,而不是只有xy轴坐标。3D精灵在很多方面和2D精灵非常相似。加载并且在屏幕上生成一个3D精灵非常容易:

auto sprite = Sprite3D::create("boss.c3b");
sprite->setScale(5.f);
sprite->setPostion(Vec2(200, 200));
scene->addChild(sprite);

这段代码使用一直的文件创建了一个3D精灵。如图:
这里写图片描述

术语

这些并不是类的名字,但是使用3D的话,这些是你非常需要知道的一些术语:

  • Mesh ——构成需要渲染的图形或者贴图的顶点
  • Model ——一个可以渲染的对象。它由Mesh的集合组成,在我们的游戏中,它就是3D精灵。
  • Camera ——由于3D世界并不是一个平面,所以你需要设置一个视角来观察它们。使用普通的Camera参数将得到不同的场景。
  • Light ——光线是为了让场景看上去更加真实。为了使物体看上去更加真实,我们需要让色彩随着光线而改变。当你面向光德时候物体看上去更加明亮,相反就会暗淡。光线效果意味着根据光线关系来计算物体的颜色。

让3D精灵开始工作

给3D精灵绑定其他3D模型

上面提到,3D模型就是mesh的集合。你可以将3D模型绑定到另一个3D模型上以创造丰富的效果,比如给角色添加武器。在绑定之前,你必须知道武器将会绑定到哪个点。使用 getAttachNode(attachment_point_name)函数可以获知。我们还可以将这个新的模型通过绑定点和addChild()函数添加到其他的对象上。你可以想象的到,我们通过绑定多个简单的3D模型来创造一个更加复杂的3D模型。一下是例子代码:

auto sp = Sprite3D::create("axe.c3b"); sprite->getAttachNode("Bip001 R Hand")->addChild(sp);

这里写图片描述

替换3D模型

在做3D开发的时候,你可能希望动态改变模型。比如能力增强,服饰改变或者其他一些视觉上的变化使玩家知道模型的状态有所改变,如果你的3D模型是由mesh组成,你可以使用getMeshByIndex()getMeshByName() 来获取mesh的数据。使用这些函数可以非常容易的实现你想要得效果,比如为角色更换武器或者衣服。让我们以一个穿着大衣的女孩为例:
这里写图片描述
我们可以通过改变我们使用的mesh对象的可见性来改变女孩所穿的大衣。下面的代码演示了这个过程是如何完成的:

auto sprite = Sprite3D::create("ReskinGirl.c3b");

// display the first coat
auto girlTop0 = sprite->getMeshByName("Girl_UpperBody01");
girlTop0->setVisible(true);

auto girlTop1 = sprite->getMeshByName("Girl_UpperBody02");
girlTop0->setVisible(false);

// swap to the second coat
girlTop0->setVisible(false);
girlTop1->setVisible(true);

结果如下:
这里写图片描述

动画

3D游戏对于游戏至关重要!我么已经知道该如何操纵它了。当时我们可能需要一些更加丰富的体验。动画!你可以使用Animation3D和Animate3D来运行3D动画。你可以使用Animation3D来创建Animate3D动画,例子如下:

// the animation is contained in the .c3b file
auto animation = Animation3D::create("orc.c3b");

// creates the Action with Animation object
auto animate = Animate3D::create(animation);

//runs the animation
sprite->runAction(RepeatForever::create(animate));

运行手册的例子代码看动画吧!记住3D动画实际上和2D动画是一个概念。你可以回顾一下第4章。

多重动画

如果你想同时运行多个动画该怎么办?使用 animation start time (动画开始时间)和animation length (动画长度)参数你一创建多重动画。所有参数的单位都是秒。例:

auto animation = Animation3D::create(fileName);

auto runAnimate = Animate3D::create(animation, 0, 2);
sprite->runAction(runAnimate);

auto attackAnimate = Animate3D::create(animation, 3, 5);
sprite->runAction(attackAnimate);

上面的示例中运行了来那个动画。第一个立即开始,并持续2秒。第二个在3秒后开始,并持续5秒。

动画播放速度

动画播放速度是正数的时候,动画播放的顺序是正的,负数的时候,将到着播放。

动画协调

当我们使用动画的时候,实际上在动画之间已经使用了自动协调。协调动画的目的是动画效果之间的过度更加平滑。已知两个动画A和B,A动画的最后级帧和B动画的开始几帧会重叠是的动画过度看上去更加自然。
默认的转化时间是0.1秒。可以通过Animate3D::setTransitionTime来设置过度时间。
Cocos2d-x现在只支持关键帧的线性补插。在动画中补充这些帧是为了确保动画的平滑连续。如果你在制作model的时候使用了其他插值法制作,我们的内建工具fbx-conv会创建额外的关键帧来补偿所缺动画帧。这些补偿帧会与目标帧保持一致性。关于fbx-conv的更多信息在本章最后进行了专门的讨论。

视角(相机)

视角是3D开发一个非常重要的部分。由于3D世界并不是一个平面,所以你需要使用视角来看世界,从不同视角看到的世界是不同的。就像你看电影的时候视角会来回移动一样。使用视角对象与次相似。视角节点继承自节点,因此支持许多动画。有两种类型的视角对象:透视视角正交视角
透视视角 看到的东西有远近效果。透视视角 看到的东西大致如下:
这里写图片描述
如你所见,透视视角下,进的物体大而远的物体小。
正交视角用于看远距离的物体,你可以把它看做是3D世界的2D表现。正交视角看东西大致如下:
这里写图片描述
由图可见,正交视角看到的东西的大小和物体与观察者的距离无关。游戏中的小地图通常会采用正交视角渲染。另外就是一些俯视视角游戏,比如地牢风格德游戏。

视角的使用

视角对象听起来非常复杂,但是Cocosd-x使他变得简单易用。当使用3D时,你不需要做什么特别的工作来创建一个视角对象。事实上,每个场景都会多会基于导演的工程属性创建一个默认的视角对象。如果你需要的视角不止一个,你可以使用以下代码来创建一个新的视角对象:

auto s = Director::getInstance()->getWinSize();
auto camera = Camera::createPerspective(60, (GLfloat)s.width/s.height, 1, 1000);

// set parameters for camera 
camera->setPosition3D(Vec3(0, 100, 100));
camera->lookAt(Vec3(0, 0, 0), Vec3(0, 1, 0));

addChild(camera); // add camera to the scene

创建正交视角

默认的视角是透视视角。如果你可以使用Camera::crateOrthographic()创建正交视角,例:

auto s = Director::getInstance(0->getWinSize();
auto camera = Camera::createOrthographic(s.width, s.height, 1, 1000);

在视角中隐藏物体

有些时候我们并不希望所有东西都显示在视角中。在一个视角中隐藏一个物体很容易。在物体上使用* setCameraMask(CameraFlag) * 并在相机上使用 setCameraFlag(CameraFlag) 就可以了。例:

// Camera 
camera->setCameraFlag(CameraFlag::USER1);

// Node
node->setCameraMask(CameraFlag::USER1);

光线

光线对于塑造环境和氛围十分重要。现在主要支持4中光线处理技术。你需要根据自己的需求来选择不同的光线处理技术。每种光线处理技术的效果都不同。

环境光(AmbientLight)

环境光适用于光线均匀的场景。想想办公室里的光线,光线来自屋顶,当你观察身边的事物的时候,你会发现它们的光线是相同的。
如下:
这里写图片描述

平行光(DirectiongLight)

平行光常用来模拟类似于太阳光的场景。适用平行光时,无论你离光源近或者远,光线的浓稠的都是一样的。你可以想象一下晴天户外的阳光。当你看向太阳的时候,太阳的光十分强烈,不论你如何移动都是如此。例:

auto light = DirectionLight::create(Vec3(-1.0f, -1.0f, 0.0f), Color3B::RED); addChild (light);

效果如下:
这里写图片描述

发散光(点光源PointLight)

电光源常用来模拟灯泡、点灯或者火炬的效果。点光源的方向是从被照亮的位置指向点光源位置的。光的强度是随着里点光源的距离发生变化的。就是说,离点光源近的受到的光照强,而远的受到光照则弱。

auto light = PointLight::create(Vec3(0.0f, 0.0f, 0.0f), Color3B::RED, 10000.0f); addChild (light);

效果:
这里写图片描述

聚光灯效果(SpotLight)

聚光灯的效果类似于手电筒。在一个固定的形状中向一个方向射出。想一想你家突然停电,你需要一个手电筒到你的地下室去检查线路。手电筒射出圆锥形的光柱,这时你只能看到圆锥形的光柱里面的东西。再举一个例子,比如在一个黑暗的地牢游戏中,你的前面的路被一个手电照亮你只能看到有限的锥形光柱中的物体。例:

auto spotLight = SpotLight::create(Vec3(-1.0f, -1.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Color3B::RED, 0.0, 0.5, 10000.0f) ;
addChild (spotLight);

效果如下:
这里写图片描述

光线遮罩

你厨房或者起居室中的光线是什么样的?或许是好几盏灯。你试过用一盏灯照亮房间的某个特定的位置么?这个时候你就是在使用光线遮罩!
光线遮罩的使用可以指定某个节点只被某一个特定的光源照亮。例如一个场景中有三个光源,我们可以指定一个节点只收到其中一个光源的照射。你可以使用 setLightFlag(LightFlag) 来控制哪一个节点收到这个光源的效果。注意所有光源都是被一次渲染的。由于性能问题,我们并不推荐在移动设备上使用多光源。默认的最大光源数是1。如果你希望打开多光照射效果,你必须在info.plist中定义下面的值:

<key> cocos2d.x.3d.max_dir_light_in_shader </key>
<integer> 1 </integer>
<key> cocos2d.x.3d.max_point_light_in_shader </key> <integer> 1 </integer>
<key> cocos2d.x.3d.max_spot_light_in_shader </key>
<integer> 1 </integer>

3D 软件

3D编辑器

3D编辑器就是编辑3D图形工具的集合。既有商业的也有免费的。下面是一些流行的编辑器:

  • Blender(免费)
  • 3DS Max
  • Cinema4D
  • Maya
    大多数编辑器都能够将文件保存为一组便于其他编辑器使用的格式,这也方便了游戏引擎的导入和使用。

Cocos2d-x 提供的工具

Cocos2d-x 提供了工具将3D文件转换成Cocos2d-x可以使用的格式。
fbx-conv command-line tool (fbx-conv命令行工具) fbx-conv可以将FBX转换成Cocos2d-x属性文件。FBX是3D最流行的文件格式,被大多数编辑器支持。fbx-conv默认输出.c3b文件。它的使用参数非常简单:

fbx-conv [-a|-b|-t] FBXFile

可能的选项:

  • -?:显示帮助
  • -a:输出所有文本和二进制格式
  • -b:输出二进制格式
  • -t:输出文本格式
    例:
fbx-conv -a boss.FBX

这里有几点需要注意:
model需要至少包含1张贴图;
只支持骨骼动画;
现在只支持一个骨骼对象,还不支持多个;
你可以通过输出多个静态模型来创建一个3d场景;
一个网格图(mesh)中的顶点数不能超过32767.

3D文件格式

Cocos2d-x现在支持两种3D文件格式:

  • Wavefront 对象文件:.obj 文件
  • Cocos2d-x 3d ad-hoc 格式:c3t,c3b文件

Wavefront 文件格式之所以被支持是因为它被很多3D编辑器采用,并且非常容易解析。但是它并不支持动画。
另一方面 c3t和c3b是Cocos2d-x属性文件格式,可以用来创建带有动画、材质和其他的高级的3d特性的对象。后缀t表示 text(文本),而b代表binary(二进制)。开发者应该使用c3b,因为它的效率跟高。如果你希望调试文件,并且在git或者其他版本控制中追踪这个文件,你需要使用c3t。另外Animation3D对象可以由c3b和c3t创建,但是.obj文件却不可以创建动画。

高级讨论

告示牌(BillBoard)

你以前肯定也听说过告示牌。但是我说的不是高速路上的告示牌。实际上这里的 BillBoard是一个特殊的精灵,它永远正对视角。当你的视角选装的时BillBoard也会随之旋转。BillBoard是一个非常普遍的成像技术。举个例子,比如一个快速滑雪游戏,任何一个树,石头或者其它在滑雪者路上的物体,都是一个BillBoard对象。下图展示了视角和BillBoard旋转关系。
这里写图片描述

BillBoard 的使用

BillBoard使用起来非常简单。BillBoard是有精灵(Sprite)精灵发展而来,所以它支持了精灵的大多数属性。我们通过下面的代码来创建它:

auto billboard = BillBoard::create("Blue_Front1.png", BillBoard::Mode::VIEW_POINT_ORIENTED)

你也可以给XOY平面创建一个BillBoard,这需要改变BillBoard的模式。

auto billboard = BillBoard::create("Blue_Front1.png", BillBoard::Mode::VIEW_PLANE_ORIENTED)

根据传入的参数不同BillBoard的效果是不同的,BillBoard可以有两种形式,VIEW_POINT_ORIENTED 和VIE_PLANE_ORIENTED.
VIEW_POINT_ORIENTED 是指BillBoard面向观察者(视角):
这里写图片描述
VIEW_PLANE_ORIENTED 是指BillBoard面向XOY平面:
这里写图片描述
你还可以设置BillBoard的其他属性,就像一个Node一样。这些包括:放缩,位置,旋转。当然还有很多。例:

billboard->setScale(0.5f); 
billboard->setPosition3D(Vec3(0.0f, 0.0f, 0.0f));
billboard->setBlendFunc(BlendFunc::ALPHA_NON_PREMULTIPLIED); 
addChild(billboard);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值