纯Shading Language绘制飞机火焰效果

简介: 上篇《纯Shading Language绘制HTML5时钟》体现了GLSL可编程性特点,但没有体现GLSL可编程出各种酷炫效果的特点,今天我们将用纯Shading Language绘制火焰效果,并将其应用到《HT图形组件设计之道(四)》飞行的飞机例子上。

上篇《纯Shading Language绘制HTML5时钟》体现了GLSL可编程性特点,但没有体现GLSL可编程出各种酷炫效果的特点,今天我们将用纯Shading Language绘制火焰效果,并将其应用到《HT图形组件设计之道(四)》飞行的飞机例子上。

Screen Shot 2015-01-01 at 8.48.26 PM

火焰的例子我已发在 http://js.do/hightopo/fireball,其本质在绘制gl.POINTS的点类型时,通过在Fragment Shader在点区域内生成noise的噪声用于绘制多种颜色效果,并将多次不同噪声算法生成的颜色进行叠加,同时噪声的生成还依赖于time的时间参数,这样最终融合成不错的圆形火焰效果。

采用gl.POINTS的绘制方式会受不同浏览器对点大小的限制,可通过gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE)获知浏览器支持的最小和最大范围,一般也都有1~255或1~300的区间,所以也基本够用于展示效果,http://js.do/hightopo/fireball的例子中52行中的float color = 3.0 – (3.*length(2.*p));其中的第一个3.0是火焰强度intensity参数,可通过改变此值达到改变火焰强度的效果,可在1.0~4.0范围体验从小火到大火的调节效果。

Screen Shot 2015-01-01 at 8.31.49 PMScreen Shot 2015-01-01 at 8.32.42 PM

HT图形组件设计之道(四)》文中的例子我将在飞机的尾部叠加该火焰效果,由于考虑到自定义GLSL的复杂性,HT并未开放图元自定义GLSL的功能,我们将要采用的是在Graph3dView的上层再次叠加一个WebGL驱动的Canvas,火焰是绘制到这个上层的Canvas,因此和HT的Graph3dView完全是松耦合,不会影响HT的3D组件自身的所有显示和交互功能,这样的应用有点类似《百度地图与HT for Web结合的GIS网络拓扑应用》中GIS地图与HT的GraphView组件叠加效果。

Screen Shot 2014-10-08 at 7.45.25 PM

当然这样叠加会导致火焰始终在最上层,无法真实反映三维空间层次的问题,但作为监控系统应用最关键的是展示重要指标,例如对于电信网管应用,当设备有告警冒泡呈现时,往往要求告警冒泡要呈现在最上层不要被其他设备遮挡住,同样如果真的飞机失火需要监控系统实时提示该告警信息时,肯定也是需要该火焰不被遮挡,因此真实世界的层次瑕疵在这里反而是合适的解决方案。

Screen Shot 2015-01-03 at 10.45.06 PM

叠加Canvas到Graph3dView比较容易,通过Graph3dView.getView().appendChild(canvas)加入,并在Graph3dView布局时同时布局Cavnas位置大小,火焰的位置我们是这样实现的,将一个隐藏的node节点host到飞机的尾部,这样该节点会自定跟随飞机飞行过程的位置变化,绘制时火焰时我们通过Graph3dView#toViewPosition函数将node三维坐标转换成二维的屏幕Cavnas的坐标,这还没完我们还得将屏幕坐标转换成WebGL驱动的Canvas的POINT点坐标,相关代码如下:

