【基础】Three.js的零基础入门篇(附案例代码)

【基础】Three.js的零基础入门篇(附案例代码)在使用 Three js 时 初学者需要了解如何从零开始创建一个简单的 3D 场景

大家好,欢迎来到IT知识分享网。

请添加图片描述
(这个案例后面会有!!)

让我们先了解一下基本的入门知识~

一、Three.js和webGL的介绍

Three.js

是一款基于原生WebGL封装的Web 3D库,向外提供了许多的接口。
它可以运用在在小游戏、产品展示、物联网、数字孪生、智慧城市园区、机械、建筑、全景看房、GIS等各个领域。

WebGL

WebGL(Web 图形库)是一个 JavaScript API,可在任何兼容的 Web 浏览器中渲染高性能的交互式 3D 和 2D 图形,而无需使用插件。WebGL 通过引入一个与 OpenGL ES 2.0 非常一致的 API 来做到这一点,该 API 可以在 HTML5 元素中使用。原生WebGL和图形学是Three.js的底层知识。

二、开发和学习环境

  1. 开发环境:项目开发引入threejs,比如vue或react脚手架引入threejs。
    • 安装:threejs是一个js库,直接通过npm命令行安装。

      🔔npm安装特定版本three.js(注意使用哪个版本,查文档就查对应版本)

      // 比如安装148版本 npm install three@0.148.0 --save 
    • 引入three.js
      // 引入three.js import * as THREE from 'three'; 
    • 引入其他拓展库

      除了three.js核心库以外,在threejs文件包中examples/jsm目录下,你还可以看到各种不同功能的扩展库。

      需要用到哪一个扩展库,再局部引入。

      // 引入扩展库OrbitControls.js import { 
              OrbitControls } from 'three/addons/controls/OrbitControls.js'; // 引入扩展库GLTFLoader.js import { 
              GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; 

      注: 新版本路径addons替换了examples/jsm

      // 引入旧版本拓展库 import { 
              OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; 
  2. 学习环境:入门threejs阶段,.html文件中直接引入threejs。再使用vscode的Live Sever插件去创建一个本地服务器。
    • script标签方式引入three.js

      three.js库可以去hreejs官方文件包下面的build目录下载。

    Three.js 的 github地址

    //在<head>中引入js文件 <script src="./build/three.js"></script> 
    //随便输入一个API,测试下是否已经正常引入three.js console.log(THREE.Scene); 
    • type=”importmap“配置路径

      官网写法:

      <script type="importmap"> { 
              "imports": { 
              "three": "./build/three.module.js"//文件从官网下载 } } </script> 
      <script type="module"> import * as THREE from 'three'; // 浏览器控制台测试,是否引入成功 console.log(THREE.Scene); </script> 
    • type=“importmap”配置:扩展库引入

三、 三个基本概念

在这里插入图片描述

1. 场景Scene

  • 三维场景:用来模拟生活中的真实三维场景。新建好的几何体、光源、相机等,都需要添加到场景中才会显示。
  • 物体形状:几何体·Geometry
  • 物体外观:材质Material
  • 物体:网格模型Mesh(虚拟物体)
  • 模型位置:.position
  • 将模型添加到三维场景scene中:.add()方法
    // 创建3D场景对象Scene const scene = new THREE.Scene(); // 创建一个长宽高为10的长方体几何对象Geometry const geometry = new THREE.BoxGeometry( 10, 10, 10 ); // 创建一个材质对象Material,并设置材质颜色 const material = new THREE.MeshBasicMaterial( { 
          color: 0xffff00 } ); // 创建网格模型Mesh,可以将它看成一个虚拟物体 const mesh = new THREE.Mesh( geometry, material ); // 设置网格模型在三维空间中的位置坐标,默认是坐标原点 mesh.position.set(0,10,0); // 将模型添加到场景中 scene.add( mesh ); 

2. 相机Camera

相机的作用是拍摄你的画面。

