实现思路:
和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));
});
实现效果: