# 8.3D
# 1.Three.js 中点击拾取是怎么做的
Three.js 中点击拾取是通过射线投射去做的。
- 1.创建一个 Raycaster 对象和一个用于存储鼠标位置的二维向量。
// 初始化射线投射器和鼠标向量
raycaster = new THREE.Raycaster();
mouse = new THREE.Vector2();
- 2.转换鼠标位置:当用户点击屏幕时,需要将鼠标的屏幕坐标转换为 Three.js 使用的标准化设备坐标(NDC)。
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;
- 3.检测物体和射线的交集:在用户点击事件的处理函数中,使用射线投射器来检测与场景中物体的交集。
// 更新射线投射方向
raycaster.setFromCamera(mouse, camera);
// 获取射线和物体的交集
const intersects = raycaster.intersectObject(cubes);
- 4.处理选中的物体:在 intersects 数组中,你会得到所有与射线相交的物体。这个数组是按距离摄像机从近到远排序的,所以 intersects[0] 是最近的物体。你可以在这里添加自己的逻辑来处理这些物体,比如更改它们的颜色、显示信息标签等。
// 还原所有线框立方体的颜色
cubes.forEach(c => c.material.color.set(0x00ff00));
if (intersects.length > 0) {
// 改变选中线框立方体的颜色
intersects[0].object.material.color.set(0xff0000);
}
# 2.Three.js性能优化
1.只渲染相机视角内的物体。
2.优化几何体或模型本身,通过建模软件或者通过合并几何体减少三角面的数量和顶点的数量。
3.不同层级加载不同精度的模型或几何体(Lod)。
4.使用webworker多线程做一些解析和复杂计算的工作
5.利用 Instancing,当需要渲染大量相同对象(变换可以不同,位置,旋转,缩放可以不同)时,使用 instancing 可以大幅提高性能。这个其实是优化了数据从CPU传输到GPU的数据量与传输的次数。
# 3.描述一下 Three.js 的主要组成和工作原理
Three.js是一个基于webgl封装的3D可视化的图形库。
- 主要组成:
1.场景(Scene): 一个场景代表了一个3D的空间,里面包含了物体、光源等元素。想象它就像一个3D的舞台。
2.相机(Camera): 相机定义了从哪个视角查看场景。Three.js 提供了多种相机,如正交相机(OrthographicCamera)和透视相机(PerspectiveCamera)。
3.物体(Objects): 在 Three.js 中,一个物体通常由几何体(Geometry)和材料(Material)组成。几何体定义了物体的形状,而材料定义了物体的表面特性,如颜色、纹理等。
4.光源(Lights): 光源影响场景中物体的明暗和颜色。Three.js 提供了多种光源,如点光源(PointLight)、方向光(DirectionalLight)、聚光灯(SpotLight)等。
5.渲染器(Renderer): 负责将场景和相机的信息转化为像素,从而在屏幕上显示3D图像。WebGLRenderer 是 Three.js 中最常用的渲染器,基于 WebGL 实现。
6.动画和交互: Three.js 提供了动画系统和射线投影(Raycasting)等工具来支持动画和交互。
- 工作原理:
1.初始化: 创建场景、相机、渲染器等基础组件。
2.添加内容: 将物体、光源等添加到场景中。
3.渲染循环: 在动画或交互期间,渲染器会不断地重新绘制场景。
4.渲染器使用场景和相机的数据,通过 WebGL API 绘制每一帧。
5.若有动画或交互,场景中的物体可能会移动或变形,需要在每一帧中更新。
6.交互: 通过监听事件和射线投影检测用户的交互操作。
7.动画: 使用 Three.js 的动画系统或请求动画帧(requestAnimationFrame)来更新场景中物体的状态。
# 4.Three.js与Babylon.js对比
# 1.性能
- 大型场景中Babylon.js提供的性能可能会比Three更好
# 2.功能
- Babylon.js拥有更多的内置功能和高级功能
# 3.适用场景
- Babylon.js可能更适用于复杂的场景和游戏开发,而Three.js更适合小型或中型的项目开发。
# 5.点和直线的对称点
1.做垂线,知道了一个在直线上的点
2.然后这条垂线的斜率也是已知的
3.通过直线上的一个点和斜率可以列两个方程,求出对称点。
向量的方法:
# 6.判断点是否在一个多边形内
1.从点 P 向任意方向发出一条射线
2.计算射线与多边形边界的交点数量。
3.如果交点数量是奇数,那么点 P 在多边形内;如果是偶数,点 P 在多边形外。
# 7.矩阵的乘法
1.两个矩阵相乘,前提是第一个矩阵的列数等于第二个矩阵的行数。
2.得到的矩阵的每一项等于第一个矩阵的行数乘以第二个矩阵的列数。