发布时间:2026/7/7 6:01:03
WebGL 2 实战:单文件移植与扩展 Heartfelt 玻璃雨滴折射效果
一、项目效果与功能概览这个项目的交付物只有一个index.html不依赖 npm、不依赖 Three.js也不需要额外资源文件。页面打开后主视觉是一个全屏 WebGL 2 canvas背景默认是双色渐变流体前景覆盖大量玻璃雨滴、拖尾水痕、雾气和轻微色散折射。项目同时提供了三个交互层右上角折叠控制面板调节雨势、雾气、折射率、水滴尺度、流速和背景混合比例。背景上传支持图片或视频上传后作为 WebGL 纹理被雨滴折射。悬浮文本框玻璃拟态样式可编辑正文可拖拽位置。这类效果很适合作为个人主页首屏、视觉展示页、互动海报、音乐可视化背景或者 WebGL shader 教学案例。“C:\Users\86182\Desktop\rainnyDay\index.html”二、整体架构DOM 负责交互Shader 负责画面虽然是单文件项目但源码结构非常清晰index.html ├── style 页面布局、玻璃拟态 UI、控制面板、悬浮文本框 ├── canvas idglCanvas WebGL 2 全屏渲染目标 ├── 控制面板 DOM sliders / upload / fullscreen / toggle ├── 悬浮文本框 DOM contenteditable pointer drag └── script ├── WebGL 2 初始化 ├── UI 参数读取与事件绑定 ├── 顶点着色器 ├── 片元着色器 ├── 媒体纹理上传 └── requestAnimationFrame 渲染循环这个架构的关键点是分工明确HTML/CSS 只负责用户界面JavaScript 只负责把用户参数和媒体资源送进 GPU真正复杂的雨滴、折射、流体背景都在片元着色器里完成。三、WebGL 2 初始化为什么使用一个全屏三角形源码中获取 WebGL 2 上下文时开启了高性能偏好同时关闭了深度、模板和 alphaconstglcanvas.getContext(webgl2,{antialias:false,alpha:false,depth:false,stencil:false,powerPreference:high-performance});这里的设计非常适合 shader toy 类型的全屏后处理效果。因为画面不是由复杂几何体组成而是每个像素根据uv、时间、鼠标和纹理计算出来所以不需要传统 3D 场景里的深度测试。顶点着色器也很极简const vec2 pos[3] vec2[3]( vec2(-1.0, -1.0), vec2( 3.0, -1.0), vec2(-1.0, 3.0) );它使用一个覆盖全屏的大三角形而不是两个三角形拼成矩形。这样可以避免屏幕中间对角线处的插值边界也减少一次顶点处理。对于全屏 shader这是非常常见也很优雅的写法。四、Uniform 参数把 UI 控制映射到 GPU控制面板中的滑块并不直接修改画面而是通过readParams()转换成统一参数在每一帧传给 shaderconstreadParams()({rain:Number(controls.rainStrength.value),fog:Number(controls.fogDensity.value),refraction:Number(controls.refraction.value),dropScale:Number(controls.dropScale.value),flowSpeed:Number(controls.flowSpeed.value),mediaMix:Number(controls.mediaMix.value)});这些参数最终对应片元着色器里的 uniformsuniform float uRainStrength; uniform float uFogDensity; uniform float uRefraction; uniform float uDropScale; uniform float uFlowSpeed; uniform float uMediaMix; uniform float uHasMedia; uniform sampler2D uMedia;这种设计有两个好处第一UI 和 shader 解耦。滑块叫什么、放在哪里不影响 shader 内部算法。第二实时性很好。每一帧只需要更新少量 uniform不需要重建纹理、重编译 shader 或重新布局 DOM。五、默认背景用 FBM 做双色流体渐变项目的默认背景不是静态 CSS 渐变而是在 shader 中实时生成的流体渐变vec3 fluidGradient(vec2 uv) { vec2 p uv - 0.5; float t uTime * 0.085 * uFlowSpeed; float f1 fbm(p * 2.2 vec2(t, -t * 0.7)); float f2 fbm(p * 4.0 - vec2(t * 1.6, t)); float swirl atan(p.y, p.x) 1.4 * f1 0.9 * sin(2.2 * length(p) - t * 5.0); ... }这里用到了fbm也就是 fractal brownian motion。简单理解它是多层噪声叠加用来生成比普通 noise 更自然的云雾、液体和纹理变化。背景色由几组颜色混合而来vec3 a vec3(0.025, 0.22, 0.31); vec3 b vec3(0.78, 0.12, 0.36); vec3 c vec3(0.95, 0.58, 0.22); vec3 d vec3(0.09, 0.05, 0.18);青蓝、玫红、暖橙和深紫不是平均铺开而是通过噪声、极坐标角度和距离共同调制所以最终画面会有一种缓慢流动的“液态渐变”质感。这比普通 linear-gradient 更适合作为折射背景因为水滴折射需要背景中有足够的色彩和明暗变化才能看出玻璃感。六、核心算法雨滴不是图片而是法线场玻璃雨滴效果的核心不在于“画出雨滴贴图”而是构造一个局部法线扰动场。片元着色器中的rainNormal()函数负责生成每个像素的雨滴法线vec2 rainNormal(vec2 uv) { vec2 aspect vec2(uResolution.x / max(uResolution.y, 1.0), 1.0); vec2 p (uv - 0.5) * aspect; float rain clamp(uRainStrength, 0.0, 1.6); float scale mix(10.0, 18.0, clamp(rain, 0.0, 1.0)) / max(0.45, uDropScale); ... }注意这里先处理了屏幕宽高比。否则在宽屏上圆形雨滴会被拉伸成椭圆。雨滴分两类静态水珠像玻璃上附着的小水滴。下滑拖尾像雨水沿玻璃向下流动形成的水痕。静态水珠由staticDrop()生成。它通过 hash 函数给每个网格单元一个随机中心和半径float staticDrop(vec2 uv, vec2 id, float sizeBias) { vec2 rnd hash22(id); vec2 center (rnd - 0.5) * vec2(0.82, 0.72); vec2 p uv - center; float radius mix(0.035, 0.14, rnd.y) * sizeBias; float d length(p); float core smoothstep(radius, radius * 0.28, d); ... }这里并没有真正存储任何雨滴对象。每个像素根据自己的坐标反推出所在网格和附近网格里的伪随机水滴。这也是 shader 编程非常迷人的地方看似复杂的粒子系统其实可以完全由数学函数实时生成。拖尾水痕由trailDrop()生成float fall fract(uTime * uFlowSpeed * mix(0.06, 0.22, rnd.x) rnd.y); vec2 center vec2(rnd.x - 0.5, 0.62 - fall * 1.55);fract()让水滴下落循环发生uFlowSpeed控制速度rnd让每条水痕速度和位置不同。后面再用head和tail分别构造水滴头部和拖尾float head smoothstep(0.075, 0.0, length(p / vec2(0.72, 1.0))); float tail smoothstep(0.035, 0.0, abs(p.x)) * smoothstep(0.42, 0.02, -p.y) * step(0.0, -p.y);这段是雨滴真实感的关键如果只有圆点会像玻璃上的水珠加入拖尾后画面才有“雨正在流动”的叙事感。七、折射与色散玻璃感的真正来源拿到雨滴法线n后shader 不直接把水滴画成白色而是用它偏移背景采样坐标vec2 n rainNormal(uv); vec2 chroma n * uRefraction; refracted.r sampleBackground(uv chroma * vec2(1.12, 0.88)).r; refracted.g sampleBackground(uv chroma).g; refracted.b sampleBackground(uv chroma * vec2(0.82, 1.2)).b;这就是折射的核心水滴区域看到的不是原本的背景而是稍微偏移后的背景。更进一步代码对 RGB 三个通道使用了略微不同的偏移量形成轻微色散。真实玻璃、水滴、镜头边缘都会出现类似现象。这个处理非常轻但能显著增强“高级感”。最后再加一点高光float highlight pow( clamp(dot(normalize(vec3(n * 1.8, 0.65)), normalize(vec3(-0.4, 0.55, 0.72))), 0.0, 1.0), 5.0 ); col highlight * vec3(0.7, 0.9, 1.0) * 0.55;折射负责形变高光负责材质两者叠加后雨滴才会像透明玻璃而不是普通噪声。八、媒体背景上传图片和视频都变成 WebGL 纹理项目支持用户上传图片或视频替换背景。核心逻辑是监听文件选择document.getElementById(mediaUpload).addEventListener(change,event{constfileevent.target.filesevent.target.files[0];if(!file)return;consturlURL.createObjectURL(file);mediaIsVideofile.type.startsWith(video/);mediaElementmediaIsVideo?document.createElement(video):newImage();});如果是视频则设置循环、静音和playsInlinemediaElement.looptrue;mediaElement.mutedtrue;mediaElement.playsInlinetrue;真正上传到 GPU 的地方在uploadMediaFrame()gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,mediaElement);图片只需要上传一次视频则在每一帧判断readyState后更新纹理。这样雨滴折射的背景就可以是动态视频视觉表现会比静态图片更强。在 shader 中背景混合由sampleBackground()完成vec3 shaderBg fluidGradient(clampedUv); vec3 mediaBg texture(uMedia, clampedUv).rgb; float mixAmount clamp(uMediaMix * uHasMedia, 0.0, 1.0); vec3 bg mix(shaderBg, mediaBg, mixAmount);这个设计保留了默认 shader 背景也允许用户逐渐混合上传媒体而不是一上传就完全替换。九、控制面板与悬浮文本框WebGL 项目也需要产品化交互很多 shader demo 只停留在“能看”但这个项目进一步做了可用性包装。右上角控制面板通过 CSS 固定定位折叠时只隐藏主体.panel{position:fixed;top:14px;right:14px;z-index:10;backdrop-filter:blur(24px)saturate(145%);}.panel.collapsed .panel-body{display:none;}悬浮文本框则使用contenteditable让用户直接编辑文字divclassfloat-contentcontenteditabletruespellcheckfalse雨夜玻璃small可编辑文字 / 拖拽移动 / 背景可替换/small/div拖拽逻辑基于 Pointer Events兼容鼠标和触摸floatHandle.addEventListener(pointerdown,event{constrectfloatingText.getBoundingClientRect();dragState{pointerId:event.pointerId,offsetX:event.clientX-rect.left,offsetY:event.clientY-rect.top};});移动时根据指针坐标更新left/top并限制在视口内避免拖出屏幕constxMath.min(Math.max(event.clientX-dragState.offsetX,8),window.innerWidth-rect.width-8);constyMath.min(Math.max(event.clientY-dragState.offsetY,8),window.innerHeight-rect.height-8);这部分虽然不是 shader 核心但对实际作品非常重要。视觉特效如果不能被用户操作很容易只是一个 demo加入参数面板和文本框后它就更像一个可发布的互动页面。十、渲染循环与性能策略主循环非常直接functionrender(now){resize();uploadMediaFrame();constpreadParams();gl.useProgram(program);...gl.drawArrays(gl.TRIANGLES,0,3);requestAnimationFrame(render);}这里有几个值得注意的性能点使用全屏三角形减少几何复杂度。DPR 限制在 2 以内避免高分屏上像素数量暴涨。UI 控制只更新 uniform不触发 shader 重编译。视频纹理只有在 readyState 满足条件时才上传。背景、雨滴、拖尾都在 shader 中程序化生成不需要大量贴图资源。不过这个 shader 中有多层循环例如rainNormal()会遍历多层雨滴网格。它的画质很好但如果要适配低端移动设备可以考虑减少 layer 数、降低静态雨滴邻域采样或在移动端降低 canvas DPR。十一、踩坑记录中文源码一定要注意 UTF-8这个项目是中文 UI源码里包含“雨势”“雾气”“折射率”等文本。编辑这类单文件 HTML 时务必保证metacharsetutf-8同时编辑器或脚本写文件时也要使用 UTF-8。否则中文可能变成乱码更严重的是如果乱码出现在 HTML 属性或 JS 字符串里还可能破坏标签结构或导致脚本语法错误。一个简单的建议是涉及中文内容的 HTML 文件尽量用现代编辑器直接保存为 UTF-8如果用脚本批量替换显式指定 UTF-8 读写。十二、总结这个项目的核心价值在于它把一个 Shadertoy 风格的视觉算法包装成了一个真正可交互、可复用、可发布的 Web 页面。从技术角度看它涵盖了 WebGL 2 全屏渲染、GLSL 噪声函数、程序化雨滴法线、折射采样、色散、高光、视频纹理上传和 DOM 交互同步。对于想学习 shader 的前端开发者来说这是一个很好的综合练习。如果继续扩展还可以加入预设主题切换比如霓虹城市、冷色雨夜、暖色室内灯光。截图导出或录制短视频。文本框字体、颜色、阴影可调。移动端自动降采样策略。多个 shader pass实现更真实的玻璃模糊与水痕累积。WebGL 的魅力就在这里只要掌握坐标、噪声、采样和时间你就可以在一个普通网页里造出很有电影感的实时视觉效果。

