HTML5+WebGL 3D机房开发实例
- 格式:docx
- 大小:4.23 MB
- 文档页数:25
基于HTML5WebGL构建智能城市3D场景前⾔随着城市规模的扩⼤,传统的⽅式很难彻底地展⽰城市的全貌,但随着 3D 技术的应⽤,出现了 3D 城市群的⽅式以动态,交互式地把城市全貌呈现出来。
配合智能城市系统,通过 Web 可视化的⽅式,使得城市管理者可以更及时地了解交通情况,城市消防,电⼒管理等⽅⾯的运⾏情况,做出处理。
本 demo 使⽤产品轻量化 HTML5/WebGL 建模的⽅案,传统的智慧楼宇/楼宇⾃动化/楼宇安防/智慧园区常会采⽤ BIM(建筑信息模型 Building information modeling)软件,如 Autodesk 的 Revit 或 Bentley 这类建筑和⼯程软件,但这些 BIM 建模模型的数据往往过于庞⼤臃肿,绝⼤部分细节信息对楼宇⾃控意义不⼤,反⽽影响拖累了⾏业 Web SCADA 或 Web 组态监控的趋势,所以我们采⽤以 Hightopo 的 HT for Web 产品轻量化 HTML5/WebGL 建模的⽅案,实现快速建模、运⾏时轻量化到甚⾄⼿机终端浏览器即可3D 可视化运维的良好效果。
预览图:代码实现加载 3d 场景新建⼀个 3d 场景,并加⼊到页⾯中。
const g3d = new ht.graph3d.Graph3dView();const dm3d = g3d.dm();g3d.addToDOM();addToDOM 函数默认将场景加载到 body 中并填充窗⼝。
接下来反序列化城市场景 json,并在反序列化函数的回调中设置了场景的视⾓,中⼼位置,天空盒,并获得各图元信息,调⽤ startAnim 函数:g3d.deserialize('scenes/ny.json', () => {g3d.setEye([1132.8386351821287, 1916.836416970022, 1479.5345608290288]);g3d.setCenter([519.9741236104874, 273.4741921410557, -319.58669041297884]);g3d.setSkyBox(dm3d.getDataByTag('skyBox'));// 获取扩散效果的图元scaleList.push(dm3d.getDataByTag('scaleBlue'),dm3d.getDataByTag('scaleRed'));···// 开始动画startAnim();});动画实现加载后的城市场景如下图所⽰:我们可以看到场景中有蓝黄⽔波纹效果,道路,消防通道的流动效果,上下浮动的效果和旋转的 logo 和卫星。
HTML5之WebGL3D概述(上)—WebGL原⽣开发开启⽹页3D渲染新时代WebGL开启了⽹页3D渲染的新时代,它允许在canvas中直接渲染3D的内容,⽽不借助任何插件。
WebGL同canvas 2D的API ⼀样,都是通过脚本操纵对象,所以步骤也是基本相似:准备⼯作上下⽂,准备数据,在canvas中绘制对象并渲染。
与2D不同的就是3D涉及的知识更多了,例如世界、光线、纹理、相机、矩阵等专业知识。
WebGL有⼀个很好的中⽂教程,就是下⾯使⽤参考中的第⼀个链接,所以这⾥不再班门弄斧,后⾯的内容只是简单的总结⼀下学习的内容。
在正常安装以上浏览器之后还是不能运⾏WebGL,那你可以强制开启WebGL⽀持试⼀试。
开启⽅法如下:Chrome浏览器我们需要为Chrome加⼊⼀些启动参数,以下具体操作步骤以Windows操作系统为例:找到Chrome浏览器的快捷⽅式,右键点击快捷⽅式,选择属性;在⽬标框内,chrome.exe后⾯的引号后⾯,加⼊以下内容:--enable-webgl--ignore-gpu-blacklist--allow-file-access-from-files点击确定后关闭Chrome,然后⽤此快捷⽅式启动Chrome浏览器。
⼏个参数的含义如下:--enable-webgl的意思是开启WebGL⽀持;--ignore-gpu-blacklist的意思是忽略GPU⿊名单,也就是说有⼀些显卡GPU因为过于陈旧等原因,不建议运⾏WebGL,这个参数可以让浏览器忽略这个⿊名单,强制运⾏WebGL;--allow-file-access-from-files的意思是允许从本地载⼊资源,如果你不是WebGL的开发者,不需要开发调试WebGL,只是想要看⼀下WebGL的Demo,那你可以不添加这个参数。
Firefox浏览器Firefox的⽤户请在浏览器的地址栏输⼊“about:config”,回车,然后在过滤器(filter)中搜索“webgl”,将webgl.force-enabled 设置为true;将webgl.disabled设置为false;在过滤器(filter)中搜索“security.fileuri.strict_origin_policy”,将security.fileuri.strict_origin_policy设置为false;然后关闭⽬前开启的所有Firefox窗⼝,重新启动Firefox。
智慧园区three案例代码智慧园区three案例代码是指基于HTML5、WebGL、WebVR以及three.js等技术实现的三维交互式园区模拟系统。
该系统为用户提供了一个虚拟园区环境,用户可以在其中浏览、查看、探索、交互和管理园区中的各类信息数据。
智慧园区three案例代码主要分为三个部分:系统框架代码、场景渲染代码和交互管理代码。
系统框架代码:该部分主要实现了系统的初始化、场景创建、相机配置、渲染器创建、渲染器大小确定、渲染效果和动画控制等功能。
其中,主要代码包括如下内容:系统初始化var scene, camera, renderer, controls, stats, clock;init();animate();场景创建scene = new THREE.Scene();scene.background = new THREE.Color(0xa0a0a0);scene.fog = new THREE.Fog(0xa0a0a0, 200, 1000);相机配置const aspect = window.innerWidth / window.innerHeight;camera = new THREE.PerspectiveCamera(50, aspect, 0.1, 10000); camera.position.set(0, 200, 500);渲染器创建renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setPixelRatio(window.devicePixelRatio);renderer.setSize(window.innerWidth, window.innerHeight);渲染器大小确定window.addEventListener("resize", onWindowResize, false); function onWindowResize() {camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix();renderer.setSize(window.innerWidth, window.innerHeight);}渲染效果和动画控制controls = new THREE.OrbitControls(camera, renderer.domElement); controls.target.set(0, 100, 0);controls.update();stats = new Stats();document.body.appendChild(stats.dom);clock = new THREE.Clock();场景渲染代码:该部分主要实现了虚拟园区的各种三维空间元素的渲染,包括建筑物、道路、景观、车辆等。
基于HTML5 WebGL 的3D SCADA 主站系统首先,还是从场景的搭建开头,这个界面是在 body 体上添加了三个部分:3d 组件,表单组件以及拓扑组件(2d 组件)。
添加的方式是这样的:为了最外层组件加载填弥漫窗口的便利性,HT 的全部组件都有addToDOM 函数,其实现规律如下,其中 iv 是 invalidate 的简写:HT 的组件普通都会嵌入 BorderPane、SplitView 和 TabView 等容器中用法,而最外层的HT组件则需要用户手工将 getView()返回的底层 div 元素添加到页面的 DOM 元素中,这里需要注重的是,当父容器大小变幻时,假如父容器是 BorderPane 和 SplitView 等这些 HT 预定义的容器组件,则 HT 的容器会自动递归调用孩子组件 invalidate 函数通知更新。
但假如父容器是原生的 html 元素,则 HT 组件无法获知需要更新,因此最外层的 HT 组件普通需要监听 window的窗口大小变幻大事,调用最外层组件 invalidate 函数举行更新。
由于这个函数是将 style 中的位置都固定了,所以不能将全部的组件都用这个函数,我们根据这个函数的方式将拓扑组件和属性组件添加进界面中,3d 组件挺直利用 addToDOM 函数即可:拓扑组件和属性组件的样式我就不再赘述了,只是设置了一个背景色彩以及 left right top bottom 位置而已。
这里要声明一下,HT 组件普通都以设置 position 为 absolute 的肯定定位方式。
大家可能会奇怪,这个鹰眼怎么生成的?在 HT 中,只要 2D 和3D 共用同一个数据容器 dataModel 即可共同拥有全部在这个dataModel 中的元素,并且位置都是对应的,只需要类似这种做法即可:第1页共2页。
HTML5+WebGL打造的⽆插件纯web3D机房(第三季新增资产容量管理、动环监控等)原本以为这次的机房资产管理项⽬告⼀段落,可以歇⼀歇,哥还是太天真了。
我们伟⼤的甲⽅⼜拿下了第⼆期的项⽬,誓把哥的才华发挥到极致啊。
国庆长假也没正经休息⼏天,硬是给⼈折腾出了个demo,加上了容量管理、电源⾛线、告警巡航这些实⽤功能,以及温湿度、风向、门禁、视频监控效果。
对了,第⼀次来看哥的童鞋,这⾥有前两篇的链接:第⼀季:如何从零开始搭建基于HTML5和WebGL的3D机房场景第⼆季:场景和功能的丰富,包括机柜、设备、⾛线、路径规划等功能说句⼤实话,⽼板给那么多活,其实哥⼀开始也是拒绝的,不过回头看成果,⼼⾥竟然还有些澎湃呢。
甲⽅虐归虐,思路还是⽐较清晰的,第⼀期重点放在三维呈现和静态的资产管理上,第⼆期着重动环监控,这样基本上⼀个⽐较完整的数据中⼼监控系统就出来了。
废话不多说了,这就开始给⼤家介(嘚)绍(瑟)。
界⾯美化这次先是做了⼀些界⾯的美化⼯作,最近跟设计师mm配合得不错,果然界⾯档次也有所提⾼。
右键菜单调整随着demo上堆砌的功能越来越多,右键的按钮也不够使了,加之有朋友反映右键菜单有点隐蔽不容易找到,我把所有的功能效果都改为从⼯具栏按钮进⼊,直接纵向显⽰放在了左侧,效果还不错:动态客户信息上次在机柜顶部显⽰资产编码的⽅式得到了客户的肯定,这次⼜尝试在机柜组地板上动态⽣成客户的信息,这就是3D的好处啊,哪⼉有空我贴哪⾥。
其它装饰性细节上次随⼿找的CCTV主播电视画⾯果断被吐槽了,看来⼤家还是很严肃地在探讨问题,所以这次我也把电视画⾯改成了统计图表,另外新增了特别合时宜的海报,给哥点个赞?资产管理功能以上都是⼀些界⾯上的⼩改动,下⾯给⼤家上⼏个硬菜。
机架可⽤空间当服务器陆续上架后,会对机柜的空间产⽣占⽤和分隔。
及时了解整个机房中每个机架的占⽤情况和空闲空间的⼤⼩情况,是⾮常重要的⽇常⼯作。
通过3d来呈现就再适合不过了:我们把有服务器占⽤的空间⽤⽩⾊块填充,有空闲的空间根据⼤⼩不同⽤不同的⾊块填充,就有了下⽅的效果:图上的颜⾊不光是为了好看,上⾯1-2U的空间⽤红⾊、5U以下的⽤紫⾊,通过不同颜⾊来表⽰连续剩余空间的数量,⽩⾊表⽰已经占⽤的空间,这样对于机房管理⼈员来说,可以迅速掌握整个机房的占⽤情况。
HTML5+WebGL 3D机房开发实例前阵子写了一篇HMTL5 3D机房开发的例子,介绍了如何用html5在网页上创建无插件的精美3d机房场景,收到很多朋友的鼓励,深表感谢。
对于索要源代码的朋友,已经尽力邮件回复。
由于精力所限,如未能收到的朋友请留言或给我发送邮件:tw-service@。
最近项目第二期又要紧锣密鼓地开始了,所以想抓紧把一些新增的内容补充上,进一步完善这个html5 3d机房的呈现效果。
上一篇中主要介绍的是如何从最基础的webgl封装到创建3d物体对象,再通过3d物体对象“搭积木”式的组建整个3d机房场景。
这一篇主要介绍一些如何在这个场景上进一步丰富更多的功能和呈现效果,以及实现这些功能在技术上的思路。
首先我们来看看上一期已经实现的纯天然无添加无PS的HTML5 3D机房效果:已经拿到过代码的朋友应该知道,这一场景可通过一个json文件进行组装和加载,可以很方便地进行修改和维护。
在此基础上,这一次我又增加了”机柜标签、机柜门、复杂设备、机房走线、人员轨迹“等效果,下面我就把第二季的干货一一为大家奉上。
机柜标签机房中最重要的物理资源——机柜——是机房管理、规划、监控人员最关注的对象之一。
对于规模在几十个、上百个甚至上千个机柜的机房,每个机柜必然会进行资产编号,方便检索和管理。
这个在多数资产管理系统中,都是最基本的。
但是在3d场景中,如何显示这些机柜编号,才能让用户更直观的看到每个机柜的位置呢?传统的方式是用标签显示资产编号,例如可以用“告警冒泡”那样的方式显示一个文字气泡。
不过当机柜产生告警时,两个气泡会有所冲突。
而且过多的气泡会产生相互遮挡覆盖,有点混乱,比如像这样:因此我尝试了一种不同的思路:把文字渲染到一个内存图片,“溶解”到机柜的上方贴图中。
想要生成一个内存的图片文字,可以通过下面的函数实现:Js代码.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中渲染不容易出现闪烁和锯齿。
基于HTML5WebGL的智慧楼宇三维可视化监控前⾔可视化的智慧楼宇在 21 世纪是有急迫需求的,中国被世界称为“基建狂魔”,全球⾼层建筑数量位居⾸位,所以对于楼宇的监控是必不可少。
智慧楼宇可视化系统更多突出的是管理⽅⾯的功能,即如何的全⾯实现优化控制和管理,节能降耗、⾼效、舒适、环境安全这样⼀个⽬的,可以这样说,判断⼀个建筑物是否具有智能建筑特点,要看它是否具有 IBMS 的系统集成,这是很重要的判定条件。
IBMS 系统的建⽴必不可少需要硬件采集信息到后台,随着⼯业互联⽹,物联⽹概念的推⼴应⽤,让硬件与软件的结合变得系统化,过程化,使得智慧楼宇可视化成为可能。
本⽂所概述的智慧楼宇是基于⼀栋真实建筑可视化简化建模之后得到的效果,楼层的轮廓在系统中抽象成线条,整体拼凑起来就形成了⼀栋简化版的楼宇,当然其中的楼层地板也是抽象成简单的⽴⽅体包裹在对应楼层线框的⾥⾯。
对应的电梯,闸机,扶梯等物体也简化抽象成六⾯体,线条。
抽象的物体全部采⽤的 API 即可创建完成,所以抽象之后具有复⽤性,同样的⽅法可以采⽤到其它所有楼宇。
可视化监控功能预览地址:⼯单监测 -- 统计楼宇收到的⼯单信息客流监测 -- 显⽰当⽇进出楼宇的⼈流量信息消防报警 -- 统计当⽇楼宇的消防报警信息重点区域监控 -- 显⽰重点区域的摄像头信息停车场车位统计 -- 统计停车场车位信息楼宇控制 -- 可单独控制不同类型楼层的闸机,电梯,扶梯,警报和客流的显⽰与隐藏,监控此时电梯,扶梯等物体的运⾏情况告警信息 -- 实时滚动显⽰当前楼宇的告警信息可视化监控预览楼宇效果楼层效果楼层控制效果可视化实现UI 以及模型实现2D 可视化2d 部分的 UI 都是采⽤ HT 暴漏的 API 进⾏描绘实现,UI 部分都绘制在⼀个 canvas 节点上,并且全都为⽮量,所以放⼤不会失真,两侧的实时数据通过实现实时刷新,HT 在处理实时刷新的时候只会刷新当前需要刷新的区域,所以不会出现例如修改⼀个页⾯上的某个⽂字⽽导致整个 canvas 重绘。
基于HTML5快速搭建3D机房设备⾯板以真实设备为模型,搭建出设备⾯板,并实时获取设备运⾏参数,显⽰在设备⾯板上,这相⽐于纯数值的设备监控系统显得更加⽣动直观。
今天我们就在的3D技术上完成设备⾯板的搭建。
我们今天模拟的设备是机房设备,先来⽬睹下最终效果:我来解释下这个模型,⼀个带有透明玻璃门的机柜,机柜⾥装有5台设备,门可以开合,设备可以插拔,那么我么该如何搭建这样的设备呢?⽅法不难,我们⼀步⼀步来。
我们先从设备开始,设备的⽰意图如下:看起来有模有样的,其实呢,它就是⼀个长⽅体,然后在长⽅体的正⾯贴上⼀张图⽚,这样⼦设备的壳就出来了,创建代码如下:var node = createNode([0, 0, 0], [475, 100, 0]);node.s({'front.image': 'panel','all.color': '#E6DEEC'});node.setToolTip('Double click to pop the server’);其中设置设备的正⾯图⽚的⽅法是通过设置节点的front.image样式属性来实现的,在代码中将front.image属性设置为’panel’,⽽’panel’属性是已经通过ht.Default.setImage()⽅法注册了的图⽚的别名,在代码中还设置了长⽅体各个⾯的颜⾊和⿏标悬停时的提⽰语。
在代码中还调⽤了createNode()的⽅法,该⽅法并没有做什么特殊的操作,只是将创建节点的代码封装起来,精简代码,避免相同的代码重复书写,具体的封装如下:/*** 创建3D拓扑节点,并添加到dataModel中* @param p3 {array} 位置信息* @param s3 {array} 长宽⾼信息* @returns {ht.Node} 3D拓扑节点*/function createNode(p3, s3) {var node = new ht.Node();node.s({'shape' : 'rect'});node.p3(p3);node.s3(s3);dataModel.add(node);return node;}该⽅法通过传⼊位置信息和⼤⼩信息创建出⼀个节点,并添加到中,最后返回该节点对象。
webgl开发示例WebGL 是一种在网页浏览器中呈现 3D 图形的技术。
以下是一个简单的 WebGL 开发示例,该示例将在浏览器中绘制一个红色的立方体:首先,在 HTML 文件中创建一个 <canvas> 元素:html<!DOCTYPE html><html><head><title>WebGL Example</title></head><body><canvas id="webgl-canvas" width="400"height="400"></canvas><script src="main.js"></script></body></html>创建一个名为 main.js 的 JavaScript 文件,并将以下代码添加到其中:javascriptconst canvas =document.getElementById('webgl-canvas');const gl = canvas.getContext('webgl');if (!gl) {console.error('Failed to get the rendering context for WebGL');}// 设置清除颜色为黑色,不透明gl.clearColor(0.0, 0.0, 0.0, 1.0);// 清空颜色缓冲区gl.clear(gl.COLOR_BUFFER_BIT);// 创建顶点着色器const vertexShaderSource = `attribute vec3 aVertexPosition;uniform mat4 uMVMatrix; // 模型视图矩阵uniform mat4 uPMatrix; // 投影矩阵varying vec4 vColor; // 用于传递给片元着色器的颜色变量void main(void) {gl_Position = uPMatrix * uMVMatrix *vec4(aVertexPosition, 1.0);vColor = vec4(1.0, 0.0, 0.0, 1.0); // 设置顶点颜色为红色}`;const fragmentShaderSource = `precision mediump float;varying vec4 vColor; // 从顶点着色器传递过来的颜色变量void main(void) {gl_FragColor = vColor; // 设置片元颜色为顶点颜色}`;// 创建着色器程序并获取输出变量const vertexShader = createShader(gl,gl.VERTEX_SHADER, vertexShaderSource);const fragmentShader = createShader(gl,gl.FRAGMENT_SHADER, fragmentShaderSource);const program = createProgram(vertexShader, fragmentShader);eProgram(program);const positionAttributeLocation =gl.getAttribLocation(program, 'aVertexPosition');const positionBuffer = gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);const vertices = new Float32Array([-1.0, -1.0, 0.0, 1.0, -1.0, 0.0, -1.0, 1.0, 0.0]); // 立方体顶点坐标数组,每个顶点有3个分量(x、y、z)gl.bufferData(gl.ARRAY_BUFFER, vertices,gl.STATIC_DRAW);gl.enableVertexAttribArray(positionAttributeLoc ation);gl.vertexAttribPointer(positionAttributeLocatio n, 3, gl.FLOAT, false, 0, 0); // 将顶点坐标数据关联到顶点着色器中的 aVertexPosition 属性变量上const modelViewMatrixLocation =gl.getUniformLocation(program, 'uMVMatrix'); // 模型视图矩阵变量位置const projectionMatrixLocation =gl.getUniformLocation(program, 'uPMatrix'); // 投影矩阵变量位置const modelViewMatrix = new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0]); // 设置模型视图矩阵为单位矩阵(即不进行任何变换)const projectionMatrix = new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, -1, 0, -1, 1]); // 设置投影矩阵为单位透视投影矩阵(即近裁剪面到远裁剪面之间的距离为无穷大)gl.uniformMatrix4fv(modelViewMatrixLocation, false, modelViewMatrix); // 将模型视图矩阵传递给着色器程序中的 uMVMatrix 变量上gl.uniformMatrix4fv(projectionMatrixLocation, false, projectionMatrix); // 将投影矩阵传递给着色器程序中的 uPMatrix 变量上。
1.3 初识HTML55 <h1>这里为文本标题1</h1>6 <h2>这里为文本标题2</h2>7 <h3>这里为文本标题3</h3>8 <h4>这里为文本标题4</h4>9 <h5>这里为文本标题5</h5>10 <h6>这里为文本标题6</h6>11 <p>这里为段落,本例主要为向读者展示先前介绍的标签的用法,这些标签为基本标签12 <hr></br>这里演示在段落中的换行<hr></br>这里接着上面的段落。
</p><!--此处为html文档注释13 本案例介绍了基础标签的一些内容-->14 此处主体结束15 </body></html>❑第1、2行为指示浏览器关于页面使用哪个HTML 版本进行编写的指令,并声明了标题。
其中<!DOCTYPE html>声明必须是html文档的第一行。
❑第5~10行为文本标题示例,类似文档中的分级标题,看图1-4所示的效果图,理解会更加深刻。
❑第3~15行为html文档的主体部分,其中向大家展示了标题<h1>~<h6>、段落标签<p>、换行标签与下划线标签<br>和<hr>的基本用法。
下面我们来看一下案例效果。
本案例以及本书中的案例都是在谷歌的Chrome浏览器或者Firefox浏览器上运行的,读者也可以自行选择合适浏览器运行案例,选择时需要注意浏览器是否支持HTML5特性。
图1-4所示为本案例的效果。
▲图1-4 Sample1_1案例效果示例图1.3.3 格式标签对基础标签有了基本认识后,那么剩下的标签在用法上与其并无太多差异,只是在功能上有所不同。
第6章纹理映射1542.截取拉伸方式截取方式中当纹理坐标的值大于1时都看作1,因此会产生边缘被拉伸的效果,具体情况如图6-6所示。
▲图6-6 截取纹理从图6-6中可以看出,需要纹理映射的矩形中4个顶点纹理坐标分别为(0,0)、(4,0)、(0,4)、(4,4),因此矩形中的各片元纹理坐标范围:S轴方向为0~4,T轴方向为0~4。
由于在此种拉伸方式下,大于1的纹理坐标都看作1,因此产生了纹理横向和纵向边缘被拉伸的效果。
纹理加载的过程中,设置纹理拉伸方式为截取的代码如下。
1 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S,2 gl.CLAMP_TO_EDGE); //设置S轴的拉伸方式为截取3 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T,4 gl.CLAMP_TO_EDGE); //设置T轴的拉伸方式为截取提示纹理拉伸在S与T轴方向上是独立的,可以在S方向上使用重复,在T方向上使用截取,反之亦然,但此种情况并不多见。
另外,在实际开发中纹理坐标大于1并采用截取方式的情况并不多见,往往仅用于这种需要边缘拉伸的特殊效果时。
6.2.2 不同拉伸方式的案例介绍完纹理拉伸的基本知识后,下面将通过一个简单的案例说明如何在开发中使用不同的纹理拉伸方式。
此案例的功能为用不同的拉伸方式、不同的纹理坐标对一个矩形进行纹理映射,其运行效果如图6-7~图6-12所示。
▲图6-7 截取纹理1 ▲图6-8 截取纹理2 ▲图6-9 截取纹理3❑图6-7、图6-8、图6-9等是程序在截取拉伸方式下的截图,从左至右矩形的纹理坐标最大值分别为(1, 1)、(4, 2)、(4, 4)。
从3幅图中可以看出,在截取纹理拉伸方式下,纹理坐标中所有大于1.0的值均被设置为1.0使用,因此纹理边缘被拉伸。
❑图6-10、图6-11、图6-12等是程序在重复拉伸方式下的截图,从左至右矩形的纹理坐标。
数百个HTML5 例子学习HT 图形组件– 3D 建模篇2016/09/30 0 hightopo/demo/pipeline/index.html《数百个HTML5 例子学习HT 图形组件– WebGL 3D 篇》里提到HT 很多情况下不需要借助3Ds Max 和Blender 等专业3D 建模工具也能做出很多效果,例如hightopo/guide/guide/core/3d/examples/example_3droom.html 这个3D 电信机房监控例子整个都是通过HT 提供的API 构建而成:不过这个例子中的模型都比较规矩,也就消防栓由一个球圆通构成,其他图形通过HT 提供的基本Node 以及Shape 对象即可搞定:但这并不意味着API 只能做简单的模型,《HT for Web 建模手册》中介绍的HT建模插件可以让有想象力的同学做出各种不可思议的效果。
例如这个餐座椅的例子:hightopo/guide/guide/plugin/modeling/examples/example_custommodel.html对于这个餐座椅的例子,特别是一些不规则的花盆、酒杯、圣诞树和那颗爱心,很多人好奇我们是怎么搞出来的。
其实蛮简单,就用了《HT for Web 建模手册》中的createRingModel 和createExtrusionModel 两个构建模型的函数,其中createRingModel 顾名思义用来构建围绕一圈的环状模型,createExtrusionModel 用来构建基于某个形状的凸出效果,这两个函数生成的3D 模型都是靠平面的2D 图形衍生而来,都是靠HT 系统中构建2D 不规则多边形时采用的Points 和Segments 两个数组参数搞定,Points 和Segments 的意义可参考《HT for Web 形状手册》:可生成不规则的3D 地板:hightopo/guide/guide/core/shape/examples/example_floor.html可生成不规则的3D 管线:hightopo/guide/guide/core/shape/examples/example_polyline.html这样大家应该理解了原理,但餐座椅的那几个不规则形状的magic 参数是如果得来的呢,这还是得借助辅助工具:hightopo/demo/3dmodel/index.html,这个工具多年前为写例子随意搞的,代码挺简单大家直接看hightopo/demo/3dmodel/index.html 源代码即可,写的比较简陋但挺实用,如何导出?打开控制台,自己打印出shape 对象的sements 和points 参数即可,或等我有空了再来写个可导入导出更完整的例子,或者you can you up?其实也不仅仅也用于Node 节点类型对象的建模,对于连线其实也可以用模型来搞定,例如hightopo/guide/guide/plugin/forcelayout/examples/example_forcelayout3.html 这个3D 弹力拓扑图例子,很多人已经觉得挺酷炫了,但我一直对这呆板规矩的管道连线很不爽,于是突发奇想搞了个像狗骨头的两头粗中间细的连线效果,整个3D 拓扑图例子一下子高大上了许多:hightopo/demo/pipeline/index.html这个例子原理是这样的,将连线Edge 设置成透明不可见的,然后针对每个Edge 对应一个Node 节点,这个节点的形状就是被拉伸并定位到连线位置替代连线来显示,而Node 图形在还没拉伸之前长得如下:这里还有个细节是通过createMatrix 函数,为每个管线设置一个指向两节点位置的矩阵坐标变换参数到style 的mat 属性上,矩阵预算不理解也没关系,直接照抄例子中代码即可,为了方便大家理解我搞了个两个节点一条连线更简单的例子供参考:今天只是抛砖引玉,《HT for Web 建模手册》中还有众多API 函数,只要有想象力还可以折腾出无数的花样,后续有空我再借助HT for Web 的WebGL 3D 自定义建模功能多搞些实用的例子。
第5章光照效果
126
▲图5-2 使用不同步长切分球体的效果图
5.1.2 案例效果概览
上一小节中已经对如何将球面切分为三角形进行了介绍,本节将使用上一小节中的球体切分策略开发出绘制球体的案例Sample5_1。
介绍本案例的详细代码之前,读者有必要先来了解一下本案例的运行效果,如图5-3所示。
▲图5-3 案例Sample5_1运行效果
从图5-3中可以看出,本案例并没有通过直接指定单一颜色的方法进行渲染,而是使用了渲染效果更加绚丽的棋盘纹理着色器进行渲染的。
棋盘纹理着色器的逻辑很简单,开发难度较小,在开发中时常用到。
其原理如图5-4所示。
▲图
5-4 棋盘纹理着色器的原理
说明
图5-4中的立方体为球的外接立方体。
球面上每个顶点都在此外接立方体之内。
从图中可以看出,此外接立方体在x、y、z轴方向上被切分成了很多同样大小的小
方块。
具体的着色策略为,首先计算出当前片元x、y、z坐标对应行数、层数和列数,然后将行数、层数、列数相加。
如果和为奇数,说明此片元位于图5-4中的黑色方块中,则此片元为红色。
若和为偶数,则此片元将被渲染为白色。
5.1.3 具体开发步骤
了解了本案例的运行效果和棋盘着色器的基本原理之后,就可以对本项目的代码部分进行详细介绍了。
由于本案例中很多类与前面案例中的十分类似,所以在这里只给出具有代表性的相关代码。
具体的开发步骤如下所示。
8.1 混合技术分别为[As, As, As, As]和[1-As, 1-As, 1-As, 1-As]。
若源片元是透明的,则根据透明度透过后面的内容;若源片元不透明,则仅能看到源片元。
源因子为SRC_COLOR,目标因子为ONE_MINUS_SRC_COLOR,即源因子和目标因子分别为[Rs, Gs, Bs, As]和[1- Rs, 1- Gs, 1- Bs, 1-As]。
此组合可以实现滤光镜效果,也就是平时透过有色眼镜或玻璃窗观察事物的感觉。
8.1.3 简单混合效果案例上一小节中介绍了两种常用的混合因子组合,本小节将通过两个简单的案例来说明这两种混合因子组合的使用。
首先介绍的是采用滤光镜效果因子组合的案例Sample8_1,其运行效果如图8-2所示。
▲图8-2 案例Sample8_1的运行效果图 ▲图8-3 触控区域 提示从图8-2中可以看出,场景中有一个可以移动的类似枪瞄镜的圆形,透过圆形可以看到后面的物体。
另外,案例运行时手指触摸屏幕的左右两侧,滤光镜圆形会左右移动,手指触摸屏幕中间的上下两侧,滤光镜会上下移动,如图8-3所示。
了解了案例的运行效果及操控方式后就可以介绍案例的开发步骤了,具体如下所列。
(1)首先用3ds Max生成5个基本物体(平面、圆环、茶壶、立方体、圆球),并导出成obj文件放入项目的obj目录待用。
(2)开发出搭建场景的基本代码,包括加载物体、摆放物体、计算光照等。
这些代码与前面章节的许多案例基本思路完全一致,因此这里不再赘述。
(3)开发一个纹理矩形TextureRect.js文件,用来呈现滤光镜。
此类在前面很多案例中已经出现过,这里也不再赘述。
(4)准备好本案例中需要用到的滤光镜纹理图片(lgq.png),其内容如图8-4所示。
▲图8-4 本案例的滤光镜纹理图(5)渲染场景的Sample8_1.html文件中的drawFrame方法内添加启用混合模式并绘制滤光镜的代码,具体内容如下。
1.3 初识HTML558 password, date pickers, number, checkbox, radio 以及 file。
-->59 </body></html>❑第2~10行为image属性应用案例。
在使用该属性时需要注意的是图片的存放位置,只需将图片与HTML文件放到同一个文件夹下即可。
如果还有上层文件,在路径上加上上层文件即可。
通过alt属性可以为用户在由于某些原因无法查看图像时提供备选的信息。
❑第11~26行为自动完成与获得焦点属性应用。
在平时浏览网页时我们输入要登录账号的开头字母或数字便会出提示,这便是因为开启了autocomplete属性。
有autofoucs属性时我们会发现,网页打开后焦点自动回到该input元素上。
❑第27~41行为max与maxlength属性的应用,应用这几个属性时只需规定好相应的数值即可。
结合使用max与min属性可以规定好一段范围,maxlength一般用在有字数限制的文本输入<input>元素。
❑第42~59行为验证输入字段属性、字段预期值属性与required属性的应用,这些在我们日常上网时都会遇到。
使用验证输入字段与required属性,在不满足条件时都会弹出提示通过使用字段预期值,在初始加载进界面后会显示预期设置的值。
到这里为止我们便将表单标签的基础内容学习完毕。
本小节的内容有些繁杂,知识点零碎,但每点都比较容易接受。
1.3.5 图像、链接、列表标签下面我们来看一下图像类、链接类与列表类的标签介绍。
表1-9所示为图像链接列表标签及其描述,我们先来总体学习一下这些标签。
表1-9 图像链接列表标签及其描述看完这些标签的类型与描述后,接下来我们先来看一下运用这些标签做出来的网页效果。
通过对这些标签效果的观察,我们再来深究一下它们的具体用法。
图1-10为图像链接列表标签应用实例图。
图中有一个图片加载失败,这是因为我们故意写错路径名进而显示alt属性。
第13章 Ammo物理引擎304案例的学习。
下面的这些方法对于学习本案例十分重要。
❑ initGraphics方法。
此方法为本案例的初始化各种信息的方法,其主要功能是创建摄像机、场景、渲染器以及初始化它们的参数。
❑ initPhysics方法。
此方法为本案例的创建及初始化物理世界的方法,其主要功能包括创建物理世界,设置碰撞检测,设置边界信息,设置重力加速度。
❑ createObjects方法。
此方法为本案例的创建物体的方法,其主要功能包括创建箱子和地面的材质、纹理、碰撞形状,以及创建它们的刚体。
❑ createRigidBody方法。
此方法为本案例的创建物体刚体的方法,其主要功能包括创建刚体,设置惯性、运动状态对象、刚体信息、反弹系数、摩擦系数,最后将刚体添加进物理世界。
❑ updatePhysics方法。
此方法为本案例的更新物理世界的方法,其主要功能是根据时间更新加入物理世界中的物体的位置。
13.3.3 主要方法的介绍了解了本案例的基本结构后,接下来将介绍本节案例的具体开发。
这里将对以后案例中频繁出现的方法进行介绍,具体方法如下。
(1)在介绍代码之前,我们需要先在案例中导入Ammo物理引擎的JavaScript文件。
首先需要在github上下载Ammo物理引擎的项目包,读者可登录如下网址进行下载:https:/// kripken/ammo.js。
(2)下载完成之后,解压缩文件,将“ammo.js-master\builds”下的ammo.js复制到案例的util 文件夹里并在example.html文件中写入“"<script type="text/javascript" src="util/ammo.js"></script>"”,以便引入Ammo,这样便完成了Ammo文件的导入。
(3)3D场景初始化方法—initGraphics方法。
HTML5+WebGL 3D机房开发实例前阵子写了一篇HMTL5 3D机房开发的例子,介绍了如何用html5在网页上创建无插件的精美3d机房场景,收到很多朋友的鼓励,深表感谢。
对于索要源代码的朋友,已经尽力邮件回复。
由于精力所限,如未能收到的朋友请留言或给我发送邮件:tw-service@。
最近项目第二期又要紧锣密鼓地开始了,所以想抓紧把一些新增的内容补充上,进一步完善这个html5 3d机房的呈现效果。
上一篇中主要介绍的是如何从最基础的webgl封装到创建3d物体对象,再通过3d物体对象“搭积木”式的组建整个3d机房场景。
这一篇主要介绍一些如何在这个场景上进一步丰富更多的功能和呈现效果,以及实现这些功能在技术上的思路。
首先我们来看看上一期已经实现的纯天然无添加无PS的HTML5 3D机房效果:已经拿到过代码的朋友应该知道,这一场景可通过一个json文件进行组装和加载,可以很方便地进行修改和维护。
在此基础上,这一次我又增加了”机柜标签、机柜门、复杂设备、机房走线、人员轨迹“等效果,下面我就把第二季的干货一一为大家奉上。
机柜标签机房中最重要的物理资源——机柜——是机房管理、规划、监控人员最关注的对象之一。
对于规模在几十个、上百个甚至上千个机柜的机房,每个机柜必然会进行资产编号,方便检索和管理。
这个在多数资产管理系统中,都是最基本的。
但是在3d场景中,如何显示这些机柜编号,才能让用户更直观的看到每个机柜的位置呢?传统的方式是用标签显示资产编号,例如可以用“告警冒泡”那样的方式显示一个文字气泡。
不过当机柜产生告警时,两个气泡会有所冲突。
而且过多的气泡会产生相互遮挡覆盖,有点混乱,比如像这样:因此我尝试了一种不同的思路:把文字渲染到一个内存图片,“溶解”到机柜的上方贴图中。
想要生成一个内存的图片文字,可以通过下面的函数实现:Js代码.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后,可以这样直接贴图使用:Js代码.var labelCanvas=demo.Default.generateAssetImage(label);.rack.setStyle('top.m.texture.image', labelCanvas);.rack.setStyle('top.m.specularmap.image', labelCanvas);通过上面代码,把贴图作为机柜立方体top面的贴图和反射映射图。
这样出来的效果如下:这样,既不用增加3d对象,也不影响机柜的美观度,关键是看得非常清晰,在大场景中也不干扰用户的视线:机柜门上一篇里,由于时间紧迫,也考虑到呈现效率,机柜采用了“双击机柜出现设备”的方案。
一个立方体的机柜虽然简单直接,但是没有机柜门,总觉得假了一点,客户也提到了这一点,因此按照机房门的思路,增加一个机柜门,增加双击开门的效果,这个比较简单:Js代码..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度”,在双击的时候触发。
复杂电信设备第一季里,机柜内的设备,主要用乐服务器来表现,加入了设备弹出、告警等效果。
后期根据现场和用户的交流,用户进一步提出要显示机架上需要安装更加复杂的电信设备,包括板卡、板卡的插拔动作、呈现方法等,也就是在机柜上显示一个有多个板卡的设备,双击板卡可以弹出。
要做这个,需要把原来的一个立方体的服务器设备做一个“挖空”处理,变成一个空的设备框的样子。
然后再生成一系列的板卡对象,插入这个空框。
每个板卡应该由面板+电路板组成,可以用两个立方体进行拼接,添加适当的贴图完成。
代码如下:Js代码.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`来定义,并设置其贴图:Js代码.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对象,然后用它来生成一个空间的“管子”对象。