如何使用WebGL实现空气高温热变形动画特效
我们在炎炎夏日,或者在火堆旁,经常会观察到热源周围空气的不稳定波动现象。
本文将讲解如何通过WebGL来实现这个特效。该效果可用于热变形、波浪、水面波光等场合。
首先让我们来看看如何能画出一个普通的图像,然后看看我们如何能使它变形。
使用WebGL绘制图像
在踏得网之前的教程中,我们已经说明过,WebGL可以通过纹理对象来加载外部图像文件并渲染。
本文略过初始化WebGL绘制上下文、着色器程序创建等基本步骤的描述,直接演示如何加载纹理贴图:
//基于image对象来创建纹理 function createTextureByImgObject(imgObj) { //设置当前激活纹理 webgl.activeTexture(webgl.TEXTURE0); //创建纹理对象,并设置其常用属性 var textureObject = webgl.createTexture(); webgl.bindTexture(webgl.TEXTURE_2D, textureObject); webgl.texImage2D(webgl.TEXTURE_2D, 0, webgl.RGBA, webgl.RGBA, webgl.UNSIGNED_BYTE, imgObj); //使用最近像素来处理纹理缩放后的点 webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_MIN_FILTER, webgl.NEAREST); webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_MAG_FILTER, webgl.NEAREST); //使用边缘颜色来封装纹理,而不是左右两边的插值 webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_WRAP_S, webgl.CLAMP_TO_EDGE); webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_WRAP_T, webgl.CLAMP_TO_EDGE); return textureObject; } //从DOM中通过img标签的id来加载并创建纹理贴图 function createTextureByImgID(imgID) { var imgObj = document.getElementById(imgID); if (imgObj == null) { return null; } return createTextureByImgObject(imgObj); }
实现变形特效
正常情况下,我们的shader程序代码如下:
<script id="fsh_wave" type="x-shader/x-fragment"> precision mediump float; varying vec2 textureCoordinate; uniform sampler2D inputImageTexture; uniform float time; void main(){ vec4 color=texture2D(inputImageTexture,vec2(textureCoordinate.x, textureCoordinate.y)); gl_FragColor = color; } </script>
要想生成变形效果,我们可以调整textureCoordinate.x和y坐标映射值,具体而言,要产生竖向的波动变形,x得和y通过波动函数关联起来,常用的是正/余弦函数:
float frequency=100.0;//波动频率 float amp=0.003;//波动幅度 float distortion=sin(textureCoordinate.y*frequency)*amp; vec4 color=texture2D(inputImageTexture,vec2(textureCoordinate.x+distortion, textureCoordinate.y));
上面的代码只是实现一个静态的波动变形,接着我们要把这个波动变成动画,可以使用requestAnimationFrame方法,
同时设置一个随着动画帧而变的时间参数:
precision mediump float; varying vec2 textureCoordinate; uniform sampler2D inputImageTexture; uniform float time;//时间参数 void main(){ float frequency=100.0; float amp=0.003; float speed=0.05; float distortion=sin(textureCoordinate.y*frequency + time*speed)*amp; vec4 color=texture2D(inputImageTexture,vec2(textureCoordinate.x+distortion, textureCoordinate.y)); gl_FragColor = color; }
time的设置在动画绘制函数中:
function draw() { webgl.uniform1f(itv.time, time++); webgl.clearColor(0.0, 0.0, 0.0, 1.0); webgl.clear(webgl.COLOR_BUFFER_BIT); webgl.drawArrays(webgl.TRIANGLE_STRIP, 0, 4); requestAnimationFrame(draw); } itv.time = webgl.getUniformLocation(programObject, "time"); draw();
你可以自己在线试试。
最新评论
- 相关文章
谷歌ARCore技术特性简介
谷歌美国时间2017.8.29号刚发布了ARCore预览版,这是一个类似于苹果ARKit的增强现实SDK,在此之前,谷歌虽然已投资AR平台Tango,但由于需要特定的硬件和传感器,...
踏得网精选2016年度10大最佳HTML5动画
踏得网精选2016年度最酷最新的HTML5动画集,评选标准为:创意新颖度+实现技术难度+趣味程度。使用一些在线H5生成工具的作品,因其主要使用图片和CSS3套路动画,...
WebGL、Asm.js和WebAssembly概念简介
随着HTML技术的发展,网页要解决的问题已经远不止是简单的文本信息,而包括了更多的高性能图像处理和3D渲染方面。这正是要引入WebGL、Asm.js和WebAssembly这些技...
CSS3弹性布局内容对齐(justify-content)属性使用详解
内容对齐(justify-content)属性应用在弹性容器上,把弹性项沿着弹性容器的主轴线(main axis)对齐。该操作发生在弹性长度以及自动边距被确定后。 它用来在存...
使用HTML5 Canvas实现的界面元素截屏功能
Three.js 对象局部坐标转换为世界坐标
在Three.js中进行顶点几何计算时,一个需要注意的地方是,需要统一坐标系。比如你通过Three.js提供的API创建了一个球体网孔对象,那么默认情况下,各网孔顶点的...
粒子运动模拟 - Verlet积分算法简介
Verlet算法是经典力学(牛顿力学)中的一种最为普遍的积分方法,被广泛运用在分子运动模拟(Molecular Dynamics Simulation),行星运动以及织物变形模拟等领域...
Three.js入门教程5 - 10个必须知道的编程技巧
作者为Google的Paul,关于如何写出好的WebGL代码的文章。和很多开发者一样,我通过实践学习,但同时我也向其他更有经验的开发者们学习。在过去的几个月中,我在c...
如何实现SVG clipPath自适应被裁剪对象
CSS3中引入的clip-path(裁剪路径)属性是一个很强大的特性。
clip-path的含义如下图所示,好比剪纸一样,你用剪刀沿着某条路径把目标对象(图像或元素)裁...如何基于Canvas来模拟真实雨景Part1:预备知识和创建基本对象
Canvas实例教程:图像移动、大小调整和裁剪
本文介绍如何使用JavaScript和HTML5 Canvas元素来移动、调整大小和...
SVG过滤器feColorMatrix矩阵变换效果用法详解
在计算机图形学(数学)中,矩阵乘法可用于把空间向量进行几何变换。我们可以把颜色的值(RGBA)表示成一个四维空间向量:color = (r, g, b, a);那么就可以应用...
更多...