相关新闻

lanhu-design-to-html skill
2026/7/7 6:01:03

lanhu-design-to-html skill

skill位置 这是一个用于对蓝湖设计稿进行还原的skill:https://github.com/ApeMan1024/lanhu-design-to-html,用于高保真的根据蓝湖设计稿还原移动端页面,使用国产模型也能达到很好的效果,目前只针对移动端。 skill模式还原和mcp模…

阅读更多
Selenium自动化测试实战:从环境搭建到框架设计与避坑指南
2026/7/7 6:01:03

Selenium自动化测试实战:从环境搭建到框架设计与避坑指南

1. 项目概述:为什么我们需要自动化Web应用测试? 如果你是一名Web开发者、测试工程师,或者正在管理一个需要频繁迭代的线上产品,那么你一定对“回归测试”这个词又爱又恨。爱的是,它能确保新功能上线不会把旧功能搞砸&a…

阅读更多
3D空间推理:打通视觉-语言-动作闭环的跨模态基建层
2026/7/7 5:01:03

3D空间推理:打通视觉-语言-动作闭环的跨模态基建层

1. 这不是“让AI看懂3D世界”那么简单:一个被严重低估的跨模态基建层你可能在新闻里看到过“机器人自己叠衣服”“自动驾驶车辆预判行人突然横穿”这类视频,背后往往归功于某个新模型又刷了SOTA。但如果你真去翻这些系统的底层日志、训练配置和推理链路&…

