我的网站,欢迎大家来踩踩呀~
www.ricolo.cn
一、安装
npm install three --save
可以百度搜索npm threejs
可以看到例程。
<script>
import * as THREE from "three";
export default {
name: "Page",
data() {
return {
camera: null,
scene: null,
renderer: null,
light: null,
cube: null,
mesh: null,
width: null,
height: null,
};
},
methods: {
init() {
this.width = document.documentElement.clientWidth;
this.height = document.documentElement.clientHeight;
this.initCamera();
this.initScene();
this.initLight();
this.initObject();
//渲染
this.renderer = new THREE.WebGLRenderer({ antialias: true });
this.renderer.setClearColor(0x333333,1); // 背景(颜色,透明度)一定要是16位的颜色
this.renderer.setSize(this.width, this.height);
page.appendChild(this.renderer.domElement);
},
initCamera() {
this.camera = new THREE.PerspectiveCamera(
70,
this.width / this.height,
0.01,
10
);
this.camera.position.z = 1;
},
initScene() {
this.scene = new THREE.Scene();
},
initLight() {
this.light = new THREE.DirectionalLight(0xffffff, 1.0, 0);
this.light.position.set(100, 100, 200);
this.scene.add(this.light);
},
initObject() {
this.mesh = new THREE.Mesh(
new THREE.CubeGeometry(0.2, 0.2, 0.2),
new THREE.MeshLambertMaterial({ color: 0xeeff00 })
);
this.scene.add(this.mesh);
this.mesh.position.set(0, 0, 0);
},
animate: function () {
requestAnimationFrame(this.animate);
this.mesh.rotation.x += 0.01;
this.mesh.rotation.y += 0.02;
this.renderer.render(this.scene, this.camera);
},
},
mounted() {
this.init();
this.animate();
},
};
</script>
二、四大组件
1.相机
正交相机和透视相机(近大远小)
//透视相机,参数含义(可视角度,宽高比,近切面,远切面)
//视角越大,中间的物体越小,看到的场景越大
//PerspectiveCamera( fov, aspect, near, far )
var camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,20);//透视投影相机
//fov 可视角度 field of view
//正交投影相机
var camera = new THREE.OrthographicCamera(
-window.innerWidth /2,
window.innerWidth / 2,
window.innerHeight / 2,
-window.innerHeight /2, 10, 1000
);
//正交相机,参数含义(左边界,右边界,上边界,下边界,近切面,远切面)
http://www.hewebgl.com/article/getarticle/59
这些参数很想理解的话可以参考文章讲解
2.场景
var scene = new THREE.Scene()
- 光
环境光与方向光
环境光与位置无关
方向光与位置有关
//第一个参数 Hex:光的颜色 第二个参数 Intensity:光源的强度,默认是1.0,如果为0.5,则强度是一半,意思是颜色会淡一些
//第三个参数 Distance:光线的强度,从最大值衰减到0,需要的距离。 默认为0,表示光不衰减,如果非0,则表示从光源的位置到Distance的距离,光都在线性衰减。到离光源距离Distance时,光源强度为0.
light = new THREE.DirectionalLight(0xFF0000,1, 0);
// 位置不同,方向光作用于物体的面也不同,看到的物体各个面的颜色也不一样
light.position.set(0,0,1);//光源的向量,即光源的位置
scene.add(light);//追加光源到场景
3. 渲染场景
var render= new THREE.WebGLRenderer();
4. 几何体
- 线段
//声明一个几何体,几何体里面有一个vertices变量,可以用来存放点
let geometry = new THREE.Geometry();
let material = new THREE.LineBasicMaterial({color: 0xff0000,vertexColors: false});//材质
let p1 = new THREE.Vector3(0,10,0); //点
let p2 = new THREE.Vector3(0,100,0);
var color1 = new THREE.Color( 0x444444 ),
color2 = new THREE.Color( 0xFF0000 );
geometry.colors.push( color1, color2 ); // 顶点颜色
geometry.vertices.push(p1);
geometry.vertices.push(p2);
this.mesh = new THREE.Line(geometry,material,THREE.LineSegments);
//'Line' | 'LineLoop' | 'LineSegments'
this.scene.add(this.mesh);
this.mesh.position.set(0, 0, 0);
LineBasicMaterial( parameters )
Parameters是一个定义材质外观的对象,它包含多个属性来定义材质,属性是:
Color:线条的颜色,用16进制来表示,默认的颜色是白色。
Linewidth:线条的宽度,默认时候1个单位宽度。( WebGLRenderer是不支持线宽度的,所以如果要画线并设置宽度请用CanvasRenderer,它是用二维canvas画布模拟3D效果,所以能够设置宽度。)
Linecap:线条两端的外观,默认是圆角端点,当线条较粗的时候才看得出效果,如果线条很细,那么你几乎看不出效果了。
Linejoin:两个线条的连接点处的外观,默认是“round”,表示圆角。
VertexColors:定义线条材质是否使用顶点颜色,这是一个boolean值。意思是,线条各部分的颜色会根据顶点的颜色来进行插值。
Fog:定义材质的颜色是否受全局雾效的影响。
let axisHelper = new THREE.AxesHelper(40); //添加坐标系
this.scene.add(axisHelper);
5. 加载3D模型
无论用哪个方式,都要把资源放在静态目录下。
this.gltfLoader.load(
//public省略
"../../Bell_Tower.glb",
(gltf) => {
gltf.scene.position.set(8, 0, -5); //定位
gltf.scene.rotation.y = -0.5;
// 模型是否否需要阴影
gltf.scene.traverse((obj) => {
obj.castShadow = true;
obj.receiveShadow = true;
});
this.scene.add(gltf.scene);
}
);
插件工具
1. 性能检测工具stats.js
1.在vscode终端控制台使用npm install stats.js安装插件
2.引入node_modules/stats.js/build/stats.min.js文件
3.初始化
var stats = new Stats();
// 0: fps, 1: ms, 2: mb, 3+: custom
stats.showPanel(0);
// css样式
stats.domElement.style.position = "absolute";
stats.domElement.style.left = "0px";
stats.domElement.style.right = "0px";
document.getElementById("canvas-frame").appendChild(stats.domElement);
4.检测性能,在检测代码的前后加上stats.begin();
和stats.end();
两个方法
function animate() {
stats.begin();
// monitored code goes here
stats.end();
requestAnimationFrame( animate );
}
Tween.js动画库
https://github.com/tweenjs/tween.js/
1.安装方法:
(1)vscode终端控制台运行npm i @tweenjs/tween.js@^18
(2)const TWEEN = require('@tweenjs/tween.js')
2.使用new TWEEN.Tween(objs.rotation).to({y:360,z:360},10000).repeat(Infinity).start();来定义一个动画
objs为需要操作的属性,to(属性状态的最终值),10000为动画所需时间,Infinity为一直播放,可填入正正数表示动画
执行次数
3.在动画更新函数中调用TWEEN.update()
DAT.GUI工具
1.vscode终端控制台运行 npm install --save dat.gui
2.HTML界面引入脚本dat.gui/build/dat.gui.min.js
3.使用方法
var param;//使用param来控制相机的视角大小
function CreateGUI(){
var paramObj=function(){
this.fov=45;
}
param=new paramObj();
var gui=new dat.GUI;
gui.add(param,"fov",0,180).name("视角大小");
}
//在初始化的时候调用CreateGUI();函数来创建一个GUI
//在动画函数中调用ChangeFov();函数来改变相机的视角
//ChangeFov函数,将param的值赋给camera的fov(视角)参数,然后更新相机的矩阵
function ChangeFov(){
camera.fov=param.fov;
camera.updateProjectionMatrix();
}
OrbitControls控制
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
page.appendChild(this.renderer.domElement);
this.controls = new OrbitControls(this.camera, this.renderer.domElement);
参考:
http://www.webgl3d.cn/Three.js/