css实现圆球旋像水波波动_Three.js图像波动特效

本文介绍如何利用three.js实现一个炫酷的图像波动特效。通过改变模型的顶点坐标,结合正弦变换,创建出漏斗状的模型,并通过动画库控制变形进度,实现全屏动态波动效果。读者可以参考源码进行学习和实践。
摘要由CSDN通过智能技术生成

近些年,我们经常会在一些网站上看到些炫酷的图片特效,这些效果大部分都是用WEBGL技术实现的, 借助shader我们可以实现css无法做到的炫酷视觉效果 。随着这门技术的兼容性越来越好,普及率越来越高,掌握它必将为你工作中的加分项。还在等什么?一起来学习下吧。

这次我们用three.js来实现一个图像波动特效,剖析其实现原理,最终可以举一反三,变成自己的东西,先来看效果。

ba38299a8db28d5b4531d96aa4809f47.gif
图片变形特效演示

实现图片全屏显示

首先我们要将图片等比例撑满窗口,并可以适应浏览器动态缩放。要实现这个效果,我们可以通过在resize事件中动态改变透视相机的视野fov来实现。

6b832abc21077ade0a9c4c9bee5388bb.png
视野fov和平面高度关系

我们将图片的高度设置为浏览器窗口的高度,根据三角函数可以很容易计算出需要的视野角度值。

const dist = this.camera.position.z this.camera.fov = 2 * (180 / Math.PI) * Math.atan(this.h / (2 * dist))

图像变形的原理

我们知道three.js中的纹理uv坐标是和模型的顶点坐标相对应的,我们只要改变模型的顶点坐标就能达到扭曲图像的目的。

为了方便观察,我先将平面的贴图去掉,变成纯色的wireframe材质。

e653de26a15ab7e3244f7f076ce973fd.png
纯色的wireframe网格平面

然后,我们在shader中对顶点坐标进行下面的变换,看看会发生什么。

vec3 pos = position;pos.z = 0.5 * sin(pos.x * 10.0);

42e92bb1b409887d885a89c95053afae.png

对顶点变形后的效果

顶点沿z方向进行了正弦变换,我们得到了一个变形后的平面模型。我们去掉网格并把材质还原,这个效果的原理就一目了然了。

ccf1d27321f2b46db58593f6e542534e.png
贴图后的效果

效果具体实现

要实现我们的效果,我们需要先将模型通过顶点变换变成漏斗状。

根据当前顶点坐标和中心点坐标的距离计算出z值,距离中心越近z值改变越小,越远则改变越大,最终得到了一个漏斗状的模型。

float dist = length(uv - vec2(0.5)) * 2.0;float maxdist = length(vec2(0.5));float normalizedDist = dist / maxdist;pos.z += normalizedDist;
8f08b0375ad7248cd972b7a4a60eebec.png
变成漏斗状模型

为了实现动画效果,我们还需要一个变量progress,它是一个0-1之间的值,用来控制变形效果从无到有的过程。

先在shader中加入progress变量,根据progress值控制变形的进度。

float dist = length(uv - vec2(0.5)) * 2.0;float maxdist = length(vec2(0.5));float normalizedDist = dist / maxdist;pos.z += normalizedDist * progress;

鼠标点击后,我们需要将progress值从0变成1。为了看到动画效果,需要将这个值渐进增加,这里用到了greensock的动画库,将动画时间控制在0.6秒,这里的ease属性是用来控制动画的缓动函数,不同的缓动函数会有不同的运动效果,可以根据需要多多尝试。

 _onTouchBegan(e) {    gsap.to(this.material.uniforms.progress, {      value: 1,      duration: 0.6,      ease: 'expo.easeOut'    })  }
a51eebdcdb23e30f13a769ce74b0563f.gif

到此这个效果的基础部分就介绍完了,具体还有一些实现细节,大家可以参考源码来理解,举一反三,如有问题欢迎给我留言。

github源码

https://github.com/imokya/threejs-image-distort

51de4ca0b2fa7f1f2acc449a270bda60.png

你“在看”我嘛? 46f293bfcf2e670eec6d581bcbddd752.gif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值