上篇《纯Shading Language绘制HTML5时钟》体现了GLSL可编程性特点,但没有体现GLSL可编程出各种酷炫效果的特点,今天我们将用纯Shading Language绘制火焰效果,并将其应用到《HT图形组件设计之道(四)》飞行的飞机例子上。
火焰的例子我已发在 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范围体验从小火到大火的调节效果。
《HT图形组件设计之道(四)》文中的例子我将在飞机的尾部叠加该火焰效果,由于考虑到自定义GLSL的复杂性,HT并未开放图元自定义GLSL的功能,我们将要采用的是在Graph3dView的上层再次叠加一个WebGL驱动的Canvas,火焰是绘制到这个上层的Canvas,因此和HT的Graph3dView完全是松耦合,不会影响HT的3D组件自身的所有显示和交互功能,这样的应用有点类似《百度地图与HT for Web结合的GIS网络拓扑应用》中GIS地图与HT的GraphView组件叠加效果。
当然这样叠加会导致火焰始终在最上层,无法真实反映三维空间层次的问题,但作为监控系统应用最关键的是展示重要指标,例如对于电信网管应用,当设备有告警冒泡呈现时,往往要求告警冒泡要呈现在最上层不要被其他设备遮挡住,同样如果真的飞机失火需要监控系统实时提示该告警信息时,肯定也是需要该火焰不被遮挡,因此真实世界的层次瑕疵在这里反而是合适的解决方案。
叠加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实现烟雾的粒子系统效果等等,但元旦假期结束了我明天还要上班,其他可完善的地方留给读者去想象了。
<iframe src="http://player.youku.com/embed/XODYyMzU3MDg0" frameborder="0" width="510" height="498"></iframe>
相关推荐
2. **Shader语言**:OpenGL ES使用GLSL(OpenGL Shading Language)编写着色器,控制像素和顶点的渲染。在火焰效果中,可能需要编写顶点着色器和片段着色器,用以计算火焰的形状、颜色和透明度。 3. **纹理映射**:...
火焰效果则更复杂,通常需要结合颜色变化、透明度变化以及粒子系统来模拟。OpenGL的顶点和片段着色器可以用来控制每个像素的颜色和亮度,以产生热浪扭曲和火焰的闪烁效果。粒子系统用于生成大量小的、短暂存在的...
3. **纹理映射**:火焰效果通常需要使用纹理映射技术,将预先绘制的火焰图像贴到3D模型上。纹理映射可以让火焰看起来更真实,通过在不同的时间和位置改变纹理坐标,可以实现火焰的动态变化。 4. **帧缓冲对象...
在这个火焰效果程序中,可能使用了OpenGL ES进行图形绘制,通过顶点坐标、颜色和纹理映射来构建火焰的形状和色彩。 2. **Shaders**:OpenGL ES中的着色器(Shader)是用GLSL(OpenGL Shading Language)编写的程序...
开发者可能使用了OpenGLESL(OpenGL Shading Language)编写自定义着色器,以实现粒子的动态行为,如随机扩散、上升、爆炸以及颜色的渐变。 在OpenGL中,粒子的渲染可能通过两种方式实现:一是使用纹理映射,将粒子...
在这个项目中,开发者可能使用了OpenGL ES来绘制火焰粒子,通过顶点坐标、颜色和纹理映射实现火焰的形状和颜色变化。 2. **粒子系统**:火焰效果通常由大量独立的粒子组成,每个粒子代表一小块火焰,它们有自己的...
开发者可以通过顶点着色器和片段着色器来定义物体的形状和颜色,这些着色器是用类似于C的语言GLSL(OpenGL Shading Language)编写的。 在WebGL-water项目中,核心部分是水波纹的生成和动画。这通常涉及到数学和...
`Three.js`提供了一些内置的着色器,但也可以编写自己的GLSL(OpenGL Shading Language)代码来实现特定的视觉效果。 8. **加载器(Loader)**:如果全景图是由多个图像拼接而成,可能需要用到`Three.js`的图像加载...
- **Shader语言**:粒子的渲染效果往往需要自定义着色器(Shader),使用GLSL(OpenGL Shading Language)编写,以控制粒子的颜色、透明度和光照等效果。 3. **源码解析** - **粒子类**:源码中可能会有一个`...
OpenGL ES 2.0是其一个重要的版本,引入了着色器语言GLSL(OpenGL Shading Language),大大提升了图形处理的灵活性和性能。 在Android平台上,OpenGL ES被广泛用于游戏开发、3D图形设计和动态壁纸等场景。本项目...
开发者会编写GLSL(OpenGL Shading Language)程序,这些程序在GPU上运行,控制每个像素的最终颜色。粒子的形状可以是简单的点、线或者自定义的纹理,通过纹理映射技术可以将复杂的图像应用到粒子上,如火焰纹理,以...
3. **着色器程序**:研究顶点和片段着色器代码,了解如何使用GLSL(OpenGL Shading Language)控制粒子的视觉效果。 4. **粒子更新**:分析粒子状态如何随时间变化,如位置、速度、旋转等。 5. **绘图循环**:理解主...
这些着色器可以通过GLSL(OpenGL Shading Language)编写,为艺术家和程序员提供了极大的灵活性。 此外,纹理映射可能也被用于增加导弹表面的细节和真实感。通过将2D图像贴在3D模型上,可以模拟出金属质感、光泽或...
例如,粒子系统中的烟雾或火焰效果通常需要透明度处理,这就需要用到alpha blending,调整源和目标颜色的组合方式。 总的来说,“粒子系统范例”是一个很好的学习资源,它涵盖了OpenGL的基本使用、粒子生成、物理...
开发者可以编写GLSL(OpenGL Shading Language)程序来控制这些着色器,实现自定义的图形效果。 2. **CHAPTER01**:通常会介绍OpenGL的基本设置,如上下文创建、窗口初始化、回调函数的设定等。还会涉及基本的绘图...
例如,一个火焰粒子可能有多个帧,随着时间的推移,不同的帧会被显示出来,形成动态的火焰效果。 7. **性能优化**:由于粒子系统可能涉及大量的粒子,因此性能优化至关重要。可以使用纹理 atlases(纹理集)减少...
9. **GLSL着色器**:现代OpenGL中,粒子系统的渲染往往使用GLSL(OpenGL Shading Language)编写自定义着色器,这允许在GPU上进行更多的计算,进一步提升性能和效果的灵活性。 10. **Lesson19源码分析**:NeHe的...
开发者会学习如何编写GLSL(OpenGL Shading Language)代码,并理解变量类型、函数和控制流。 第3章至第9章通常会涉及更高级的主题,如矩阵变换(平移、旋转、缩放)、纹理贴图、光照模型、深度测试和剔除等。这些...
主要包括顶点着色器(Vertex Shader)和片段着色器(Fragment Shader),这些着色器通过着色语言如GLSL(OpenGL Shading Language)编写。 3. **缓冲区对象(Buffer Objects)**:用于存储顶点数据、索引数据等,常见的有...