Three.js:开启Web 3D世界的魔法钥匙

简介: Three.js是基于WebGL的JavaScript 3D库,简化了网页中3D图形的创建与渲染。它提供场景、相机、光照、动画等完整架构,支持丰富几何体、材质及高级特效,助力开发者轻松实现交互式3D可视化。

Three.js:开启Web 3D世界的魔法钥匙

Three.js是一个基于WebGL的JavaScript 3D库,它简化了在网页中创建和渲染3D图形的过程。作为一个强大的3D图形库,Three.js为开发者提供了丰富的功能和灵活的API,使得在浏览器中实现复杂的3D可视化效果变得更加容易。

Three.js的发展历程

Three.js由Ricardo Cabello在2010年创建,最初是为了让开发者能够更容易地在网页中使用WebGL技术。随着WebGL标准的不断发展和浏览器性能的提升,Three.js也经历了多次重大更新,从最初的简单3D渲染库发展成为功能完善的3D图形开发框架。

在过去的十多年里,Three.js经历了多个重要版本的迭代:

  • r1 - r45 (2010-2012): 初期版本,奠定了基本的架构
  • r50 - r70 (2012-2015): 添加了更多材质和光照效果
  • r71 - r100 (2015-2018): 支持更多渲染技术和优化
  • r101 - r128 (2018-2021): 大幅改进性能和API设计
  • r129 - 现在 (2021-至今): 持续优化和新功能添加

image.png

核心概念与架构

Three.js的架构设计遵循了3D图形渲染的基本原理,主要包括以下几个核心组件:

组件类型 功能描述 常用类
Scene 3D场景容器 THREE.Scene
Camera 视角控制 THREE.PerspectiveCamera
Renderer 渲染引擎 THREE.WebGLRenderer
Geometry 几何体定义 THREE.BoxGeometry
Material 材质属性 THREE.MeshBasicMaterial
Light 光照系统 THREE.DirectionalLight
Object 3D对象 THREE.Mesh

基础场景构建

19c4131a-2af5-4baf-bdd8-1125f3e800a2.png

<!DOCTYPE html>
<html>
<head>
    <title>Three.js基础场景</title>
    <style>
        body {
    margin: 0; padding: 0; }
        canvas {
    display: block; }
    </style>
</head>
<body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
    <script>
        // 创建场景
        const scene = new THREE.Scene();

        // 创建相机
        const camera = new THREE.PerspectiveCamera(
            75, 
            window.innerWidth / window.innerHeight, 
            0.1, 
            1000
        );

        // 创建渲染器
        const renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        // 创建几何体
        const geometry = new THREE.BoxGeometry(1, 1, 1);

        // 创建材质
        const material = new THREE.MeshBasicMaterial({
    color: 0x00ff00 });

        // 创建网格对象
        const cube = new THREE.Mesh(geometry, material);
        scene.add(cube);

        // 设置相机位置
        camera.position.z = 5;

        // 渲染循环
        function animate() {
   
            requestAnimationFrame(animate);

            // 旋转立方体
            cube.rotation.x += 0.01;
            cube.rotation.y += 0.01;

            renderer.render(scene, camera);
        }

        animate();

        // 响应窗口大小变化
        window.addEventListener('resize', () => {
   
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        });
    </script>
</body>
</html>

几何体与材质系统

Three.js提供了丰富的几何体类型,从基本的立方体、球体到复杂的自定义几何体,开发者可以根据需要选择合适的几何体类型。

常用几何体类型

image.png

<!DOCTYPE html>
<html>
<head>
    <title>Three.js几何体示例</title>
    <style>
        body {
    margin: 0; padding: 0; }
        canvas {
    display: block; }
    </style>
