Laya3D 1.8阅读笔记

Scene3D场景

​ 场景即为LayaAir引擎的3D世界容器,用于呈现游戏的3D画面和加载各种3D元素,游戏中的摄像机,灯光,人物,物品等都需要放到场景中才能展示出画面,相当于一个游戏3D播放器或者3D视图。

Camera摄像机

  • 摄像机的Transform:
    Camera摄影机继承于Sprite3D,也是精灵的一种,也一样可以对它进行3D变换的操作,通过它transform属性在3D场景中移动旋转变化,多角度取景,使观众或游戏者获得更真实的空间体验。
    如果场景内没有摄像机,那么游戏画面内就不会显示任何物体。场景中的摄像机还可以放置在场景中的子节点中,比如添加到主角角色模型中,同样可以呈现3D画面。
    //实例化一个相机,设置纵横比0为自动匹配。0.1最近看到的距离(近裁剪面),100最远看到的距离(远裁剪面)。
    var camera = new Laya.Camera(0, 0.1, 100)
    
  • 在代码中加载摄像机后,怎么获取摄像机呢?
    可以通过场景的子节点索引或名称来获取,如可以用getChildByName(“Main Camera”)方法得到了摄像机(在Untiy中,摄像机默认名为“Main Camera”),获取后我们还可以对它进行移动旋转、设置天空盒、添加脚本等操作。
    回顾WebGL中基本概念:视图矩阵(视点,目标点,上方向),投影矩阵(正射投影,透视投影),模型矩阵。摄像机相当于其中的视图矩阵+投影矩阵(设置裁剪和视野)
  • 摄像机的正交投影和透视投影(配置投影矩阵)
    3D引擎中,为了更好的模拟人眼所看到的世界,默认的摄像机带着“透视投影”的效果。
    但有很大一部分游戏,特别是斜45度视角的2D、3D混合游戏,游戏画面是不能带透视效果的,那么这个时候,我们需要设置摄像机为“正交投影”,使它不产生近大远小的透视效果。
    //正交投影属性设置
    camera.orthographicProjection = true;
    //正交垂直矩阵距离,控制3D物体远近与显示大小
    camera.orthographicVerticalSize = 7;
    
  • 摄像机的裁剪和视野(配置投影矩阵)
    ​ 1. 摄像机还可以设置远近距离的裁剪,只显示远近距离之间的场景模型,之外的模型不进行渲染显示。它最大的优势在于提高游戏的性能。
    创建摄像机时,摄像机构造函数会默认剪切为近距0.3米,远距为1000米。开发者可以在构造函数中设置或通过摄像机属性进行设置。
    一般在游戏中,我们会把雾效与摄像机剪切同时使用,雾效远距以外的地方基本都看不清楚,这时就可以设置远距离剪切,提高游戏渲染性能。
    2. 视野:摄像机视野类似于焦距,通过视野参数的调整,可以看到视图中的场景范围、透视的近大远小变化,它是通过角度值进行调整,角度越大,视野范围越大,开发者可以根据自己的需求进行设置。
      //设置相机的视野范围90度
      camera.fieldOfView = 90;
    
  • 摄像机的纵横比:(配置投影矩阵)
    我们一般不会手动设置屏幕的横纵比,在运行过程中会通过计算自动设置横纵比。但是在一些特殊的情况下需要对横纵比手动设置时,可以自己手动设置。如果需要重置横纵比,变回自动改变横纵比,只需要将这个值设置为0。
      //手动设置横纵比
      camera.aspectRatio = 2;
      //重置
      camera.aspectRatio = 0;
    
  • 摄像机捕捉目标(配置视图矩阵)
    创建摄像机时,我们经常需要调整摄像机的位置,用于对准显示某个三维物体,或显示某个区域。LayaAir 3D引擎3D变换提供了一个lookAt()方法,用于捕捉目标,自动调整3D对象对准目标点。摄像机也可以使用它达到我们的调整视角的目的。
    // 参数:观察目标,向上向量,是否局部空间
    camera.transform.lookAt(target, up,isLocal);
  • 摄像机的背景色和天空盒
    1.背景色:在3D场景中,背景颜色我们是用摄像机去控制的,通过设置摄像机clearColor属性来改变3D空间的背景色,颜色使用三维向量Vector3(红,绿,蓝)方式赋值调整,引擎默认设为纯黑色。
       //相机设置清楚标记,使用固定颜色
       camera.clearFlag = Laya.BaseCamera.CLEARFLAG_SOLIDCOLOR;    
       //设置背景颜色
       camera.clearColor = new Laya.Vector4(0.5,0.5,0.6,1);
    
    2.天空盒:
    场景中大多时候需要表现天空远景,比如蓝天白云、黄昏、星空等,在LayaAir 3D引擎中,是通过在摄像机属性上添加天空盒(SkyBox)的方式创建。
    不过如果摄像机使用了正交投影,天空盒将达不到所要效果,开发者们可以尝试。
    天空盒是由一个立方体模型及6张可以无缝相接的材质贴图构成,有点类似于360全景地图,随着视角的旋转改变,我们可以观察到四面八方都有远景效果。
    //天空盒代码
    Laya.BaseMaterial.load("res/.../skyBox.lmat", this.Handler.create(null, function(mat) {
        //设置相机的清除标识为天空盒
        camera.clearFlag = Laya.BaseCamera.CLEARFLAG_SKY;
        //获取相机的天空渲染器
        var skyRenderer = camera.skyRenderer;
        //创建天空盒的mesh
        skyRenderer.mesh = Laya.SkyBox.instance;
        //设置天空盒材质
        skyRenderer.material = mat;
    }));
    
    在使用背景色和天空盒时,一定要保证Camera(摄像机)的clearFlag清除标记属性,与自己需要的效果对应。
    • 下一篇:多摄像机窗口,摄像机的射线,可视遮罩,目标纹理

灯光

  • 网格和纹理决定了一个物体的形状和外观,光源决定了环境的颜色和氛围。灯光的种类有多种,不同的光源呈现的效果不同,可以设置不同的参数。目前的种类有:PointLight(点光),DirectionLight(平行光),SpotLight(聚光)3种

  • 点光源:向四面八方发射光线的光源,又称全向光或者球状光,现实中的点光源比如灯泡、蜡烛。点光源是有强度、颜色和衰减半径属性

    //创建点光源
    var pointLight = scene.addChild(new Laya.PointLight()) as Laya.PointLight;
    //设置点光源位置
    pointLight.transform.position = new Laya.Vector3(0.4, 0.4, 0.0);
    //设置点光源的范围
    pointLight.range = 6.0;
    

    range 为设置点光源的范围,相当于点光的照射范围,数值越大,光照范围越大。

  • 方向光:有固定的一个方向,可通过弧度值设定,并且也没有衰减和光照范围,会对全场景所有模型进行照亮。3D世界中经常用来模拟固定方向的太阳光。

    //创建方向光
    var directionLight = scene.addChild(new Laya.DirectionLight()) as Laya.DirectionLight;
    //方向光的颜色
    directionLight.color = new Laya.Vector3(1, 1, 1);
    //设置平行光的方向
    var mat = directionLight.transform.worldMatrix;
    mat.setForward(new Laya.Vector3(-1.0, -1.0, -1.0));
    directionLight.transform.worldMatrix=mat;
    

    setForward 平行光的方向,分别代表x、y、z轴上的方向,负数为负轴,正数为正轴,值的范围为-1—0—1,超过范围后为-1或1

  • 聚光:从特定光源方向射出的光,比如手电筒,舞台筒灯等。光照区域根据距离因素逐渐放大,同时光照区域边缘也有衰减现象。

    //聚光灯
    var spotLight = scene.addChild(new Laya.SpotLight()) as Laya.SpotLight;
    //设置聚光灯颜色
    spotLight.color = new Laya.Vector3(1, 1, 0);
    //设置聚光灯位置
    spotLight.transform.position = new Laya.Vector3(0.0, 1.2, 0.0);
    //设置聚光灯方向
    var mat = spotLight.transform.worldMatrix;
    mat.setForward(new Laya.Vector3(0.15, -1.0, 0.0));
    spotLight.transform.worldMatrix = mat;
    //设置聚光灯范围
    spotLight.range = 6.0;
    //设置聚光灯锥形角度
    spotLight.spotAngle = 32;
    

    range 为聚光的照射范围,与点光类似,区别只是聚光有方向,而点光无方向。
    spotAngle 为聚光灯的锥形角度,设置的值越小,聚光光圈的越小,反之光圈越大。

  • 为灯光添加阴影:投影是灯光照射模型时产生的即时阴影,可随着灯光角度、灯光强度、模型位置等变化而变化。投影是3D世界最重要的因素之一,能产生更加强烈的立体感。即时阴影非常损耗性能,不能用得太多,特别是游戏场景,模型量较大,一般我们不使用即时投影,而使用静态的光照贴图。
    要让场景中产生投影,我们需了解灯光的以下属性:

    1. shadow:是否开启投影,布尔值,设置为true后生效。
    2. shadowDistance:产生投影的范围,范围是指摄像机到模型的距离,单位为米。大于这个范围模型将不会接受投影与产生投影,开发者可以根据场景大小进行设置。
    3. shadowPCFType:阴影模糊等级0-3,模糊值越大,阴影越柔和,效果越好,但更耗性能。
    4. shadowPSSMCount:产生阴影贴图的数量,数量越高,阴影越细腻,性能损耗越大。
    5. shadowResolution:投影的质量,投影范围中的阴影大小。通过数值设置质量,数值越大,投影质量越高,性能损耗也会随之加高。投影的质量值是以2的N次幂为单位设置,默认为512,可以设置成1024、2048……等。

    除此之外,还要需要在模型上设置投影属性:

    1. receiveShadow:是否接受投影,当模型此属性为true时,计算出的投影会在此模型上显示出来。在游戏中,我们可以把场景的地面,及场景中可走动区域中的模型castShadow属性设置为true。
    2. castShadow:是否产生投影,当模型此属性为true时,灯光根据产生阴影的模型位置、模型网格形状大小、与灯光的角度等进行投影计算,然后在接受阴影的模型上产生投影。比如场景中的角色、NPC等活动游戏元素可以开启此属性。
    //灯光开启阴影
    directionLight.shadow = true;
    //可见阴影距离
    directionLight.shadowDistance = 3;
    //生成阴影贴图尺寸
    directionLight.shadowResolution = 2048;
    //生成阴影贴图数量
    directionLight.shadowPSSMCount = 1;
    //模糊等级,越大越高,更耗性能
    directionLight.shadowPCFType = 3;
    //地面加到场景上 并且获取地面
    var grid = this.scene.addChild(Laya.Loader.getRes("res/threeDimen/staticModel/grid/plane.lh")) as Laya.Sprite3D;
    //地面接收阴影
    (grid.getChildAt(0) as Laya.MeshSprite3D).meshRenderer.receiveShadow = true;
    .......
    //设置猴子能产生阴影
    (layaMonkey.getChildAt(0).getChildAt(0) as Laya.SkinnedMeshSprite3D).skinnedMeshRenderer.castShadow = true;
    

精灵

Sprite3D精灵

  • Sprite3D 是3D的基本节点对象,是LayaAir3D中所有节点类型的父类(像Sprite3D空精灵,在3D世界中使物体产生立体光影变化投影等效果的Light灯光精灵用于渲染的MeshSprite3D网格精灵SkinnedMeshSprite3D蒙皮网格精灵TrailSprite3D拖尾精灵ShuriKenParticle粒子特效精灵等等),包含很多3D精灵基本的功能属性,除此之外还是所有3D组件和脚本的容器
    Sprite3D包含 transform 属性,该属性具备使Sprite3D在世界空间中变换的功能。同时和Node节点一样具备子父节点的关联关系,使变换操作更灵活。
  • Sprite3D的子父级关系
    Sprite3D继承自Node节点,是LayaAir3D中所有3D对象的父类
  • Layer蒙版(图层)属性。该属性设置可以在使用摄影机可视遮罩层,射线检测等情况下起作用。
  • 克隆
    1. clone()
    2. cloneto()
    3. instantiate() Sprite3D中特有的克隆接口,该方法可以在克隆时携带父节点信息,世界位置信息和世界旋转信息。
      在这里插入图片描述
  • 添加Component 组件:给物体添加组件时,需要物体使用addComponent方法。
    属性:
    1.enable:Boolean 是否启用组件
    2.destroyed 获取组件是否已经被销毁
    3.id 获取唯一标识id
    4.owner:Node 只读 获取所属Node节点
    方法:
    1.destroy() 销毁组件
    2.onReset() 重置组件的所有参数到默认值
  • 各种渲染精灵简介
    1.MeshSprite3D精灵:引擎中最常用的 静态网格精灵,可根据于美术软件预制作或自定义的网格数据渲染模型。游戏中绝大多数地图都包含静态网格体,例如场景中的各种建筑模型、山体岩石一般均为MeshSprite3D。
    2.SkinnedMeshSprite3D精灵:引擎中的 蒙皮动画网格精灵,可根据美术软件预制作的网格数据和Animator组件的动画数据产生动作形变。常用于带蒙皮动画的角色、怪物等。和MeshSprite3D相比具产生网格形变的能力。
    3.TrailSprite3D精灵:引擎中的 拖尾精灵,可根据精灵运动轨迹产生动态的拖尾特效。
    4.ShuriKenParticle3D精灵:引擎中的 粒子精灵,可根据美术人员编辑的粒子参数产生奇妙炫酷的粒子特效。一般用于各种角色技能特效或火焰、烟雾等场景特效。
    5.PixelLineSprite3D精灵:引擎中的 像素线精灵,可根据脚本的绘制数据产生任意颜色的像素线。一般用于场景中的引导效果或项目调试数据用途。

