H5 WebGL实现水波特效

这篇具有很好参考价值的文章主要介绍了H5 WebGL实现水波特效。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

零几年刚开始玩电脑的时候,经常在安装程序上看到一种水波特效,鼠标划过去的时候,就像用手在水面划过一样,感觉特别有意思。但是后来,就慢慢很少见过这种特效了。最近突然又想起了这种特效,于是开始折磨怎么实现这种效果。

思路

我们知道,水波的运动轨迹可以看成随时间变化的三角函数,那么我们可以记录每个水波形成的原点和运行时间,就能知道任一时刻水波的高度。但是,这种方法的运算量会随着水波数量而线性增长,当水波数量很多时,就很可能出现性能问题。

有没有一种办法,可以根据上一时刻的水波幅度,计算出下一时刻的水波幅度呢?如果对于一个点,如果我们把它与其周围的几个点的均值的差作为加速度运动,会怎样呢?

以二维平面为例,即加速度a有

a = (h(x-1) + h(x+1)) / 2 - h(x)

先用三角函数得到我们的水波的初始状态:

然后套用上面的公式把结果可视化

可见,水波会从中心想四周散开,这和我们平时看到的水波运动轨迹不正好相似吗?我们把它推导成3维的:

a = ( 
    h(x-1, y-1) + h(x-1, y+1) 
    + h(x+1, y-1) + h(x+1, y+1) 
    )/4 - h(x, y)

所以,我们只需要画出第一帧的水波图像,就能通过上面的公式计算出下一帧水波的图像了。

有了水波的图像,再根据冯氏光照模型去计算镜面光,就能模拟出较为真实的水波了。

先来看看最终效果:

在线体验地址:https://kason.site/

实现

首先,我们需要一个生成初始化水波的着色器

precision highp float;
const float PI = 3.141592653589793;
uniform sampler2D texture;
uniform vec2 centerCoord;
uniform float radius;
uniform float strength;			
varying vec2 coord;
void main() {
    vec4 info = texture2D(texture, coord);
    float d = min(distance(centerCoord, coord) / radius, 1.0);
    info.r += (cos(d * PI) * 0.5 + 0.5) * strength;
    gl_FragColor = info;
}

然后,再搞个更新水波的着色器

precision highp float;
uniform sampler2D texture;
uniform vec2 delta;
varying vec2 coord;
void main() {
    vec4 old = texture2D(texture, coord);
    vec2 dx = vec2(delta.x, 0.0);
    vec2 dy = vec2(0.0, delta.y);
    float avg = (
        texture2D(texture, coord - dx).r + texture2D(texture, coord - dy).r +
        texture2D(texture, coord + dx).r + texture2D(texture, coord + dy).r
    ) / 4.0;
    old.g += avg - old.r;
    old.g *= 0.995;
    old.r += old.g;
    gl_FragColor = old;
}

最后,再来个计算镜面光并完成最终渲染的着色器

precision highp float;
attribute vec2 vertex;
uniform vec2 ripplesRatio;
varying vec2 ripplesCoord;
varying vec2 backgroundCoord;
void main() {
    gl_Position = vec4(vertex, 0.0, 1.0);
    backgroundCoord = vertex * 0.5 + 0.5;
    ripplesCoord = backgroundCoord  * ripplesRatio;
}
`, `
precision highp float;
uniform sampler2D samplerBackground;
uniform sampler2D samplerRipples;
uniform vec2 delta;
uniform float perturbance;
varying vec2 ripplesCoord;
varying vec2 backgroundCoord;

void main() {
    float height = texture2D(samplerRipples, ripplesCoord).r;
    float heightX = texture2D(samplerRipples, vec2(ripplesCoord.x + delta.x, ripplesCoord.y)).r;
    float heightY = texture2D(samplerRipples, vec2(ripplesCoord.x, ripplesCoord.y + delta.y)).r;
    vec3 dx = vec3(delta.x, heightX - height, 0.0);
    vec3 dy = vec3(0.0, heightY - height, delta.y);
    vec2 v = normalize(vec2(1.0, 1.0));
    vec2 r = -normalize(cross(dy, dx)).xz;
    vec4 specular = vec4(0.8, 0.8, 0.8, 1) * pow(max(0.0, dot(v, r)), 5.0);
    gl_FragColor = texture2D(samplerBackground, backgroundCoord + r * perturbance) + specular;
}

至此,核心着色器的代码都写完了,只需要结合requestAnimationFrame调用WebGL接口完成最终渲染即可。

完整代码可以查看本人Github: https://github.com/kasonyang/ripples.js文章来源地址https://www.toymoban.com/news/detail-545715.html

