1.安装three.js
npm install three --save
2.导入three以及项目所需要的模块
import * as THREE from “three/build/three.module.js”;
import Stats from “three/examples/jsm/libs/stats.module.js”;
import { OrbitControls } from “three/examples/jsm/controls/OrbitControls.js”;
import { FBXLoader } from “three/examples/jsm/loaders/FBXLoader.js”;
知识点:
OrbitControls:通过Three.js的相机控件OrbitControls.js可以对Threejs的三维场景进行缩放、平移、旋转操作。
stats:两张图片分别表示当前场景的渲染帧率和显存占用情况;要使用该功能,必须包含如下源文件:stats.js或stats.min.js;
用法如下:
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
document.body.appendChild(_stats.domElement);
在渲染函数中,需要添加如下代码:
stats.update();
循环渲染代码如下:
function Animate()
{
requestAnimationFrame(Animate);
Render();
}
function Render()
{
stats.update();
render.render(scene,camera);
}
材料(Materials)
光照(Lights)
- 环境光(AmbientLight)所有角度看到的亮度一样,通常用来为整个场景指定一个基础亮度,没有明确光源位置
- 平行光(DirectionalLight)亮度与光源和物体之间的距离无关,只与平行光的角度和物体所在平面有关
- 平行光阴影(DirectionalLightShadow)
- 半球光源(HemisphereLight)
- 光照(Light)
- 光照阴影(LightShadow)
- 点光源(PointLight)一个点发出的光源,照到不同物体表面的亮度线性递减
- 聚光光源(SpotLight)投射出的是类似圆锥形的光线
- 聚光阴影(SpotLightShadow)
常见的Loader:
- 音频加载器(AudioLoader)
- 巴比伦加载器(BabylonLoader)
- 缓存几何模型加载器(BufferGeometryLoader)
- 缓存(Cache)
- Collada加载器(ColladaLoader)
- GLTF加载器(glTFLoader)
- 图像加载器(ImageLoader)
- JSON加载器(JSONLoader)
- 加载器(Loader)
- 加载管理器(LoadingManager)
- 材料加载器(MaterialLoader)
- MTL加载器(MTLLoader)
- OBJ加载器(OBJLoader)
- 对象加载器(ObjectLoader)
- PDB加载器(PDBLoader)
- SVG加载器(SVGLoader)
- 纹理加载器(TextureLoader)
- TGA加载器(TGALoader)
- XHR加载器(XHRLoader)
3.创建场景、照相机、以及灯光
container = document.createElement("div");
height = document.getElementsByClassName("main-bim")[0].clientHeight;
document.getElementById("threeView").appendChild(container);
camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / height,
1,
20000
);
camera.position.set(1000, 800, 0);
scene = new THREE.Scene();
scene.background = new THREE.Color(0x151c29);
light = new THREE.HemisphereLight(0xffffff, 0x151c29);
light.position.set(0, 200, 0);
scene.add(light);
light = new THREE.DirectionalLight(0x151c29);
light.position.set(0, 200, 100);
scene.add(light);
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, 710);
renderer.shadowMap.enabled = true;
container.appendChild(renderer.domElement);
controls = new OrbitControls(camera, renderer.domElement);
controls.target.set(80, 0, 0);
controls.update();
stats = new Stats();
stats.dom.style.display = "none";
container.appendChild(stats.dom);
4.加载FBX格式模型
loader.load("fbx/喷涂机器人换电池分解.fbx", function(object) {
actions = [];
object.scale.set(2, 2, 2);
object.position.set(290, 0, 430);
object.name = "充电站机器人换电池";
object.visible = false;
mixer = new THREE.AnimationMixer(object);
object.animations.map(function(item, index) {
let obj = mixer.clipAction(object.animations[index]);
obj.setLoop(0, 0);
obj.setDuration(7);
obj.clampWhenFinished = true;
actions.push(obj);
});
scene.add(object);
});
FBX动画执行
index里面含有多个动画的每一个索引值
actions[index].stop();//暂停动画
actions[index].reset();//重置动画为初始状态
actions[index].play();//执行动画
加载JSON文件
现在的JSON格式有两个类型:
一个是Geometry类型,需要JSONLoader加载;
一个是Object类型,需要ObjectLoader加载。
加载json格式数据
var js_loader = new THREE.JSONLoader(manager);
js_loader.load('./models/hmj/frame001.json', function(geometry, materials) {
var material = new THREE.MultiMaterial(materials); // 多个纹理
var mesh = new THREE.Mesh(geometry, material);
mesh.scale.multiplyScalar(.06);
scene.add(mesh);
}, onProgress, onError);
var js_loader = new THREE.JSONLoader(manager);
json格式动画
var js_loader = new THREE.JSONLoader(manager);
js_loader.load('./models/body/climb.js', function(geometry, materials) {
for(var i = 0; i < materials.length; i++) {
materials[i].skinning = true;
}
var material = new THREE.MultiMaterial(materials);
var mesh = new THREE.SkinnedMesh(geometry, material); // 划重点啊!!!
var mixer = new THREE.AnimationMixer(mesh);
mixer.clipAction(geometry.animations[0]).play();
mixers.push(mixer);
mesh.scale.multiplyScalar(.05);
mesh.lookAt(new THREE.Vector3(0, 0, 0));
scene.add(mesh);
}, onProgress, onError);
加载object格式数据
var object_loader = new THREE.ObjectLoader(manager);
object_loader.load('./models/teapot-claraio.json', function(object) {
object.scale.multiplyScalar(5);
scene.add(object);
});
下面给出两种数据类型的区别:
Geometry类型
Object类型
纹理加载
obj格式文件不支持动画数据存储,只用于静态模型。
首先需要引入OBJLoader.js插件,如果纹理贴图是tga或dds格式的,
则还需要另外引入TGALoader.js或DDSLoader.js(纹理贴图问题同样适用于其他模型格式)。
var obj_loader = new THREE.OBJLoader(manager);
obj_loader.setPath('./models/mooncake/'); // 设置文件路径
var tga_loader = new THREE.TGALoader();
var material = new THREE.MeshPhongMaterial({
map: tga_loader.load('./models/mooncake/Diffuse.tga'),设置颜色纹理贴图
normalMap: tga_loader.load('./models/mooncake/Normal.tga'),
specularMap: tga_loader.load('./models/mooncake/S.tga'),
bumpMap: tga_loader.load('./models/mooncake/Bump.tga')
});
存在多个纹理材质,具体参数Phong网孔材料(MeshPhongMaterial)
obj_loader.load('mooncake.obj', function(group) {
var geometry = group.children[0].geometry;
geometry.attributes.uv2 = geometry.attributes.uv;
geometry.center();
var mesh = new THREE.Mesh(geometry, material);
mesh.scale.multiplyScalar(.1);
scene.add(mesh);
}, onProgress, onError);
obj+mtl(obj静态模型 - 外部载入纹理)
需要额外引用MTLLoader.js文件
var mtl_loader = new THREE.MTLLoader();
mtl_loader.setPath('./models/mooncake/');
mtl_loader.load('mooncake.mtl', function(materials) {
materials.preload();
obj_loader.setMaterials(materials);
obj_loader.load('mooncake.obj', function(object) {
object.scale.multiplyScalar(.1);
scene.add(object);
}, onProgress, onError);
});