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

Three.js 残影效果教程

残影效果 ·Afterimage· ▶ 在线运行案例

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

你将学到什么

  • glTF/FBX/OBJ 外部模型加载
  • EffectComposer 后期处理管线
  • 相机交互控制器
  • 轮廓高亮 OutlinePass
  • requestAnimationFrame 渲染循环

效果说明

本案例演示残影效果效果:原场景渲染后经 EffectComposer 叠加 Bloom/模糊等全屏后期;核心用到 EffectComposer、OrbitControls、glTF/Draco。建议先打开文首在线案例查看动态画面,再对照下方源码逐步理解。

核心概念

  • Loader异步加载模型;glTF 返回gltf.scene,加载后注意scale与坐标系。Draco 需配置DRACOLoader
  • EffectComposer多 Pass 链式渲染:RenderPass → 特效 Pass → 输出屏幕。composer.render()替代renderer.render()
  • OrbitControls轨道旋转缩放;开enableDamping时每帧需controls.update()
  • 选中物体外轮廓发光,常用于编辑器选中态。

实现步骤

  • 搭建 Scene / Camera / Renderer 与 OrbitControls
  • Loader 异步加载模型/纹理资源
  • EffectComposer 组装 Pass 链并 render
  • 代码要点

    import * as THREE from 'three';

    import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js '; import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js'; import { AfterimagePass } from 'three/examples/jsm/postprocessing/AfterimagePass.js'; import Stats from 'three/examples/jsm/libs/stats.module.js'; import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; import * as dat from 'dat.gui';

    // 初始化场景、相机、渲染器 const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(40, 40, 40);

    const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true, logarithmicDepthBuffer: true }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setClearColor('#000'); document.body.appendChild(renderer.domElement);

    // 初始化控制器 const controls = new OrbitControls(camera, renderer.domElement); controls.enableDamping = true; // 添加光源 const directionalLight = new THREE.DirectionalLight('#fff'); directionalLight.position.set(30, 30, 30).normalize(); scene.add(directionalLight); const ambientLight = new THREE.AmbientLight('#fff', 2); scene.add(ambientLight);

    // 添加性能监控 const stats = new Stats(); document.body.appendChild(stats.dom);

    scene.fog = new THREE.Fog(0x000000, 1, 1000);

    const geometry = new THREE.BoxGeometry(10, 10, 10); const material = new THREE.MeshNormalMaterial(); const mesh = new THREE.Mesh(geometry, material); mesh.position.set(15, 0, 0) scene.add(mesh);

    new GLTFLoader().load(FILE_HOST + "files/model/Fox.glb", (gltf) => {

    scene.add(gltf.scene)

    gltf.scene.scale.multiplyScalar(0.1)

    })

    // 后期处理 const composer = new EffectComposer(renderer); composer.addPass(new RenderPass(scene, camera)); const afterimagePass = new AfterimagePass(); composer.addPass(afterimagePass);

    // GUI控制 const params = { enable: true }; const gui = new dat.GUI({ name: 'Damp setting' }); gui.add(afterimagePass.uniforms["damp"], 'value', 0, 1).step(0.001); gui.add(params, 'enable');

    // 窗口大小调整 window.addEventListener('resize', onWindowResize, false);

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

    // 动画渲染 function animate() { requestAnimationFrame(animate); stats.update(); controls.update();

    mesh.rotation.x += 0.005; mesh.rotation.y += 0.01;

    if (params.enable) { composer.render(); } else { renderer.render(scene, camera); } }

    animate();

    完整源码:GitHub

    小结

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

相关文章:

  • GB/T 7714参考文献排版解决方案深度解析:企业级学术出版架构设计与最佳实践
  • 场外衍生品的详细解读:从产品结构到业务流程,一文看懂核心逻辑
  • 使用PHP对接韩国股票市场API 实时数据、IPO和K线(Kline)的PHP对接方案
  • 2026智能门锁硬核横评:安全、AI与售后全维度大解密,谁才是真正的“看门神”?
  • 深度拆解维普露禾AI教科研平台:学术知识图谱+大模型如何破解教育场景AI幻觉问题
  • 共同关心的话题进行了建设性交流
  • 基于 RFID 的企业固定资产全生命周期数字化管控技术方案
  • PIC18LF4620驱动WS2812 LED灯带的嵌入式开发实践
  • 每个人的遗忘程度都不一样,建议第二天复习前一天的内容,
  • 《TCP 客户端代码逐行寻宝:三次握手、死循环 close 的谜底全拆解》
  • Java中String.valueOf(null)的惊天大坑:对比两个数时,日志打印的两数都是null,但Objects.equals()返回false!
  • 拆解大健康爆火七人拼团,P1 到 P10 晋升逻辑全曝光
  • 房颤史患者用匹妥布替尼Pirtobrutinib,出血风险比伊布替尼低吗
  • AI大模型面试高频题:20道API工程化考点详解
  • 最初的需求
  • GPU内核融合技术:性能优化原理与实践
  • 计算机毕业设计之基于弹幕文本大数据的情感分析与可视化
  • 计算机毕业设计之基于大数据技术的新能源汽车销售数据可视化平台设计与实现
  • 【课程设计/毕业设计】基于 Java 的高中生多元素质评价管理系统的设计与实现【附源码、数据库、万字文档】
  • 低门槛股票量化工具横评:回测盯盘风控和条件单怎么分工
  • IPv6改造后,如何验证全国用户是否都能正常访问
  • 苹果重启iRing传言背后:健康监测优势凸显,欲在医疗健康市场分一杯羹
  • 大数据算法——布隆过滤器
  • 关于ThreadLocal为何不能在webflux中使用的问题
  • 生产级AI Agent系统架构:开源、可观测、可运维的六层栈
  • Java毕设项目: 基于 SpringBoot 的智能机器人企业官网管理系统的设计与实现 基于 SpringBoot 的协作机器人案例展示平台(源码+文档,讲解、调试运行,定制等)
  • 广州小程序开发十大品牌哪家好?
  • Java毕设选题推荐:基于 Java 的高中生德育实践档案管理系统的设计与实现 基于 Java 的高中学生学业素质综合档案系统【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 传统包装仅起保护作用,编程包装文案视觉溢价测算,高颜值文化包装,提升礼盒服饰成交单价。
  • 还不懂Redis?看完这个故事就明白了!