Component组件

Component 组件是附加到所有3D对象的内容的基类 。组件的种类也是非常多的,比较常用的像Animator动画组件,PhysicsCollider物理碰撞器和RigidBody3D刚体这些物理组件等

模型和网格

  • 模型由Mesh(网格)与 Material(材质)2个部分组合而成。LayaAir3D中的模型精灵有两种。MeshSprite3D(静态网格精灵)与 SkinnedMeshSprite3D(蒙皮动画网格精灵)。
    Mesh是指模型的网格数据,一个3D模型的表面是由多个彼此相连的三角面构成。三维空间中,构成这些三角形的顶点的数据以及三角形的索引数据的集合就是Mesh。
  • 通过PrimitiveMesh创建简单Mesh:创建时需注意的是,加载到场景中的引擎自带模型,轴心点在模型正中心,因此我们是以模型中心点为参考进行移动、旋转、缩放加载到场景中时,模型默认会放置到场景的世界座标原点上
    //创建一个空节点用来防止各模型
     sprite3D = scene.addChild(new Laya.Sprite3D());
     //正方体
     var box = sprite3D.addChild(new Laya.MeshSprite3D(Laya.PrimitiveMesh.createBox(0.5, 0.5, 0.5)));
     box.transform.position = new Laya.Vector3(2.0, 0.25, 0.6);
     box.transform.rotate(new Laya.Vector3(0, 45, 0), false, false);
     //球体
     var sphere = sprite3D.addChild(new Laya.MeshSprite3D(Laya.PrimitiveMesh.createSphere(0.25, 20, 20)));
     sphere.transform.position = new Laya.Vector3(1.0, 0.25, 0.6);
     //圆柱体
     var cylinder = sprite3D.addChild(new Laya.MeshSprite3D(Laya.PrimitiveMesh.createCylinder(0.25, 1, 20)));
     cylinder.transform.position = new Laya.Vector3(0, 0.5, 0.6);
     //胶囊体
     var capsule = sprite3D.addChild(new Laya.MeshSprite3D(Laya.PrimitiveMesh.createCapsule(0.25, 1, 10, 20)));
     capsule.transform.position = new Laya.Vector3(-1.0, 0.5, 0.6);
     //圆锥体
     var cone = sprite3D.addChild(new Laya.MeshSprite3D(Laya.PrimitiveMesh.createCone(0.25, 0.75)));
     cone.transform.position = new Laya.Vector3(-2.0, 0.375, 0.6);
     //平面
     var plane = sprite3D.addChild(new Laya.MeshSprite3D(Laya.PrimitiveMesh.createPlane(6, 6, 10, 10)));
    
  • 模型功能简介
    3D模型在有时候会由多个子模型对象构成,例如场景模型.ls,基本都是由多个物体模型与材质构成,外层是Sprite3D容器,内部才是真正的模型MeshSprite3D或SkinnedMeshSprite3D。并且还可能会有多个层次嵌套。
    1.获取子对象模型网格:在编写游戏逻辑时,有的模型需要被修改,或者是切换与删除模型、或者是给模型加组件、或者是获取模型上的动画组件及修改模型的材质等。这都需要从加载的模型中去获取子对象,我们可以通过 getChildAt()、getChildByName() 方法去获取子对象,这与2D引擎获取子对象方法一样。在3ds max中建模时,建议对模型的子对象取名,并且制定项目的资源命名规则,不要用默认的模型名称。
    //加载一个场景的.ls文件,然后获取它的子对象。在获取子对象之前,建议打开.ls文件查看模型的父子层级关系,因为在制作模型时,我们也不能确定模型是由多少个子对象模型构成,及它们的命名规则。
    //初始化3D场景  
    var scene = Laya.stage.addChild(Laya.Loader.getRes("res/threeDimen/scene/ChangeMaterialDemo/Conventional/scene.ls"));
    //获取球型精灵
    var sphere = scene.getChildByName("Sphere");
    //获取精灵的mesh
    var sphereMesh = sphere.meshFilter.sharedMesh;
    //此时已经拿到了场景中的球体的网格
    
    获取子对象时还应注意一个问题,就是模型与材质未加载完成,是无法获取子对象的,因此需要资源预加载,或异步加载时进行完成事件监听。
    2.修改子对象模型网格:在游戏中,我们经常打造角色换装系统,有时是换模型,有时是换贴图,有时候两者都换。模型MeshSprite3D或SkinnedMeshSprite3D中有 meshFilter 属性,它是一个网格过滤器类实例,这个属性中的sharedMesh 就是模型的网格,可以对它进行重新创建更换及销毁。
    //新建四个mesh
    var box = Laya.PrimitiveMesh.createBox(0.5, 0.5, 0.5);//立方体
    var capsule = Laya.PrimitiveMesh.createCapsule(0.25, 1, 10, 20);
    var cylinder = Laya.PrimitiveMesh.createCylinder(0.25, 1, 20);
    var cone = Laya.PrimitiveMesh.createCone(0.25, 0.75);
    var index = 0;
    //.............按钮点击事件 监听
    changeMeshButton.on(Laya.Event.CLICK, this, function(){
        index++;
        if (index % 5 === 1 ){
            //切换mesh
            sphere.meshFilter.sharedMesh = box;
        }
        else if (index % 5 === 2){
            //切换mesh
            sphere.meshFilter.sharedMesh = capsule;
        }
        else if(index % 5 === 3){
            //切换mesh
            sphere.meshFilter.sharedMesh = cylinder;
        }
        else if(index % 5 === 4){
            //切换mesh
            sphere.meshFilter.sharedMesh = cone;
        }
        else{
            //切换mesh
            sphere.meshFilter.sharedMesh = sphereMesh;
        }
    });
    

