安装
npm install three
场景
this.scene = new THREE.Scene()添加东西到场景(物体、坐标、光线)
this.scene.add(东西)
物体
传送门点击
贴图
const loader = new THREE.TextureLoader() const texture = loader.load('文件路径') //物体 const Geometry = new THREE.PlaneGeometry(2,2) const Material = new MeshBasicMaterial({ map: texture, //图片 side: THREE.DoubleSide, //两面都贴上图片 如果是正方形不用写 })正方体多面贴图点击
-------------------------------------------
贴图的方式
1.THREE.NearestFilter
const loader = new THREE.TextureLoader() //定义贴图对象 const texture = loader.load('文件路径') // 贴图对象加载图片 texture.magFilter = THREE.NearestFilter texture.wrapS = THREE.RepeatWrapping //X轴方向平铺 texture.wrapT = THREE.RepeatWrapping //X轴方向平铺 texture.repeat.set(10, 10) //x方向和y方向的平铺数 //物体 const Geometry = new THREE.PlaneGeometry(2,2) const Material = new MeshBasicMaterial({ map: texture, //图片 side: THREE.DoubleSide, //两面都贴上图片 如果是正方形不用写 })效果图
-------------------------------------------
2.THREE.LinearFilter
const loader = new THREE.TextureLoader() //定义贴图对象 const texture = loader.load('文件路径') // 贴图对象加载图片 texture.magFilter = THREE.LinearFilter texture.wrapS = THREE.RepeatWrapping //X轴方向平铺 texture.wrapT = THREE.RepeatWrapping //X轴方向平铺 texture.repeat.set(10, 10) //x方向和y方向的平铺数 //物体 const Geometry = new THREE.PlaneGeometry(2,2) const Material = new MeshBasicMaterial({ map: texture, //图片 side: THREE.DoubleSide, //两面都贴上图片 如果是正方形不用写 })
平面
const planeM = new THREE.MeshPhongMaterial({ color: 0xcccccc }) const planeG = new THREE.PlaneGeometry(4, 4) const plane = new THREE.Mesh(planeG, planeM) plane.rotation.x = -0.5 * Math.PI scene.add(plane)如图
光线
传送门点击
阴影
传送门点击
相机
透视相机(近大远小)
//this.camera = new THREE.PerspectiveCamera(75, w / h, 0.1, 100) this.camera = new THREE.PerspectiveCamera(fov, aspect, near, far) this.camera.position.set(1, 1, 3) //相机放的位置 this.camera.lookAt(0, 0, 0) //相机朝向原点位置 this.camera。zoom = 1 //相机的放大倍数相机的更新
this.camera.updateProjectionMatrix()
参数一
:fov摄像机视锥体垂直视野角度。 (45接近人的视角)参数二:
aspect摄像机视锥体长宽比。参数三:
near摄像机视锥体近端面。参数四:
far摄像机视锥体远端面。注意:近端面和远端面之间是我们能看到的范围
正交相机(不近大远小)
//this.camera = new THREE.OrthographicCamera(-left, right, top, -bottom, 0.1, 100) //前四个参数是对称的 this.camera = new THREE.OrthographicCamera(-2, 2, 2, -2, 0.1, 100)跟上面透视相机相比除了相机类型不同, 其他用法都一样
辅助坐标轴
三个参数为x、y、z对应的长度
const axes = new THREE.AxesHelper(7, 7, 7)
渲染器
//渲染器 this.renderer = new THREE.WebGLRenderer() this.renderer.setSize(w, h)//设置画布的大小 this.renderer.render(this.scene, this.camera) //把照相机和场景放到里面 const element = document.getElementById('container') //获取dom节点 element.appendChild(this.renderer.domElement) //在获取的节点下显示
帧数率
引入
import Stat from 'three/examples/jsm/libs/stats.module'获取帧数率实例
this.stat = new Stat在指定的dom节点显示帧数率组件
element.appendChild(this.stat.dom) //在获取的节点下显示定义一个实时刷新的方法里不停获取帧数率
this.stat.update()例如如图下这样
鼠标交互
引入
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'获取鼠标交互实例
//this.orbitcontrols = new OrbitControls(this.camera, this.renderer.domElement) this.orbitcontrols = new OrbitControls(相机, 渲染器.domElement)实时刷新
this.orbitcontrols.update()图片
物体组合
获取一个group对象
const group = new THREE.Group()把所有物体添加到group中 并把group添加到场景里
//物体1 const geometry1 = new THREE.BoxGeometry(1, 1, 1) const material1 = new THREE.MeshBasicMaterial({color: 0xff0000}) const cube1 = new Mesh(geometry1, material1) group.add(cube1) //把物体添加到组合里面 cube1.position.y = 1.5 //物体2 const geometry2 = new THREE.BoxGeometry(1, 1, 1) const material2 = new THREE.MeshBasicMaterial({color: 0xff0000}) const cube2 = new Mesh(geometry2, material2) group.add(cube2) //把物体添加到组合里面 //物体3 const geometry3 = new THREE.BoxGeometry(1, 1, 1) const material3 = new THREE.MeshBasicMaterial({color: 0xff0000}) const cube3 = new Mesh(geometry3, material3) group.add(cube3) //把物体添加到组合里面 cube3.position.y = -1.5 //最后我们要把组合放到场景里面 scene.add(group)我们给整个组一个旋转
group.rotation.z = time图片
现在场景里面就只有一个group 所以group旋转就相当于三个作为一个整体在旋转
图形控制界面
图形控制界面是一个新的东西 并且有点多 写在这个链接里点击
窗口大小发生改变时
问题: 窗口大小发生变化 页面没有实时被铺满
解决:发生改变时把需要修改的参数放到里面来
window.addEventListener('resize', () => { //窗口变化时把需要更新的东西放进来 })
线
方法一:
// 定义坐标点 const p1 = new THREE.Vector3(1, 0, 0) //参数为 x、y、x const p2 = new THREE.Vector3(0, 1, 0) //参数为 x、y、x const points = [p1, p2] // 物体(线) const geometry = new THREE.BufferGeometry().setFromPoints(points) //把点数组给这个弄成线 const material = new THREE.LineBasicMaterial({ color: 0xff0000, }) this.cube = new THREE.Line(geometry, material) this.scene.add(this.cube)如图:
方法二
const n = 10 const points = new Float32Array(n * 3) //获取一个数组里面有30个元素 值为0 也相当于开辟了30个元素的数组空间 for ( let i = 0; i < n; i++ ) { let x= (Math.random() - 0.5) * 4 let y= (Math.random() - 0.5) * 4 let z= (Math.random() - 0.5) * 4 //i * 3 + 0 的意思是每次的坐标的值放在的数组位置 因为三个数字为一个坐标0坐标为第一个点的x轴的坐标 第二个点的x坐标为3 points[i * 3 + 0] = x points[i * 3 + 1] = y points[i * 3 + 2] = z } // 物体(线) const geometry = new THREE.BufferGeometry() //把数组三个数传进position 组成一个顶点 geometry.setAttribute('position', new THREE.BufferAttribute(points, 3)) const material = new THREE.LineBasicMaterial({ color: 0xff0000, }) this.cube = new THREE.Line(geometry, material) this.scene.add(this.cube)如图: