初始3d
1. 3d教程
2. 目录结构
three.js-文件包
└───build——three.js相关库,可以引入你的.html文件中。
│
└───docs——Three.js API文档文件
│───index.html——打开该文件,本地离线方式预览threejs文档
└───examples——大量的3D案例,是你平时开发参考学习的最佳资源
│───jsm——threejs各种功能扩展库
└───src——Three.js引擎的源码,有兴趣可以阅读。
│
└───editor——Three.js的可视化编辑器,可以编辑3D场景
│───index.html——打开应用程序
3. 项目开发环境引入threejs
通过npm安装
// 比如安装148版本
npm install three@0.148.0 --save
引入three.js
// 引入three.js
import * as THREE from 'three';
引入其他的扩展库
一般来说,你项目用到那个扩展库,就引入那个,用不到就不需要引入。
// 引入扩展库OrbitControls.js
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
// 引入扩展库GLTFLoader.js
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
// 扩展库引入——旧版本,比如122, 新版本路径addons替换了examples/jsm
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
4. 3D概念
三个基本概念: 场景Scene、相机Camera、渲染器Renderer
基本关系
4.1 场景Scene
三维场景Scene
就是很简单的概念,就当是现实生活,有X、Y、Z轴
创建
// 创建3D场景对象Scene
const scene = new THREE.Scene();
物体形状:几何体Geometry
| 长方体 | BoxGeometry |
| 圆柱体 | CylinderGeometry |
| 球体 | SphereGeometry |
| 圆锥 | ConeGeometry |
| 矩形平面 | PlaneGeometry |
| 圆平面 | CircleGeometry |
创建
//创建一个长方体几何对象Geometry
const geometry = new THREE.BoxGeometry(100, 100, 100);
物体外观:材质Material
如果想定义物体的外观效果,比如颜色,就需要通过材质Material相关的API实现。
threejs最简单的网格基础材质
| 材质Material | |
|---|---|
| 网格基础材质 | MeshBasicMaterial |
| 网格漫反射材质 | MeshLambertMaterial |
| 网格高光材质 | meshPhongMaterial |
| 物理材质 | MeshStandardMaterial MeshPhysicalMaterial |
| 点材质 | PointsMaterial |
| 线基础材质 | LineBasicMaterial |
| 精灵材质 | SpriteMaterial |
创建一个材质对象Material
const material = new THREE.MeshBasicMaterial({
color: 0xff0000,//0xff0000设置材质颜色为红色
});
物体:网格模型Mesh
对物体形状还有物体外观进行绘制
const mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
模型位置.position
定义模型在三维中具体的位置
const mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
//设置网格模型在三维空间中的位置坐标,默认是坐标原点
mesh.position.set(0,10,0);
.add()方法
通过.add()方法将模型进行添加到Scene中
scene.add(mesh)
4.2 虚拟相机Camera
类似于,你在现实生活中拍照,3D分为两种投影:正投影相机OrthographicCamera、透视投影相机PerspectiveCamera
透视投影相机PerspectiveCamera
常用的是透视投影相机。这个的本质是模拟人眼观察世界
//实例化
const camera = new THREE.PerspectiveCamera
相机位置.position
就是你拍照时距离风景有多远
//相机在Three.js三维坐标系中的位置
// 根据需要设置相机位置具体值
camera.position.set(200, 200, 200);
相机观察目标.lookAt()
你想拍的是那个风景
camera.lookAt(0, 0, 0); //坐标原点
camera.lookAt(0, 10, 0); //y轴上位置10
camera.lookAt(mesh.position);//指向mesh对应的位置 中心点???
canvas画布
定义宽高(单位是px)
const width = 800; //宽度
const height = 500; //高度
透视投影相机PerspectiveCamera:视锥体
// width和height用来设置Three.js输出的Canvas画布尺寸(像素px)
const width = 800; //宽度
const height = 500; //高度
// 30:视场角度, width / height:Canvas画布宽高比, 1:近裁截面, 3000:远裁截面
const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);
PerspectiveCamera参数介绍:
PerspectiveCamera( fov, aspect, near, far )
| 参数 | 含义 | 默认值 |
|---|---|---|
| fov | 相机视锥体竖直方向视野角度 | 50 |
| aspect | 相机视锥体水平方向和竖直方向长度比,一般设置为Canvas画布宽高比width / height | 1 |
| near | 相机视锥体近裁截面相对相机距离 | 0.1 |
| far | 相机视锥体远裁截面相对相机距离,far-near构成了视锥体高度方向 | 2000 |
4.3 渲染器
WebGL渲染器WebGLRenderer
// 创建渲染器对象
const renderer = new THREE.WebGLRenderer();
设置Canvas画布尺寸.setSize()
// 定义threejs输出画布的尺寸(单位:像素px)
const width = 800; //宽度
const height = 500; //高度
renderer.setSize(width, height); //设置three.js渲染区域的尺寸(像素px)
渲染器渲染方法.render()
渲染器WebGLRenderer执行渲染方法.render()就可以生成一个Canvas画布(照片),并把三维场景Scene呈现在canvas画布上面,你可以把.render()理解为相机的拍照动作“咔”。
renderer.render(scene, camera); //执行渲染操作
渲染器Canvas画布属性.domElement
渲染器WebGLRenderer通过属性.domElement可以获得渲染方法.render()生成的Canvas画布,.domElement本质上就是一个HTML元素:Canvas画布。
document.body.appendChild(renderer.domElement);
Canvas画布插入到任意HTML元素中
<div id="webgl" style="margin-top: 200px;margin-left: 100px;"></div>
document.getElementById('webgl').appendChild(renderer.domElement);
到目前为止代码展示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>3d学习</title>
</head>
<div id="webgl" style="margin-top: 200px;margin-left: 100px;"></div>
<body>
</body>
<script src="./js/three.min.js"></script>
<script>
// 创建3D场景对象Scene
const scene = new THREE.Scene();
const geometry = new THREE.BoxGeometry(100, 100, 100);
const material = new THREE.MeshBasicMaterial({
color: 0xff0,//0xff0000设置材质颜色为红色
});
const mesh = new THREE.Mesh(geometry, material);
mesh.position.set(0, 10, 0)
scene.add(mesh);
const width = 800; //宽度
const height = 500; //高度
// 30:视场角度, width / height:Canvas画布宽高比, 1:近裁截面, 3000:远裁截面
const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);
camera.position.set(200, 200, 200)
camera.lookAt(0, 10, 0)
// width和height用来设置Three.js输出的Canvas画布尺寸(像素px)
const renderer = new THREE.WebGLRenderer();
renderer.setSize(width,height);
renderer.render(scene,camera)
document.getElementById('webgl').appendChild(renderer.domElement);
</script>
</html>
5.三维坐标系
辅助观察坐标系
THREE.AxesHelper()的参数表示坐标系坐标轴线段尺寸大小,你可以根据需要改变尺寸。
// AxesHelper:辅助观察的坐标系
const axesHelper = new THREE.AxesHelper(150);
scene.add(axesHelper);
three.js坐标轴颜色红R、绿G、蓝B分别对应坐标系的x、y、z轴,对于three.js的3D坐标系默认y轴朝上
6.光源
基础材质MeshBasicMaterial不受光照影响,漫反射,高光,物理受光照影响
几种光源
| 环境光 | AmbientLight |
| 点光源 | PointLight |
| 聚光灯光源 | SpotLight |
| 平行光 | DirectionalLight |
实例化光源 (点光源为例)
//点光源:两个参数分别表示光源颜色和光照强度
// 参数1:0xffffff是纯白光,表示光源颜色
// 参数2:1.0,表示光照强度,可以根据需要调整
const pointLight = new THREE.PointLight(0xffffff, 1.0);
光源位置
你把点光源想象为一个电灯泡,你在3D空间中,放的位置不同,模型的渲染效果就不一样。
注意光源位置尺寸大小:如果你希望光源照在模型的外表面,那你就需要把光源放在模型的外面。
//点光源位置
pointLight.position.set(400, 0, 0);//点光源放在x轴上
改变光源位置,观察网格模型表面的明暗变化。
directionalLight.position.set(100, 60, 50);
光源添加到场景
光源和网格模型Mesh对应一样是三维场景的一部分,自然需要添加到三维场景中才能起作用。
scene.add(directionalLight); //点光源添加到场景中