阅读更多
终极GTA5安全菜单:YimMenu完整防护与功能指南
2026/7/7 7:01:04

终极GTA5安全菜单:YimMenu完整防护与功能指南

终极GTA5安全菜单:YimMenu完整防护与功能指南 【免费下载链接】YimMenu YimMenu, a GTA V menu protecting against a wide ranges of the public crashes and improving the overall experience. 项目地址: https://gitcode.com/GitHub_Trending/yi/YimMenu …

阅读更多
3个痛点解析:如何用Balena Etcher安全高效地制作系统启动盘
2026/7/7 7:01:04

3个痛点解析:如何用Balena Etcher安全高效地制作系统启动盘

3个痛点解析:如何用Balena Etcher安全高效地制作系统启动盘 【免费下载链接】etcher Flash OS images to SD cards & USB drives, safely and easily. 项目地址: https://gitcode.com/GitHub_Trending/et/etcher 在数字时代,系统安装和嵌入式…

阅读更多
2026年,如何逆袭成为年薪40K的AI Agent工程师?(全阶段进阶指南)
2026/7/7 7:01:04

2026年,如何逆袭成为年薪40K的AI Agent工程师?(全阶段进阶指南)

如果说 2025 年大家还在摸索大模型的 API 怎么调,那么 2026 年,整个搞 AI 的风向已经彻底变了——大模型应用开发全面进入“Agent 时代”。打开现在的招聘软件,你会发现大模型应用开发岗位极少再要求“必须硕博学历”,基本全是本科…

