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

Three.js 点星感谢教程

点星感谢 ·Text Star· ▶ 在线运行案例

  • 案例合集:三维可视化功能案例(threehub.cn)
  • 开源仓库github地址:https://github.com/z2586300277/three-cesium-examples
  • 400个案例代码:网盘链接

你将学到什么

  • ShaderMaterial 自定义着色器实现核心视觉效果
  • 监听窗口resize同步更新 camera 与 renderer

效果说明

本案例演示点星感谢效果:基于 WebGL 实现「点星感谢」可视化效果,附完整可运行源码;核心用到 ShaderMaterial。建议先打开文首在线案例查看动态画面,再对照下方源码逐步理解。

核心概念

  • Scene / Camera / WebGLRenderer构成最小渲染闭环;大场景可开logarithmicDepthBuffer缓解 Z-fighting。
  • ShaderMaterial通过uniforms+ 自定义 GLSL 控制逐像素/逐点效果;透明粒子常配合depthTest: false
  • 阅读下方完整源码时,建议从init/load/animate三条主线入手,再深入 shader 与工具函数。

实现步骤

  • 搭建 Scene、PerspectiveCamera、WebGLRenderer,挂载 canvas 并处理resize
  • 定义 uniforms / onBeforeCompile 或 ShaderMaterial,编写 GLSL 与材质参数
  • requestAnimationFrame循环中更新状态并 render(Cesium 为viewer.render或自动渲染)
  • 代码要点

    import * as THREE from 'three';

    import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; import { TessellateModifier } from 'three/addons/modifiers/TessellateModifier.js'; import { FontLoader } from 'three/addons/loaders/FontLoader.js'; import { TextGeometry } from 'three/addons/geometries/TextGeometry.js';

    const data = await new Promise((r) => { fetch('https://api.github.com/repos/z2586300277/three-cesium-examples').then(res => res.json()).then(d => r(d)) setTimeout(() => r({ stargazers_count: 230, forks_count: 40 }), 1000) })

    let mesh, uniforms, renderer, scene, camera, controls;

    const loader = new FontLoader() loader.load(FILE_HOST + 'files/json/font.json', font => init(font))

    const text =three-cesium-examples

    Stars ${data.stargazers_count} Fork ${data.forks_count}

    Thanks for your star

    function init(font) {

    camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 10000); camera.position.set(100, 400, 600);

    scene = new THREE.Scene(); scene.background = new THREE.Color(0x050505);

    let geometry = new TextGeometry(text, { font: font, size: 30, depth: 5, curveSegments: 3, bevelThickness: 2, bevelSize: 1, bevelEnabled: true })

    geometry.center(); const tessellateModifier = new TessellateModifier(4, 3); geometry = tessellateModifier.modify(geometry); const numFaces = geometry.attributes.position.count / 3; const colors = new Float32Array(numFaces33); const displacement = new Float32Array(numFaces33); const color = new THREE.Color();

    for (let f = 0; f < numFaces; f++) { const index = 9 * f; if (Math.random() > 0.5) {

    const h = 0.2 * Math.random(); const s = 0.5 + 0.5 * Math.random(); const l = 0.5 + 0.5 * Math.random();

    color.setHSL(h, s, l); } else color.set(0xa58fb5); const d = 60 * (0.5 - Math.random()); for (let i = 0; i < 3; i++) { colors[index + (3 * i)] = color.r; colors[index + (3 * i) + 1] = color.g; colors[index + (3 * i) + 2] = color.b; displacement[index + (3 * i)] = d; displacement[index + (3 * i) + 1] = d; displacement[index + (3 * i) + 2] = d; } }

    geometry.setAttribute('customColor', new THREE.BufferAttribute(colors, 3)); geometry.setAttribute('displacement', new THREE.BufferAttribute(displacement, 3));

    uniforms = { amplitude: { value: 0.0 }, opacityf: { value: 0.8 } }

    const shaderMaterial = new THREE.ShaderMaterial({ uniforms: uniforms, vertexShader:uniform float amplitude; attribute vec3 customColor; attribute vec3 displacement; varying vec3 vNormal; varying vec3 vColor; varying vec2 vUv; void main() { vUv = uv; vNormal = normal; vColor = customColor; vec3 newPosition = position + normalamplitudedisplacement; gl_Position = projectionMatrixmodelViewMatrixvec4( newPosition, 1.0 ); }, fragmentShader:varying vec3 vNormal; varying vec3 vColor; varying vec2 vUv; uniform float opacityf; uniform float amplitude; void main() {

    vec2 uv = vUv; float iTime = amplitude; vec3 wave_color = vec3(0.0); float wave_width = 0.0; for(float i = 0.0; i <= 28.0; i++) { uv.y += (0.2+(0.9sin(iTime0.4)sin(uv.x + i/3.0 + 3.0iTime ))); uv.x += 1.7sin(iTime0.4); wave_width = abs(1.0 / (200.0abs(cos(iTime))uv.y)); wave_color += vec3(wave_width( 0.4+((i+1.0)/18.0)), wave_width(i / 9.0), wave_width((i+1.0)/ 8.0)1.9); } const float ambient = 0.4; vec3 light = vec3( 1.0 ); light = normalize( light ); float directional = max( dot( vNormal, light ), 0.0 ); gl_FragColor = vec4( mix(( directional + ambient ) * vColor, wave_color, 0.6), opacityf ); }, transparent: true, wireframe: true, wireframeLinewidth: 4 }) mesh = new THREE.Mesh(geometry, shaderMaterial); scene.add(mesh);

    renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setAnimationLoop(render); document.body.appendChild(renderer.domElement); controls = new TrackballControls(camera, renderer.domElement) window.addEventListener('resize', onWindowResize);

    }

    function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); }

    function render() { uniforms.amplitude.value = Math.sin(Date.now() * 0.001); controls.update(); renderer.render(scene, camera); }

    完整源码:GitHub

    小结

    • 本文提供点星感谢完整 Three.js 源码与在线 Demo,建议先运行案例再改 uniform/参数做二次实验
    • 更多 Three.js 实战案例见 three-cesium-examples 合集 与 GitHub 开源仓库
