Laya的3D项目,场景和模型数据暂时还是借助unity导出。
Laya版本:LayaAir IDE 2.11.0
Unity插件:使用2.11对应的插件
Unity版本: unity2018.4.35官方要求2018.4.7一直没找到,4.35暂时也可以用。
导出文件说明:
.ls:场景文件,Scene3D类
.lh: 3D物体,Sprite3D类
.lm:模型网格数据,MeshSprite3D,如果是人物模型则是 SkinnedMeshSprite3D。
注意MeshRender并非组件,直接从Sprite3D对象的meshRenderer属性获得。
unity导出的相机,laya使用后,在ios手机帧频会降得很低,建议使用Laya自己的3D相机,原因不详。
如何加载使用:
加载场景和模型的代码就不在这里演示了,游戏中的换装或者换武器的会使用到挂点动画,主要说一下挂点动画。
Laya2.3版本之前:会导出avatar,可以这样挂点动画:
var role= Laya.Loader.getRes("role.lh") as Laya.Sprite3D;
var weapon = Laya.Loader.getRes("weapon.lh") as Laya.Sprite3D;
scene.addChild(role);
actor.addChild(weapon);
var animator = role.getComponent(Laya.Animator);
//将模型weapon直接挂到 avatar的RHand节点上
animator .linkSprite3DToAvatarNode("RHand", weapon);
animator .play("attack");
Laya2.3版本之后:会导出unity骨骼节点,注意avatar不会导出。
laya官方新版动画示例:1.骨骼挂点 2.蒙皮动画挂点
Laya.Scene3D.load("LayaScene_SceneMonkey/Conventional/SceneMonkey.ls",Laya.Handler.create(this,function(res){
Laya.stage.addChild(res);
//用于挂点的精灵
var box = new Laya.MeshSprite3D(Laya.PrimitiveMesh.createBox(1,1,1));
var material = new Laya.BlinnPhongMaterial();
Laya.Texture2D.load("res/layabox.png", Laya.Handler.create(this, function(tex) {
material.albedoTexture = tex;
}));
box.meshRenderer.material = material;
var monkey = res.getChildByName("LayaMonkey");
//查找节点
var bonePoint:Sprite3D = this.findChild(monkey,"bonepoint");
//将盒子精灵添加到找到的骨骼节点上
bonePoint&&bonePoint.addChild(box);
}));
挂点动画经常遇到的问题,要么模型明明加载了就是没有显示,或者显示的位置不对。我们知道骨骼动画控制的是骨骼的坐标,旋转和缩放,只要把骨骼挂点下模型的transform相对数据(localPosition和localRotation)初始化搞定就可以了。下边我们看看如何解决?
1.在unity创建一个空对象,拖入到骨骼挂点weapon下。
2.在laya代码中首先找到骨骼节点weapon,然后将weapon模型添加到weapon骨骼节点下,然后把GameObject的localPosition和localRotation赋值给weapon模型。代码一定按照这个顺序来。现在我们已经明白了,我们就是先在骨骼节点下用GameObject记录了一个transform的数值,待模型添加到相同位置后,再把标记的transform赋值给模型,这样就确保transform信息是一直的了。
理论上来说,laya通过骨骼节点添加武器模型时,transform信息是会自动转换的,先在发现转化后的初始transform信息是有问题的,所以导致位置偏差。
模型资源导出比较暗,如何解决?
导出laya模型资源的,用Laya插件自带的shader:LayaAir3D->mesh->unlit,不会出现黑乎乎的图片。也可以试试laya其他的shader。
性能优化方向
复用3D材质:
Laya3D会对相同的材质进行合并优化,减少drawcall。
控制常用模型的面数:
Laya3D会对20个面以下的相同模型,自动合并(例如特效和子弹等),因此要求美术对反复使用的模型尽量控制页数。一个模型中配 5000面,高配 10000面,再多的话gpu应该会出现发热耗电的问题了。
模型原始资源:6M 加载到内存GPU:30M 加载到场景GPU:60M
摄像机裁剪优化:
3D场景,如果远处的部分看不清楚时,可将摄像机可视区域裁剪,将远处看不清的模型与材质不渲染,添加一些场景雾效果,可减少Sprite数量与DrawCall数量。
canvas 和webgl区别
canvas:翻译成中文就是 画布,可以理解是一张白纸,可以用来画画。canvas 2d 可以理解为内置的2d图形接口,可以理解为一个画笔,可以画点,直线,矩形,圆弧,贝塞尔曲线。
//html网页
<html>
<head>
<script>
//获得画布
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
//获得上下文,相当于获得一个画笔
var ctx = canvas.getContext('2d');
//绘制矩形
ctx.fillRect(25, 25, 100, 100);
//绘制路径,准备开始,图形由点和线组成
ctx.beginPath();
//移动笔触,设置一个起始点
ctx.moveTo(75, 50);
//绘制直线
ctx.lineTo(100, 75);
ctx.lineTo(100, 25);
//填充路径颜色
ctx.fill();
//绘制圆弧:坐标,半径,圆弧始末范围,顺时针还是逆时针
ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);
//绘制二次贝塞尔曲线:cp1x,cp1y为一个控制点,x,y为结束点
ctx.quadraticCurveTo(cp1x, cp1y, x, y);
//绘制三次贝塞尔曲线:cp1x,cp1y为控制点一,cp2x,cp2y为控制点二,x,y为结束点
ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
}
</script>
</head>
<body>
<canvas id="canvas">画布载体</canvas>
</body>
</html>
webgl:是一组3D的绘图接口类库,允许浏览器直接调用GPU渲染加速。webgl是基于opengl es的javascript版本。
由于webgl提供的接口写起来比较困难,于是出现了一些封装了webgl的游戏类库:three.js ,Babylon.js等。
webgl绘制流程:
1.获取顶点坐标:根据三维模型的数据获得。
2.图元装配:将得到的顶点坐标数据,画出对应的三角形,以便进行模型渲染。
3.光栅化:生成片元,可以理解为很多个对应的像素点,生成完成后,需要着色。
这些完成后, 最终交与cavas呈现出来。