html5 3d效果 飞机,纯Shading Language绘制飞机火焰效果

news/2024/11/6 12:29:40/

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

08dd73836addb19935cc04f802e6b6ff.png

火焰的例子我已发在 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范围体验从小火到大火的调节效果。

900b3652d3832c3e2d4fed497ada44c7.png38e59e3a1e56d358191d805da467698f.png

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

55511a801e61f8b44b2c3f46ab5f3a94.png

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

3c36e27480b8ccabf4080b7cfd5a42f4.png

叠加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实现烟雾的粒子系统效果等等,但元旦假期结束了我明天还要上班,其他可完善的地方留给读者去想象了。

71f4ee1dc854ef37de3c28d0f3b43826.png


http://www.ppmy.cn/news/132130.html

相关文章

航拍部分

航拍前准备 天时、地利、人和 天时:风力不宜超过三级,光线充足,避免在中午前后三小时,避开飞机场和军事飞行路线。 地利:提前侦察地形,规划拍摄路径。 人和:掌握必要的理论知识、拥有过硬的飞行…

航拍图像目标检测数据集汇总

2023/2/23 1.DOTA 2.UCAS-AOD 3.NWPU VHR-10 4.RSOD-Dataset 5.DIOR 6.LEVIR 7.VEDAI 8.HRRSD 9.HRSC2016 10.COWC 11.ITCVD 1. DOTA (A Large-scale Dataset for Object DeTection in Aerial Images) 由武汉大学于 2017 年 11 月 28 日发布在 arXiv 上 图像大小:8…

航拍全景拍摄教程,如何制作航拍全景?

对于全景图片摄影爱好者来说,航拍绝对算得上是一个大工程,航拍全景对于设备和技术的要求非常高,拍摄出来的照片具有地拍达不到的震撼效果,也成为了一些摄影爱好者的终极目标。那么对于我们刚刚入门的小白来说,航拍全景…

无人机航拍数据集整理

目录 1.VisDrone 2.DOTA 3.UCAS-AOD 4.UAVDT 5.UAV123 6.CARPK 7.AU-Air 8.ERA 9.VEDAI 10.ITCVD 11.DLR3kVehicle 12.OIRDS 13.NWPU 14.DIOR 1.VisDrone VisDrone2022数据集由中国天津大学机器学习与数据挖掘实验室的AISKYEYE团队收集。基准数据集由 265&#…

航拍遥感数据集

一、Roundabout Aerial Images for Vehicle Detection 本数据集是从无人机拍摄的西班牙环形交叉口航空图像数据集,使用PASCAL VOC XML文件进行注释,指出车辆在其中的位置。此外,还附带一个CSV文件,其中包含与捕获的环形交叉口的位…

四轴笔记----航拍和FPV的区别

许多新手总是分不清什么是航拍,什么是FPV,以至于买飞机的时候买到的不是自己想要的,白花冤枉钱。下面以我自己的经验为大家分享一下航拍和FPV的区别。 首先说,航拍和FPV都是在飞机上安装摄像头,这一点是相同的&#x…

c语言飞机源代码,C语言写的飞机源码

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 #include #include #include #include #define N 35 void print(int [][N]);//输出函数 void movebul(int [][N]);//子弹移动函数 void movepla(int [][N]);//敌机移动函数 void setting(void);//设置函数 void menu(void);//…

FP6151

FP6151是一款输入可达36V的非同步降压型稳压器,内置75mΩ内阻的高位NMOS,具有出色的负载和线路调节能力,可在宽输入电压范围内实现5A的连续输出电流。 电流模式工作下提供了快速动态和简化回路的稳定性,工作开关频率可通过外部电阻…