Three,js中有两种相机:

  1. 正交投影相机(OrthographicCamera)

    这种投影模式下,无论物体距离相机距离远或者近,在最终渲染的图片中物体的大小都保持不变。常用于渲染2D场景或者UI元素

  2. 透视投影相机(PerspectiveCamera)

    近大远小,模拟人眼所看到场景。它是3D场景的渲染中用得最普遍的投影模式。

    • 透视投影相机PerspectiveCamera:视锥体
      请添加图片描述
    • 相机距离物体的位置:.position
    • 相机镜头对准哪个物体(坐标):.lookAt()
      // width和height用来设置Three.js输出的Canvas画布尺寸(像素px) const width = 800; //宽度 const height = 500; //高度 // 45:视场角度, width / height:Canvas画布宽高比, 1:近裁截面, 3000:远裁截面 const camera = new THREE.PerspectiveCamera(45, width / height, 1, 3000); //相机在Three.js三维坐标系中的位置 camera.position.set(200, 200, 200); //相机观察目标指向Threejs 3D空间中某个位置 camera.lookAt(0, 0, 0); //1. 坐标原点 camera.lookAt(mesh.position);//2. 指向mesh对应的位置 

      请添加图片描述

3. 渲染器Renderer

  • WebGL渲染器:WebGLRenderer
  • 设置Canvas画布尺寸:.setSize()
  • 设置背景颜色: .setClearColor()
  • 渲染器渲染方法:.render()
  • 获取画布元素:.domElement
    // 创建渲染器对象 const renderer = new THREE.WebGLRenderer(); const width = 800; //宽度 const height = 500; //高度 renderer.setSize(width, height); //设置画布(渲染区域)的尺寸(像素px) renderer.render(scene, camera); //执行渲染操作 // 将画布插入到HTML元素中 document.getElementById('demo').appendChild(renderer.domElement); 
    <div id="demo" ></div> 

四、三维坐标系

设置辅助坐标系可以更好地在空间中观察物体。

const axesHelper = new THREE.AxesHelper(10)//设置坐标轴线段尺寸 scene.add(axesHelper); 

如果想看到坐标轴原点,可以将材质为半透明