Material材质

  • 材质就是物体的材料质感,例如木头、金属、玻璃、毛发、水等,它们的粗糙度、光泽度、反射、透明、颜色、纹理等材质属性都有所不同,大多数3D引擎中都有独立的材质类用于程序代码控制,三维制作软件中有标准材质、多维材质、合成材质、双面材质、光线跟踪材质等。在LayaAir 3D引擎中目前主要支持的是标准材质 BlinnPhongMaterial ,UnlitMaterail,PBRStandardMaterial 等。*.lmat文件就是材质文件: Json文件,包含光照,贴图,渲染模式等基本材质信息。
  • 创建材质:如果在代码中的模型没有赋材质,在3D视图中无法显示模型的纹理、质感等,只默认为纯白色。实际的项目运用中,很少用代码的方式给模型赋材质,而是直接在3D软件制作或在unity中创建材质,然后通过工具导出LayaAir格式后使用
    //添加自定义模型
    var box = scene.addChild(new Laya.MeshSprite3D(Laya.PrimitiveMesh.createBox(1, 1, 1)));
    box.transform.rotate(new Vector3(0, 45, 0), false, false);
    //创建材质
    var material = new Laya.BlinnPhongMaterial();
    Laya.Texture2D.load("res/layabox.png", Laya.Handler.create(this, function(tex){
         //纹理加载完成后赋值
       material.albedoTexture = tex;
    }));
    //将材质赋值给自定义模型
    box.meshRenderer.material = material;
    
    • 加载材质:加载.ls、.lh数据时,会自动加载模型所对应的材质。这时可以使用导出后产生的.lmat材质文件,加载创建标准材质并赋给模型,方式与模型加载类似。
    //材质加载
    Laya.BaseMaterial.load("res/skyBox2/skyBox2.lmat",Laya.Handler.create(this,function(mat) {
           var skyRenderer = camera.skyRenderer;
           //创建天空盒的mesh
           skyRenderer.mesh = Laya.SkyBox.instance;
           //设置天空盒材质
           skyRenderer.material = mat;    
    }));
    
    • 材质的功能:
      1.从模型上获取材质:​ 使用导出的模型时,引擎会自动在模型上加载材质,并且很多时候一个模型上会有多个标准材质,但在这种情况下,如果我们需要改变、更换材质怎么呢?首先需要在模型上获取当前的材质。可以使用网格渲染器MeshRenderer类和蒙皮动画网格渲染器SkinnedMeshRenderer获取模型上的材质。 获取的材质分为两种类型:​ 1自身材质 Material,如果自身材质被修改了,只有自身模型显示进行变化;2 共享材质 SharedMaterial ,因为材质相对独立,多个模型都可以用同一个材质,如果获取的是共享材质并修改了,自身模型显示会变化,其他模型用到这个材质的部分也会发生改变。

