初始3d

206 阅读5分钟

初始3d

1. 3d教程

3d.js官网

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

基本关系

img

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 / height1
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分别对应坐标系的xyz轴,对于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); //点光源添加到场景中