如何使用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建模技术就是为了解决...
WebGL Roadmap
Unity 5.0 shipped with a working preview of our WebGL technology in March this year. Since then, Google has disabled (by default) NPAPI support in the...
JavaScript语言多编程范式简介
和C++等语言类似,JS支持多范式(paradigms)编程。我们常常混合这些范式来完成一些大型Web项目。JS支持3种编程范式:命令式、面向对象和函数式。命令式(Imperative JavaScript)命令式就是简单的从上而下完成任务,流水账过程式编码风格:function
HTML5动画背后的数学 - 粒子群仿生算法简介
本站收录了多个算法可视化动画,如模拟鸟群运动:http://wow.techbrood.com/fiddle/30529等等。这里面除...
纹理基础知识和过滤模式详解
1、 为什么在纹理采样时需要texture filter(纹理过滤)。
我们的纹理是要贴到三维图形表面的,而三维图形上的pixel中心和纹理上的texel中心并不一至(pixe...Blender2.7 快捷键一览表
通用操作
停止当前操作:ESC
快捷搜索:SPACE撤销:ctrl+z重做:ctrl+shift+z渲染:F12
单选:鼠标右键(RMB)全选:A
框选:B
刷选:...如何使用Three.js加载obj和mtl文件
OBJ和MTL是3D模型的几何模型文件和材料文件。在最新的three.js版本(r78)中,以前的OBJMTLLoader类已废弃。现在要加载OBJ和MTL文件,需要结合OBJLoader和MTLLoade...
IE各版本CSS Hack(兼容性处理)语法速查表
为了兼容IE各个版本,需要在CSS中添加额外的代码,比如以前常用的_width。之所以工作,是因为浏览器会忽略不能解析的样式规则,因此举个例子来说,把_width写在w...
如何基于Canvas来模拟真实雨景Part1:预备知识和创建基本对象
HTML网页布局:静态、自适应、流式、响应式
静态布局(Static Layout)即传统Web设计,对于PC设计一个Layout,在屏幕宽高有调整时,使用横向和竖向的滚动条来查阅被遮掩部分;对于移动设备,单独设计一个布...
Three.js 3D打印数据模型文件(.STL)加载
3D打印是当下和未来10年产品技术主流方向之一,影响深远。对于电子商务类的3D打印网站,一个主要功能是把商品以3D的方式呈现出来,也就是3D数据可视化技术。HTML...
使用纯CSS3实现一个3D旋转的书本
有一些前沿的电商网站已经开始使用3D模型来展示商品并支持在线定制,而其中图书的展示是最为简单的一种,无需复杂的建模过程,使用图片和CSS3的一些变换即可实现...
SVG过滤器feColorMatrix矩阵变换效果用法详解
在计算机图形学(数学)中,矩阵乘法可用于把空间向量进行几何变换。我们可以把颜色的值(RGBA)表示成一个四维空间向量:color = (r, g, b, a);那么就可以应用...
更多...