纹理

Script3D脚本

​ Script3D脚本在开发过程中使用的非常频繁的。脚本是一种特殊的组件,为了方便开发者使用,他有自己的生命周期。脚本的功能也是非常大的,例如角色控制脚本,NPC控制脚本、场景物体控制脚本等,实现了控制与显示分离。

3D基础数学工具

  • 向量Laya.Vector 234
  • 颜色 Laya.Vector 34
  • 四元数 用于计算旋转 Laya.Quater
  • 包围盒 基本思想是用体积稍大且特性简单的几何体(称为包围盒)来近似地代替复杂的几何对象
  • 矩阵
  • 射线 ​ 射线是一个数据类型,并不是显示对象,它有原点origin 与 方向direction两个属性 。

Transform变换

(有关显示对象变化的都会用到他)

  • 移动(translate),旋转(rotate),缩放(scale)这三种变换 用三维向量代表x,y,z的值。三种方法都可以在参数中设置是否为局部空间移动,旋转,缩放。
    //移动摄像机  true代表是局部坐标,false是相对世界坐标
    camera.transform.translate(new Laya.Vector3(0, 3, 3),false);
    //旋转摄像机  参数:局部坐标,弧度制(false为角度制)
    camera.transform.rotate(new Laya.Vector3(-30, 0, 0), true, false);
  • transform中常用的方法
    lookAt(target:Vector3, up:Vector3, isLocal:Boolean = false):void 观察目标位置。
  • transform中常用的属性
    localPosition:Vector3 局部位置。
    position:Vector3 世界位置。
    localMatrix:Matrix4x4 局部矩阵。
    worldMatrix:Matrix4x4 世界矩阵
    localRotation:Quaternion 局部旋转。
    rotation:Quaternion 世界旋转。
    localScale:Vector3 局部缩放。
    scale:Vector3 世界缩放。
    right:Vector3 [read-only] 获取向右方向。
    forward:Vector3 [read-only]获取向前方向。
  • 3D世界中的子父关系
    ​ 在3D世界中父节点变换,其子节点会跟着响应的变换。但是子节点发生变换并不会影响父物体。