到了这里,关于H5 WebGL实现水波特效的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于 H5 与 WebGL 的3D太阳系立体展示

    前言 近年来随着引力波的发现、黑洞照片的拍摄、火星上存在水的证据发现等科学上的突破,以及文学影视作品中诸如《三体》、《流浪地球》、《星际穿越》等的传播普及,宇宙空间中那些原本遥不可及的事物离我们越来越近,人们对未知文明的关注和对宇宙空间的好奇达

    2024年02月20日
    浏览(50)
  • uniapp 在 H5、App、微信小程序中使用 svga 格式动画详细示例教程,附插件源码及示例源码(常见于网页直播刷礼物特效功能)

    兼容 h5 网页,微信小程序 和 App。 本文详细讲解在 uni-app项目中,如何实现 svga 格式动画的引入及展示。 组件源码及使用文档都有! 你直接复制本文的源码,即可得到封装好的 svga 组件,样式随便更改:

    2024年02月10日
    浏览(124)
  • 快速上手WebGL,代码+图解手把手教你使用WebGL一步步实现热力图

    大家好,我是南木元元,热衷分享有趣实用的文章。 项目中需要绘制热力图,热力图其实就是数值大小用颜色来进行区分,每个点的数值需根据颜色映射表(调色板)映射为指定颜色。需要3个数值字段,可绘制在平行坐标系中(2个数值字段分别确定x、y轴,1个数值字段确定

    2024年01月18日
    浏览(55)
  • 我做云原生的那几年

    在2020年6月,我加入了一家拥有超过500人的企业。彼时,前端团队人数众多,有二三十名成员。在这样的大团队中,每个人都要寻找自己的独特之处和核心竞争力。否则,你可能会沉没于常规的增删改查工作中,无法展现自己的真正价值,或者在别人已经铺好的道路上与同伴

    2024年02月06日
    浏览(42)
  • Unity webgl 嵌入Vue实现过程

    Unity webgl嵌入到前端网页中,前端通过调用Unity webgl内方法实现需要展示的功能,前端点击Unity webgl内的交互点,Unity webgl返回给前端一些需要的数据。 例如:当我们需要在三维场景中展示库区中一些监控设备的部署位置,通过点击三维场景中的监控按钮打开当前监控设备的实

    2024年02月05日
    浏览(43)
  • WebGL笔记:矩阵的变换之平移的实现

    矩阵的变换 变换 变换有三种状态: 平移 、 旋转 、 缩放 。 当我们变换一个图形时,实际上就是在移动这个图形的所有顶点。 解释 webgl 要绘图的话,它是先定顶点的,就比如说我要画个三角形,那它会先把这三角形的三个顶点定出来。 然后它再考虑以什么样的方式去绘制

    2024年02月04日
    浏览(43)
  • 网络安全的红利还能吃几年?

    在我看来这是一个伪命题,因为网络安全的核心和本质是持续对抗,只要威胁持续存在,网络安全的红利就会持续存在! 对于网络安全新入行的同学们来说,这是一个最坏的时代,因为你只能自己搭环境才能重现那些大牛们、教科书上的漏洞了。 同时,对于网络安全新入行

    2024年02月06日
    浏览(36)
  • Unity+chatgpt+webgl实现声音录制+语音识别

            AI二次元女友这个项目持续更新,在window端的语音识别和语音合成的功能,在上一篇博文里已经详细说明了微软Azure语音服务的代码实现。也是为了实现一次代码,多端复用这样的诉求,所以全部的代码实现都改成了web api的方式。然而在实测发布到webgl的时候,就发现

    2024年02月16日
    浏览(46)
  • 体渲染原理及WebGL实现【Volume Rendering】

    体渲染(Volume Rendering)是NeRF神经场辐射AI模型的基础,与传统渲染使用三角形来显示 3D 图形不同,体渲染使用其他方法,例如体积光线投射 (Volume Ray Casting)。本文介绍体渲染的原理并提供Three.js实现代码,源代码可以从Github下载。 推荐:用 NSDT编辑器 快速搭建可编程3D场景。

    2024年02月13日
    浏览(44)
  • 【CSS加载动画特效】28种纯CSS实现的加载loading动态特效(附源码)

    今天其实还是有点期待6月份城市赛道的成绩公布,但是可能因为出现城市太多等问题,官方也还在快马加鞭的统计中,我也趁机再发一篇前端的文章了,其实在很多系统里面我们都看到过各种各样的加载中样式,但是总有些显得平平无奇,今天我就统计了28种load加载动画特效

    2024年02月15日
    浏览(62)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包