轻松上手Three.js:JavaScript 3D库指南

1.Three.js概述

Three.js是使用JavaScript语言编写的一款运行在浏览器中的3D引擎。与WebGL不同,开发人员在使用Three.js进行开发时,无须掌握高深的图形学知识,只需使用少量JavaScript代码即可创建出一个3D场景。可以说,Three.js的出现对3D开发领域产生了巨大的推动作用。

1.1 Three.js简介

Three.js 3D引擎被开发出来,其功能如下。

❑ 根据开发人员的需求方便快捷地创建出3D图形。

❑ 为物体的渲染提供多种类型的纹理和材质。

❑ 自带阴影计算功能,可实现逼真的阴影效果。

❑ 支持多种格式的3D物体和骨骼动画,使3D场景更加丰富。

❑ 引擎中带有多种着色器,可实现多种逼真效果。

Three.js是Github上的一个开源项目,发展极其迅速。到目前为止,Three.js已经成为一个较为完善的3D引擎,被国内外开发人员广泛使用。

在正式学习Three.js的代码开发之前,先了解一下准备工作。

下载整个Three.js项目。build目录存储着Three.jsThree.min.jsThree.module.js这3个文件。three.js没有进行代码压缩,适合调试使用。Three.min.js进行了压缩,但是调试比较烦琐,适合用于最终发布。

下载完成后,在HTML中将Three.js文件作为外部文件来引入,通过全局变量THREE对库中所有变量和方法进行操作,引入的代码如下。

java 复制代码
<script src="./three.js/three.js-master/build/three.js""></script>

1.2 Three.js效果展示

下面的几幅图就是使用Three.js3D引擎制作的截图。

使用Three.js可以开发出酷炫、逼真的3D场景,给用户带来强烈的视觉冲击。另一方面,Three.js又具有封装度高、开发难度低等优势。相信在不久的将来,Three.js会迸发出更大的能量。

提示:有兴趣的读者可以登录Three.js的官方网站体验各类优秀的作品。

2.初识Three.js应用

通过简单的案例,详细介绍使用Three.js进行开发的基本步骤,进一步提高读者对程序开发的理解。

案例一的运行效果如图所示。

案例一代码:

html 复制代码
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
        <title>第一个Threejs案例</title>
        <script src="./three.js/three.js-master/build/three.js"></script>
        <style>
            * {
                margin: 0;
                padding: 0;
                box-sizing: border-box;
            }
 
            #webgl {
                width: 100%;
                height: 100vh;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
 
        <div id="webgl"></div>
 
        <script>
            
            // 获取渲染容器
            let webgl = document.getElementById("webgl");
            
            // 获取渲染容器的宽高
            let webglWidth = webgl.offsetWidth;
            let webglHeight = webgl.offsetHeight;
            
            // 创建场景
            let scene = new THREE.Scene();
            
            // 创建三维坐标(轴线长度)
            // 用于调试:红色:x轴、绿色:y轴、蓝色:z轴
            let axes = new THREE.AxesHelper(60);
            
            // 添加三维坐标到场景中
            scene.add(axes);
            
            // 设置环境光(十六进制颜色)
            let ambient = new THREE.AmbientLight(0x444444);
            
            // 将环境光添加到场景中
            scene.add(ambient);
            
            // 设置点光源(十六进制颜色)
            let point = new THREE.PointLight(0xffffff);
            
            // 设置点光源的位置(x轴, y轴, z轴)
            point.position.set(400, 200, 300); 
            
            // 将点光源添加到场景中
            scene.add(point); 
            
            // 创建立方几何体(x轴, y轴, z轴)
            let cubeGeometry = new THREE.BoxGeometry(20,20,20);
            
            // 创建网格基础材质
            let cubeMaterial = new THREE.MeshLambertMaterial({color:0x00FFFF});
            
            // 创建立方体(几何体, 材质)
            let cube = new THREE.Mesh(cubeGeometry,cubeMaterial);
            
            // 调整立方体位置(x轴, y轴, z轴)
            cube.position.set(0, 0, 0); 
            
            // 将立方体添加到场景中
            scene.add(cube);
            
            // 创建透视相机(角度, 宽高比, 最近距离, 最远距离)
            let camera = new THREE.PerspectiveCamera(60,webglWidth/webglHeight,0.1,2000);
            
            // 设置相机的位置(x轴, y轴, z轴)
            camera.position.set(100, 100, 100); 
            
            // 将相机指向场景中心
            camera.lookAt(scene.position);
            
            // 创建渲染器
            let renderer = new THREE.WebGLRenderer();
            
            // 设置渲染器的初始颜色(十六进制颜色, 透明度)
            renderer.setClearColor(0xEEEEEE,1);
            
            // 设置渲染器大小(标签宽度, 标签高度)
            renderer.setSize(webglWidth,webglHeight);
            
            // 将渲染器添加到渲染容器中(渲染器元素)
            webgl.appendChild(renderer.domElement);
            
            // 创建渲染函数
            function render(){
                // 渲染场景和相机(场景, 相机)
                renderer.render(scene,camera);
            }
            
            // 调用渲染函数
            render();
            
            // 设置窗口变化自适应调整事件
            window.onresize = function(){
                
                // 重新获取渲染容器的宽高
                webglWidth = webgl.offsetWidth;
                webglHeight = webgl.offsetHeight;
                
                // 重置渲染器canvas画布大小
                renderer.setSize(webglWidth,webglHeight);
                
                // 重置相机显示范围的宽高比
                camera.aspect = webglWidth/webglHeight;
              
                // 更新相机的投影矩阵
                camera.updateProjectionMatrix();
                
                // 重新调用渲染函数
                render();
            };            
        </script>
    </body>