资源加载

  • 资源文件类型
    1. .ls为场景文件,选择导出Scene类别时生成。其中包含了场景需要的各种数据、光照贴图、模型、位置等。需使用 Scene3D 类加载。
    2. .lh为预设文件,选择导出Sprite3D类别时生成。其中缺少场景信息,其他的特征与.ls文件相同,但是需要使用 Sprite3D 类加载。
    3. .lm为模型数据文件,通常是FBX格式的转换而成。可以使用 MeshSprite3D 类加载。
    4. .lmat为材质数据文件,是在unity中为模型设置的材质信息。加载.ls或.lh文件时会自动加载.lmat文件来产生材质。可以使用 BaseMaterial 类来加载。
    5. .lani为动画数据文件。如果模型上有动画,导出后将生成的动画配置文件,其中包含了动画帧数据。加载可以使用 AnimationClip 类来加载。
    6. .jpg,.png,.ltc,.ktx,.pvr等是贴图文件。如果有使用到贴图,unity导出后将会生成贴图文件。可以使用 Texture2D 类来加载
  • 加载资源的方法:
    1. 单个场景加载的时候,使用的Laya.Scene3D.load(‘’,,Laya.Handler.create())方法。
    2. 单个材质进行加载的时候,我们使用的Laya.BaseMaterial.load(‘’,,Laya.Handler.create())方法
    3. 加载单个纹理使用Laya.Texture2D.load(‘’,,Laya.Handler.create())方法(纹理为png格式)
    4. 单个网格加载使用的 Laya.Mesh.load(‘’,,Laya.Handler.create()) 方法
    5. 单个预设的加载,我们使用Sprite3D.load(‘’,,Laya.Handler.create())方法
    6. 单个动画加载Laya.AnimationClip.load(‘’,,Laya.Handler.create())
    7. 批量预加载资源(有时候3D的资源比较大,需要使用预加载器预加载来提升首屏的体验,在项目中,一般都会采用加载器的方式,可以对资源有很好的管理)使用Laya.loader.create([],Laya.Handler.create())。在加载完成后,我们可以直接使用Laya.loader.getRes()这个方法来获取加载完成的资源。