</head>
<body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
    <script>
        const scene = new THREE.Scene();
        scene.background = new THREE.Color(0x222222);

        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        const renderer = new THREE.WebGLRenderer({
    antialias: true });
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.setPixelRatio(window.devicePixelRatio);
        document.body.appendChild(renderer.domElement);

        // 创建不同类型的几何体
        const geometries = [
            new THREE.BoxGeometry(1, 1, 1),           // 立方体
            new THREE.SphereGeometry(0.8, 32, 32),   // 球体
            new THREE.ConeGeometry(0.8, 1.5, 8),     // 圆锥体
            new THREE.CylinderGeometry(0.6, 0.6, 1.5, 32), // 圆柱体
            new THREE.TorusGeometry(0.8, 0.3, 16, 100)     // 圆环体
        ];

        const materials = [
            new THREE.MeshBasicMaterial({
    color: 0xff0000 }),
            new THREE.MeshBasicMaterial({
    color: 0x00ff00 }),
            new THREE.MeshBasicMaterial({
    color: 0x0000ff }),
            new THREE.MeshBasicMaterial({
    color: 0xffff00 }),
            new THREE.MeshBasicMaterial({
    color: 0xff00ff })
        ];

        const objects = [];

        for (let i = 0; i < geometries.length; i++) {
   
            const mesh = new THREE.Mesh(geometries[i], materials[i]);
            mesh.position.x = (i - 2) * 2.5;
            scene.add(mesh);
            objects.push(mesh);
        }

        camera.position.z = 8;

        function animate() {
   
            requestAnimationFrame(animate);

            objects.forEach((obj, index) => {
   
                obj.rotation.x += 0.01;
                obj.rotation.y += 0.01;

                // 添加不同的动画效果
                obj.position.y = Math.sin(Date.now() * 0.001 + index) * 0.5;
            });

            renderer.render(scene, camera);
        }

        animate();

        window.addEventListener('resize', () => {
   
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        });
    </script>
</body>
</html>

光照与阴影系统

光照是3D渲染中最重要的元素之一,Three.js提供了多种光照类型来模拟真实世界的光照效果。

光照类型与应用

image.png

<!DOCTYPE html>
<html>
<head>
    <title>Three.js光照系统</title>
    <style>
        body {
    margin: 0; padding: 0; }
        canvas {
    display: block; }
    </style>
</head>
<body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
    <script>
        const scene = new THREE.Scene();
        scene.background = new THREE.Color(0x222222);

        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        const renderer = new THREE.WebGLRenderer({
    antialias: true });
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.shadowMap.enabled = true;
        renderer.shadowMap.type = THREE.PCFSoftShadowMap;
        document.body.appendChild(renderer.domElement);

        // 环境光
        const ambientLight = new THREE.AmbientLight(0x404040, 0.6);
        scene.add(ambientLight);

        // 方向光
        const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
        directionalLight.position.set(5, 10, 7);
        directionalLight.castShadow = true;
        directionalLight.shadow.mapSize.width = 1024;
        directionalLight.shadow.mapSize.height = 1024;
        scene.add(directionalLight);

        // 点光源
        const pointLight = new THREE.PointLight(0xff0000, 1, 100);
        pointLight.position.set(10, 10, 10);
        pointLight.castShadow = true;
        scene.add(pointLight);

        // 创建带阴影的物体
        const geometry = new THREE.BoxGeometry(2, 2, 2);
        const material = new THREE.MeshLambertMaterial({
    color: 0x00ff00 });
        const cube = new THREE.Mesh(geometry, material);
        cube.castShadow = true;
        cube.receiveShadow = true;
        scene.add(cube);

        // 地面
        const planeGeometry = new THREE.PlaneGeometry(20, 20);
        const planeMaterial = new THREE.MeshLambertMaterial({
    color: 0x888888 });
        const plane = new THREE.Mesh(planeGeometry, planeMaterial);
        plane.rotation.x = -Math.PI / 2;
        plane.position.y = -2;
        plane.receiveShadow = true;
        scene.add(plane);

        camera.position.set(5, 5, 10);
        camera.lookAt(0, 0, 0);

        function animate() {
   
            requestAnimationFrame(animate);

            cube.rotation.x += 0.01;
            cube.rotation.y += 0.01;

            // 移动点光源
            pointLight.position.x = 10 * Math.sin(Date.now() * 0.001);
            pointLight.position.z = 10 * Math.cos(Date.now() * 0.001);

            renderer.render(scene, camera);
        }

        animate();

        window.addEventListener('resize', () => {
   
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        });
    </script>
</body>
</html>

动画与交互系统

Three.js提供了强大的动画系统,支持基于时间的动画、骨骼动画、变形动画等多种动画类型。

动画实现示例

image.png

<!DOCTYPE html>
<html>
<head>
    <title>Three.js动画系统</title>
    <style>
        body {
    margin: 0; padding: 0; }
        canvas {
    display: block; }
    </style>
