当前位置: 首页 > news >正文

three案例 Three.js波纹效果演示

在这里插入图片描述
波纹效果,在智慧城市可视化开发中经常用到,这里分享一个比较好玩的案例
以下是详细的步骤:

初始化部分:设置 Three.js 环境,包括场景、相机、渲染器和控制器
几何体和纹理:创建平面几何体并加载波纹纹理
着色器材质:使用自定义着色器实现波纹效果,包括顶点着色器和片段着色器
波纹算法:核心是 circleWave 函数,通过计算距离和时间来生成向外扩散的波纹
颜色混合:根据波纹强度混合两种颜色,形成视觉层次感
交互控制:使用 GUI 工具允许用户实时调整波纹颜色
动画循环:通过不断更新时间变量来驱动波纹动画
浏览地址:https://aivogenx.github.io/threejs-cesium-webgpu-vue-js/#/codeMirror?navigation=Three.js%E6%A1%88%E4%BE%8B&classify=shader&id=circleWave
代码

<!DOCTYPE html>
<html lang="zh-CN"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Three.js波纹效果演示</title><!-- 这里可以添加CSS样式文件 -->
</head><body><!-- 导入模块映射,配置Three.js依赖路径 --><script type="importmap">{"imports": {"three": "./threejs/build/three.module.js","three/addons/": "./threejs/examples/jsm/"}}</script><script type="module">// 导入Three.js核心库和辅助工具import * as THREE from 'three'import { OrbitControls } from "three/addons/controls/OrbitControls.js"; import { GUI } from "three/addons/libs/lil-gui.module.min.js";// 获取渲染容器,使用整个body元素const box = document.body;// 创建Three.js场景,作为所有3D对象的容器const scene = new THREE.Scene()// 创建透视相机,参数依次为:视野角度、宽高比、近裁剪面、远裁剪面const camera = new THREE.PerspectiveCamera(50, box.clientWidth / box.clientHeight, 0.1, 1000)// 设置相机位置,从(1,1,1)的位置观察场景camera.position.set(1, 1, 1)// 创建WebGL渲染器,启用抗锯齿、透明背景和对数深度缓冲区const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true, logarithmicDepthBuffer: true })// 设置渲染器尺寸为容器大小renderer.setSize(box.clientWidth, box.clientHeight)// 将渲染器的DOM元素添加到页面中box.appendChild(renderer.domElement)// 创建轨道控制器,允许用户通过鼠标交互旋转和缩放场景const controls = new OrbitControls(camera, renderer.domElement)// 启用阻尼效果,使相机移动更平滑controls.enableDamping = true// 窗口大小变化时的响应函数,保持渲染内容适配窗口window.onresize = () => {// 更新渲染器尺寸renderer.setSize(box.clientWidth, box.clientHeight)// 更新相机的宽高比camera.aspect = box.clientWidth / box.clientHeight// 更新相机投影矩阵camera.updateProjectionMatrix()}// 创建平面几何体,作为波纹效果的载体const geometry = new THREE.PlaneGeometry(2, 2);// 加载波纹纹理,这是实现波纹效果的基础纹理// 注意:FILE_HOST变量需要在实际使用时替换为真实的资源路径const texture = new THREE.TextureLoader().load(FILE_HOST + 'images/channels/wave.png')// 设置纹理在水平和垂直方向上重复texture.wrapS = THREE.RepeatWrappingtexture.wrapT = THREE.RepeatWrapping// 创建自定义着色器材质,实现波纹效果的核心部分const material = new THREE.ShaderMaterial({side: THREE.DoubleSide,          // 双面渲染transparent: true,             // 启用透明度blending: THREE.AdditiveBlending, // 添加混合模式让效果更亮uniforms: {uTime: { value: 0.0 },           // 时间变量,控制波纹动画uScanTex: { value: texture },    // 波纹纹理uScanColor: { value: new THREE.Color(0x00ffff) },    // 主要扫描颜色uScanColorDark: { value: new THREE.Color(0x0088ff) } // 暗部扫描颜色},// 顶点着色器:处理几何体顶点,传递纹理坐标和位置信息给片段着色器vertexShader: `varying vec2 vUv;         // 传递给片段着色器的纹理坐标varying vec3 vPosition;   // 传递给片段着色器的顶点位置void main() {vUv = uv;vPosition = position;gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);}`,// 片段着色器:计算每个像素的颜色,实现波纹效果的核心逻辑fragmentShader: `// 波纹原点和波纹扩展速度常量#define uScanOrigin vec3(0.0, 0.0, 0.0)#define uScanWaveRatio1 3.2#define uScanWaveRatio2 2.8uniform float uTime;           // 时间变量uniform sampler2D uScanTex;    // 波纹纹理uniform vec3 uScanColor;       // 波纹主颜色uniform vec3 uScanColorDark;   // 波纹暗部颜色varying vec2 vUv;              // 从顶点着色器传递的纹理坐标varying vec3 vPosition;        // 从顶点着色器传递的顶点位置// 计算圆形波纹效果float circleWave(vec3 p, vec3 origin, float distRatio) {float t = uTime;float dist = distance(p, origin) * distRatio;  // 计算到原点的距离并应用缩放float radialMove = fract(dist - t);            // 创建随时间移动的波纹float fadeOutMask = 1.0 - smoothstep(1.0, 3.0, dist); // 波纹随距离衰减radialMove *= fadeOutMask;float cutInitialMask = 1.0 - step(t, dist);    // 控制波纹从中心向外扩展return radialMove * cutInitialMask;}// 根据位置和纹理计算波纹颜色vec3 getScanColor(vec3 worldPos, vec2 uv, vec3 col) {// 从纹理采样,获取波纹基础图案float scanMask = texture2D(uScanTex, uv).r;// 计算两种不同速度的波纹效果,形成层次感float cw = circleWave(worldPos, uScanOrigin, uScanWaveRatio1);float cw2 = circleWave(worldPos, uScanOrigin, uScanWaveRatio2);// 为第一种波纹创建遮罩,控制波纹的显示范围和强度float mask1 = smoothstep(0.3, 0.0, 1.0 - cw);mask1 *= (1.0 + scanMask * 0.7);  // 结合纹理增强效果// 为第二种波纹创建遮罩float mask2 = smoothstep(0.07, 0.0, 1.0 - cw2) * 0.8;mask1 += mask2;// 创建波纹边缘高亮效果float mask3 = smoothstep(0.09, 0.0, 1.0 - cw) * 1.5;mask1 += mask3;// 根据遮罩强度混合两种颜色,形成波纹的颜色变化vec3 scanCol = mix(uScanColorDark, uScanColor, mask1);return scanCol * mask1; // 返回最终的波纹颜色}void main() {vec3 col = vec3(0.0);// 计算波纹颜色,纹理坐标乘以10.0增强波纹密度col = getScanColor(vPosition, vUv * 10.0, col);// 根据颜色强度计算透明度,使波纹边缘更柔和float alpha = length(col);gl_FragColor = vec4(col, alpha);}`});// 创建网格对象,将几何体和材质组合,并添加到场景中const mesh = new THREE.Mesh(geometry, material);// 将平面旋转90度,使其水平放置mesh.rotation.x = Math.PI / 2scene.add(mesh);// 创建图形界面控制器,允许用户交互调整参数const gui = new GUI()const params = {uScanColor: '#00ffff',         // 波纹主颜色uScanColorDark: '#0088ff'      // 波纹暗部颜色}// 添加颜色控制器,允许用户修改波纹主颜色gui.addColor(params, 'uScanColor').onChange((value) => {material.uniforms.uScanColor.value.set(value)})// 添加颜色控制器,允许用户修改波纹暗部颜色gui.addColor(params, 'uScanColorDark').onChange((value) => {material.uniforms.uScanColorDark.value.set(value)})// 动画循环函数,驱动整个场景的渲染和更新animate()function animate() {// 请求下一帧动画requestAnimationFrame(animate)// 更新控制器状态controls.update()// 渲染场景renderer.render(scene, camera)// 更新时间变量,驱动波纹动画material.uniforms.uTime.value += 0.005;}</script>
</body></html>
http://www.lryc.cn/news/582426.html