const material = new THREE.MeshBasicMaterial({ 
    color: 0x0000ff, //设置材质颜色 transparent:true,//开启透明 opacity:0.5,//设置透明度 }); 

注:three.js坐标轴颜色红x、绿y、蓝z,对于three.js的3D坐标系默认y轴朝上
❓为什么y轴朝上
因为在在Three.js 中,空间是基于右手笛卡尔坐标系展示的。
请添加图片描述


五、材质Material

🔔MeshBasicMaterial材质不受光源影响,场景中不添加光源也可以看见。

如果使用其他材质时,页面不显示模型就要检查是不是光源忘记添加了~

基础网格材质:MeshBasicMaterial(不受光)

漫反射网格材质:MeshLambertMaterial

高光镜面网格材质:MeshPhongMaterial

标准网格材质:MeshStandardMaterial (最真实)

基于物理的渲染(PBR)最近已成为许多3D应用程序的标准,例如Unity, Unreal和 3D Studio Max。

物理网格材质: MeshPhysicalMaterial

请添加图片描述

六、光源

1. 点光源

从一个点向各个方向发射的光源,类似一个灯泡发出的光。

设置点光源:PointLight

 // 【设置光源】(参数1: 颜色, 参数2: 光源强度, 参数3: 光源距离, 参数4: 光源范围) const pointLight = new THREE.PointLight(0xffffff, 1, 0, 0); 

点光源辅助观察器:PointLightHelper

 const pointLightHelper = new THREE.PointLightHelper(pointLight, 5); scene.add(pointLightHelper); 

2. 环境光

环境光会均匀的照亮场景中的所有物体,因为它没有方向,所以不能用来投射阴影。

设置环境光:AmbientLight

 const ambient = new THREE.AmbientLight(0xffffff, 0.4); scene.add(ambient); 

3. 平行光:

平行光是沿着特定方向发射的光,常常用平行光来模拟太阳光的效果。

设置平行光:DirectionalLight

 const directionalLight = new THREE.DirectionalLight(0xffffff, 1); // 设置光源的方向:通过光源position属性和目标指向对象的position属性计算 directionalLight.position.set(80, 100, 50); directionalLight.intensity = 0.5;// 设置光源强度 

平行光源辅助观察器:DirectionalLightHelper

 const dirLightHelper = new THREE.DirectionalLightHelper(directionalLight, 1, 0xff0000);//参数1:光源,参数2:长度,参数3:颜色 scene.add(dirLightHelper); 

七、常见几何体

请添加图片描述

八、渲染器-设置设备像素比

如果遇到canvas画布输出模糊问题,需要按着你屏幕设备的像素比去设置。

🔔为了适应不同的硬件设备屏幕,通常需要执行setPixelRatio该方法。

 console.log(`查看当前屏幕设备像素比`,window.devicePixelRatio) renderer.setPixelRatio(window.devicePixelRatio); 

九、渲染器-锯齿属性

💬为什么要在渲染时设置锯齿属性?

在 Three.js 中,渲染器负责将场景和相机转换为实际图像。为了获得更好的图像质量减少图像锯齿

💬什么是图像锯齿呢?

图片锯齿,全称叫图像折叠失真,是指在图片的画面轮廓边缘出现不平滑的棱角

出现这种情况,说明画面的分辨率不够或太大而画面拥挤,或者是3D游戏时显卡没启用抗锯齿功能 (抗锯齿标准翻译为抗图像折叠失真)

在这里插入图片描述

抗锯齿(Antialiasing)就是指对图像边缘进行柔化处理,使图像边缘看起来更平滑真实

Three.js 中提供了多种抗锯齿选项,例如:antialias: true(自动抗锯齿)和 antialias: 0.5(抗锯齿强度为 0.5)。

// 设置自动抗锯齿 // 方式一 const renderer = new THREE.WebGLRenderer({ 
    antialias:true, }); // 方式二 renderer.antialias = true 

十、小案例

请添加图片描述
代码如下:

<template> <div class="wrapper"> <div ref="threeRef"></div> </div> </template> <script setup lang="ts"> // 引入three.js import * as THREE from "three"; // 引入扩展库OrbitControls.js import { 
      OrbitControls } from "three/addons/controls/OrbitControls.js"; import { 
      onMounted, ref } from "vue"; const threeRef = ref(); const init = () => { 
      //! 1.创建场景 // 创建3D场景对象Scene const scene = new THREE.Scene(); // 设置场景颜色 scene.background = new THREE.Color("#c1c5d8"); // 创建一个长宽高为10的长方体几何对象Geometry const geometry = new THREE.BoxGeometry(10, 10, 10); // const material = new THREE.MeshStandardMaterial({ 
      // transparent: true, //开启透明 // opacity: 0.5, //设置透明度 // }); // 模拟镜面反射,产生一个高光效果 const material = new THREE.MeshPhongMaterial({ 
      color: 0xff0000, shininess: 20, //高光部分的亮度,默认30 specular: 0x, //高光部分的颜色 }); // 创建网格模型Mesh,可以将它看成一个虚拟物体 const mesh = new THREE.Mesh(geometry, material); // 设置网格模型在三维空间中的位置坐标,默认是坐标原点 mesh.position.set(0, 10, 0); // 将模型添加到场景中 scene.add(mesh); //! 2.创建相机 // 30:视场角度, width / height:Canvas画布宽高比, 1:近裁截面, 3000:远裁截面 const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 3000 ); camera.position.set(0, 0, 20); // 相机位置 camera.lookAt(mesh.position); //指向mesh对应的位置 // !AxesHelper:辅助观察的坐标系 const axesHelper = new THREE.AxesHelper(50); scene.add(axesHelper); // !3.创建渲染器 // 创建渲染器对象 const renderer = new THREE.WebGLRenderer({ 
      antialias: true, // 设置锯齿属性,为了获得更好的图像质量 }); // 定义threejs输出画布的尺寸(单位:像素px) renderer.setSize(window.innerWidth, window.innerHeight); // 为了适应不同的硬件设备屏幕,设置设备像素比 renderer.setPixelRatio(window.devicePixelRatio); // 插入到任意HTML元素中 threeRef.value.append(renderer.domElement); //执行渲染操作 renderer.render(scene, camera); // !添加光源 // 平行光 const directionalLight = new THREE.DirectionalLight(0xffffff, 1); // 设置光源的方向:通过光源position属性和目标指向对象的position属性计算 directionalLight.position.set(80, 100, 50); // 方向光指向对象网格模型mesh,可以不设置,默认的位置是0,0,0 directionalLight.target = mesh; // 将光源添加到场景中 scene.add(directionalLight); // !设置相机控件轨道控制器 const controls = new OrbitControls(camera, renderer.domElement); // 如果OrbitControls改变了相机参数,重新调用渲染器渲染三维场景 controls.addEventListener("change", function () { 
      renderer.render(scene, camera); //执行渲染操作 }); //监听鼠标、键盘事件 // ! 创建循环动画,使物体可以动起来 function rotateRender() { 
      renderer.render(scene, camera); //执行渲染操作 mesh.rotateY(0.01); //每次绕y轴旋转0.01弧度 requestAnimationFrame(rotateRender); //请求再次执行渲染函数render,渲染下一帧 } rotateRender(); // !处理窗口大小调整 window.onresize = function () { 
      // 更新相机纵横比 camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); // 更新渲染器的大小 renderer.setSize(window.innerWidth, window.innerHeight); }; }; onMounted(() => { 
      init(); }); </script> <style scoped> .wrapper { 
      overflow: hidden; margin: 0px; } </style> 

