【Threejs】03缓冲区几何体

缓冲区几何体

缓冲区集合体可以用来表示线、面和集合体(也就是一维、二维、三维图形)

利用缓冲区几何体创建三角形

创建简单的缓冲区集合体对象

js 复制代码
// 创建缓冲区集合体
const geometry1 = new THREE.BufferGeometry();

创建顶点向量

  • 要创建的是一个三角形图形,需要有三个点
  • 每三个值创建一个顶点
js 复制代码
// 创建向量

const vertices = new Float32Array([
    -1.0,-1.0,0.0,
    1.0,-1.0,0.0,
    1.0,1.0,0.0,
]);

// 创建顶点属性,每三个值创建一个顶点
geometry1.setAttribute('position',new THREE.BufferAttribute(vertices,3));

将三角形放入场景中

  1. 创建材质
  2. 创建网格
  3. 将cube1放入场景中
js 复制代码
const material1 = new THREE.MeshBasicMaterial({color: 0xf9f871});
const cube1 = new THREE.Mesh(geometry1,material1);
cube1.position.set(0,0,0);
scene.add(cube1);

完整代码

js 复制代码
// 导入threejs
import * as THREE from "three";
// 导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";

// 创建场景
const scene = new THREE.Scene();

// 创建相机
const camera = new THREE.PerspectiveCamera(
    45,//视角
    window.innerWidth/window.innerHeight,//宽高比
    0.1,//近平面
    1000//远平面
);

// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth,window.innerHeight);
document.body.appendChild(renderer.domElement);

// 创建缓冲区集合体
const geometry1 = new THREE.BufferGeometry();

// 创建向量
const vertices = new Float32Array([
    -1.0,-1.0,0.0,
    1.0,-1.0,0.0,
    1.0,1.0,0.0,
]);

// 创建顶点属性,每三个值创建一个顶点
geometry1.setAttribute('position',new THREE.BufferAttribute(vertices,3));
console.log(geometry1);
const material1 = new THREE.MeshBasicMaterial({color: 0xf9f871});
const cube1 = new THREE.Mesh(geometry1,material1);
cube1.position.set(0,0,0);
scene.add(cube1);

// 设置相机的位置
camera.position.z = 5;
camera.position.y = 2;
camera.position.y = 2;
camera.lookAt(0,0,0);//默认看向原点

// 添加世界坐标辅助器
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);

// 创建轨道控制器
const controls = new OrbitControls(camera,renderer.domElement);
// 设置带阻尼的惯性
controls.enableDamping = true;
// 设置阻尼系数
controls.dampingFactor = 0.09;
// 渲染函数
function animate() {
    controls.update();//不断更新
    requestAnimationFrame(animate);//不断请求下一帧
    renderer.render(scene,camera);
    // sxesHelper.axesHelper(camera,sxesHelper);
}
animate();

最后完整效果

当我们输出这个缓冲区几何体的属性时可以发现其顶点数是3

利用缓冲区几何体创建正方形

用缓冲区几何体正方形很简单,只需要在向量部分再添加三个节点

js 复制代码
// 创建向量

const vertices = new Float32Array([
    -1.0,-1.0,0.0,
    1.0,-1.0,0.0,
    1.0,1.0,0.0,

    1.0,1.0,0,
    -1.0,1.0,0,
    -1.0,-1.0,0
]);

最后的效果如下图所示

此时就可以发现我们创建的正方形有6个顶点,这是为什么呢,正常我们所认知的正方形应该是4个顶点。其实仔细查看我们上面创建向量的代码就可以发现我们创建了6顶点,其中有两个顶点被重复使用了。 那要如何用缓冲区几何体创建出一个有4个顶点的正方形呢? 这时就需要用到index(索引)了。

index

index允许顶点在多个三角形中重复使用。故在正方形中只有4个顶点,我们在向量中也只需要创建4组向量。

js 复制代码
// 使用索引绘制
const vertices = new Float32Array([
    -1.0,-1.0,0.0,
    1.0,-1.0,0.0,
    1.0,1.0,0.0,
    -1.0,1.0,0
])

// 创建顶点属性,每三个值创建一个顶点

geometry.setAttribute("position",new THREE.BufferAttribute(vertices,3))

这之后需要创建索引并将索引添加到几何体中。

  • BufferAttribute(indices,1)存储indices数组,且该数组为1元组
js 复制代码
// 创建索引
const indices = new Uint16Array([0,1,2,2,3,0]);

// 在几何体中添加索引
geometry.setIndex(new THREE.BufferAttribute(indices,1))

addGroup

接着用addGroup创建两个组为两个三角片添加不同的材质。

js 复制代码
// 设置两个顶点组,形成两个材质
geometry.addGroup(0,3,0);//从0这个索引开始添加3个顶点,用的是第0个材质
geometry.addGroup(3,3,1);//从3这个索引开始添加3个顶点,用的是第1个材质

接着创建不同材质并且将创建好的正方形添加到场景中。

js 复制代码
console.log(geometry);

// 创建材质
const material = new THREE.MeshBasicMaterial({
    color:0x567634,
    // wireframe:true,
    side:THREE.DoubleSide
})

const material1 = new THREE.MeshBasicMaterial({
    color:0x11338f,
    // wireframe:true,
    // side:THREE.DoubleSide
})
const plane = new THREE.Mesh(geometry,[material,material1]);
scene.add(plane)

完整代码如下:

js 复制代码
// 导入threejs
import * as THREE from "three";
// 导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";

// 创建场景
const scene = new THREE.Scene();

// 创建相机
const camera = new THREE.PerspectiveCamera(
    45,//视角
    window.innerWidth/window.innerHeight,//宽高比
    0.1,//近平面
    1000//远平面
);

// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth,window.innerHeight);
document.body.appendChild(renderer.domElement);
const material1 = new THREE.MeshBasicMaterial({
    color:0x11338f,
    // wireframe:true,
    // side:THREE.DoubleSide
})
const plane = new THREE.Mesh(geometry,[material,material1]);
scene.add(plane)

// 设置相机的位置
camera.position.z = 5;
camera.position.y = 2;
camera.position.y = 2;
camera.lookAt(0,0,0);//默认看向原点

// 添加世界坐标辅助器
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);

// 创建轨道控制器
const controls = new OrbitControls(camera,renderer.domElement);
// 设置带阻尼的惯性
controls.enableDamping = true;
// 设置阻尼系数
controls.dampingFactor = 0.09;

// 渲染函数
function animate() {
    controls.update();//不断更新
    requestAnimationFrame(animate);//不断请求下一帧
    // 渲染
    renderer.render(scene,camera);
    // sxesHelper.axesHelper(camera,sxesHelper);

}
animate();

最后实现效果如下:

可以看到最后顶点个数为4,且两个三角片的颜色不同。

相关推荐
答案—answer2 天前
开源项目:Three.js3D模型可视化编辑系统
javascript·3d·开源·开源项目·three.js·three.js编辑器
贝格前端工场2 天前
困在像素里:我的可视化大屏项目与前端价值觉醒
前端·three.js
全栈王校长3 天前
Three.js 材质进阶
webgl·three.js
全栈王校长3 天前
Three.js Geometry进阶
webgl·three.js
烛阴4 天前
3D字体TextGeometry
前端·webgl·three.js
全栈王校长4 天前
Three.js 开发快速入门
three.js
全栈王校长4 天前
Three.js 环境搭建与开发初识
three.js
DaMu4 天前
Dreamcore3D ARPG IDE “手搓”游戏引擎,轻量级实时3D创作工具,丝滑操作,即使小白也能轻松愉快的创作出属于你自己的游戏世界!
前端·架构·three.js
烛阴6 天前
从“无”到“有”:手动实现一个 3D 渲染循环全过程
前端·webgl·three.js
烛阴7 天前
拒绝配置地狱!5 分钟搭建 Three.js + Parcel 完美开发环境
前端·webgl·three.js