Cocos Creator 3D初体验
- 官方文档 https://docs.cocos.com/creator3d/manual/zh/
- 下载 https://www.cocos.com/creator3d
- 目前个人使用的版本是v1.1.1,官方已发布v1.2版本
整体的使用感受
- UI界面的制作一如既往的便捷高效
- 对Cocos Creator 2D上手很友好
- 有自己的3D编辑器
- 材质系统非常的灵活
- 当前版本对2D游戏的支持不够完善
目前不太完善的地方
- 2D方面
- 不支持LabelAtlas,可以使用bmfont间接来实现
- mask不支持图片作为模板
- 场景资源的自动释放不可用,可以通过一些特殊手段来释放内存
- 暂不支持动态合图
- 暂不支持spine、龙骨
- 3D方面
- 不支持动画分层,也就是不支持角色上下半身播放不同的动作。
- v1.1.1阴影只支持平面阴影,也就是说阴影只能投到地上但无法投射到模型身上。v1.2阴影支持shadowMap但不是很完善。
- v1.1.1不支持雾效,v1.2已支持。
- 暂不支持后处理(HDR、景深、泛光)
- 其他
- 暂不支持通过npm的方式引入代码库
帮助美术同学上手新引擎的相关文档
- 材质系统
- https://docs.cocos.com/creator3d/manual/zh/material-system/overview.html
- 文档最下面列出了常用参数的意义和用法
- 动画系统
- 粒子相关
跟Creator 2D不一样的地方
- UI的layer需要设置为 UI_2D
- 相对于旧版Creator所有组件名称都加了一个Component后缀 如 Sprite -> SpriteComponent node.getComponent(SpriteComponent)
- Node节点里面不再提供colo,Node新版api https://docs.cocos.com/creator3d/api/zh/classes/scene_graph.node.html
- action已经被废弃了,请使用tween。tween文档 https://docs.cocos.com/creator3d/manual/zh/tween/
- opacity透明度的用法变化,相关文档https://docs.cocos.com/creator3d/manual/zh/ui-system/components/editor/ui-opacity.html
- 1 Sprite组件和 Label组件可以直接修改color属性alpha分量
- 2 其他情况需要增加一个透明度组件。例如, this.node.getComponent(UIOpacityComponent).opacity = 0
- 导入UI图片记得修改图片类型为sprite-frame,否则无法在UI里使用。
- cc.director 这种ts会报错但实际可以运行,只是会丢失代码提示
- cc.audioEngine已废弃。 见文档 https://docs.cocos.com/creator3d/manual/zh/audio-system/overview.html
- convertToNodeSpaceAR相关api被移到UITransformComponent下
- 动态加载图片路径需要加后缀 /spriteFrame
- mask在编辑器里不生效,实际预览是生效的.
- 没有看到动态合图相关文档或接口
2D版本的UI组件预制体移植到3D版本注意事项
- 官方暂时还没有Creator导出到Creator 3D的工具,可以自己写一个简单的脚本
- prefab中组件重命名 例 “type”: “cc.Sprite”, -> “type”: “cc.SpriteComponent”,
- 添加UITransform 组件
- 根节点的layer改成ui_2D
- 资源需要重新拖一遍
3D相关
对3D的理解
场景中的光线照射到模型的表面,经过反射、漫反射后被相机拍摄到构成了我们看到的画面。
-
3D核心概念之模型
- 模型由网格和材质组成
- 网格mesh定义了物体表面的形状,也就是空间结构。mesh由一个个三角面片构成。一个三角面片又包含三个顶点。每一个顶点的信息包括顶点在模型坐标系下的位置、法线等。shader中的vertexShader就是专门处理顶点数据的,它的主要作用就是将顶点坐标从模型空间坐标系转换到屏幕空间(实际上vs中计算出的坐标并不是屏幕空间坐标,这里只是为了方便理解)。
- 材质决定了模型表面在光照下看起来的效果。材质中使用的shader决定了光照的计算方式(unlit、blinn-phong、pbr)。调整材质中的参数就可以实现不同的效果,例如pbr中材质参数就有:模型表面粗糙程度、对光线的反射率、金属度、ao等。
- 可以简单理解为,材质决定了这些三角面上色的方式。
-
Creator 3D跟Laya一样使用右手坐标系,unity使用的是左手坐标系。
-
3D场景编辑常用操作 https://docs.cocos.com/creator3d/manual/zh/editor/scene/
-
材质常用选项(文档最下面部分) https://docs.cocos.com/creator3d/manual/zh/material-system/overview.html
-
如果要修改fbx里的材质,需要先dump出来再修改。
-
平行光只支持一盏
-
场景里面同一个物体出现多次,可以开启材质里的gpu instancing选项进行性能优化
-
开启阴影会造成物体绘制的三角面数量翻倍,应该尽可能少的去开启物体的阴影。
-
粒子数值太大会消耗大量内存
-
UI里面显示模型记得模型放大100倍,材质切换成不受光材质。相关文档https://docs.cocos.com/creator3d/1.1/manual/zh/ui-system/components/editor/ui-model.html?h=uimodel
-
涉及到透明贴图的材质注意切换到transparent,另外还可以通过修改材质的priority来调整透明物体的绘制顺序.
-
四元数
- api文档https://docs.cocos.com/creator3d/api/zh/classes/core_math.quat.html
- 旋转相关接口记得检查是否归一化以及区分弧度和度数
- 帮助理解的视频 https://www.bilibili.com/video/BV1SW411y7W1
性能优化
- 3D场景使用压缩纹理,可以显著降低显存。注意:etc1不支持透明通道。prv尺寸要求:尺寸为2的N次幂,并且宽高相同。
- 尺寸太大的图改小从而降低显存占用(例如界面背景大图)
- UI通过合图并调整组件层级减少drawcall
- 关于3D合批 https://docs.cocos.com/creator3d/manual/zh/engine/renderable/model-component.html#%E5%90%88%E6%89%B9%E7%9A%84%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5
- 3D场景重复物体建议开启gpu instance
- 低端机可以关闭阴影并锁帧30
- 地面避免使用引擎默认材质。引擎默认使用的材质是pbr性能消耗较大。
推荐的一些文章、博客、教程
- OpenGL官方 https://www.khronos.org/opengl/wiki/Main_Page
- OpenGL教程
- 对Gamma的理解 https://www.zhihu.com/question/27467127#answer-10413243
- Cocos论坛里的一些帖子 https://forum.cocos.org/t/topic/95807
- 关于压缩纹理https://www.jianshu.com/p/a0d7eed9f44d
一些实用功能的实现细节
blinn-phong
- 由于引擎默认的pbr性能消耗过大,然后unlit又没有光照效果,所以想到了经典光照blinn-phong。由于引擎没有内置blinn-phong,所以翻译了一个。
- 翻译自这篇文章https://gameinstitute.qq.com/community/detail/123553
- v1.2.0版本effect文件
- v1.1.1版本effect文件
碎文件合并
cocos里面每一个音频、图片、预制体、模型、动画等资源都会对应生成一个json,构建后的将会导致文件数量翻倍。如果资源是放在网络上将会导致大量资源下载请求从而大大降低加载速度。
- 实现原理:通过修改构建后的setting.js。这个文件其实就是一个配置文件,里面主要记录了resource目录下所有文件的路径到uuid的映射,以及有哪些json文件被合并到哪个大的json文件里去了。引擎在下载任意json文件之前都会去检查当前json文件是否被合并了,如果已经被合并就去下载合并后的json文件。
- 写了一个json合并的脚本将所有json文件合并成了一个大的json文件,脚本运行环境是nodejs。缺点是合并之后单个json文件巨大
- 贴一下引擎源码方便理解。
正常打包后的setting文件
运行脚本后会产生一个unionPack.json文件和另外一个无法被合并进去的json文件,以及修改后的setting文件。
- 脚本文件mergeJson.rar (11.1 KB)
3D UI的显示
3D场景里面显示UI是一个比较常见的需求,可以使用renderTexture来进行实现。
-
在资源管理器中新建一个renderTexture资源,根据需要设置宽高
-
在场景上新建一个canvas,并设置Canvas组件的targetTexture为刚刚新建的renderTexture。
-
场景中新建一个3D面片,面片材质选用unlit Effect,然后代码里设置面片材质的纹理为renderTexture。
json文件压缩。合并后的大json文件是1.1M压缩后是144k。需要修改引擎
燃烧效果shader
原理:简单的法线利用
shader.rar (2.9 KB)
3D进度条的两种实现方式
- 自定义mesh顶点数据
原理:矩形拆分成5个三角形,然后根据百分度换成对应的角度。红线代表边界,绿色代表构成部分。UI中使用的环形进度条,在引擎底层应该也是用的类似实现方式。这种方法优点是可以开启动态合批减少drawcall。
代码 (1.0 KB) - shader进行圆形的剪裁
radial-1.1.1.rar (1.2 KB)
3D中倒计时数字的一种实现方式
因为倒计时通常是个位数,此种方法就是通过找到单个数字在纹理中所在的位置,再设置uv偏移和缩放就可以了。另外计算位置的时候需要考虑到合图后的旋转。
原始BMFont文件
打包合图后
来源:oschina
链接:https://my.oschina.net/u/4397452/blog/4686838