最近一直在看three.js的相关资料,官网的看了,基本上是对新手很不友好的。下面是我的一个练习。
光照+控制器+模型+材质等等知识都用了一下…
效果图
由于懒得拍成视频然后转GIF图,直接用静态图了。
下载项目相关
npm install three --save-dev
npm install three-trackballcontrols --save-dev
template
<template>
<div>
<diV id="myThree"></diV>
</div>
</template>
import
const THREE = require("three");//主要
const TrackballControls = require("three-trackballcontrols");//控制器
vue - data
domContainer: null, //容器
renderer: null, //渲染器
scene: null, //场景
camera: null, //相机
geometry: null, //模型
material: null, //材质
mesh: null, //网格
ambientLight: null, //全局光
directionalLight: null, //平行光
debug: null, //灯光辅助
control: null,
plane: null, //平面
texture: [//纹理图片数组
require("../../../../assets/img/wl/1.jpg"),
require("../../../../assets/img/wl/2.jpg"),
require("../../../../assets/img/wl/3.jpg"),
require("../../../../assets/img/wl/4.jpg"),
require("../../../../assets/img/wl/5.jpg")
],
/*模型信息*/
models: {
maxW: 100,
maxH: 100,
minW: 10,
minH: 10,
maxZCount: 6,
minZCount: 1
}
vue - methods
//初始化渲染器
initRenderer() {
let self = this;
self.renderer = new THREE.WebGLRenderer({ antialias: true }); //创建渲染器实例
self.renderer.setSize(
self.domContainer.offsetWidth,
self.domContainer.offsetHeight
); //设置渲染器宽高
self.renderer.shadowMap.enabled = true; //告诉渲染器需要阴影效果
self.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
self.domContainer.appendChild(self.renderer.domElement);
},
//初始化场景
initScene() {
this.scene = new THREE.Scene();
},
//初始化相机
initCamera() {
this.camera = new THREE.PerspectiveCamera(
45,
this.domContainer.offsetWidth / this.domContainer.offsetHeight,
0.1,
1000
); //透视相机
this.camera.position.set(0, 150, 200);
this.camera.lookAt(new THREE.Vector3(0, 0, 0));
},
onWindowResize() {
this.camera.aspect =
this.domContainer.offsetWidth / this.domContainer.offsetHeight;
this.camera.updateProjectionMatrix();
this.renderer.setSize(
this.domContainer.offsetWidth,
this.domContainer.offsetHeight
);
},
//初始化光
initLight() {
let self = this;
self.ambientLight = new THREE.AmbientLight("yellow");
self.scene.add(self.ambientLight);
self.directionalLight = new THREE.DirectionalLight("#FFFFFF");
self.directionalLight.position.set(40, 60, 10);
self.directionalLight.shadow.camera.near = 20; //产生阴影的最近距离
self.directionalLight.shadow.camera.far = 100; //产生阴影的最远距离
self.directionalLight.shadow.camera.left = -50; //产生阴影距离位置的最左边位置
self.directionalLight.shadow.camera.right = 50; //最右边
self.directionalLight.shadow.camera.top = 50; //最上边
self.directionalLight.shadow.camera.bottom = -50; //最下面
//这两个值决定生成阴影密度 默认512
self.directionalLight.shadow.mapSize.height = 1024;
self.directionalLight.shadow.mapSize.width = 1024;
//告诉平行光需要开启阴影投射
self.directionalLight.castShadow = true;
self.scene.add(self.directionalLight);
},
//创建模型(模型,材质,网格)
initModel() {
let self = this;
//立方体
for (let x = 1; x < self.models.maxW / self.models.minW - 1; x++) {
for (let z = 1; z < self.models.maxW / self.models.minW - 1; z++) {
for (
let y = 0;
y <
Math.floor(Math.random() * self.models.maxZCount) +
self.models.minZCount;
y++
) {
let geometry = new THREE.CubeGeometry(
self.models.minW,
self.models.minW,
self.models.minW
);
let r = Math.floor(Math.random() * 255);
let g = Math.floor(Math.random() * 255);
let b = Math.floor(Math.random() * 255);
let a = Math.random();
let str = "rgb(" + r + "," + g + "," + b + "," + a + ")";
let material = new THREE.MeshBasicMaterial({
color: str
});
let texture = new THREE.TextureLoader().load(
self.texture[Math.floor(self.texture.length * Math.random())]
); //纹理
material.map = texture;
let mesh = new THREE.Mesh(geometry, material);
mesh.position.x = -45 + x * self.models.minW;
mesh.position.z = -45 + z * self.models.minW;
mesh.position.y = 0 + y * self.models.minW;
mesh.castShadow = true; //开启立方体的阴影
self.scene.add(mesh);
}
}
}
//底部平面
let planeGeometry = new THREE.PlaneGeometry(
self.models.maxW,
self.models.maxH
);
let planeMaterial = new THREE.MeshLambertMaterial({ color: 0xaaaaaa });
self.plane = new THREE.Mesh(planeGeometry, planeMaterial);
self.plane.rotation.x = -0.5 * Math.PI;
self.plane.position.y = -5;
self.plane.receiveShadow = true; //开启平面模型的接收阴影
self.scene.add(self.plane);
self.renderer.render(self.scene, self.camera);
},
//初始化控制器
initControl() {
let self = this;
self.control = new TrackballControls(
self.camera,
self.renderer.domElement
);
// 是否开启当前的控制器 默认值为true
self.control.enabled = true;
// 设置当前控制器的焦点 默认为原点位置
self.control.target = new THREE.Vector3();
self.control.rotateSpeed = 3.0; //控制相机旋转速度
self.control.zoomSpeed = 2; //控制相机缩放速度
self.control.panSpeed = 0.3; //控制相机移动速度
self.control.noRotate = false; //关闭相机旋转 默认false
self.control.noZoom = false; //关闭相机缩放 默认false
self.control.noPan = true; //关闭相机移动 默认false
self.control.staticMoving = true; //关闭惯性拖拽 默认值false
self.control.dynamicDampingFactor = 0.2; //设置惯性拖拽的阻力 默认值是0.2
// 控制器控制相机可移动的距离焦点的最远距离和最近距离 默认值是0到无限远的距离
self.control.minDistance = 0;
self.control.maxDistance = 800;
},
animate() {
//更新控制器
this.control.update();
this.renderer.render(this.scene, this.camera);
requestAnimationFrame(this.animate);
},
//初始化所有
init() {
let self = this;
self.domContainer = document.getElementById("myThree");
self.initRenderer();
self.initScene();
self.initCamera();
self.initLight();
self.initModel();
self.initControl();
self.animate();
window.onresize = self.onWindowResize;
}
vue - mounted
let self = this;
self.init();
style
#myThree {
width: 100%;
height: 800px;
}
基本上是这样,具体可以看 我的一个练习网址
推荐一位大佬的博客