关于几何体
什么是几何体
几何体是由点线面构成的
两个点构成一条线,三个点构成一个面
在 three.js 里面,物体是由几何体构成的
我们打印出来对应的物体和几何体
// 物体 -> 方形
const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
// 材质 -> vue 的主题色
const cubeMaterial = new THREE.MeshBasicMaterial({ color: 0x4fc08d });
// 生成物体
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
console.log('---------------')
console.log(cubeGeometry)
console.log(cube)
console.log('---------------')
在浏览器里面可以看到
在物体里面有一个几何体,可以通过 geometry 属性进行访问
然后再几何体里面的构造函数里面
有一个 attributes 属性
这里面是存放着我们的一些数据,例如法相量( normal )、顶点位置( position )、UV 坐标( uv )
顶点位置
因为立方体有6个面,每个面有4个点,所以他的顶点位置有24个
因为每个顶点需要用 XYZ 轴的值来确认位置
所以这里有七十二条数据
UV
那什么是 UV 呢?
首先可以肯定的是,这个 UV 绝对不是这个 AUV 🤣
简单来说,UV 想当于一个展开图
还是那立方体举个例子
这是一个立方体的展开图,也是他的 UV 图
六个面,一共有24个点
因为展开图没有 Z 轴,所以我们只需要给他48条数据就可以了
就是我们可以通过 UV 来制作包装纸类似的
法向量
法向量就是指比如有光照射进来,主要是计算光的反射角度是什么,当前的面的朝向之类的
设置新的几何体
之前我们是用 BoxGeometry 这个构造函数来生成一个立方体的
现在我们如果要生成一个正方形改咋办呢
我们应该用这个函数 BufferGeometry 然后再在其中设置对应的顶点的值
请看以下代码
// 物体 -> 方形
const geometry = new THREE.BufferGeometry();
const vertices = new Float32Array([
-1.0,-1.0,0,
1.0,1.0,0,
-1.0,1.0,0,
1.0,-1.0,0,
1.0,1.0,0,
-1.0,-1.0,0
])
// 去设置属性当中的顶点的位置
geometry.setAttribute('position', new THREE.BufferAttribute(vertices,3))
// 材质 -> vue 的主题色
const material = new THREE.MeshBasicMaterial({ color: 0x4fc08d });
// 生成物体
const mesh = new THREE.Mesh(geometry, material);
// 将物体添加到场景中,因为我们没有给他设置 UV 和法向量,所以目前没有 UV 和法向量的效果出现
scene.add(mesh)
BoxGeometry 和 BufferGeometry 的区别是什么
首先 BufferGeometry 是面片、线或点几何体的有效表述
包括顶点位置,面片索引、法相量、颜色值、UV 坐标和自定义缓存属性值
使用 BufferGeometry 可以有效减少向 GPU 传输上述数据所需的开销
简单来说就是可以通过这个进行自定一个东西出来
BoxGeometry 是四边形的原始几何类
它通常使用构造函数所提供的“width”、“height”、“depth”参数来创建立方体或者不规则四边形
简单来说,这个就是通过之前的那个构造函数,帮我们进行了一个封装
构造出来一个立方体
构建炫酷科技感立方体
我们在之前构建出来了一个正方形
接下来,我们就来整点花活
我们去构建一个由很多个随机三角形组装起来的
很有科技感的这么一个图形
话不多说,直接开始贴代码吧
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
// 创建一个场景
const scene = new THREE.Scene();
// 创建一个相机
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
// 给相机一个位置
camera.position.set(0, 0, 10);
// 在场景里面添加相机
scene.add(camera);
// 物体 -> 方形
for (let i = 0; i < 50; i++) {
const geometry = new THREE.BufferGeometry();
const vertices = new Float32Array(9)
for (let j = 0; j < 9; j++) {
vertices[j] = Math.random() * 10 - 5
}
// 去设置属性当中的顶点的位置
geometry.setAttribute('position', new THREE.BufferAttribute(vertices,3))
// 材质 -> vue 的主题色
let color = new THREE.Color(Math.random(),Math.random(),Math.random())
const material = new THREE.MeshBasicMaterial({ color,transparent:true, opacity:0.5 });
// 生成物体
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh)
}
// 生成渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
// 渲染器渲染的是画布 -> canvas
// 需要将渲染的 canvas 内容添加到 body 上
document.body.appendChild(renderer.domElement);
// 控制器需要一个相机,还有指定渲染的元素,否则谁知道你是哪个相机,监听哪个页面的元素呢,对吧
const controls = new OrbitControls(camera, renderer.domElement);
// 给控制器设置阻尼,使其更加真实
controls.enableDamping = true;
// 坐标轴辅助器
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);
function render() {
// 调用 update 方法
controls.update();
renderer.render(scene, camera);
// 浏览器自带方法,在刷新的时候自动执行某个函数↓
requestAnimationFrame(render);
}
render();
window.addEventListener("dblclick", () => {
if (!document.fullscreenElement) {
renderer.domElement.requestFullscreen();
} else {
document.exitFullscreen();
}
});
window.addEventListener("resize", () => {
// 更新摄像头宽高比
camera.aspect = innerWidth / innerHeight;
// 更新摄像机的投影矩阵
camera.updateProjectionMatrix();
// 更新渲染器
renderer.setSize(window.innerWidth, window.innerHeight);
// 设置渲染器的像素比
renderer.setPixelRatio(window.devicePixelRatio);
});
主要代码是下面这个,让他生成50个随机颜色的三角形添加到场景中
for (let i = 0; i < 50; i++) {
const geometry = new THREE.BufferGeometry();
const vertices = new Float32Array(9)
for (let j = 0; j < 9; j++) {
vertices[j] = Math.random() * 10 - 5
}
// 去设置属性当中的顶点的位置
geometry.setAttribute('position', new THREE.BufferAttribute(vertices,3))
// 材质 -> vue 的主题色
let color = new THREE.Color(Math.random(),Math.random(),Math.random())
const material = new THREE.MeshBasicMaterial({ color,transparent:true, opacity:0.5 });
// 生成物体
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh)
}
今天的知识就到这里了,不知道你们知识从脑袋进去又匆匆出来的感觉如何呢
多谢大家看到这里,以上是今天的内容,希望能对你们有所帮助
那么我们下集再见啦~
拜拜