</html>

案例二的运行效果如图所示。

案例二代码:

html 复制代码
<html>
  <head>
    <title>My first three.js app</title>
    <style>
      body {
        margin: 0;
      }
      canvas {
        display: block;
      }
    </style>
  </head>
  <body>
    <script src="./three.js/three.js-master/build/three.js"></script>
    <script>
      //创建场景和相机
      var scene = new THREE.Scene();
      var camera = new THREE.PerspectiveCamera(
        75,
        window.innerWidth / window.innerHeight,
        0.1,
        1000
      );

      //创建渲染器,设置尺寸为窗口尺寸,并将渲染后的元素添加到body
      var renderer = new THREE.WebGLRenderer();
      renderer.setSize(window.innerWidth, window.innerHeight);
      document.body.appendChild(renderer.domElement);

      //创建一个Mesh(绿色的3D立方体),并添加到场景中
      var geometry = new THREE.BoxGeometry();
      var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
      var cube = new THREE.Mesh(geometry, material);
      scene.add(cube);

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

      //浏览器每次渲染的时候更新立方体的旋转角度
      var animate = function () {
        requestAnimationFrame(animate);

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

        renderer.render(scene, camera);
      };

      animate();
    </script>
  </body>
</html>

主要的思路为新建一个html文件,将Three.js文件作为外部文件引入,之后通过编写JavaScript代码对整个项目进行操作。

相关推荐
初晴~32 分钟前
【Redis分布式锁】高并发场景下秒杀业务的实现思路(集群模式)
java·数据库·redis·分布式·后端·spring·
盖世英雄酱5813638 分钟前
InnoDB 的页分裂和页合并
数据库·后端
小_太_阳1 小时前
Scala_【2】变量和数据类型
开发语言·后端·scala·intellij-idea
直裾1 小时前
scala借阅图书保存记录(三)
开发语言·后端·scala
星就前端叭2 小时前
【开源】一款基于Vue3 + WebRTC + Node + SRS + FFmpeg搭建的直播间项目
前端·后端·开源·webrtc
小林coding3 小时前
阿里云 Java 后端一面,什么难度?
java·后端·mysql·spring·阿里云
AI理性派思考者3 小时前
【保姆教程】手把手教你在Linux系统搭建早期alpha项目cysic的验证者&证明者
后端·github·gpu
从善若水3 小时前
【2024】Merry Christmas!一起用Rust绘制一颗圣诞树吧
开发语言·后端·rust
机器之心3 小时前
终于等来能塞进手机的文生图模型!十分之一体量,SnapGen实现百分百的效果
人工智能·后端
机器之心3 小时前
首次!大模型自动搜索人工生命,做出AI科学家的Sakana AI又放大招
人工智能·后端