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

Three.js 下雪教程

下雪 ·Snow· ▶ 在线运行案例

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

你将学到什么

  • 自定义 ShaderMaterial / 修改内置 shader
  • 相机交互控制器
  • 点云 / 粒子 / 实例化渲染
  • requestAnimationFrame 渲染循环

效果说明

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

核心概念

  • ShaderMaterial完全自定义 GLSL;onBeforeCompile可在内置材质 shader 中注入代码。关注uniforms与 rAF 更新。
  • OrbitControls轨道旋转缩放;开enableDamping时每帧需controls.update()
  • Points大量顶点用点精灵渲染;InstancedMesh相同几何体批量绘制,降低 draw call。

实现步骤

  • 搭建 Scene / Camera / Renderer 与 OrbitControls
  • 定义材质/shader 与 uniforms,rAF 中更新
  • rAF 循环中 update 并 render
  • 代码要点

    import * as THREE from "three";

    import { OrbitControls } from "three/addons/controls/OrbitControls.js"; let renderer, scene, camera, stats, controls;

    let mesh, uniforms, geometry; let snowMaterial; const particles = 1000;

    init(); animate();

    function init() { camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 10000 );

    scene = new THREE.Scene();

    snowMaterial = new THREE.PointsMaterial({ size: 5, blending: THREE.AdditiveBlending, transparent: true, });

    geometry = new THREE.BufferGeometry();

    let positions = new Float32Array(particles * 3);

    for (let i = 0; i < particles * 3; i += 3) { positions[i] = Math.random() * 200 - 100; positions[i + 1] = Math.random() * 200 - 100; positions[i + 2] = Math.random() * 200 - 100; } geometry.setAttribute( "position", new THREE.Float32BufferAttribute(positions, 3) );

    snowMaterial.onBeforeCompile = (shader) => { shader.uniforms.uColor = { value: new THREE.Color(0xffffff), };

    shader.fragmentShader = shader.fragmentShader.replace(#include,#include uniform vec3 uColor;);

    shader.fragmentShader = shader.fragmentShader.replace(#include,#include float distanceLen = distance(gl_PointCoord,vec2(0.5)); distanceLen = 1.0 - distanceLen; distanceLen = pow(distanceLen,10.0); vec4 color = vec4(uColor,distanceLen); // if(color.a<0.1) // discard; gl_FragColor = color;); };

    mesh = new THREE.Points(geometry, snowMaterial); scene.add(mesh);

    renderer = new THREE.WebGLRenderer(); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(window.innerWidth, window.innerHeight);

    controls = new OrbitControls(camera, renderer.domElement);

    const container = document.getElementById("box"); container.appendChild(renderer.domElement);

    window.addEventListener("resize", onWindowResize); }

    function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix();

    renderer.setSize(window.innerWidth, window.innerHeight); }

    function animate() { requestAnimationFrame(animate);

    render(); controls.update(); }

    function update(time, position) { if (snowMaterial) { const positions = mesh.geometry.getAttribute("position").array; for (let i = 0; i < positions.length; i += 3) { positions[i + 1] -= 0.1; positions[i] -= Math.sin(i) * 0.1; positions[i + 2] -= Math.sin(i) * 0.1; if (positions[i + 1] < -100) { positions[i + 1] = 100; } }

    mesh.geometry.getAttribute("position").needsUpdate = true; } }

    function render() { const time = Date.now() * 0.005; update(); // mesh.rotation.z = 0.01 * time;

    renderer.render(scene, camera); }

    完整源码:GitHub

    小结

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

相关文章:

  • FSD全自动驾驶中基于SR环境感知传感器实时渲染与避障规划AI辅助决策3D智驾可视化系统
  • 打破NVIDIA垄断:如何在非NVIDIA GPU上无缝运行CUDA程序的终极方案
  • 核聚变产业爆火:资本疯抢,两条路线赛跑,商业化落地还有多远?
  • GPT-5.5插件系统开发怎么做?手写自定义工具调用教程与选型攻略
  • HarmonyOS APP《画伴梦工厂》开发第24篇:AI 编排流程——从拍照到动画的完整链路
  • C++20:用好Coroutines:让异步编程不再复杂
  • 轻量化进销存方案:AI零代码搭建采购、入库、出库、库存、对账全链路管理
  • 抖音黑科技兵马俑总站简博科技解读:抖音上线肖像保护功能,AI仿冒治理进入新阶段
  • Linux 系统编程 08:System V IPC
  • WandEnhancer开源增强工具:解锁游戏修改新体验的完整指南
  • QuickLookVideo:彻底解决Mac视频预览难题的高效实用解决方案
  • 都说东莞注塑模具好用,哪家公司才是真正的“宝藏”?
  • STM32与DC-DC控制器171010550的工业电源设计实践
  • 毕设 基于协同过滤的电影推荐系统
  • 【第三部分:线性回归(Linear Regression)】
  • 缠论量化交易实战指南:从理论到策略的完整实现
  • 地层分割设计服务高频细节优化与降噪增效方案
  • 百考通:AI精准赋能期刊论文写作,让学术创作更高效,满足多元研究场景
  • 2026年不容错过!专业AI论文工具大揭秘,让写作不再犯难
  • ClaudeCode 安装 superPower 程序员工作方法论 Skill 集合
  • 百考通:AI精准赋能任务书生成,让科研与项目启动更高效,满足多元研究场景
  • 开源机械臂实战指南:从入门到精通7自由度机器人系统
  • 汽车电子智能散热方案:DRV8213与PIC18F87J10温控设计
  • 多维聚合中的数据变形术:维度语义与度量聚合规则实战
  • 排查嵌套JSON接口返回,我用JSONPath在线工具省了半天调试时间
  • 终极指南:如何快速部署基于.NET Core的YiShaAdmin权限管理系统
  • 为什么开发团队远程访问代码仓库,不建议直接开放整个内网?
  • 全国县域多政策 DID 面板数据集
  • 2026怀化黄金回收白银回收铂金回收旧料回收怎么选?五家高实价铂金白银线下门店测评清单 + 联系方式
  • 架构选型:多Agent协同在跨境网店的工程落地