安装
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)
?如图:?
|