文档章节

HTML5+WebGL打造的无插件纯Web 3D机房(第二季新增视频)

MonoLog
 MonoLog
发布于 2015/09/17 14:31
字数 3134
阅读 11141
收藏 263

前情提要

前阵子写了一篇HTML5打造的无插件纯web 3D机房,介绍了如何用html5在网页上创建无插件的精美3d机房场景。这两个月以来,陆续收到很多朋友的鼓(膝)励(盖),受宠若惊之余,对索要源代码的朋友都已经尽力邮件回复。由于精力所限,未能收到的朋友请留言或给我发送邮件:tw-service@servasoft.com。最近项目第二期又要紧锣密鼓地开始了,所以想抓紧把一些新增的内容补充上,进一步完善这个html5 3d机房的呈现效果。

上一篇中主要介绍的是如何从最基础的webgl封装到创建3d物体对象,再通过3d物体对象“搭积木”式的组建整个3d机房场景。这一篇主要介绍一些如何在这个场景上进一步丰富更多的功能和呈现效果,以及实现这些功能在技术上的思路。

首先我们来看看第一季已经实现的纯天然无添加无PS的HTML5 3D机房效果: 这里写图片描述

已经拿到过代码的朋友应该知道,这一场景是通过一个json文件进行组装和加载,可以很方便地进行修改和维护。在此基础上,这一次我又增加了机柜标签、机柜门、复杂设备、机房走线、人员轨迹等效果,下面我就把第二季的干货一一为大家奉上。

录了个渣画质的视频,有兴趣的童鞋可以点开看看: http://v.youku.com/v_show/id_XMTMzNzk5MjQzNg==.html?f=25854892&from=y1.7-3

机柜标签

机房中最重要的物理资源——机柜——是机房管理、规划、监控人员最关注的对象之一。对于规模在几十个、上百个甚至上千个机柜的机房,每个机柜必然会进行资产编号,方便检索和管理。这个在多数资产管理系统中,都是最基本的。但是在3d场景中,如何显示这些机柜编号,才能让用户更直观的看到每个机柜的位置呢?

传统的方式是用标签显示资产编号,例如可以用“告警冒泡”那样的方式显示一个文字气泡。不过当机柜产生告警时,两个气泡会有所冲突。而且过多的气泡会产生相互遮挡覆盖,有点混乱,比如像这样: 这里写图片描述

因此我尝试了一种不同的思路:把文字渲染到一个内存图片,**“溶解”**到机柜的上方贴图中。

想要生成一个内存的图片文字,可以通过下面的函数实现:

	generateAssetImage: function(text){         
		var width=512, height=256;

		var canvas = document.createElement('canvas');
		canvas.width  = width;
		canvas.height = height;

		var ctx = canvas.getContext('2d');		
		ctx.fillStyle='white';
		ctx.fillRect(0,0,width,height);
		
		ctx.font = 150+'px "Microsoft Yahei" bold';
		ctx.fillStyle = 'black';
		ctx.textAlign = 'center';
		ctx.textBaseline = 'middle';
		ctx.fillText(text, width/2,height/2);
		ctx.strokeStyle='black';
		ctx.lineWidth=15;
		ctx.strokeText(text, width/2,height/2);

		return canvas;   
	}

需要留意的是:

  1. 生成的图片宽高数值最好是2的幂,例如128、256、512等,这样在3d中渲染不容易出现闪烁和锯齿。相关原理请查阅google。
  2. 文字绘制尽量居中、充满整个图,不要太小,否则看上去比较奇怪。
  3. 空白处保持透明,不必填充色,方便和机柜本身贴图的“溶解”。
  4. 直接返回canvas对象即可,不必生成图片点阵数组。

生成canvas后,可以这样直接贴图使用:

	var labelCanvas=demo.Default.generateAssetImage(label);
	rack.setStyle('top.m.texture.image', labelCanvas);
	rack.setStyle('top.m.specularmap.image', labelCanvas);

通过上面代码,把贴图作为机柜立方体top面的贴图和反射映射图。这样出来的效果如下: 这里写图片描述

这样,既不用增加3d对象,也不影响机柜的美观度,关键是看得非常清晰,在大场景中也不干扰用户的视线: 这里写图片描述

机柜门

上一篇里,由于时间紧迫,也考虑到呈现效率,机柜采用了“双击机柜出现设备”的方案。一个立方体的机柜虽然简单直接,但是没有机柜门,总觉得假了一点,客户也提到了这一点,因此按照机房门的思路,增加一个机柜门,增加双击开门的效果,这个比较简单:

	var rackDoor = new mono.Cube(width, height, 2);
	rackDoor.s({
		'm.type':'phong',
		'm.color': '#A5F1B5',
		'm.ambient': '#A4F4EC',
		'front.m.texture.image': 'images/rack_front_door.png',
		'back.m.texture.image': 'images/rack_door_back.png',
		'm.envmap.image': demo.Default.getEnvmap('envmap1'),
	});
	rackDoor.setParent(rack);
	rackDoor.setPosition(0, 0, depth/2+1); 
	rackDoor.setClient('animation','rotate.right.120');	

上面代码创建了一个薄薄的立方体作为机柜门。设置贴图、颜色等,再设置其parent是机柜。这样,如果拖拽机柜位置,机柜也会跟着移动,简单方便。最后,在设置一下机柜门的动画。通过一个字符串进行定义:rotate.right.120表示动画是“向右侧旋转120度”,在双击的时候触发。 这里写图片描述

复杂电信设备

第一季里,机柜内的设备,主要用乐服务器来表现,加入了设备弹出、告警等效果。后期根据现场和用户的交流,用户进一步提出要显示机架上需要安装更加复杂的电信设备,包括板卡、板卡的插拔动作、呈现方法等,也就是在机柜上显示一个有多个板卡的设备,双击板卡可以弹出。

要做这个,需要把原来的一个立方体的服务器设备做一个“挖空”处理,变成一个空的设备框的样子。然后再生成一系列的板卡对象,插入这个空框。每个板卡应该由面板+电路板组成,可以用两个立方体进行拼接,添加适当的贴图完成。代码如下:

	var parts=[{
		//card panel
		type: 'cube',
		width: width,
		height: height,
		depth: 1,
		translate: [x, y, z+1],
		rotate: rotate,
		op: '+',
		style:{
			'm.color': color,
			'm.ambient': color,
			'm.texture.image': 'images/gray.png',
			'front.m.texture.image': pic,
			'back.m.texture.image': pic,
		}
	},{
		//card body
		type: 'cube',
		width: 1,
		height: height*0.95,
		depth: depth,
		translate: [x, y, z-depth/2+1],
		rotate: rotate,
		op: '+',
		style:{
			'm.color': color,
			'm.ambient': color,
			'm.texture.image': 'images/gray.png',
			'left.m.texture.image': 'images/card_body.png',
			'right.m.texture.image': 'images/card_body.png',
			'left.m.texture.flipX': true,
			'm.transparent': true,	
		}
	}];
	
	var card=demo.Default.createCombo(parts);
	card.setClient('animation', 'pullOut.z');
	box.add(card);

上面代码可以生成一个板卡对象。循环重复,设置位置,即可生成整个设备。通过设置animation属性,定义板卡动画为**“双击拉出”**,再次双击推回。效果如下图:

这里写图片描述

这里写图片描述

当然,实际项目中,各种结构的电信设备千奇百怪,要通过代码定义是不现实的。所以我们还开发了一个设备编辑器,可以通过拖拽方式快速生成设备结构图。

这里写图片描述

机房线缆和走线架

除了机柜之外,线缆的连接走向和连接关系是管理员关注的另外一个焦点。机架中的电信设备或服务器设备会通过端口和线缆进行连接,组成一定结构的网络。而线缆的走向在物理上通过肉眼是很难看清晰的。更多线缆会从机柜连出,延伸到屋顶上方或地板下方的隐蔽工程中(例如走线架)固定和布线,用肉眼更无法观察。此时,需要3d机房界面能清晰的显示电缆从端口到走线架再到端口的**“端到端”**的物理走线,方便管理员了解网络情况和管理。

线缆

线缆,可以用一个空间的path来定义,并设置其贴图:

	var path = demo.Default.create3DPath(json.data);
	var cable=new mono.PathNode(path, 100, 1);
	cable.s({
		'm.type': 'phong',
		'm.specularStrength': 30,
		'm.color': json.color,
		'm.ambient': json.color, 		
		'm.texture.image': 'images/flow.jpg',
		'm.texture.repeat': new mono.Vec2(200, 1),
	});
	box.add(cable);

通过json定义的[x, y, z]数组来生成一个path对象,然后用它来生成一个空间的“管子”对象。流动效果可以通过一个动画来修改贴图纹理的offset,让眼睛产生贴图不断**“移动”**的效果。

这里写图片描述

走线架

走线架可以通过简单的镂空贴图来模拟,不需要建一个复杂的框架模型,减少对GPU的压力。实际的走线架有很多种,例如下图是一种典型的走线架: 这里写图片描述

我们通过程序模拟一下:

	var rail=demo.Default.createPathObject(railInfo);
	rail.s({
		'm.texture.image': 'images/rail.png',
		'm.type': 'phong',
		'm.transparent': true,
		'm.color': '#CEECF5',
		'm.ambient': '#CEECF5',
		'aside.m.visible': false,
		'zside.m.visible': false,
		'm.specularStrength': 50,
	});
	rail.setPositionY(263);
	box.add(rail);

最终走线架+线缆的效果如下: 这里写图片描述

路径规划

在3d场景中,经常需要计算规划并显示一个最优的空间或平面路径,用来指示如何最快、最合理的到达目标,或通过路径显示一个移动物体的轨迹,方便进行监控和分析。例如,客户提出一个实际需求:现场检修人员手持平板进入机房,输入设备id后,直接给出前方走动路径,并进行实时导航引导

我们可以把这个需求分解为导航路径显示和人员模拟两步。 导航路径

导航线可以通过一个浮在地板上方的path路径来定义。做一个简单的颜色渲染和弯角处理,就可以比较清晰的展示底面的走动路径。

			var path=new mono.Path();
			path.moveTo(object.getPositionX(), object.getPositionZ());
			for(var i=0;i<points.length; i++){
				path.lineTo(points[i][0], points[i][13]);
			}
			path = mono.PathNode.prototype.adjustPath(path, 20);

			var trail=new mono.PathCube(path, 10, 3);
			trail.s({
				'm.type': 'phong',
				'm.specularStrength': 30,
				'm.color': '#298A08',
				'm.ambient': '#298A08', 		
				'm.texture.image': 'images/flow.jpg',
				'm.texture.repeat': new mono.Vec2(150, 1),
			});
			trail.setRotationX(Math.PI);
			//trail.setStartCap('plain');
			//trail.setEndCap('plain');
			trail.setPositionY(5);
			trail.setClient('type', 'trail');
			box.add(trail);

这里写图片描述

拉近后看下细节: 这里写图片描述

移动轨迹的显示也有很多变化,形状、颜色的变化,空间坐标的变化,都可以产生一些不同的效果。例如下图是另外一个3d车库导航系统的场景: 这里写图片描述

加载人物模型

接下来,要加载一个人的模型进来,放在路径上。可以在网上找一些3d max做的模型,并转成obj格式的文件,这样就可以方便的导入场景中。Obj通过对应的mtl文件进行定义材质,需要的贴图也需要一并涵盖进来。通过下面几行代码即可完成obj模型的导入:

		var obj='images/worker.obj';
		var mtl='images/worker.mtl';               
			
		var loader = new mono.OBJMTLLoader();
		loader.load(obj, mtl, {'worker': 'images/worker.png',}, function (object) {                    			
			box.addByDescendant(object);
		});

效果如下图: 这里写图片描述

需要留意的是,人的模型不要太大,能把人物轮廓大概渲染清晰即可。例如上面的模型也就几百k,加载和显示几乎瞬间完成,不会产生卡顿。如果加载几十兆上百兆的高清模型,则可能出现卡顿,也会拖慢场景的渲染速度。毕竟我们的主要场景对象是3d机房,对模型选择要有所取舍,千万不要喧宾夺主。

让任务沿着路径移动,可以通过动画进行控制,对path中每一段路线进行平移,连续、反复的播放,即可实现人物的移动效果。 这里写图片描述

当然这里有一个缺点,人物的移动是僵硬不动的,不能像真实人物一样迈腿一步一步的走路进行移动。如果要做,需要用到骨骼动画等技术,相对复杂一些,目前项目紧急,就留给以后找时间研究了。当然对于3d机房这样的企业应用来说,必要性不一定很大,毕竟不是游戏。

通过这些技术,大家可以轻松构建一个比较完整的3d机房系统,就跟我们这次的项目一样: 这里写图片描述

这里写图片描述

这里写图片描述

后记

篇幅有限,这一篇就介绍这么多,希望对大家有所启发和帮助,后续找时间会继续给大家介绍如何拖拽移动机柜、显示机房中的温度云图、风向监控、摄像头及视频监控,如何创建一个大的园区和楼宇等内容。大家有什么好的想法和意见,或需要相关代码的同学可以发邮件到tw-service@servasoft.com,或留下邮箱,我会尽力回复。谢谢!

© 著作权归作者所有

MonoLog
粉丝 206
博文 74
码字总数 26200
作品 0
浦东
高级程序员
私信 提问
加载中

评论(79)

温柔丶恋旧
温柔丶恋旧
太牛啊,仰慕,求代码学习 825042246@qq.com
连七
连七
大神,求份源码,膜拜一下,谢谢1217272252@qq.com
小寶
小寶
大神威武,homeemail@qq.com 求份源码膜拜0
喵小强
喵小强
真是大神!!361897986@qq.com 求份源码膜拜下!! 13
宇宙星星
宇宙星星
犀利,dmyz3214382@163.com
梦之海澜
梦之海澜
厉害👍:skin-tone-2: 834031168@qq.com
f
flybutter

引用来自“MonoLog”的评论

引用来自“venjiang”的评论

venjiang@gmail.com
gmail退信了。。有其他邮箱么?

非常棒!!
GS晓东
GS晓东
好牛逼啊!
MonoLog
MonoLog 博主

引用来自“venjiang”的评论

venjiang@gmail.com
gmail退信了。。有其他邮箱么?
MonoLog
MonoLog 博主

引用来自“杨三更”的评论

感觉这玩意用unity实现更好一些吧
U3D也不错,就是略重
打造最美HTML5 3D机房(MONO哥强势归来,第四季惊艳发布)

前言 初次见面的朋友们大家好,简单自我介绍一下:我是Mono哥,性别男,爱好。。。编程,自从一年多前入了HTML5和WebGL的坑,就再也没有爬出来过,目前正在钻研3D机房以及相关的3D应用。这篇...

MonoLog
2016/11/16
816
0
HTML5 + WebGL打造的无插件纯web 3D机房(第三季新增资产容量管理、动环监控等)

@MonoLog 你好,想跟你请教个问题: HTML5 + WebGL打造的无插件纯web 3D机房(第三季新增资产容量管理、动环监控等) 可否把这个代码发给小弟一份,小弟好好学习学习670717@qq.com...

欢喜哥_桃旺旺
2016/03/14
1K
1
打造最美HTML5 3D机房(MONO哥强势归来,第四季惊艳发布)

前言 初次见面的朋友们大家好,简单自我介绍一下:我是Mono哥,性别男,爱好。。。编程,自从一年多前入了HTML5和WebGL的坑,就再也没有爬出来过,目前正在钻研3D机房以及相关的3D应用。这篇...

MonoLog
2017/11/29
0
0
无插件纯Web 3D机房,HTML5+WebGL倾力打造

最近项目开发任务告一段落,刚好有时间整理这大半年的一些成果。使用html5时间还不久,对js的认识还不够深入。没办法,以前一直搞java,对js的一些语言特性和概念一时还转换不过来。 上一篇介...

MonoLog
2015/07/09
18.1K
148
打造最美HTML5 3D机房(第二季)

写在前面的前面 现在拍电影、搞真人秀都流行拍续集,哥今天给大家带来的是打造最美3D机房的续集,哥的目标是成为3D机房界的网红。 -------------------------------我是这个系列已经有了第三...

MonoLog
2017/11/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

自定义ApiBoot Logging链路以及单元ID生成策略

ApiBoot Logging会为每一个请求都对应创建链路编号(TraceID)以及单元编号(SpanID),用于归类每一次请求日志,通过一个链路下日志单元的Parent SpanID可以进行上下级关系的梳理。 前文回顾...

恒宇少年
27分钟前
12
0
浅谈 Application 和 activity

对于 在 Application初始化一些变量,为什么不可以放在activity 或者其他的组件里呢? 这里就根据个人的理解来讲述一下,欢迎补充指正。 首先 activity 是以栈的形式出现,一个app应用会有多...

MrLins
27分钟前
11
0
Allegro的脚本文件内容里都有哪些

小伙伴们在使用Allegro的时候是否经常用到脚本文件夹呢?scr的用法其实可真不简单。。。 首先脚本文件的运行模式就存在很多种,比如不提示错误信息,不弹出确认对画框(这样很有利于我们执行...

demyar
29分钟前
21
0
微信升级外链管理规范,「砍一刀帮我加速」要被禁止了

原创: 蒋鸿昌 首发:「知晓程序」公众号 - 最好的微信新商业媒体 几天前,知名互联网评论人阑夕模仿皮尤研究中心(Pew Research Center)在美国做的互联网通识调查问卷,做了一份中文版问卷...

知晓云
29分钟前
16
0
CentOS 7接投影仪

我将一台安装着CentOS 7图形界面的惠普笔记本电脑当桌面使用。最近,想要连接投影仪时却遇到了问题。笔记本有一个HDMI接口。我买了一个HDMI---->VGA的转接线,连上笔记本电脑后,屏幕一直在闪...

大别阿郎
33分钟前
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部