function draw(){
    gl.viewport(0, 0, canvas.width, canvas.height);
    gl.clearColor(0.0, 0.0, 0.0, 0.0);
    gl.clear(gl.COLOR_BUFFER_BIT);     

    gl.uniform1f(gl.getUniformLocation(program, 'time'), (Date.now() - startTime)/1000 ); 
    gl.uniform1f(gl.getUniformLocation(program, 'intensity'), intensity ); 

    var vertexBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);

    var position = g3d.toViewPosition(node.p3());                                
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
         position.x/g3d.getWidth()*2 - 1,
         1 - position.y/g3d.getHeight()*2
    ]), gl.STATIC_DRAW);
    var vertexLocation = gl.getAttribLocation(program, "aVertexPosition");
    gl.vertexAttribPointer(vertexLocation, 2, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(vertexLocation);                   
    gl.drawArrays(gl.POINTS, 0, 1);

    requestAnimationFrame(draw); 
}              

function resizeCanvas(){
    canvas.width = g3d.getWidth() * devicePixelRatio;
    canvas.style.width = g3d.getWidth() + 'px';  
    canvas.height = g3d.getHeight() * devicePixelRatio;
    canvas.style.height = g3d.getHeight() + 'px';                 
}

以上代码我们还传入了intensity的强度参数,该参数我们通过ht.Default.startAnim动画函数,控制其值在0~4之间不断来回变化,这样可达到火焰有小变大来回变换的类似告警闪烁提示效果。还有var devicePixelRatio = window.devicePixelRatio;参数也是容易被忽略的细节,该值会根据设备的retina支持程度有不同的值,避免在高分辨率设备下出现锯齿模糊的问题,当然通过devicePixelRatio增大canvas.width和canvas.height也是有内存绘制性能代价的,如果效果要求不是太高情况下也可以都采用1来处理,其实要求不太高的三维场景即使时retina为3的iphone 6强制用devicePixelRatio为1的方式也不会有太大问题,并且能节省内存提高绘制性能,某些低性能的终端某些情况下甚至可以再降级到小于1的值以牺牲效果换取性能。

千辛万苦终于让飞机飞出了我想要的效果(http://v.youku.com/v_show/id_XODYyMzU3MDg0.html),当然还有无数的细节可以完善,例如可以根据飞机离eye的距离动态改变POINT点的大小,或改造GLSL实现烟雾的粒子系统效果等等,但元旦假期结束了我明天还要上班,其他可完善的地方留给读者去想象了。

Screen Shot 2015-01-03 at 11.18.30 PM

 

目录
相关文章
|
9月前
GEE图表——GEE绘制图表,设定双纵坐标图形以NDVI和RVI为例
GEE图表——GEE绘制图表,设定双纵坐标图形以NDVI和RVI为例
115 0
Threejs实现下雨,下雪,阴天,晴天,火焰
Threejs实现下雨,下雪,阴天,晴天,火焰
1916 0
|
2月前
Highcharts 测量图
Highcharts 测量图
61 4
|
7月前
|
Python
Python模拟火焰文字效果:炫酷的火焰字动效
Python模拟火焰文字效果:炫酷的火焰字动效
128 1
|
9月前
|
数据采集 数据处理
GEE图表——利用NOAA气象数据绘制气温预测图
GEE图表——利用NOAA气象数据绘制气温预测图
151 0
|
数据可视化
ComplexHeatmap|根据excel表绘制突变景观图(oncoplot)
ComplexHeatmap|根据excel表绘制突变景观图(oncoplot)
331 0
|
数据采集 数据可视化 数据挖掘
还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
本文讲解9种『炫酷高级』的数据图表,可视化地表示比例或百分比:哑铃图、甜甜圈图、华夫饼图、堆积条形图...附上代码,快快用起来吧!
889 2
还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
|
定位技术 Python
综合练习之海龟作图
综合练习之海龟作图
118 0
|
人工智能 API
手把手教你如何绘制自己的跳舞词云图~
首先我们要先准备一个热舞视频,从哪里下载的都可以,我是用You-Get从B站上下载的,命令如下:
368 0
【D3.js - v5.x】(4)绘制饼图 | 附完整代码
【D3.js - v5.x】(4)绘制饼图 | 附完整代码
338 0
【D3.js - v5.x】(4)绘制饼图 | 附完整代码

热门文章

最新文章