场景渲染配置

  1. 雾化
    LayaAir 3D引擎可以设置场景的雾效可见距离(相当于浓度)及雾效的颜色。雾化使用的恰当不但可以提升游戏性能,还可以增加游戏的体验。
    //雾化代码
    scene.enableFog = true;
    //设置雾化的颜色
    scene.fogColor = new Laya.Vector3(0,0,0.6);
    //设置雾化的起始位置,相对于相机的距离
    scene.fogStart = 10;
    //设置雾化最浓处的距离。
    scene.fogRange = 40
    
  2. 天空盒
    天空盒是一种让场景看上去更广阔无垠的一种视觉技术,用无缝对接的封闭纹理将摄像机的视口360度无死角的包裹起来。
    //加载相机天空盒材质
    Laya.BaseMaterial.load("res/.../SkyBox.lmat", Laya.Handler.create(null, function(mat){})
    
  3. 环境光
    环境光颜色(ambientColor),是对材质进行颜色融合染色,使材质趋于某种颜色色调,同时还能对材质进行提亮,模拟灯箱发光效果。如果设置了天空盒且不设置Scene3D场景的AmbientColor,那么LayaAir3D会默认使环境光来源于天空盒。
    //设置场景环境光
    scene.ambientColor = new Laya.Vector3(0.6, 0, 0);
    
  4. 环境反射
  5. 光照贴图
    光照贴图是场景中3D模型产生的投影、阴影过渡、灯光氛围、模型材质与材质之间的颜色影响等。
    很少有3D游戏场景是靠灯光与模型即时渲染产生投影及颜色影响,这是非常耗性能的方式,特别又是手机游戏,手机的显卡功能并不强大,全部用即时光影游戏会变得很卡顿。
    场景光照贴图就是为了解决这个问题,它是以贴图的方式模拟游戏场景的光影光色,减少大量的即时运算。
    光照贴图建议通过unity3D 编辑器渲染光照贴图并导出使用,加载场景时,引擎会自动加载光照贴图达到较好的效果。
    如果unity中并未渲染光照贴图,导出后引擎也不会加载报错,但游戏的效果会大打折扣。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Laya3D是一款基于HTML5技术的3D游戏引擎,它可以运行在多个平台上,包括PC、移动设备和Web。实现战争迷雾效果需要以下步骤: 1. 创建一个地图模型,包括战场和障碍物。 2. 创建一个相机,并设置其位置和朝向,以便能够正确地观察地图。 3. 创建一个光源,可以使用点光源、方向光源或者环境光源。 4. 创建一些材质,用于给地图和障碍物上色。 5. 创建一个迷雾层,用于遮挡地图和障碍物。 6. 在场景中添加一个渲染器,用于将场景渲染到屏幕上。 7. 在每帧更新时,根据相机的位置和迷雾层的范围,计算出需要显示的部分,并将其渲染到屏幕上。 以下是一个简单的示例代码: ```javascript Laya3D.init(0, 0, true); // 创建场景和相机 var scene = Laya.stage.addChild(new Laya.Scene()); var camera = scene.addChild(new Laya.Camera(0, 0.1, 100)); camera.transform.translate(new Laya.Vector3(0, 10, -20)); camera.transform.rotate(new Laya.Vector3(-30, 0, 0), true, false); // 创建光源 var light = scene.addChild(new Laya.DirectionLight()); light.color = new Laya.Vector3(1, 1, 1); light.direction = new Laya.Vector3(0.3, -1, 0); // 创建地图模型和材质 var map = scene.addChild(new Laya.MeshSprite3D(Laya.PrimitiveMesh.createPlane(50, 50))); var mapMat = new Laya.BlinnPhongMaterial(); mapMat.albedoColor = new Laya.Vector4(0.5, 0.5, 0.5, 1); mapMat.renderMode = Laya.BlinnPhongMaterial.RENDERMODE_OPAQUE; map.meshRenderer.material = mapMat; // 创建障碍物模型和材质 var obstacle = scene.addChild(new Laya.MeshSprite3D(Laya.PrimitiveMesh.createBox(1, 2, 1))); var obstacleMat = new Laya.BlinnPhongMaterial(); obstacleMat.albedoColor = new Laya.Vector4(0, 0.5, 0, 1); obstacleMat.renderMode = Laya.BlinnPhongMaterial.RENDERMODE_OPAQUE; obstacle.meshRenderer.material = obstacleMat; obstacle.transform.translate(new Laya.Vector3(-5, 0, 0)); // 创建迷雾层和材质 var fogLayer = scene.addChild(new Laya.MeshSprite3D(Laya.PrimitiveMesh.createPlane(50, 50))); var fogMat = new Laya.UnlitMaterial(); fogMat.albedoColor = new Laya.Vector4(0, 0, 0, 1); fogMat.renderMode = Laya.UnlitMaterial.RENDERMODE_TRANSPARENT; fogMat.renderQueue = Laya.Material.RENDERQUEUE_TRANSPARENT; fogLayer.meshRenderer.material = fogMat; fogLayer.transform.translate(new Laya.Vector3(0, 10, 0)); fogLayer.transform.rotate(new Laya.Vector3(90, 0, 0), true, false); // 创建渲染器 var renderer = Laya.stage.addChild(new Laya.Renderer()); renderer.render(scene, camera); // 更新迷雾层 Laya.timer.frameLoop(1, this, function() { var range = 5; // 迷雾范围 var pos = camera.transform.position; var fogPos = fogLayer.transform.position; fogPos.x = pos.x; fogPos.z = pos.z; fogMat.tilingOffset = new Laya.Vector4(range, range, -pos.x / range, -pos.z / range); }); ``` 在这个示例中,我们创建了一个简单的地图和障碍物,并使用BlinnPhongMaterial和UnlitMaterial给它们上色。然后创建了一个迷雾层,使用UnlitMaterial和透明渲染模式来遮挡地图和障碍物。在每帧更新时,根据相机的位置和迷雾范围,更新迷雾层的位置和纹理坐标,以实现迷雾效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值