</head>
<body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
    <script>
        const scene = new THREE.Scene();
        scene.background = new THREE.Color(0x111111);

        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        const renderer = new THREE.WebGLRenderer({
    antialias: true });
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        // 创建动画物体
        const geometry = new THREE.TorusGeometry(1, 0.4, 16, 100);
        const material = new THREE.MeshBasicMaterial({
    
            color: 0x00ff00,
            wireframe: true
        });

        const torus = new THREE.Mesh(geometry, material);
        scene.add(torus);

        // 创建多个物体形成动画序列
        const objects = [];
        for (let i = 0; i < 10; i++) {
   
            const geo = new THREE.SphereGeometry(0.3, 16, 16);
            const mat = new THREE.MeshBasicMaterial({
    
                color: new THREE.Color(Math.random(), Math.random(), Math.random()) 
            });
            const obj = new THREE.Mesh(geo, mat);

            obj.position.x = Math.sin(i) * 3;
            obj.position.y = Math.cos(i) * 2;
            obj.position.z = Math.cos(i * 0.5) * 3;

            scene.add(obj);
            objects.push(obj);
        }

        camera.position.z = 8;

        function animate() {
   
            requestAnimationFrame(animate);

            // 基础旋转动画
            torus.rotation.x += 0.01;
            torus.rotation.y += 0.01;

            // 复杂动画序列
            objects.forEach((obj, index) => {
   
                obj.rotation.x += 0.01 * (index + 1);
                obj.rotation.y += 0.02 * (index + 1);

                // 位置动画
                obj.position.x = Math.sin(Date.now() * 0.001 * (index + 1)) * 3;
                obj.position.y = Math.cos(Date.now() * 0.001 * (index + 1)) * 2;
                obj.position.z = Math.cos(Date.now() * 0.0005 * (index + 1)) * 3;
            });

            renderer.render(scene, camera);
        }

        animate();

        window.addEventListener('resize', () => {
   
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        });

        // 添加鼠标交互
        renderer.domElement.addEventListener('click', (event) => {
   
            const raycaster = new THREE.Raycaster();
            const mouse = new THREE.Vector2();

            mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
            mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

            raycaster.setFromCamera(mouse, camera);

            const intersects = raycaster.intersectObjects(scene.children);

            if (intersects.length > 0) {
   
                intersects[0].object.material.color.setHex(Math.random() * 0xffffff);
            }
        });
    </script>
</body>
</html>

高级功能与扩展

Three.js不仅支持基础的3D渲染功能,还提供了粒子系统、后处理效果、加载器、物理引擎集成等高级功能。

粒子系统示例

image.png

<!DOCTYPE html>
<html>
<head>
    <title>Three.js粒子系统</title>
    <style>
        body {
    margin: 0; padding: 0; }
        canvas {
    display: block; }
    </style>
</head>
<body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
    <script>
        const scene = new THREE.Scene();
        scene.background = new THREE.Color(0x000000);

        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 2000);
        const renderer = new THREE.WebGLRenderer({
    antialias: true });
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        // 创建粒子系统
        const particleCount = 5000;
        const particles = new THREE.BufferGeometry();
        const posArray = new Float32Array(particleCount * 3);

        // 初始化粒子位置
        for (let i = 0; i < particleCount * 3; i++) {
   
            posArray[i] = (Math.random() - 0.5) * 10;
        }

        particles.setAttribute('position', new THREE.BufferAttribute(posArray, 3));

        // 创建粒子材质
        const particleMaterial = new THREE.PointsMaterial({
   
            size: 0.02,
            color: 0xffffff,
            transparent: true,
            opacity: 0.8
        });

        // 创建粒子系统
        const particleSystem = new THREE.Points(particles, particleMaterial);
        scene.add(particleSystem);

        camera.position.z = 5;

        function animate() {
   
            requestAnimationFrame(animate);

            // 更新粒子位置
            const positions = particles.attributes.position.array;
            for (let i = 0; i < particleCount * 3; i += 3) {
   
                positions[i + 1] += 0.01; // Y轴移动

                // 重置超出边界的粒子
                if (positions[i + 1] > 5) {
   
                    positions[i + 1] = -5;
                    positions[i] = (Math.random() - 0.5) * 10;
                    positions[i + 2] = (Math.random() - 0.5) * 10;
                }
            }

            particles.attributes.position.needsUpdate = true;

            renderer.render(scene, camera);
        }

        animate();

        window.addEventListener('resize', () => {
   
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        });
    </script>
</body>
</html>

性能优化与最佳实践

