HTML音乐圣诞树

写在前面

这是一个基于WebGL技术实现的3D圣诞树场景,融合了音乐可视化效果和粒子系统,营造出一个充满节日氛围的虚拟空间。通过Three.js引擎的强大渲染能力,结合着色器编程和音频分析技术,创造出一个可以与音乐互动的圣诞树森林。

系列文章

序号 目录
1 HTML满屏跳动的爱心
2 HTML五彩缤纷的爱心
3 HTML满屏漂浮爱心
4 HTML情人节爱心
5 HTML蓝色爱心射线
6 HTML跳动的爱心
7 HTML跳动的双爱心
8 HTML粒子爱心
9 HTML蓝色动态爱心
10 HTML橙色动态粒子爱心
11 HTML旋转爱心
12 HTML爱情树
13 HTML元素周期表
14 HTML飞舞的花瓣
15 HTML星空特效
16 HTML黑客帝国字母雨
17 HTML哆啦A梦
18 HTML流星雨
19 HTML沙漏爱心
20 HTML爱心字母雨
21 HTML爱心流星雨
22 HTML生日蛋糕
23 HTML流光爱心
24 HTML粉色爱心
25 HTML满屏飘字
26 HTML飞舞爱心
27 HTML音乐圣诞树
28 HTML星空圣诞树
29 HTML礼物圣诞树
30 HTML旋转圣诞树
31 HTML旋转相册①
32 HTML旋转相册②
33 HTML旋转相册③
34 HTML大雪纷飞①
35 HTML大雪纷飞②
36 HTML炫酷烟花①
37 HTML炫酷烟花②
38 HTML炫酷烟花③
39 HTML炫酷烟花④
40 HTML炫酷烟花⑤
41 HTML炫酷烟花⑥
42 HTML炫酷烟花⑦
43 HTML炫酷烟花⑧
44 HTML炫酷烟花⑨
45 HTML金色流星雨
敬请期待......

技术需求

  1. WebGL渲染引擎核心功能

    • Three.js框架集成:引入完整的Three.js库文件,提供3D场景渲染基础;加载EffectComposer、RenderPass等后期处理模块,实现高级视觉效果。
    • 场景管理:构建Scene对象作为容器,管理所有3D对象的层次结构;通过PerspectiveCamera设置透视投影,模拟人眼观察效果。
    • 渲染循环控制:使用requestAnimationFrame创建平滑动画循环,确保60FPS流畅体验;配合WebGLRenderer进行硬件加速渲染。
  2. 音频可视化处理机制

    • 音频分析器构建:集成AudioListener和AudioAnalyser对象,实时分析音频频谱数据;设置2048大小的FFT分析窗口,捕捉音乐细节变化。
    • 频谱数据映射:将音频频谱信息通过DataTexture传递给着色器,实现音乐节拍与视觉效果同步;通过纹理采样控制粒子大小和透明度变化。
  3. 粒子系统与着色器编程

    • 自定义着色器材质:编写vertexShader和fragmentShader程序,实现粒子的动态变换和颜色混合;利用attribute变量为每个粒子设置独立属性。
    • 缓冲几何体优化:使用BufferGeometry高效管理大量粒子数据;通过Float32BufferAttribute优化内存使用,提升渲染性能。
  4. 用户交互与界面设计

    • 文件上传处理:实现本地音频文件读取功能,支持多种音频格式;通过FileReader接口解析音频数据,提供个性化体验。
    • 界面响应式布局:构建HTML界面元素,提供音乐选择和上传功能;使用CSS样式美化界面,确保跨设备兼容性。
  5. 后期处理与视觉增强

    • 泛光效果实现:集成UnrealBloomPass后期处理通道,营造梦幻光晕效果;通过参数调节控制辉光强度和范围。
    • 抗锯齿优化:启用WebGL抗锯齿功能,提升画面质量;使用EffectComposer管理多个渲染通道,实现复合视觉效果。

主要代码

创作不易,订阅后可查看完整代码

html 复制代码
<!DOCTYPE html>
<html lang="en">
 
