LayaBox1.8.4实现战争迷雾效果
实现思路:
和Unity实现思路一样,可看我写的下面的一篇文章
战争迷雾FogOfWar---Unity中实现-CSDN博客
根据碰撞点可以计算出需要透明的位置,怎样计算如下:
根据迷雾mesh的长宽和纵向横向的的像素数可以得出,每个小方格的长和宽,然后就可以计算出碰撞点属于第几个格子,然后将周围一定范围内的格子透明即可。
实现代码:
自定义迷雾mesh代码:
var FogOfWarMesh=(function(_super){function FogOfWarMesh(long,width,stacks,slices){/**@private */this._long=NaN;/**@private */this._width=NaN;/**@private */this._stacks=0;/**@private */this._slices=0;(long===void 0)&& (long=10);(width===void 0)&& (width=10);(stacks===void 0)&& (stacks=100);(slices===void 0)&& (slices=100);FogOfWarMesh.__super.call(this);this._long=long;this._width=width;this._stacks=stacks;this._slices=slices;this.activeResource();this._positions=this._getPositions();this._generateBoundingObject();this.pos = new Laya.Vector2();this.isInit = true;}Laya.class(FogOfWarMesh,'laya.d3.resource.models.FogOfWarMesh',_super);var __proto= FogOfWarMesh.prototype;__proto.recreateResource=function(){this._numberVertices=(this._stacks+1)*(this._slices+1);this._numberIndices=this._stacks *this._slices *2 *3;var indices=new Uint16Array(this._numberIndices);var vertexDeclaration=Laya.VertexPositionNormalColor.vertexDeclaration;var vertexFloatStride=vertexDeclaration.vertexStride / 4;this.vertices= this.vertices || new Float32Array(this._numberVertices *vertexFloatStride);var halfLong=this._long / 2;var halfWidth=this._width / 2;var stacksLong=this._long / this._stacks;var slicesWidth=this._width / this._slices;this.FillVert(this.vertices,stacksLong,slicesWidth,halfLong,halfWidth,this.pos);var indiceIndex=0;for (i=0;i < this._slices;i++){for (j=0;j < this._stacks;j++){indices[indiceIndex++]=(i+1)*(this._stacks+1)+j;indices[indiceIndex++]=i *(this._stacks+1)+j;indices[indiceIndex++]=(i+1)*(this._stacks+1)+j+1;indices[indiceIndex++]=i *(this._stacks+1)+j;indices[indiceIndex++]=i *(this._stacks+1)+j+1;indices[indiceIndex++]=(i+1)*(this._stacks+1)+j+1;}}this._vertexBuffer=new Laya.VertexBuffer3D(vertexDeclaration,this._numberVertices,/*laya.webgl.WebGLContext.STATIC_DRAW*/0x88E4,true);this._indexBuffer=new Laya.IndexBuffer3D(/*laya.d3.graphics.IndexBuffer3D.INDEXTYPE_USHORT*/"ushort",this._numberIndices,/*laya.webgl.WebGLContext.STATIC_DRAW*/0x88E4,true);this._vertexBuffer.setData(this.vertices);this._indexBuffer.setData(indices);this.memorySize=(this._vertexBuffer._byteLength+this._indexBuffer._byteLength)*2;this.completeCreate();}__proto.FillVert = function(vertices,stacksLong,slicesWidth,halfLong,halfWidth,pos){var verticeCount=0;for (var i=0;i <=this._slices;i++){for (var j=0;j <=this._stacks;j++){vertices[verticeCount++]=j *stacksLong-halfLong;vertices[verticeCount++]=0;vertices[verticeCount++]=i *slicesWidth-halfWidth;vertices[verticeCount++]=0;vertices[verticeCount++]=1;vertices[verticeCount++]=0;vertices[verticeCount++]=0;vertices[verticeCount++]=0;vertices[verticeCount++]=0;vertices[verticeCount]= pos && ((Math.abs(i - pos.x - 15) < 10 && Math.abs(j - pos.y) < 10)?0:this.isInit? 1 :vertices[verticeCount]);verticeCount++}};this.isInit = false;}__proto.updateVert = function (pos) {this.pos = pos;this.recreateResource();}return FogOfWarMesh;
})(Laya.PrimitiveMesh)
迷雾调用代码:
//添加3D场景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, 10));camera.transform.rotate(new Laya.Vector3(-60, 0, 0), true, false);camera.clearColor = null;//添加方向光var directionLight = scene.addChild(new Laya.PointLight());directionLight.transform.translate(new Laya.Vector3(0,2,0));directionLight.color = new Laya.Vector3(0.5, 0.5, 0.5);directionLight.direction = new Laya.Vector3(0, 1, 0);var player = scene.addChild(new Laya.MeshSprite3D(new Laya.BoxMesh(1,1,1)));player.transform.translate(new Laya.Vector3(0,0,-1));player.transform.rotate(new Laya.Vector3(0, 0, 0), false, false);var st = new Laya.BlinnPhongMaterial();st.albedoTexture = Laya.Texture2D.load("res/layabox.png");player.meshRender.shareMaterial = st;//添加自定义模型var width = 50;var height = 50;var stacks = 200;var slices = 200;this.mesh = new FogOfWarMesh(width,height,stacks,slices);//new CustomMesh(10, 10);var box = scene.addChild(new Laya.MeshSprite3D(this.mesh));box.transform.translate(new Laya.Vector3(0,3,-1));box.transform.rotate(new Laya.Vector3(0, 0, 0), false, false);var material = new Laya.StandardMaterial();material.blend = Laya.BaseMaterial.BLEND_ENABLE_SEPERATE;box.meshRender.material = material;var boxCollider = box.addComponent(Laya.BoxCollider);boxCollider.setFromBoundBox(this.mesh.boundingBox)var w = width/stacks;var h = height/stacks;var fogPos = new Laya.Vector3();Laya.Vector3.subtract(box.transform.position, new Laya.Vector3(width/2,0,height/2),fogPos);var self = this;Laya.timer.loop(100,this,function(){var pos = player.transform.position;var up = new Laya.Vector3(0, 100, 0);Laya.Vector3.add(pos,up,up);var ray = new Laya.Ray(pos, up);var _outHitInfo = new Laya.RaycastHit();Laya.Physics.rayCast(ray, _outHitInfo, 30, 0);self.mesh.updateVert(new Laya.Vector2((_outHitInfo.position.z - fogPos.z)/h,(_outHitInfo.position.x - fogPos.x)/w));});
实现效果: