BufferGeometry缓冲几何体
<canvas id="mainCanvas"></canvas>
<script type="importmap">
{
"imports": {
"three": "./js/build/three.module.js",
"three/addons/": "./js/jsm/"
}
}
</script>
<script type="module">
import * as THREE from "three";
import { GUI } from "three/addons/libs/lil-gui.module.min.js";
import { TrackballControls } from "three/addons/controls/TrackballControls.js";
import { initRenderer, initPerspectiveCamera, initAmbientLight, initSpotLight, addPlane, addBox } from "./init.js";
async function init() {
const renderer = initRenderer("mainCanvas");
const scene = new THREE.Scene();
const camera = initPerspectiveCamera();
camera.position.set(50, 0, 200);
scene.add(camera);
const ambientLight = initAmbientLight();
scene.add(ambientLight);
const spotLight = initSpotLight();
scene.add(spotLight);
const trackballControls = new TrackballControls(camera, renderer.domElement);
const clock = new THREE.Clock();
const axesHelper = new THREE.AxesHelper(150);
scene.add(axesHelper);
const material = new THREE.MeshLambertMaterial({
color: 0xff0000,
side: THREE.DoubleSide,
});
const material_v = new THREE.MeshBasicMaterial({
vertexColors: true, //默认false,设置为true表示使用顶点颜色渲染
side: THREE.DoubleSide,
});
const textureLoader = new THREE.TextureLoader();
const texture = await textureLoader.load("./textures/uv/ash_uvgrid01.jpg");
texture.colorSpace = THREE.SRGBColorSpace; //设置为SRGB颜色空间
// 设置阵列模式
// texture.wrapS = THREE.RepeatWrapping;
// texture.wrapT = THREE.RepeatWrapping;
// uv两个方向纹理重复数量
// texture.repeat.set(2, 2);
const material_t = new THREE.MeshLambertMaterial({
map: texture,
side: THREE.DoubleSide,
});
const vertices = new Float32Array([0, 0, 0, 30, 0, 0, 30, 30, 0, 0, 0, 0, 30, 30, 0, 0, 30, 0]);
const vertices_norepeat = new Float32Array([0, 0, 0, 30, 0, 0, 30, 30, 0, 0, 30, 0]);
{
// 根据顶点坐标生成面
const geometry = new THREE.BufferGeometry();
geometry.attributes.position = new THREE.BufferAttribute(vertices, 3);
const mesh = new THREE.Mesh(geometry, material);
mesh.position.set(-40, -40, 0);
scene.add(mesh);
// 几何体顶点索引数据
const geometry2 = new THREE.BufferGeometry();
geometry2.attributes.position = new THREE.BufferAttribute(vertices_norepeat, 3);
const indexes = new Uint16Array([0, 1, 2, 0, 2, 3]);
geometry2.index = new THREE.BufferAttribute(indexes, 1);
const material2 = material.clone();
material2.color.set(0x00ff00);
const mesh2 = new THREE.Mesh(geometry2, material2);
mesh2.position.set(0, -40, 0);
scene.add(mesh2);
// 顶点法线数据 法线的就是平面的垂线,如果是光滑曲面,一点的法线就是该点切面的法线。每个顶点的法线数据和顶点位置数据一一对应
const geometry3 = geometry.clone();
const normals = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]);
geometry3.attributes.normal = new THREE.BufferAttribute(normals, 3);
const mesh3 = new THREE.Mesh(geometry3, material);
mesh3.position.set(40, -40, 0);
scene.add(mesh3);
const geometry4 = geometry2.clone();
const normals4 = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]);
geometry4.attributes.normal = new THREE.BufferAttribute(normals, 3);
const mesh4 = new THREE.Mesh(geometry4, material2);
mesh4.position.set(80, -40, 0);
scene.add(mesh4);
}
{
// 顶点颜色:3个一组表示一个顶点的颜色数据RGB
const geometry = new THREE.BufferGeometry();
geometry.attributes.position = new THREE.BufferAttribute(vertices_norepeat, 3);
const indexes = new Uint16Array([0, 1, 2, 0, 2, 3]);
geometry.index = new THREE.BufferAttribute(indexes, 1);
const colors = new Float32Array([1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1]);
geometry.attributes.color = new THREE.BufferAttribute(colors, 3);
const mesh = new THREE.Mesh(geometry, material_v);
mesh.position.set(-40, 0, 0);
scene.add(mesh);
const geometry2 = new THREE.BufferGeometry();
const pointsArr2 = [new THREE.Vector3(0, 0, 0), new THREE.Vector3(30, 0, 0), new THREE.Vector3(30, 30, 0)];
geometry2.setFromPoints(pointsArr2);
const pos = geometry2.attributes.position;
const count = pos.count;
const colorsArr2 = [];
for (let i = 0; i < count; i++) {
const percent = i / count;
colorsArr2.push(percent, 0, 1 - percent);
}
const colors2 = new Float32Array(colorsArr2);
geometry2.attributes.color = new THREE.BufferAttribute(colors2, 3);
const mesh2 = new THREE.Mesh(geometry2, material_v);
mesh2.position.set(0, 0, 0);
scene.add(mesh2);
const colorsArr3 = [];
const c1 = new THREE.Color(0x00ffff);
const c2 = new THREE.Color(0xffff00);
for (let i = 0; i < count; i++) {
const percent = i / count;
const c = c1.clone().lerp(c2, percent);
colorsArr3.push(c.r, c.g, c.b);
}
const colors3 = new Float32Array(colorsArr3);
const geometry3 = geometry2.clone();
geometry3.attributes.color = new THREE.BufferAttribute(colors3, 3);
const mesh3 = new THREE.Mesh(geometry3, material_v);
mesh3.position.set(40, 0, 0);
scene.add(mesh3);
}
// 顶点uv坐标
// 顶点uv坐标,是二维顶点坐标,顶点UV坐标geometry.attributes.uv和顶点位置坐标geometry.attributes.position是一一对应的。
// 作用:纹理贴图上提取像素映射到网格模型Mesh的几何体表面上。
{
const geometry = new THREE.BufferGeometry();
geometry.attributes.position = new THREE.BufferAttribute(vertices_norepeat, 3);
const indexes = new Uint16Array([0, 1, 2, 0, 2, 3]);
geometry.index = new THREE.BufferAttribute(indexes, 1);
const mesh = new THREE.Mesh(geometry, material_t);
mesh.position.set(-40, 40, 0);
scene.add(mesh);
const uvs2 = [0, 0, 1, 0, 1, 1, 0, 1];
const geometry2 = geometry.clone();
geometry2.attributes.uv = new THREE.BufferAttribute(new Float32Array(uvs2), 2);
const mesh2 = new THREE.Mesh(geometry2, material_t);
mesh2.position.set(0, 40, 0);
scene.add(mesh2);
const uvs3 = [0, 0, 1, 0, 0.5, 0.5, 0, 1];
const geometry3 = geometry.clone();
geometry3.attributes.uv = new THREE.BufferAttribute(new Float32Array(uvs3), 2);
const mesh3 = new THREE.Mesh(geometry3, material_t);
mesh3.position.set(40, 40, 0);
scene.add(mesh3);
}
render();
function render() {
trackballControls.update(clock.getDelta());
requestAnimationFrame(render);
renderer.render(scene, camera);
}
}
init();
</script>