webGl之three.js学习笔记
Posted 人间随笔
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了webGl之three.js学习笔记相关的知识,希望对你有一定的参考价值。
WebGL three.js学习笔记以及加载外部模型
咱前虽然是做前端的,但是最近老板来需求,咱也只能硬着头皮往下做。
<script src="https://cdn.bootcdn.net/ajax/libs/three.js/r122/three.js"></script>
下面采用了es6的module语法,方便管理
首先是main.js文件
1
Scene
《场景(Scene)》
:它是一个树状结构,由很多对象组成,一个场景(Scene
)对象定义了场景图最基本的要素,并包了含背景色和雾等属性。这些对象通过一个层级关系明确的树状结构来展示出各自的位置和方向。子对象的位置和方向总是相对于父对象而言的。比如说汽车的轮子是汽车的子对象,这样移动和定位汽车时就会自动移动轮子。
2
Camera
《摄像机(Camera)》
:在这之前我们先了解一下THREE.js中使用的坐标系,THREE.js使用的的是右手坐标系,想象一下右手握空心拳,手指完全的方向就是从x轴到y轴的方向,而z轴则垂直于手指弯曲的方向从 拳头中心穿过。相机就相当于视点,相机决定了场景中那个角度的景色会显示出来 ,就是我们所看到的,人站在不同位置,抬头或者低头都能够看到不同的景色 ,默认的照相机与加载进来的模型都处于坐标原点,为了能够看到模型,需要将照相机位置偏移。相机分正交相机(OrthographicCamera)、透视相机(PerspectiveCamera)等,其区别后面再说。这里使用正交相机(OrthographicCamera)
3
render
《渲染器》
可以与canvas元素进行绑定,
var renderer = new THREE.WebGLRenderer({
canvas: document.getElementById('viewer')
});
也可以动态添加:
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth,window.innerHeight);
document.body.appendChild(renderer.domElement);
4
LIGHT
《光源》
在3D的应用当中, 光源Light是相当普遍的运用, 如果该3D场景Scene沒有光源, 通常会是黑漆漆的一片, 看不到东西
这里主要做一下开始配置,创建场景,相机及渲染器
export default function (callback) {
// 场景
var scene = new THREE.Scene();
// 创建相机Camera
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 2000);
camera.position.set(0, 0, 900);
// 添加一个全局光源
var ambient = new THREE.AmbientLight(0xffffff);
scene.add(ambient);
// 创建渲染器Renderer
var renderer = new THREE.WebGLRenderer({
antialias: true, // 是否执行抗锯齿
}); // 创建渲染器
renderer.setSize(window.innerWidth, window.innerHeight); // 设置画布大小
renderer.setClearColor('#3E3E3E', 1); // 设置默认背景色
document.body.appendChild(renderer.domElement); // 把画笔插入到dom中
callback(scene,render);//需要将物品添加入场景
// 渲染函数
function render() {
renderer.render(scene, camera);
}
// 创建视图控制器OrbitControls,鼠标控制
var controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.addEventListener('change', render);
controls.enablePan = true;//右键拖拽
}
然后新建文件planeBlack.js文件
添加两条隧道
export default function (scene) {//需要传入场景
const whd = {
width: 20,
height: 10,
deep: 1800
};
//PI属性就是π,还表示了弧度π = 180°,Math.PI = 3.14 = 180°
//将模型z轴旋转90度,三种写法都可以
const bottom = function (x, y, z) {
//黑色底盘
var geometry = new THREE.PlaneBufferGeometry(whd.deep, whd.width, whd.height);
var material = new THREE.MeshBasicMaterial({
color: '#000',
})
var plan = new THREE.Mesh(geometry, material);
var axis = new THREE.Vector3(x, y, z)//向量
var trans = new THREE.Vector3(0, 0, 0) //0.3); // 旋转向量
plan.translateOnAxis(axis, whd.width)//平移
plan.rotateOnAxis(trans, Math.PI / 4); //旋转45'
scene.add(plan)
}
bottom(0, 0, 0);//v1
bottom(0, 10, 0);//v2
const slider = (x, y, z, d = 2) => {
// 物体
var geometry = new THREE.PlaneBufferGeometry(whd.deep, whd.width, whd.height); // 创建一个长方体,用来定义物体的形状
var material = new THREE.MeshBasicMaterial({
color: '#339BA0',
transparent: true,
opacity: 0.5
});
var plan = new THREE.Mesh(geometry, material);
var axis = new THREE.Vector3(x, y, z); //平移向量
var trans = new THREE.Vector3(d, 0, 0); // 旋转向量
plan.translateOnAxis(axis, whd.width / 2); //沿平移
plan.rotateOnAxis(trans, Math.PI / 4); //旋转45'
scene.add(plan);
}
slider(0, -1, 1);//v1
slider(0, 1, 1);//v1
slider(0, 0, 2, 0); //v1
slider(0, 19, 1);//v2
slider(0, 21, 1);//v2
slider(0, 20, 2, 0); //v1
}
然后新建truckOBJ.js文件,导入obj格式的卡车模型。
var object;
//创建MTL加载器
var mtlLoader = new THREE.MTLLoader();
//设置文件路径
mtlLoader.setPath('./module/OBJ/');
function truck(scene, callback) {
//加载mtl文件
mtlLoader.load('Isuzu.mtl', function (material) {
//创建OBJ加载器
material.preload();
var objLoader = new THREE.OBJLoader();
//设置当前加载的纹理
objLoader.setMaterials(material);
objLoader.load("./module/OBJ/Isuzu.obj", function (object) {
//设置模型缩放比例
object.scale.set(8, 8, 8);
//设置模型的坐标
object.position.set(850, 0, 0);
//PI属性就是π,还表示了弧度π = 180°,Math.PI = 3.14 = 180°
var Y90 = -Math.PI * 0.5;
var X90 = Math.PI * 0.5;
object.rotation.set(X90, Y90, 0);//选装角度
// var material = new THREE.MeshBasicMaterial({ color: '#fff' });//暂时变成白色的
// object.children.forEach(function (child) {
// child.material = material;
// child.geometry.computeFaceNormals();
// child.geometry.computeVertexNormals();
// });
callback(object);
scene.add(object);
});
});
}
export { truck };
最后,在index.html中使用
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>
Document
</title>
</meta>
</meta>
</head>
<style>
html,
body {
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
<body>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/17.1.1/Tween.min.js"></script>
<script src="./three.js-dev/build/three.js"></script>
<script src="./three.js-dev/examples/js/controls/OrbitControls.js"></script>
<script src="./three.js-dev/examples/js/loaders/DDSLoader.js"></script>
<script src="./three.js-dev/examples/js/loaders/OBJLoader.js"></script>
<script src="./three.js-dev/examples/js/loaders/MTLLoader.js"></script>
<script type="module">
import main from './main.js';
import planeBlack from './module/planeBlack.js';
import { truck } from './module/truckOBJ.js';
main((scene, render) => {
planeBlack(scene);//管道
truck(scene, (group) => {//模型
// 动画
function animate() {
if (group.position.x <= -850) {
group.position.x = 850
}
group.position.x -= 1;
render();
requestAnimationFrame(animate);
}
animate();
});
});
</script>
</html>
以上是关于webGl之three.js学习笔记的主要内容,如果未能解决你的问题,请参考以下文章
通过three.js源码学习计算机图形学/webgl系列之camerarendererscene