十一 、总结

在使用Three.js时,初学者需要了解如何从零开始创建一个简单的3D场景。以下是创建步骤和一些注意点:

1. 初始化基本组件

每个Three.js场景需要几个核心组件:场景(Scene)、相机(Camera)和渲染器(Renderer)

// 创建场景 const scene = new THREE.Scene(); // 创建透视相机 const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.z = 5; // 设置相机位置 // 创建WebGL渲染器并设置大小 const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 将渲染器的canvas添加到DOM中 ,这里是添加到了body上 

2. 添加几何体(物体)和材质

要显示一个3D对象,你需要定义其几何体(Geometry)和材质(Material)。

// 创建一个立方体的几何体 const geometry = new THREE.BoxGeometry(1, 1, 1); // 创建一种基本的材质并赋予颜色 const material = new THREE.MeshBasicMaterial({ 
    color: 0x00ff00 }); // 使用几何体和材质创建网格(Mesh) const cube = new THREE.Mesh(geometry, material); // 将网格添加到场景中 scene.add(cube); 

3. 添加光源(如果需要)

如果使用非基本材质(如MeshPhongMaterial或MeshStandardMaterial),需要添加光源。MeshBasicMaterial不需要光源。

// 创建点光源 const light = new THREE.PointLight(0xffffff, 1, 100); light.position.set(10, 10, 10); scene.add(light); 

4. 创建动画循环

通过动画循环来不断渲染场景,使3D图形动起来。

function animate() { 
    requestAnimationFrame(animate); // 在每一帧中旋转立方体 cube.rotation.x += 0.01; cube.rotation.y += 0.01; // 渲染场景 renderer.render(scene, camera); } // 启动动画循环 animate(); 

5. 处理窗口大小调整

为了在用户调整浏览器窗口大小时保持合适的比例和视图,需要添加一个事件监听器来处理相机和渲染器的尺寸调整。

 window.onresize = function () { 
    // 更新相机纵横比 camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); // 更新渲染器的大小 renderer.setSize(window.innerWidth, window.innerHeight); }; 

注:以上引用图来自Three.js中文网,借鉴学习,加入自己理解整理而得的学习笔记。


免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/113997.html

(0)
上一篇 2025-12-11 12:45
下一篇 2025-12-11 13:10

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信