threeJs 入门篇
·
1.什么是threeJs
- 简单的说 ,就是一门 绘制 3D 的 javaScript 轻量级框架;
- 主要采用 ,HTML5 Canvas提供硬件3D加速渲染;
- 于是web 端 ,就能制作出 3D 系统 ,访问就能操作 ,十分方便。
文章目录
Ⅰ.为什么要学这门前沿技术
-
threeJs 是前端3D框架中最突出的一个;
-
优点:WebGL 前端工程师的工资,相比较于做vue,react 项目开发的工资普遍要高的多,竞争较少;
-
缺点:threeJs资源匮乏, 文档粗糙 ,three要有一定的数学基础.
Ⅱ.应用场景
- 引用场景十分之多,未来会更多。
- 游戏,地图,智能工厂,智慧园区,360°模型 ,建筑家装,3d物联网 …
- 应用场景是十分之多, 目前 threeJs 学习的人并不多 , 所以threeJs 的工资普遍较高。
2. 学习Three .js 入门篇 (一)
下面 以下例子 入门第一篇 :
Ⅰ.安装下载
- 官方包比较大,建议单独下载该文件(存在大量实例) => https://github.com/mrdoob/three.js/blob/dev/build/three.js
- 初始化准备 ↓
<script src="./build/three.js"></script>
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
<body>
<div id="threeBox"></div>
</body>
<script>
function init() { /* 页面加载完成开始渲染Three内容 */}
window.onload = init;
</script>
- 通过 window.onload 页面加载完成,开始操作 three 实例、
Ⅱ. 创建场景、摄像机、渲染器(画布)
- 场景(scene) :用于把创建完成的模型 添加到 画布中。
- 摄像机 (camera): 相当于人眼所在的位置 ;
- 渲染器(renderer):相当于canvas 画布元素。
- 创建三个元素 ,然后把画布 插入到html 元素中 ↓
function init() {
// 创建场景
let scene = new THREE.Scene();
// 创建摄像机
let camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 2000); // (角度 , 长款比 , 最近看到的距离, 最远)
camera.position.x = -30;
camera.position.y = 40;
camera.position.z = 30;
camera.lookAt(scene.position); //将相机指向场景
//创建渲染器 (画布)
let renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0xeeeeee); //canvas画布颜色
renderer.setSize(window.innerWidth, window.innerHeight); //canvas 画布大小
// 将这个canvas元素插入到 html中
document.getElementById('threeBox').appendChild(renderer.domElement);
renderer.render(scene, camera);
}
window.onload = init;
- 之后我们可以看到一个灰色的画布
Ⅲ. 创建坐标系
- 以便更好的确定其他元素的位置
- 用scene.add 去添加元素到画布;
- 必须在appendChild 插入前 ↓
let axes = new THREE.AxesHelper(30); //坐标系的长度
scene.add(axes); //坐标系添加到场景中
Ⅳ.平面、立方体、球 的创建
- 平面的创建,需要大小(PlaneGeometry)和材质(MeshStandardMaterial) 两个对象;
- 然后用 THREE.Mesh 去创建模型 (包括后面的 球 和 立方体)
- 同样模型,创建完成后 scene.add 添加到画布中
let planeGeometry = new THREE.PlaneGeometry(60, 20); // 创建地面的大小
let planeMaterial = new THREE.MeshStandardMaterial({ color: 0x999999 }); //地面的材质
let plane = new THREE.Mesh(planeGeometry, planeMaterial); // 创建地面
plane.rotation.x = -0.5 * Math.PI; // 旋转角度
plane.position.x = 15; // 设置地面 xyz 轴的位置
plane.position.y = 0;
plane.position.z = 0;
scene.add(plane); // 将地面添加到坐标轴中
- 立方体的创建 (同理)
let cubeGeometry = new THREE.BoxGeometry(4, 4, 4); //长宽高
let cubeMaterial = new THREE.MeshLambertMaterial({ color: 0xff0000 }); //材质颜色
let cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.x = 3; //三轴的位置
cube.position.y = 8;
cube.position.z = 3;
scene.add(cube);
- 球的创建 ( 同理 )
let sphereGeometry = new THREE.SphereGeometry(2,20,20); //半径,圆滑程度
let sphereMaterial = new THREE.MeshLambertMaterial({ color: 'blue' }); //材质颜色
let sphere = new THREE.Mesh(sphereGeometry,sphereMaterial);
sphere.position.x = 24; //三轴的位置
sphere.position.y = 4;
sphere.position.z = 4;
scene.add(sphere);
- 此时我们可以看到,地面,立方体,和球,都没有颜色 , 说明我们没有光源 ,下面我们要添加光源。
Ⅴ. 光源的创建
- 创建灯光的类型,和颜色;
- 设置光源的位置;
- 设置光源,投影的长度;
- 同理用 scene.add 去添加到 canvas画布。
// 添加聚光灯
let point = new THREE.SpotLight(0xffffff); //设置灯光的颜色
point.position.set(80, 100, 80); //点光源位置
point.angle = Math.PI/10; //设置投影的程度
point.shadow.mapSize.set(1024,1024);
scene.add(point)
- 我们发现此时 并没有投影。
Ⅵ.添加投影
- 要投影的元素设置 castShadow 设置为 true;
- 被投影的元素设置 receiveShadow 设置为 true;
- 同理添加到 appendChild 插入前;
- 该场景 地面为要投影的位置,球和立方体为被投影物体 ↓
plane.receiveShadow = true; //地面被投影
sphere.castShadow = true; //球投影
cube.castShadow = true; //立方体投影
point.castShadow = true; //灯光投影
renderer.shadowMap.enabled=true; //让渲染器支持投影
- 低版本threeJs 让渲染器支持投影 => renderer.shadowMapEnabled = true
- 最后就差 鼠标的拖到旋转,和滚轮的缩放
Ⅶ.鼠标操控三维场景
- 鼠标操控三维场景 需要再添加一个threeJs 的三方插件
下载地址: https://github.com/mrdoob/three.js/blob/dev/examples/js/controls/OrbitControls.js
- 在appendChild 插入后 添加
- 监听鼠标的事件 ,一但发生 重新调用 rander() 方法
<script type="text/javascript" src="../threeJs/three.js"></script>
<script src="../threeJs/OrbitControls.js"></script>
...
<script>
function init() {
// ... 在appendChlid 后面添加
let controls = new THREE.OrbitControls(camera,renderer.domElement);
controls.addEventListener('change',()=>{
renderer.render(scene, camera);
});
}
window.onload = init;
</script>
- 然后就属性这个小案例了
3. 整合代码
- 这个threeJs 包太大,包括许多案例,建议直接下载这两个文件。
threeJs => https://github.com/mrdoob/three.js/blob/dev/build/three.js
OrbitControls.js => https://github.com/mrdoob/three.js/blob/dev/examples/js/controls/OrbitControls.js
<!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>Document</title>
</head>
<script src="../threeJs/three.js"></script>
<script src="../threeJs/OrbitControls.js"></script>
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
<body>
<div id="threeBox"></div>
<script>
function init() {
// 创建场景
let scene = new THREE.Scene();
// 创建摄像机
let camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 2000);
//定位相机
camera.position.x = -30;
camera.position.y = 40;
camera.position.z = 30;
camera.lookAt(scene.position); //将相机指向场景
//创建渲染器 (画布)
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0xeeeeee); //渲染初始颜色
renderer.setSize(window.innerWidth, window.innerHeight); //canvas 画面大小
//渲染设置 3d 投影
renderer.shadowMap.enabled=true;
//显示三维坐标
let axes = new THREE.AxesHelper(20); //坐标系的长度
scene.add(axes); //坐标系添加到场景中
// 创建地面的大小
let planeGeometry = new THREE.PlaneGeometry(60, 20); //地面的宽高
//地面上色
let planeMaterial = new THREE.MeshStandardMaterial({ color: 0x999999 });
// 创建地面
let plane = new THREE.Mesh(planeGeometry, planeMaterial);
// 设置地面的位置
plane.rotation.x = -0.5 * Math.PI;
plane.position.x = 15;
plane.position.y = 0;
plane.position.z = 0;
// //将地面添加到坐标轴中
scene.add(plane);
plane.receiveShadow = true;
// //添加正方形
let cubeGeometry = new THREE.BoxGeometry(4, 4, 4);
let cubeMaterial = new THREE.MeshLambertMaterial({ color: 0xff0000 });
let cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.x = 3;
cube.position.y = 8;
cube.position.z = 3;
scene.add(cube);
cube.castShadow = true;
//添加球
let sphereGeometry = new THREE.SphereGeometry(2,20,20);
let sphereMaterial = new THREE.MeshLambertMaterial({ color: 'blue' });
let sphere = new THREE.Mesh(sphereGeometry,sphereMaterial);
sphere.position.x = 24;
sphere.position.y = 4;
sphere.position.z = 4;
sphere.castShadow = true;
scene.add(sphere);
// 添加聚光灯
var point = new THREE.SpotLight(0xffffff);
point.position.set(80, 100, 80); //点光源位置
// 通过add方法插入场景中,不插入的话,渲染的时候不会获取光源的信息进行光照计算
point.angle = Math.PI/10;
point.shadow.mapSize.set(1024,1024)
scene.add(point)
point.castShadow = true;
document.getElementById('threeBox').appendChild(renderer.domElement);
renderer.render(scene, camera);
let controls = new THREE.OrbitControls(camera,renderer.domElement);
controls.addEventListener('change',()=>{
renderer.render(scene, camera);
});
}
window.onload = init;
</script>
</body>
</html>
更多推荐
已为社区贡献4条内容
所有评论(0)