如何使用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();
你可以自己在线试试。
最新评论
- 相关文章
微信公众号在线生成二维码带参数怎么搞?
带参数二维码是微信公众号渠道二维码的一种实现
微信的带参数二维码有两种,一种是临时二维码,一种是永久二维码,但是永久二维码的生成是有个数限制的,微...3D感知和建模关键硬件技术:双目、3D结构光和TOF
无论VR、AR和3D打印,其核心技术包含3D成像和建模。而3D建模属于劳动密集型的工作,耗时耗力,凡这类工作都会是被新技术革命的地方,自动3D建模技术就是为了解决...
HTML5 And Canvas 2D Specs Are Now Feature Complete, First HTML 5.1 Working Draft Published
We’ve been writing about HTML5 for quite a while, but, until today, the actual HTML5 specs and standards were still moving targets. Now, however, the...
如何使用BabylonJS加载OBJ或STL模型
BabylonJS(也就是babylon.js,这是一个和three.js类似的WebGL开发框架),更多的用在游戏领域。
本文说明和演示如何使用babylon.js来加载一个标准3d模型文...JavaScript事件模型图解
在JavaScript中用户交互的核心部分就是事件处理。本文为对事件模型和处理机制的总体性描述。Event是什么?
event是用户操作网页时发生的交互动作,比如clic...深入理解JS和CSS3动画性能问题和技术选择
本文对比了JS及其框架和CSS3的动画性能,并深入剖析了其内在原因。技术结论大致如下:1. jQuery出于设计原因,在动画性能上表现最差2. CSS3由于把动画逻辑推给了...
HTTP/2背景和新特性简介
HTML5、Hybrid APP、Native APP对比和技术选型
HTML5和Native APP都很容易理解。为了获得HTML5的移植性和移动本地应用的高性能,搞出来一些混合APP的解决方案。比如Apache的Cordova(也就是以前的PhoneGap),...
Babylon.js入门教程和开发实例
Babylon.js是一款WebGL开发框架。和Three.js类似。主要的技术区别是Three.js还试图回退兼容CSS 3D。Three.js是完全社区推动的,比Babylon.js要成熟些,而Babylon...
计算WebGL中的uniforms变量使用数
在使用Three.js为人体模型加载皮肤材料时,启用了skinning:true的参数。有时候会导致GL编译错误,提示“too many uniforms”。下面的文章有助于理解错误原因和检...
Three.js入门教程2 - 着色器(上)
如何基于Canvas来模拟真实雨景Part1:预备知识和创建基本对象
D3.js读取外部json数据
D3.js是一个很好的数据可视化工具,支持从web服务读取json数据,或者从外部文件如.json, .csv文件中直接读取。由于部分服务比如flickrs上的图文数据服务需要VPN...
SVG过滤器feColorMatrix矩阵变换效果用法详解
在计算机图形学(数学)中,矩阵乘法可用于把空间向量进行几何变换。我们可以把颜色的值(RGBA)表示成一个四维空间向量:color = (r, g, b, a);那么就可以应用...
更多...