Threejs_05 几何体顶点索引

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

使用顶点坐标构建几何体

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

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

2.构造一个顶点坐标组

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
]);

这里使用的每三个值一个的坐标, 对应的是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轴位置");

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/169469.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

51单片机直流电机控制

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、pwm波形?1.1高低电平交互,LED亮灭。1.2 驱动电机时?1.3 怎么调节电机的速度? 二、怎么用51单片机产生PWM波形…

OpenVPN Connect使用连接公网VPN服务器实现内网穿透

安装并运行OpenVPN Connect 点击AGREE 添加配置.OVPN文件 点击连接 连接成功 两个内网主机通过公网VPN穿透

哪些软件可以监控电脑(保姆级教程!值得收藏!)

今天了解到了一个软件,真的把我吓到了。 我才知道原来我上班时摸鱼时多么愚蠢的一件事情。原来老板可以通过一些软件轻而易举的知道你用电脑做的所有事情,怪不得我每次摸鱼时老板看我的眼神都不对…… 安装好域之盾软件以后,打开就能监控你使…

电容的耐压值是什么意思呢?

电容是什么? 电容是一种能以电荷的形式储存能量的装置。与同样大小的电池相比,电容能储存的能量要小得多,大约1w个电容存储的能量才顶一节电池存储的能量,但对于许多电路设计来说却足够使用了。 看下图的直插式电容,…

竞赛 题目:基于深度学习的中文汉字识别 - 深度学习 卷积神经网络 机器视觉 OCR

文章目录 0 简介1 数据集合2 网络构建3 模型训练4 模型性能评估5 文字预测6 最后 0 简介 🔥 优质竞赛项目系列,今天要分享的是 基于深度学习的中文汉字识别 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! &a…

[JDK工具-2] javap 类文件解析工具-帮助理解class文件,了解Java编译器机制

文章目录 1. javap -version 版本信息2. javap -verbose 输出附加信息3. javap -l 显示行号和局部变量列表4. javap -c 对代码进行反汇编(或叫反编译生成汇编代码,一般说反编译是生成java代码),分解方法代码,也就是显示…

OSG文字-显示汉字 (1)

OSG文字 适当的文字信息对于显示场景信息是非常重要的。在 OSG中,osgText 提供了向场景中添加文字的强大功能,由于有第三方插件 FreeType 的支持,它完全支持TrueType字体。 读者可能对 FreeType和TrueType还不太了解,下面进行具体…

Openlayer【二】—— 绘制不同的点、线以及给其添加监听事件

Openlayer【二】—— 绘制不同的点、线以及给其添加监听事件 接上篇:OpenLayer初始化 在openlayer当中,图层Layer与地图源Source是一对一的关系。当创建了一个图层Layer,相应的需要给图层添加地图源Source,然后将图层Layer添加到…

企业经营好不好?看看官方评价指标(适电子元、器件制造业)

一家企业经营的到底好不好?有没有评价标准呢?这里我们不妨参考一下国资委对全国各个行业的考核指标,对照一下自己的企业,就比较清楚自身企业的经营水平了。另外,我们也希望使用ODOO-ERP业财一体系统的企业,…

docker swarm集群部署

文章目录 前言一、安装docker1.1 解压1.2 配置docker 存储目录和dns1.3 添加docker.service文件1.4 docker 启动验证 二、docker swarm 集群配置2.1 关闭selinux2.2 设置主机名称并加入/etc/hosts2.3 修改各个服务器名称(uname -a 进行验证)2.4 初始化sw…

Java-类和类的关系

代码 总结: 【1】面向对象的思维:找参与者,找女孩类,找男孩类 【2】体会了什么叫方法的形参,什么叫方法的实参: 具体传入的内容 实参: 【3】类和类可以产生关系: (1…

Django(九、choices参数的使用、多对多表的三种创建方式、Ajax技术)

文章目录 一、choices参数choices参数的用法choices 参数用法总结 二、MVC与MTV模式1.MVC2.MTV 三、多对多的三种创建方式1.全自动创建2.纯手动创建半自动创建 四、Django与Ajax1.什么是Ajax常见的场景Ajax案例 一、choices参数 在没有用到choices参数之前,我们在D…

如何科学的进行Android包体积优化

这篇文章会分享小厂如何做包体积优化相关主题,涉及内容包括:1) Android包体积优化的一种可能是比较标准的推进做法,2) 大致流程的心路历程和思考方式,3) 如何去总结和分享你们进行过的包体积优化项目。本文不仅仅是一篇分享&#…

PCIe协议加持,SD卡9.1规范达到媲美SSD的速度4GB/s

近日,SD协会(SDA)宣布了最新的SD Express存储卡的进化,将microSD Express存储卡的速度提高了一倍,达到2GB/s,并引入了4个新的SD Express速度等级,以确保新的SD 9.1规范中最低的顺序性能水平。这…

【自动驾驶解决方案】C++取整与保留小数位

一、C基础 1.1double型保留小数为&#xff0c;并以字符输出 #include <iostream> #include <sstream> #include <iomanip> // 包含std::fixedint main() {//浮点数double number 3.1415926;//转换工具类streamstd::stringstream stream;stream << s…

U-boot(三):start.S

本文主要探讨x210的uboot的start.S文件,也是uboot启动的第一阶段。 头文件 config.h config.h x210_sd.h,由mkconfig脚本生成,包含了开发板的配置宏 rootkaxi-virtual-machine:~/qt_x210v3s_160307/uboot/include# cat config.h /* Automatically generate…

LangChain 组件

输入输出模块 该模块负责与LLM做交互&#xff0c;通过该接口向模型输入 Prompt 并提取模型输出信息。主要包括&#xff1a;提示词、语言模型&#xff0c;输出解析器。 数据连接 已训练好的大语言模型&#xff0c;在训练时使用了大量的训练数据&#xff0c;但这些训练数据中可能…

Windows 下 Sublime Text 2.0.2 下载及配置

1 下载地址&#xff1a; https://www.sublimetext.com/2 Sublime Text 2.0.2 (此版本选择了 portable version)&#xff0c;直接解压就可以使用。 https://download.sublimetext.com/Sublime Text 2.0.2.zip 2 配置Python相关环境 (前提 Pyhon 已加入环境变量) 2.1 新建 py …

为什么大家都不用postman而选择 Apifox呢?

丢掉 Postman&#xff0c;Apifox 更香 作为开发者&#xff0c;丢掉 Postman 和 Jmeter吧&#xff0c;这款国产 API 工具更香&#xff0c;更安全&#xff01;一键即可导入 Postman 数据&#xff01; 一、Apifox 是什么&#xff1f; 1、Apifox 定位 Apifox Postman Swagger …

安全项目简介

安全项目 基线检查 密码 复杂度有效期 用户访问和身份验证 禁用administrator禁用guest认证失败锁定 安全防护软件操作系统安全配置 关闭自动播放 文件和目录权限端口限制安全审计… 等保测评 是否举办了安全意识培训是否有应急响应预案有无第一负责人 工作内容 测评准备…