在使用Three.js开发3D应用时,性能优化是一个重要的考虑因素。以下是一些常见的性能优化策略:

  1. 对象池管理: 重复使用对象而不是频繁创建和销毁
  2. LOD技术: 根据距离使用不同细节层次的模型
  3. 实例化渲染: 对于大量相似对象使用实例化渲染
  4. 纹理压缩: 使用适当的纹理格式和压缩技术
  5. 剔除技术: 视锥体剔除和遮挡剔除

Three.js凭借其强大的功能和活跃的社区支持,已经成为Web 3D开发的首选框架。无论是创建简单的3D演示还是复杂的交互式应用,Three.js都能提供强大的支持和灵活的解决方案。

参考文献

three.js官网



关于作者



🌟 我是suxiaoxiang,一位热爱技术的开发者

💡 专注于Java生态和前沿技术分享

🚀 持续输出高质量技术内容



如果这篇文章对你有帮助,请支持一下:




👍 点赞


收藏


👀 关注



您的支持是我持续创作的动力!感谢每一位读者的关注与认可!


目录
相关文章
|
20天前
|
运维 自然语言处理 监控
AIOps 实战:我用 LLM 辅助分析线上告警
本文分享AIOps实战中利用大型语言模型(LLM)智能分析线上告警的实践经验,解决告警洪流、关联性分析难等问题。通过语义理解与上下文感知,LLM实现告警分类、优先级排序与根因定位,显著提升运维效率与准确率,助力系统稳定运行。
129 5
|
26天前
|
人工智能 搜索推荐 API
蚂蚁百宝箱联手深铁打造全国首个地铁 AI 智能体「深铁宝」:你的全能城市向导来啦~
蚂蚁百宝箱联合深铁集团、深圳通推出全国首个“公共出行+城市服务”AI智能体「深铁宝」,上线于深圳地铁、深圳通及支付宝APP,实现一句话直达、秒级响应的智慧出行体验,涵盖出行规划、乘车码快捷调取、周边生活服务推荐等一站式功能,助力城市交通与服务数字化升级。
226 30
|
21天前
|
搜索推荐 算法 小程序
基于微信小程序的个性化漫画阅读推荐系统
本研究设计并实现基于微信小程序的个性化漫画推荐系统,结合用户行为数据与先进算法,提升阅读体验与平台黏性,推动漫画产业数字化发展。
|
20天前
|
机器学习/深度学习 数据可视化 算法
基于YOLOv8的可回收瓶类垃圾快速识别与自动化分拣|完整源码数据集+PyQt5界面+完整训练流程+开箱即用!
本项目基于 YOLOv8 构建了一套可回收瓶类垃圾的实时识别与自动化分拣系统,从数据集构建、模型训练到 PyQt5 可视化界面部署,形成了完整的工程化闭环。系统能够对多种瓶类废弃物进行高精度识别,并支持图片、视频、摄像头流等多场景实时处理,适用于垃圾回收站、环卫中转站、产线分拣系统等实际应用场景。
基于YOLOv8的可回收瓶类垃圾快速识别与自动化分拣|完整源码数据集+PyQt5界面+完整训练流程+开箱即用!
|
存储 安全 数据安全/隐私保护
Token 是什么?全面解析身份认证中的 Token 机制
本文全面解析Token在身份认证中的核心机制,涵盖JWT、Session Token、OAuth等类型,深入讲解其工作原理、安全性策略、生命周期管理及实际应用场景,助力开发者构建安全高效的现代Web应用认证体系。
1530 3
|
21天前
|
机器学习/深度学习 人工智能 算法
面向 AI 工作负载的 Java:从数值计算到模型服务化
本文探讨Java在AI工作负载中的应用,涵盖数值计算、深度学习、模型服务化及性能优化,展示如何利用DeepLearning4J、ND4J与Spring Boot构建高效、可扩展的AI系统,推动Java在人工智能领域的落地实践。
186 7
|
16天前
|
人工智能 安全 开发者
|
24天前
|
SQL 人工智能 API
LangChain 不只是“拼模型”:教你从零构建可编程的 AI 工作流
LangChain 不只是“拼模型”:教你从零构建可编程的 AI 工作流
153 8
|
2月前
|
人工智能 监控 数据可视化
智慧工地一体化信息管理平台源码
智慧工地一体化平台融合大数据、AI、物联网等技术,构建覆盖人、机、料、法、环的数字化管理体系,实现施工全过程可视化、智能化管理,提升效率,推动建筑产业信息化升级。
311 4