http://www.jsqmd.com/news/1151143/

相关文章:

  • AI算力基建动态简报(2026.07.08)
  • 效率如何?8款AI论文网站排行榜,毕业护航利器!
  • 终极指南:如何用FlyOOBE绕过Windows 11硬件限制轻松安装系统
  • 差生文具多?我给自己改造了一款AI周计划工具
  • Ubuntu 20.04 安装后黑屏、无法进入图形界面:联想双显卡笔记本完整排查与解决教程
  • 数据采集需要重视代理的合规性
  • RPG Maker解密工具终极指南:快速免费提取加密游戏资源
  • ESP32 C3开发实战 -8(BLE广播数据)
  • 基于高等代数视角:(7,4)汉明码矢量分区与标准译码表解析——P124302052汪梓然
  • 2026年面试复盘分析推荐AI快速整理,清晰省事体验比手动好太多
  • 我怎么把开发过程中的笔记,慢慢整理成后续还能继续用的资产
  • 抗衰防病五道防线:从第一性原理导出的健康老龄化框架
  • STM32F723ZE直流电机控制实战:从有刷到无刷
  • YOLOv5 5款模型对比评测:从n到x的精度/速度/显存占用实测
  • 容器网络与存储:lxcfs-tools如何协同其他容器技术栈
  • 揭阳解决电商财税哪家专业:2026本土全品类服务商TOP实力解析
  • 3步掌握VASPsol:免费开源的VASP隐式溶剂模型完整指南
  • MHmarkets迈汇平台:工具可用性的标准归纳
  • 生产力直接拉满,能生成连续剧情视频的AI工具推荐!
  • 容器故障排查:lxcfs-tools调试与日志分析完全手册
  • 如何用STM32实现±0.5°C高精度温度控制:从新手到专家的实践指南
  • 告别Switch游戏安装烦恼:NS-USBLoader一站式解决方案完全指南
  • 番茄小说永久保存全攻略:告别网络限制,打造个人数字图书馆
  • 叉车司机N1培训推荐:创星职培适合急需实操的学员吗
  • FanControl V270:Windows终极风扇控制解决方案,告别噪音拥抱静音
  • RMQ/稀疏表加速静态区间查询
  • AI商业洞察动态简报(2026.07.08)
  • 我和 Fable 5 聊了一晚上 AI,得出的结论大吃一惊
  • 围绕MonetaMarkets多端体验看,会更顺畅吗?
  • 游戏云服务器推荐的技术梳理