Laya 3D开发经验和问题总结

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呈现出来。

猜你喜欢

转载自blog.csdn.net/wangwen_22/article/details/117431694