- A+
所属分类:Web前端
Demo代码地址:
https://gitee.com/s0611163/three.js-demo
Three.js
Three.js下载
-
从GitHub上下载一个Release版本,https://github.com/mrdoob/three.js,本Demo使用的是r112版本,下载地址:three.js-r112
-
解压,复制build文件夹到Demo的threejs/build文件夹,examples/jsm文件夹到threejs/js文件夹,examples/textures/equirectangular/venice_sunset_1k.hdr文件复制到threejs/assets文件夹
-
threejs/js文件夹中的文件,引用three.module.js的路径需要修改
-
修改threejs/js/OrbitControls.js,交换841和864行、843和866行即可,修改前鼠标右键控制旋转、中键控制放大缩小,修改后鼠标中键控制旋转,鼠标右键控制放大缩小
-
修改threejs/js/OrbitControls.js,分别在文件开头和607行代码前添加如下代码
import { Euler } from "../../build/three.module.js";
var euler = new Euler(0, 0, 0, 'YXZ'); function getTarget(length) { var position = scope.object.position.clone(); var length = length || (spherical.radius > 700 ? spherical.radius : 700); euler.setFromQuaternion(scope.object.quaternion); position.set(position.x - length * Math.sin(euler.y), position.y + length * Math.sin(euler.x), position.z - length * Math.cos(euler.y)); return position; } this.getTarget = getTarget;
场景(Scene)
import * as THREE from '../build/three.module.js'; let scene = new THREE.Scene();
相机(Camera)
let near = 1; let far = 20000; let el = document.querySelector("#threeContainer"); /* 创建相机对象 PerspectiveCamera透视投影相机 OrthographicCamera正交投影相机 */ let camera = new THREE.PerspectiveCamera(60, el.clientWidth / el.clientHeight, near, far); scene.add(camera);
渲染器(Renderer)
let renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.domElement.id = 'threeCanvas'; renderer.physicallyCorrectLights = true; renderer.outputEncoding = THREE.sRGBEncoding; renderer.setClearColor(0x002b4b); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(el.clientWidth, el.clientHeight); el.appendChild(renderer.domElement);
灯光
//环境光 let ambientLight = new THREE.AmbientLight(0xFFFFFF, 0.5); camera.add(ambientLight); //平行光 let directionalLight = new THREE.DirectionalLight(0xFFFFFF, 1); directionalLight.position.set(0.5, 0, 0.866); // ~60º camera.add(directionalLight);
相机控制
import { MapControls } from '../js/controls/OrbitControls.js'; //创建场景控制对象 let controls = new MapControls(this.camera, this.renderer.domElement); controls.autoRotate = false; controls.autoRotateSpeed = -10; //设置相机位置和焦点 camera.position.set(-12.34, 120.88, -48.14); controls.target.set(-12.52, 3.72, -12.54); controls.update();
加载模型
以GLTF格式的模型为例
import { GLTFLoader } from '../js/loaders/GLTFLoader.js'; let onProgress = function (xhr) { }; //加载进度 let onError = function (xhr) { }; //加载出错 let url = '"./GLTF/four/hefeiqizhong/hfqz_yc.glb"'; let loader = new GLTFLoader(); loader.load(url, gltf => { const model = gltf.scene || gltf.scenes[0]; scene.add(model); }, onProgress, onError);
几何体、材质、网格
圆柱几何体的构造函数: CylinderGeometry(radiusTop : Float, radiusBottom : Float, height : Float, radialSegments : Integer, heightSegments : Integer, openEnded : Boolean, thetaStart : Float, thetaLength : Float) radiusTop — 圆柱的顶部半径,默认值是1。 radiusBottom — 圆柱的底部半径,默认值是1。 height — 圆柱的高度,默认值是1。 radialSegments — 圆柱侧面周围的分段数,默认为8。 heightSegments — 圆柱侧面沿着其高度的分段数,默认值为1。 openEnded — 一个Boolean值,指明该圆锥的底面是开放的还是封顶的。默认值为false,即其底面默认是封顶的。 thetaStart — 第一个分段的起始角度,默认为0。(three o'clock position) thetaLength — 圆柱底面圆扇区的中心角,通常被称为“θ”(西塔)。默认值是2*Pi,这使其成为一个完整的圆柱。
//圆柱几何体 let cylinder = new THREE.CylinderGeometry(0, 100, 300, 32); //参数分别表示 圆柱的顶部半径、圆柱的底部半径、圆柱的高度、圆柱侧面周围的分段数 //几何体旋转 cylinder.rotateX(Math.PI / 2); //绕x轴旋转90度 //基础网格材质 let material = new THREE.MeshBasicMaterial({ color: 0xff0000, opacity: 0.5, transparent: true }); //网格 let mesh = new THREE.Mesh(cylinder, material); //将物体添加到场景中 scene.add(mesh);
动画
使用tween.js实现动画
let position = [-205, 3479, 4412]; let target = [-179, 186, 519]; let tween = new TWEEN.Tween(camera.position).to({ x: position[0], y: position[1], z: position[2] }, 3000).start().onUpdate(() => { controls.target.set(...target); controls.update(); }).onComplete(() => { TWEEN.remove(this.tween); });
着色器
实现Three.js未提供的特殊效果时需要使用着色器语言,例如实现带箭头的线、火焰效果时可能会用到,语法类似C语言
WebGL和Three.js在线教程
http://www.yanhuangxueyuan.com/