先去下载代码,它的地址是:
github.com/mrdoob/thre…
可以用script引用
<script src="https://wow.techbrood.com/libs/three.r73.js"></script>
在Three.js中要渲染物体到网页中我们需要3个组件
场景scene
场景是所有物体的容器,如果要显示一个苹果,就需要将苹果对象加入场景中
let scene = new THREE.Scene();
相机camera
另一个组建是相机,相机决定了场景中那个角度的景色会显示出来。相机就像人的眼睛一样,人站在不同位置,抬头或者低头都能够看到不同的景色。
场景只有一种,但是相机却有很多种
只要设置不同的相机参数,就能够让相机产生不一样的效果
透视相机这里使用的是透视相机
let camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000)
设置不同的相机需要不同的参数
会出现不同的效果
渲染器renderer
渲染器决定了渲染的结果应该画在页面的什么元素上面
并且以怎样的方式来绘制
let renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement)
let geometry = new THREE.CubeGeometry(1, 1, 1);
renderer.render(scene, camera)
function render() {
cube.rotation.x += 0.1
cube.rotation.y += 0.1
renderer.render(scene, camera)
requestAnimationFrame(render)
模型操作:
生成几何体 => 生成材质 => 混合生成模型
商城模型 => 添加到场景中
生成场景(配置参数...) => 模型导入场景
生成相机 = > 添加控制器(控制相机)
渲染器操作
生成渲染器 => 场景和相机添加到渲染器中 => 建立和canvas
关联
更新模块(动画模块)
动画的连续 ,相机 ,场景的更新控制
案例演示 :创建一个简单的立方体
three.js
里面的颜色是 new THREE.Color()
简单的控制相机
const camera = new THREE.PerspectiveCamera(75, width / height, 0.01, 1000);
camera.position.z = 6;camera.lookAt(0, 0, 0);
const control = new THREE.OrbitControls(camera);
创建好后在动画渲染里面更新控制器
control.update();
案例演示 点击拖动: 简单的控制相机
常见的几何体 Geometry
生成一个辅助网格体
就是带有辅助线的立方体
THREE.WireframeGeometry
THREE.BoxGeometry
: 立体矩形
构造函数: 前面三个参数(x, y, z)默认1
后面还有三个参数(每个面的分段)
THREE.CircleGeometry
: 圆
const geometry = new THREE.CircleGeometry(3,30,Math.PI * 2)
THREE.CylinderGeometry
: 圆柱
const geometry = new THREE.CylinderGeometry(2,2,5);
THREE.ConeGeometry
: 圆锥
const geometry = new THREE.ConeGeometry(2,5);
THREE.DodecahedronGeometry
:十二面几何体(球)
const geometry = new THREE.DodecahedronGeometry(2,2);
PlaneGeometry
平面几何体 (重要)生成底面
const geometry = new THREE.PlaneGeometry(10,10,30,30);
RingGeometry
平面圆环几何体
const geometry = new THREE.RingGeometry(2,5,20,8);
TorusGeometry
:圆环几何体
const geometry = new THREE.TorusGeometry( 4,1,10,20 );
案例演示: 常见的几何体
自定义几何体
必须要有端点(定义制作)
必须要有面(三点形成一个面 手动添加面的关联)
建立一个坐标系 AxesHelper
const axesHelper = new THREE.AxesHelper(5);
scene.add( axesHelper );
创建自定义
描述一个点 THREE.Vector3()
描述一个面 THREE.Faces()
const geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(1,0,0));
geometry.vertices.push(new THREE.Vector3(0,1,0));
geometry.vertices.push(new THREE.Vector3(0,0,1));
geometry.faces.push(new THREE.Face3(0,1,2, normal, color));
创建点可以写坐标 也可以写极坐标
Vector3().applyEuler
参数里面要生成一个欧拉角 Euler
geometry.vertices.push(new THREE.Vector3(5,0,0).applyEuler(new THREE.Euler(0,0,1,'XYZ')));
案例演示: 自定义几何体
几何体组合
Object3D
实例对象内部可以存放多个mesh ,每个mesh都是独立控制的
THREE.Object3D
let obj = new THREE.Object3D();
obj.add(mesh1);
obj.add(mesh2);
scene.add(obj);
案例演示 :小案例
LineBasicMaterial()
基础线条
/生成Geometry的实例
const geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(1,1,1));
geometry.vertices.push(new THREE.Vector3(3,3,3));
const material = new THREE.LineBasicMaterial();
new THREE.Line(geometry,material)
线条渐变色
const geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(1,1,1));
geometry.vertices.push(new THREE.Vector3(3,3,3));
geometry.vertices.push(new THREE.Vector3(5,3,2));
geometry.colors.push(
new THREE.Color(0xff0000),
new THREE.Color(0x0000ff)
const material = new THREE.LineBasicMaterial({ vertexColors:true});
new THREE.Line(geometry,material)
案例演示: 线的绘画
法线网格材质(初学) MeshNormalMaterial
物体内部有光
const material = new THREE.MeshNormalMaterial({
side:THREE.DoubleSide
基础网格材质 MeshBasicMaterial
一个以简单着色(平面或线框)方式来绘制几何体的材质。
基础材质可以进行贴图
new THREE.MeshNormalMaterial({side:THREE.DoubleSide})
const material = new THREE.MeshNormalMaterial({
side:THREE.DoubleSide,
wireframe:true
const geometry = new THREE.BoxGeometry( 2, 2, 2, 2, 2, 2);
const mesh = new THREE.Mesh( geometry, material );
mesh.position.x = index * 3 - meshList.length;
scene.add(mesh);
可以载入纹理
Lambert网格材质MeshLambertMaterial
一种非光泽表面的材质,没有镜面高光。
new THREE.MeshLambertMaterial({map:texture})
new THREE.MeshLambertMaterial({map:texture,flatShading:true})
Phong网格材质 MeshPhongMaterial
具有镜面高光的光泽表面的材质
new THREE.MeshPhongMaterial({flatShading:true,envMap:scene.background})
卡通网格材质 MeshToonMaterial
new THREE.MeshToonMaterial({map:texture,side:THREE.DoubleSide})
案例演示: 材质
纹理和材质
纹理 : 本质是一张图片或者Canvas
,或视频
材质: 包含了贴图的纹理 ,相当于实际物体的质感, 物体在场景中的表现
纹理(texture)
需要引入贴图 , 加载纹理贴图到物体表面, 或者是作为镜面反射或折射的贴图
简单的纹理引入 : TextureLoader
const loader = new THREE.TextureLoader();
const texture = loader.load("图片地址");
const material = new THREE.MeshBasicMaterial({
map:texture,
side:THREE.DoubleSide
例如下面这个案例
案例演示 : 几何体的纹理
盒子世界纹理引入 CubeTextureLoader
const loader = new THREE.CubeTextureLoader();
scene.background = loader.setPath( '../lib/textures/cube/Park3Med/' )
.load( [
'px.jpg','nx.jpg',
'py.jpg','ny.jpg',
'pz.jpg','nz.jpg'
例如下面这个案例
案例演示 : 世界纹理
PerspectiveCamera
透视相机(近大远小)
const camera = new THREE.PerspectiveCamera(75, width / height, 0.01, 1000);
camera.position.z = 10;
camera.lookAt(0, 0, 0);
OrthographicCamera
正交相机
环境光 AmbientLight
没有一个固定光源的时候, 周围的物体会根据环境折射光线
不能投射阴影
const ambientLight = new THREE.AmbientLight( 0xffffff, 0.3 );
scene.add( ambientLight );
点光源 PointLight
const light2 = new THREE.PointLight( 0xffffff, 1, 1000 );
light2.position.set( 0, 8, 8 );
scene.add( light2 );
点光源辅助线THREE.PointLightHelper
平行光 DirectionalLight
const directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
scene.add( directionalLight );
DirectionalLightHelper
平行光的辅助线
半球光 HemisphereLight
模拟日出日落
不能投射阴影
const hemisphereLight = new THREE.HemisphereLight( 0xffffff, 0x000000, 1 );
scene.add( hemisphereLight );
聚光灯 SpotLight
const spotLight = new THREE.SpotLight( 0xffffff );
spotLight.position.set( 0, 10, 0 );
spotLight.angle = Math.PI/6;
scene.add( spotLight );
平面光光源 RectAreaLight
从一个矩形平面上均匀地发射光线
不支持阴影
const rectLight = new THREE.RectAreaLight( 0xffffff, 1, 10, 10 );
rectLight.position.set( 5, 5, 0 );
rectLight.lookAt( 0, 0, 0 );
scene.add( rectLight );
特殊的光源 比如 点光源 聚光灯
必须有 产生阴影的物体
必须要有 显示(接收)阴影的物体
灯光照射产生阴影
const spotLight = new THREE.SpotLight( 0xffffff );
spotLight.position.set( 0, 10, 0 );
spotLight.angle = Math.PI/6;
this.spot.castShadow = true;
scene.add( spotLight );
物体要产生阴影
const geometry =new THREE.BoxGeometry(3, 3, 3);
const material = new THREE.MeshLambertMaterial({
color:new THREE.Color(0xffffff),
side:THREE.DoubleSide,
map:new THREE.TextureLoader().load('图片地址')
const mesh = new THREE.Mesh(geometry,material);
scene.add(mesh);
mesh.castShadow = true;
底面接收阴影
const geometry = new THREE.PlaneGeometry(100,100,10,10);
const material = new THREE.MeshPhongMaterial({
color: 0xeeeeee,
side: THREE.DoubleSide
const mesh = new THREE.Mesh(geometry,material);
mesh.rotateX(- Math.PI / 2);
mesh.position.set(0, -5 ,0);
scene.add(mesh);
mesh.receiveShadow = true;
产生阴影要开启阴影模式
renderer.shadowMap.enabled = true;
加载方式是一个异步加载: 使用回调函数添加到场景当中
GLTFLoader
加载器
const loader = new THREE.GLTFLoader()
loader.load("path/to/sourse",res=>{
scene.add(res.scene)
res.scene.traverse(mesh=>{
if (mesh.isMesh){
mesh.material.side = THREE.BackSide
mesh.material.envMap = scene.background;
MMDLoader
加载器
const loader = new THREE.MMDLoader();
loader.load('pmd后缀的文件',mesh=>{
mesh.position.set(0,-10,0)
scene.add(mesh);
MMD
动画效果
需要引入AMMO
物理引擎
MMDAnimationHelper
动画效果
const helper = new THREE.MMDAnimationHelper();
const loader = new THREE.MMDLoader();
loader.loadWithAnimation(
'pmd后缀文件',
'vmd后缀文件',
mmd => {
helper.add(mmd.mesh, {
animation: mmd.animation,
physics: true
scene.add( mmd.mesh );
const clock = new THREE.Clock();
helper.update(clock.getDelta());
镜面效果Reflector
import {Reflector} from "three/examples/jsm/objects/Reflector";
const geometry = new THREE.PlaneGeometry(10,10);
const mirrorMesh = new Reflector(geometry,{
color:new THREE.Color(0x7f7f7f)
mirrorMesh.position.set(0,0,-5);
mirrorMesh.lookAt(0,0,0)
拖拽控制 OrbitControls
let control = new OrbitControls(camera,renderer.domElement);
control.enabled = true
control.update();
进阶拖拽控制器 TrackballControls
let control = new TrackballControls(camera,renderer.domElement);
control.noPan = true
control.noZoom = true
control.noRotate = true
control.rotateSpeed = 5
control.zoomSpeed = 5
control.panSpeed = 5
control.update();
飞行控制器 FlyControls
let control = new FlyControls(camera,renderer.domElement);
control.movementSpeed = 10;
control.rollSpeed = 3;
control.autoForward = true;
control.dragToLook = true;
const clock = new THREE.Clock()
control.update(clock.getDelta());
第一人称控制器FirstPersonControls
let control = new FirstPersonControls(camera,renderer.domElement);
control.lookSpeed = 0.15
control.movementSpeed = 10
const clock = new THREE.Clock()
control.update(clock.getDelta());
锁定鼠标控制器 PointerLockControls
3D游戏的最佳选择
let control = new PointerLockControls(camera,renderer.domElement);
canvas.addEventListener("click",()=>{
control.lock()
controls.addEventListener( 'lock', ()=> {
controls.addEventListener( 'unlock', ()=> {
复制代码