<head>
  <meta charset="UTF-8">
 
  <title>圣诞树🎄</title>
 
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
 
  <style>
    * {
      box-sizing: border-box;
    }
 
    body {
      margin: 0;
      height: 100vh;
      overflow: hidden;
      display: flex;
      align-items: center;
      justify-content: center;
      background: #161616;
      color: #c5a880;
      font-family: sans-serif;
    }
 
    label {
      display: inline-block;
      background-color: #161616;
      padding: 16px;
      border-radius: 0.3rem;
      cursor: pointer;
      margin-top: 1rem;
      width: 300px;
      border-radius: 10px;
      border: 1px solid #c5a880;
      text-align: center;
    }
 
    ul {
      list-style-type: none;
      padding: 0;
      margin: 0;
    }
 
    .btn {
      background-color: #161616;
      border-radius: 10px;
      color: #c5a880;
      border: 1px solid #c5a880;
      padding: 16px;
      width: 300px;
      margin-bottom: 16px;
      line-height: 1.5;
      cursor: pointer;
    }
 
    .separator {
      font-weight: bold;
      text-align: center;
      width: 300px;
      margin: 16px 0px;
      color: #a07676;
    }
 
    .title {
      color: #a07676;
      font-weight: bold;
      font-size: 1.25rem;
      margin-bottom: 16px;
    }
 
    .text-loading {
      font-size: 2rem;
    }
  </style>
 
  <script>
    window.console = window.console || function (t) { };
  </script>
 
 
 
  <script>
    if (document.location.search.match(/type=embed/gi)) {
      window.parent.postMessage("resize", "*");
    }
  </script>
 
 
</head>
 
<body translate="no">
  <script src="https://cdn.jsdelivr.net/npm/three@0.115.0/build/three.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/postprocessing/EffectComposer.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/postprocessing/RenderPass.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/postprocessing/ShaderPass.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/shaders/CopyShader.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/shaders/LuminosityHighPassShader.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/postprocessing/UnrealBloomPass.js"></script>
 
  <div id="overlay">
    <ul>
      <li class="title">请选择音乐</li>
      <li><button class="btn" id="btnA" type="button">Music1</button></li>
      <li><button class="btn" id="btnB" type="button">Music2</button></li>
      <li><button class="btn" id="btnC" type="button">Music3</button></li>
      <li><button class="btn" id="btnD" type="button">Music4</button></li>
      <li class="separator">或者</li>
      <li>
        <input type="file" id="upload" hidden />
        <label for="upload">本地音乐</label>
      </li>
    </ul>
  </div>
 
  <script id="rendered-js">
    const { PI, sin, cos } = Math;
    const TAU = 2 * PI;
 
    const map = (value, sMin, sMax, dMin, dMax) => {
      return dMin + (value - sMin) / (sMax - sMin) * (dMax - dMin);
    };
 
    const range = (n, m = 0) =>
      Array(n).
        fill(m).
        map((i, j) => i + j);
 
    const rand = (max, min = 0) => min + Math.random() * (max - min);
    const randInt = (max, min = 0) => Math.floor(min + Math.random() * (max - min));
    const randChoise = arr => arr[randInt(arr.length)];
    const polar = (ang, r = 1) => [r * cos(ang), r * sin(ang)];
 
    let scene, camera, renderer, analyser;
    let step = 0;
    const uniforms = {
      time: { type: "f", value: 0.0 },
      step: { type: "f", value: 0.0 }
    };
 
    const params = {
      exposure: 1,
      bloomStrength: 0.9,
      bloomThreshold: 0,
      bloomRadius: 0.5
    };
 
    let composer;
 
    const fftSize = 2048;
    const totalPoints = 4000;
 
    const listener = new THREE.AudioListener();
 
    const audio = new THREE.Audio(listener);
 
    document.querySelector("input").addEventListener("change", uploadAudio, false);
 
    const buttons = document.querySelectorAll(".btn");
    buttons.forEach((button, index) =>
      button.addEventListener("click", () => loadAudio(index)));
 
......

创作流程

当我开始构思这个圣诞树项目时,脑海中浮现的是一个充满魔法和温暖的冬日场景。我希望创造出一个不仅视觉上令人惊叹,还能与音乐产生共鸣的3D体验。整个创作过程就像是在构建一个虚拟的圣诞世界,每一个元素都承载着我对节日氛围的理解和想象。