相关文章:

  • 【操作系统】进程(二)内存管理、通信
  • MySQL Galera Cluster部署
  • 如何利用AI大模型对已有创意进行评估,打造杀手级的广告创意
  • 算法学习笔记:11.冒泡排序——从原理到实战,涵盖 LeetCode 与考研 408 例题
  • 【计算机网络】王道考研笔记整理(1)计算机网络体系结构
  • 高效学习之一篇搞定分布式管理系统Git !
  • 【字节跳动】数据挖掘面试题0013:怎么做男女二分类问题, 从抖音 app 提供的内容中。
  • 视频号账号矩阵运营中定制开发开源 AI 智能名片 S2B2C 商城小程序的赋能研究
  • main(int argc,char **agrv)的含义
  • 第0章:开篇词 - 嘿,别怕,AI应用开发没那么神!
  • Nat.C|RiNALMo:通用 RNA 语言模型新突破,3600 万序列预训练,跨家族结构预测、剪接识别与功能注释全能泛化
  • 【Note】《Kafka: The Definitive Guide》 第8章: Cross-Cluster Data Mirroring
  • 安卓10.0系统修改定制化____如何修改ROM 实现开机自动开启开发者选项与隐藏开发者选项
  • 【Python进阶篇 面向对象程序设计(3) 继承】
  • 龙旗科技社招校招入职测评25年北森笔试测评题库答题攻略
  • 创意Python爱心代码
  • 软件架构升级中的“隐形地雷”:版本选型与依赖链风险
  • stm32--SPI原理应用W25Q64(二)
  • python中MongoDB操作实践:查询文档、批量插入文档、更新文档、删除文档
  • 基于Java+SpringBoot的在线小说阅读平台
  • 网络安全之注入攻击:原理、危害与防御之道
  • 【C语言】const、volatile、restrict、static四大关键字学习笔记
  • javaScirpt学习第八章-第一部分
  • RoboRefer:面向机器人视觉-语言模型推理的空间参考
  • 针对Exhcnage Server的攻击防范措施
  • Qt中的QProcess类
  • 内网渗透——红日靶场五
  • 【PyTorch】PyTorch中torch.nn模块的循环层
  • L0:让大模型成为通用智能体的强化学习新范式
  • Eslint基础使用