赞
踩
你将它理解成three + js就可以了
three表示3D的意思
js表示javascript的意思
three.js就是使用javascript 来写3D程序的意思
先去下载代码,它的地址是: https://github.com/mrdoob/three.js
可以用script引用
<script src="https://wow.techbrood.com/libs/three.r73.js"></script>
在Three.js中要渲染物体到网页中我们需要3个组件
场景是所有物体的容器,如果要显示一个苹果,就需要将苹果对象加入场景中
let scene = new THREE.Scene();
另一个组建是相机,相机决定了场景中那个角度的景色会显示出来。相机就像人的眼睛一样,人站在不同位置,抬头或者低头都能够看到不同的景色。
场景只有一种,但是相机却有很多种
只要设置不同的相机参数,就能够让相机产生不一样的效果
透视相机这里使用的是透视相机
let camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000)
设置不同的相机需要不同的参数
会出现不同的效果
渲染器决定了渲染的结果应该画在页面的什么元素上面
并且以怎样的方式来绘制
let renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
//挂载到页面
document.body.appendChild(renderer.domElement)
添加物体
let geometry = new THREE.CubeGeometry(1, 1, 1);
//width:立方体x轴的长度,height:立方体y轴的长度,depth:立方体z轴的长度也是深度
渲染物体
renderer.render(scene, camera)
//scene:前面定义的场景,camera:前面定义的相机
//renderTarget:渲染的目标默认是是渲染到前面定义的render变量中
//forceClear:每次绘制之前都将画布的内容给清除,即使自动清除标志autoClear为false,也会清除
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
: 圆//创建圆形 CircleGeometry: 半径 分段 第一个分段的起始角度 旋转角度/弧度
//分段越多越像圆
const geometry = new THREE.CircleGeometry(3,30,Math.PI * 2)
THREE.CylinderGeometry
: 圆柱//创建圆柱 CylinderGeometry : 顶部半径 底部半径 高
const geometry = new THREE.CylinderGeometry(2,2,5);
THREE.ConeGeometry
: 圆锥//圆锥 ConeGeometry : 底面半径 高
const geometry = new THREE.ConeGeometry(2,5);
THREE.DodecahedronGeometry
:十二面几何体(球)//十二面几何体 DodecahedronGeometry :半径 第二个参数越大越接近球
const geometry = new THREE.DodecahedronGeometry(2,2);
PlaneGeometry
平面几何体 (重要)生成底面//平面几何体 生成底面 PlaneGeometry : 宽 高 宽分段 高分段
const geometry = new THREE.PlaneGeometry(10,10,30,30);
RingGeometry
平面圆环几何体//圆环几何体 RingGeometry : 内部半径 外部半径 圆的分段数越大越圆 圆环表面的分段数
const geometry = new THREE.RingGeometry(2,5,20,8);
TorusGeometry
:圆环几何体//圆环几何体 TorusGeometry : 圆环的半径 管道的半径 圆环的分段 管道的分段越多越圆
const geometry = new THREE.TorusGeometry( 4,1,10,20 );
案例演示: 常见的几何体
AxesHelper
//建立一个简单的坐标系 坐标系的长度
const axesHelper = new THREE.AxesHelper(5);
scene.add( axesHelper );
描述一个点 THREE.Vector3()
描述一个面 THREE.Faces()
//生成Geometry的实例
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')));//参数 前三个是根据多少值 旋转 对应 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)
//生成Geometry的实例
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})
//wireframe 显示线条
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);
可以载入纹理
MeshLambertMaterial
一种非光泽表面的材质,没有镜面高光。
new THREE.MeshLambertMaterial({map:texture})
//flatShading 每一个面接受光照
new THREE.MeshLambertMaterial({map:texture,flatShading:true})
MeshPhongMaterial
具有镜面高光的光泽表面的材质
new THREE.MeshPhongMaterial({flatShading:true,envMap:scene.background})
//envMap 环境贴图
MeshToonMaterial
new THREE.MeshToonMaterial({map:texture,side:THREE.DoubleSide})
案例演示: 材质
纹理 : 本质是一张图片或者Canvas
,或视频
材质: 包含了贴图的纹理 ,相当于实际物体的质感, 物体在场景中的表现
需要引入贴图 , 加载纹理贴图到物体表面, 或者是作为镜面反射或折射的贴图
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
固定光源
//十六进制光照颜色 光照强度 从光源到光照强度为0的位置
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);
//旋转90度
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()//获取加载器的实例方法 //path/to/sourse 资源的加载地址 loader.load("path/to/sourse",res=>{ //res 是加载的资源 //res.scene是模型的场景 scene.add(res.scene) //res的材质十多个面 //数组遍历每一个面设置不同的反光效果 //res.scene.traverse 相当于 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
动画效果
//需要一个pmd后缀文件和vmd后缀文件 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//鼠标移动速度 默认值 0.001
control.movementSpeed = 10//移动速度 默认值 1
//在动画里渲染 需要传入一个时间的参数
const clock = new THREE.Clock()
control.update(clock.getDelta());
PointerLockControls
3D游戏的最佳选择
let control = new PointerLockControls(camera,renderer.domElement);
//需要锁定指针
canvas.addEventListener("click",()=>{
control.lock()
})
//监听lock事件
controls.addEventListener( 'lock', ()=> {
//锁定指针
} );
controls.addEventListener( 'unlock', ()=> {
//没有锁定指针
} );
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。