Threejs_05 几何体顶点索引

2023-11-20 16:20

本文主要是介绍Threejs_05 几何体顶点索引,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Threejs中的任何一个几何体都是由若干个索引点构成的,然后这些索引点其实构成的都是三个坐标的三角形。

使用顶点坐标构建几何体

1.我们需要一个支持几何体属性的物料

//创建几何体(三角形)
const geometry = new THREE.BufferGeometry();

2.构造一个顶点坐标组

const vertices = new Float32Array([-1.0, -1.0, 0.0, //11.0, 1.0, 0.0,  //21.0, -1.0, 0.0, //31.0, 1.0, 0.0,  //4-1.0, 1.0, 0.0,  //5-1.0, -1.0, 0.0, //6
]);

这里使用的每三个值一个的坐标, 对应的是threejs画布上的坐标,但是感觉四个值就可以完成一个正方形,为什么是六个点呢? 

这是因为在threejs的世界之中,所有的内容都是由三角形狗造成的,所以我们需要绘制两个三角形,拼凑成一个正方形

 三个一组 每三个数对应一个顶点坐标,这里使用到了Float32Array

 其实就是用这个存点的

3.将参数融合 通过BufferAttribute方法构建几何体

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

new THREE.BufferAttribute(vertices, 3)  这个方法可以创建一个新的BufferAttribute对象,它用于存储顶点的数据。vertices 是一个包含顶点坐标的数组,而 3 表示每个顶点有三个分量(x、y、z坐标)。

什么是BufferAttribute对象呢????

BufferAttribute 是 Three.js 中用于存储顶点数据的对象之一。它是 Three.js 中对底层 WebGL 缓冲区的一个抽象,用于高效地存储和管理大量顶点数据。

在 3D 图形中,一个模型的几何信息通常包括顶点坐标、法线、颜色等数据。BufferAttribute 主要用于存储这些顶点相关的数据。它可以包含诸如顶点坐标、颜色、法线等信息,并将这些信息存储在一个 WebGL 缓冲区中,以便在 GPU 上进行高效的渲染。

4.一个自己构建的几何体就做好了

正面:

背面:

 当然,我们也可以简答的使用四个点来绘制一个正方形,使用我们的索引绘制

使用索引绘制几何体

1. 构造几何体

//创建几何体
const geometry = new THREE.BufferGeometry();

2. 使用索引制作数组

//使用索引绘制
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,
]);

3.创建顶点属性

//创建顶点属性
geometry.setAttribute("position", new THREE.BufferAttribute(vertices, 3));

4.创建索引 

这里比较重要,这里的意思是取坐标构建三角形  三个为一组,0 1 2 代表 拿数组之中的 第0个 1个 2个 构建第一个三角形 第二个同上, 所以一共构建两个三角形。

//创建索引
const indices = new Uint16Array([0, 1, 2, 2, 3, 0]);

 5.创建索引属性

//创建索引属性
geometry.setIndex(new THREE.BufferAttribute(indices, 1));

 6.构建完成

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

这里的side 是让threejs的渲染器 双面渲染 而不是渲染一面,添上线框属性可以暂时规避这个问题。

所有代码

//导入 threejs
import * as THREE from "three";
//导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
//导入lil.gui
// import * as dat from "dat.gui";  // 旧
import { GUI } from "three/examples/jsm/libs/lil-gui.module.min.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);
// 将渲染器的dom元素添加到body中
document.body.appendChild(renderer.domElement);//创建几何体
const geometry = new THREE.BufferGeometry();
// // //创建顶点数据 顶点是由顺序的 每三个为一个顶点,逆时针为正面
// const vertices = new Float32Array([
//     -1.0, -1.0, 0.0, //1
//      1.0, 1.0, 0.0,  //2
//      1.0, -1.0, 0.0, //3
//      1.0, 1.0, 0.0,  //4
//     -1.0, 1.0, 0.0,  //5
//     -1.0, -1.0, 0.0, //6
// ]);
// // //下面这个代码什么意思
// // //创建顶点属性
// geometry.setAttribute("position", new THREE.BufferAttribute(vertices, 3));//使用索引绘制
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,
]);
// console.log(geometry)
//创建顶点属性
geometry.setAttribute("position", new THREE.BufferAttribute(vertices, 3));
//创建索引
const indices = new Uint16Array([0, 1, 2, 2, 3, 0]);
//创建索引属性
geometry.setIndex(new THREE.BufferAttribute(indices, 1));// 创建材质
const material = new THREE.MeshBasicMaterial({color: 0xff0000,wireframe: true,// side: THREE.DoubleSide,
});
const plane = new THREE.Mesh(geometry, material);
scene.add(plane);
// 设置立方体的旋转 绕着x旋转
// cube.rotation.x = Math.PI / 4;//将网格体添加到场景中
// scene.add(parentCube);// 设置相机的位置
camera.position.z = 5;
// 为了看到z轴
camera.position.y = 2;
// 设置x轴
camera.position.x = 2;
//设置相机的焦点 (相机看向哪个点)
camera.lookAt(0, 0, 0);//添加世界坐标辅助器  (红色x轴,绿色y轴,蓝色z轴)一个线段 参数为 线段长度
const axesHelper = new THREE.AxesHelper(5);
//添加到场景之中
scene.add(axesHelper);// 添加轨道控制器 (修改侦听位置)  一般监听画布的事件  不监听document.body
const controls = new OrbitControls(camera, renderer.domElement);
// 这里传递阻塞掉了 会导致无法点击
// const controls = new OrbitControls(camera, document.body);// 设置带阻尼的旋转
controls.enableDamping = true;
// 设置阻尼系数
controls.dampingFactor = 0.01;
// 自动旋转
controls.autoRotate = false;//渲染函数
function animate() {controls.update();//请求动画帧requestAnimationFrame(animate);//旋转网格体// cube.rotation.x += 0.01;// cube.rotation.y += 0.01;//渲染renderer.render(scene, camera);
}
animate();
//渲染// 监听窗口的变化 重新设置渲染器的大小 画布自适应窗口
window.addEventListener("resize", () => {// 重新设置渲染器的大小renderer.setSize(window.innerWidth, window.innerHeight);// 重新设置相机的宽高比camera.aspect = window.innerWidth / window.innerHeight;// 重新计算相机的投影矩阵camera.updateProjectionMatrix();
});//1.gui控制按钮
let eventObj = {Fullscreen: function () {document.body.requestFullscreen();},exitFullscreen: function () {document.exitFullscreen();},
};//创建gui实例
const gui = new GUI();
//添加按钮  第一个参数为对象实例  第二个参数为对象中属性名称
gui.add(eventObj, "Fullscreen").name("全屏");
//退出按钮
gui.add(eventObj, "exitFullscreen").name("退出全屏");//2.gui控制立方体的位置
// gui.add(cube.position, "x", -5, 5).name("立方体x轴位置");

这篇关于Threejs_05 几何体顶点索引的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/395881

相关文章

一文详解MySQL索引(六张图彻底搞懂)

《一文详解MySQL索引(六张图彻底搞懂)》MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度,:本文主要介绍MySQL索引的相关资料,文中通过代码介绍的... 目录一、什么是索引?为什么需要索引?二、索引该用哪种数据结构?1. 哈希表2. 跳表3. 二叉排序树4.

MySQL 索引简介及常见的索引类型有哪些

《MySQL索引简介及常见的索引类型有哪些》MySQL索引是加速数据检索的特殊结构,用于存储列值与位置信息,常见的索引类型包括:主键索引、唯一索引、普通索引、复合索引、全文索引和空间索引等,本文介绍... 目录什么是 mysql 的索引?常见的索引类型有哪些?总结性回答详细解释1. MySQL 索引的概念2

Oracle查询表结构建表语句索引等方式

《Oracle查询表结构建表语句索引等方式》使用USER_TAB_COLUMNS查询表结构可避免系统隐藏字段(如LISTUSER的CLOB与VARCHAR2同名字段),这些字段可能为dbms_lob.... 目录oracle查询表结构建表语句索引1.用“USER_TAB_COLUMNS”查询表结构2.用“a

MySQL 强制使用特定索引的操作

《MySQL强制使用特定索引的操作》MySQL可通过FORCEINDEX、USEINDEX等语法强制查询使用特定索引,但优化器可能不采纳,需结合EXPLAIN分析执行计划,避免性能下降,注意版本差异... 目录1. 使用FORCE INDEX语法2. 使用USE INDEX语法3. 使用IGNORE IND

MySQL逻辑删除与唯一索引冲突解决方案

《MySQL逻辑删除与唯一索引冲突解决方案》本文探讨MySQL逻辑删除与唯一索引冲突问题,提出四种解决方案:复合索引+时间戳、修改唯一字段、历史表、业务层校验,推荐方案1和方案3,适用于不同场景,感兴... 目录问题背景问题复现解决方案解决方案1.复合唯一索引 + 时间戳删除字段解决方案2:删除后修改唯一字

浅谈mysql的not exists走不走索引

《浅谈mysql的notexists走不走索引》在MySQL中,​NOTEXISTS子句是否使用索引取决于子查询中关联字段是否建立了合适的索引,下面就来介绍一下mysql的notexists走不走索... 在mysql中,​NOT EXISTS子句是否使用索引取决于子查询中关联字段是否建立了合适的索引。以下

MySQL之InnoDB存储引擎中的索引用法及说明

《MySQL之InnoDB存储引擎中的索引用法及说明》:本文主要介绍MySQL之InnoDB存储引擎中的索引用法及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录1、背景2、准备3、正篇【1】存储用户记录的数据页【2】存储目录项记录的数据页【3】聚簇索引【4】二

全面解析MySQL索引长度限制问题与解决方案

《全面解析MySQL索引长度限制问题与解决方案》MySQL对索引长度设限是为了保持高效的数据检索性能,这个限制不是MySQL的缺陷,而是数据库设计中的权衡结果,下面我们就来看看如何解决这一问题吧... 目录引言:为什么会有索引键长度问题?一、问题根源深度解析mysql索引长度限制原理实际场景示例二、五大解决

MySQL中的索引结构和分类实战案例详解

《MySQL中的索引结构和分类实战案例详解》本文详解MySQL索引结构与分类,涵盖B树、B+树、哈希及全文索引,分析其原理与优劣势,并结合实战案例探讨创建、管理及优化技巧,助力提升查询性能,感兴趣的朋... 目录一、索引概述1.1 索引的定义与作用1.2 索引的基本原理二、索引结构详解2.1 B树索引2.2

python3如何找到字典的下标index、获取list中指定元素的位置索引

《python3如何找到字典的下标index、获取list中指定元素的位置索引》:本文主要介绍python3如何找到字典的下标index、获取list中指定元素的位置索引问题,具有很好的参考价值,... 目录enumerate()找到字典的下标 index获取list中指定元素的位置索引总结enumerat