首先,我需要确定整体的视觉风格和色彩搭配。我选择了深邃的暗色调作为背景,这样可以让圣诞树的光芒更加突出。金色、绿色和白色的组合让我联想到传统的圣诞装饰,而淡蓝色的点缀则增添了一丝冬日的清冷感。这种色彩方案既要营造节日气氛,又要确保视觉上的和谐统一。

接下来,我开始思考如何构建圣诞树的基本形状。我意识到使用粒子系统是最佳选择,因为它可以创造出轻盈、闪烁的效果,就像真正的圣诞灯饰一样。我设计了一个数学函数来生成树的轮廓,通过极坐标变换创造出螺旋上升的枝条效果。每棵树由数千个粒子组成,这些粒子按照特定的规律分布在空间中,形成逼真的树形结构。

为了让场景更加生动,我决定添加飘落的雪花效果。雪花同样使用粒子系统实现,但它们具有不同的运动轨迹和速度。我为每片雪花设置了随机的相位和振幅,让它们在空中以自然的方式飘舞。不同形状的雪花纹理增加了视觉层次,营造出真实的雪景氛围。

地面的设计也不能忽视。我创建了一个粒子平面,散布着各种颜色的光点,模拟雪地反射的光芒。这些光点随着音乐节拍闪烁,与空中的圣诞树形成呼应,构建出完整的场景层次。

音频可视化是这个项目的核心亮点。我需要将音乐的频谱数据实时映射到视觉元素上。通过分析音频的频率分布,我可以控制圣诞树粒子的大小、亮度和颜色变化。当音乐节奏强烈时,圣诞树会变得更加明亮和动态;而在柔和的旋律中,它则显得宁静而优雅。

用户交互体验是我关注的重点之一。我设计了一个简洁直观的界面,让用户可以选择预设音乐或上传自己的音频文件。加载过程中的动画提示增强了用户体验,让用户感受到即将到来的视觉盛宴。

后期处理效果的添加让整个场景更加梦幻。我集成了泛光效果,让光源产生柔和的光晕,营造出温暖的氛围。这种效果在暗色背景下特别突出,让圣诞树的光芒显得更加迷人。

在技术实现过程中,我特别注重性能优化。大量粒子的渲染对硬件要求很高,因此我使用了缓冲几何体和高效的着色器程序。通过合理管理内存和优化渲染循环,确保了流畅的动画效果。

测试阶段,我尝试了不同风格的音乐来验证可视化效果。从轻柔的圣诞颂歌到欢快的节日舞曲,每种音乐都能产生独特的视觉反馈。这种音乐与视觉的完美结合,让整个作品充满了生命力。

最终,当我看到满屏幕闪烁的圣诞树随着音乐节拍摇摆,雪花在空中优雅飞舞时,我知道这个项目成功地传达了我想要表达的节日温暖和魔法氛围。

写在后面

我是一只有趣的兔子,感谢你的喜欢!

相关推荐
老前端的功夫1 小时前
前端浏览器缓存深度解析:从网络请求到极致性能优化
前端·javascript·网络·缓存·性能优化
Running_slave2 小时前
你应该了解的TCP滑窗
前端·网络协议·tcp/ip
程序员小寒2 小时前
前端高频面试题之CSS篇(一)
前端·css·面试·css3
颜酱3 小时前
Monorepo 架构以及工具选型、搭建
前端·javascript·node.js
oden3 小时前
ChatGPT不推荐你?7个GEO技巧让AI主动引用你的内容
前端
李游Leo3 小时前
前端安全攻防指南:XSS / CSRF / 点击劫持与常见防护实践(含真实案例拆解)
前端·安全·xss
我命由我123454 小时前
微信开发者工具 - 模拟器分离窗口与关闭分离窗口
前端·javascript·学习·微信小程序·前端框架·html·js
E***q5394 小时前
Vue增强现实开发
前端·vue.js·ar
S***42804 小时前
JavaScript在Web中的Angular
前端·javascript·angular.js