阅读更多
光谱仪设计实战:Zemax中系统孔径与焦距对衍射极限分辨率的2个影响
2026/7/7 7:01:04

光谱仪设计实战:Zemax中系统孔径与焦距对衍射极限分辨率的2个影响

光谱仪设计实战:Zemax中系统孔径与焦距对衍射极限分辨率的深度解析当一束白光穿过棱镜时,我们会看到彩虹般的光谱展开——这是光学中最迷人的现象之一。而现代光谱仪将这一原理推向极致,成为科研和工业中不可或缺的分析工具。作为光学工程师&…

阅读更多
Windows HEIC格式转换终极指南:用HEIF Utility轻松解决iPhone照片兼容问题
2026/7/7 7:01:04

Windows HEIC格式转换终极指南:用HEIF Utility轻松解决iPhone照片兼容问题

Windows HEIC格式转换终极指南:用HEIF Utility轻松解决iPhone照片兼容问题 【免费下载链接】HEIF-Utility HEIF Utility - View/Convert Apple HEIF images on Windows. 项目地址: https://gitcode.com/gh_mirrors/he/HEIF-Utility 你是否曾遇到过这样的困扰…

阅读更多
圆管坡口机哪款耐用又精准?行业资深用户评价来参考
2026/7/7 6:01:03

圆管坡口机哪款耐用又精准?行业资深用户评价来参考

在工业制造领域,圆管坡口机对于工程质量起着至关重要的作用。精准且耐用的圆管坡口机能够确保焊接质量,提高工程的稳定性和安全性。然而,如果选错了圆管坡口机,可能会导致坡口尺寸参差不齐,增加焊接返工率,…

阅读更多
通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御
2026/7/7 2:21:40

通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

1. 项目概述与漏洞背景最近在梳理一些历史OA系统的安全风险时,通达OA v11.6版本中的一个老漏洞又进入了我的视线。这个漏洞位于/general/bi_design/appcenter/report_bi.func.php文件中,是一个典型的SQL注入点。虽然这个漏洞的利用方式看起来并不复杂&am…

阅读更多
3步彻底解决Windows右键菜单混乱问题:ContextMenuManager使用全攻略
2026/7/6 12:19:58

3步彻底解决Windows右键菜单混乱问题:ContextMenuManager使用全攻略

3步彻底解决Windows右键菜单混乱问题:ContextMenuManager使用全攻略 【免费下载链接】ContextMenuManager 🖱️ 纯粹的Windows右键菜单管理程序 项目地址: https://gitcode.com/gh_mirrors/co/ContextMenuManager 你是否曾为Windows右键菜单中那些…

阅读更多
GXDE OS下Wayland兼容性实战:从deepin-mutter原理到VMware Tools修复
2026/7/6 14:01:07

GXDE OS下Wayland兼容性实战:从deepin-mutter原理到VMware Tools修复

如果你正在用 GXDE OS 或者任何基于 Deepin 的发行版,并且遇到了“检测到窗口系统采用 Wayland 协议,程序即将退出”这类弹窗,或者发现 VMware Tools 在 Ubuntu 24.04 这类默认 Wayland 的系统上启动失败,那这篇文章就是为你准备的…

阅读更多
国产化信创改造:达梦/人大金仓适配与多数据库兼容方案实战(SpringBoot)
2026/7/7 0:01:01

国产化信创改造:达梦/人大金仓适配与多数据库兼容方案实战(SpringBoot)

国产化信创改造:达梦/人大金仓适配与多数据库兼容方案实战(SpringBoot) 🌐 演示地址:http://ruoyioffice.com | 📦 源码1GitHub:ruoyi-office | 📦 源码2GitCode:ruoyi-o…

阅读更多
CentOS 7/8 SSH 连接失败:5步系统性排错流程与决策树
2026/7/7 0:01:01

CentOS 7/8 SSH 连接失败:5步系统性排错流程与决策树

CentOS SSH连接故障排查:从基础检查到深度修复的完整指南引言当你尝试通过Xshell或其他SSH客户端连接CentOS服务器时,突然遭遇"Connection refused"或"Connection timed out"的错误提示,这种经历对任何运维人员或开发者来…

阅读更多
B站评论删除 API 逆向分析:3 个关键参数 (oid, type, csrf) 获取与实战
2026/7/7 0:01:01

B站评论删除 API 逆向分析:3 个关键参数 (oid, type, csrf) 获取与实战

B站评论删除API逆向工程实战:关键参数解析与自动化操作指南1. 理解B站评论删除机制的核心逻辑在视频平台内容管理中,评论删除功能涉及复杂的权限验证和数据交互流程。B站的评论删除API采用了一套基于Web安全标准的防护机制,主要依赖三个关键参…

阅读更多
基于Dify与DeepSeek构建私有知识库问答系统实战指南
2026/7/6 13:57:42

基于Dify与DeepSeek构建私有知识库问答系统实战指南

在业务中快速构建一个能理解私有文档、准确回答专业问题的智能助手,是很多开发团队面临的共同挑战。传统方案往往需要从零开始搭建复杂的 RAG(检索增强生成)系统,涉及文档解析、向量化、检索、大模型调用等多个环节,整…

阅读更多
FAE放射组学分析工具:医学影像特征探索的完整解决方案
2026/7/6 7:18:59

FAE放射组学分析工具:医学影像特征探索的完整解决方案

FAE放射组学分析工具:医学影像特征探索的完整解决方案 【免费下载链接】FAE FeAture Explorer 项目地址: https://gitcode.com/gh_mirrors/fae/FAE 你是否曾经面对海量医学影像数据感到无从下手?想要从CT、MRI等影像中提取有价值的定量特征&#…

阅读更多
DesktopNaotu:你的终极离线思维导图解决方案,告别网络依赖!
2026/7/5 15:33:35

DesktopNaotu:你的终极离线思维导图解决方案,告别网络依赖!

DesktopNaotu:你的终极离线思维导图解决方案,告别网络依赖! 【免费下载链接】DesktopNaotu 桌面版脑图 (百度脑图离线版,思维导图) 跨平台支持 Windows/Linux/Mac OS. (A cross-platform multilingual Mind Map Tool) 项目地址:…

阅读更多