当前位置: 首页 > news >正文

【基础】Three.js 自定义几何体和复制几何体

通过自定义顶点数据,可以创建任意的几何体。像threejs的长方体BoxGeometry、球体SphereGeometry等几何体都是基于BufferGeometry类构建的,它表示一个没有任何形状的空几何体。
请添加图片描述

1. 自定义点模型

通过javascript 类型化数组 Float32Array创建一组xyz坐标数据用来表示几何体的顶点坐标。每3个一组为一个坐标点。
在这里插入图片描述

point.ts文件:

import * as THREE from "three";//创建一个空的几何体对象
const geometry = new THREE.BufferGeometry();//类型化数组创建顶点数据
const vertices = new Float32Array([0,0,0, //顶点1坐标20,0,0, //顶点2坐标20,20,0, //顶点3坐标0,20,0, //顶点4坐标10,30,30, //顶点5坐标10,40,15, //顶点6坐标
]);// 创建属性缓冲区对象: 3个为一组,表示一个顶点的xyz坐标
const attribute = new THREE.BufferAttribute(vertices, 3);
geometry.attributes.position = attribute; // 设置几何体attributes属性的位置属性// 点材质
const material = new THREE.PointsMaterial({color: 0xffff00,size: 2.0, //点对象像素尺寸
});
const points = new THREE.Points(geometry, material); // 点对象
export {points}

主文件:

<template><div class="wrapper"><div ref="threeRef"></div></div>
</template>
<script setup lang="ts">
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
import { points} from "./components/points";
import { onMounted, ref } from "vue";
const threeRef = ref();onMounted(() => {// 场景const scene = new THREE.Scene();// 添加点进入场景scene.add(points);// 相机const camera = new THREE.PerspectiveCamera(75,window.innerWidth / window.innerHeight,0.1,1000);camera.position.set(50, 50, 50); // 相机位置// 渲染器const renderer = new THREE.WebGLRenderer({antialias: true, // 设置锯齿属性,为了获得更好的图像质量});// 定义threejs输出画布的尺寸(单位:像素px)renderer.setSize(window.innerWidth, window.innerHeight);// 为了适应不同的硬件设备屏幕,设置设备像素比renderer.setPixelRatio(window.devicePixelRatio);// 插入到任意HTML元素中threeRef.value.append(renderer.domElement);renderer.render(scene, camera);// AxesHelper:辅助观察的坐标系const axesHelper = new THREE.AxesHelper(50);scene.add(axesHelper);// 可拖拽查看模型const controls = new OrbitControls(camera, renderer.domElement);controls.addEventListener("change", function () {renderer.render(scene, camera); //执行渲染操作});window.onresize = function () {// 更新相机纵横比camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();// 更新渲染器的大小renderer.setSize(window.innerWidth, window.innerHeight);};
});
</script>
<style scoped></style>

2. 自定义线模型

new THREE.Line( geometry, material ); 创建一条连续的线
在这里插入图片描述

new THREE.LineLoop( geometry, material ); 创建环线
在这里插入图片描述

new THREE.LineSegments( geometry, material ); 创建线段
在这里插入图片描述
(为了观察由哪些点生成的线,保留了点模型)

//创建一个空的几何体对象
const geometry = new THREE.BufferGeometry();//类型化数组创建顶点数据
const vertices = new Float32Array([0,0,0, //顶点1坐标20,0,0, //顶点2坐标20,20,0, //顶点3坐标0,20,0, //顶点4坐标10,30,30, //顶点5坐标10,40,15, //顶点6坐标
]);// 创建属性缓冲区对象: 3个为一组,表示一个顶点的xyz坐标
const attribute = new THREE.BufferAttribute(vertices, 3);
geometry.attributes.position = attribute; // 设置几何体attributes属性的位置属性// 点材质
const material = new THREE.PointsMaterial({color: 0xffff00,size: 2.0, //点对象像素尺寸
});
// 线材质
const material1 = new THREE.LineBasicMaterial({color: 0xff0000, //线条颜色
});
const points = new THREE.Points(geometry, material); // 点对象
const lines = new THREE.Line(geometry, material1); // 线对象
export {points,lines } // 在主文件中引入,并添加到场景中即可

4. 网格模型(三角形概念)

网格模型Mesh其实就一个一个三角形(面)拼接构成。使用网格模型Mesh渲染几何体geometry,就是几何体所有顶点坐标三个为一组,构成一个三角形,多组顶点构成多个三角形,就可以用来模拟表示物体的表面。

可见性:
三个顶点的顺序是【逆时针】方向,该面视为【正面】
三个顶点的顺序是【顺时针】方向,该面视为【反面】,默认不可见
在这里插入图片描述

import * as THREE from "three";//创建一个空的几何体对象
const geometry = new THREE.BufferGeometry();
//顶点数据
const vertices = new Float32Array([0, 0, 0, //顶点1坐标50, 0, 0, //顶点2坐标50,50, 0, //顶点3坐标
]);
// 创建属性缓冲区对象: 3个为一组,表示一个顶点的xyz坐标
const attribute = new THREE.BufferAttribute(vertices, 3);
geometry.attributes.position = attribute; // 设置几何体attributes属性的位置属性// 网格模型:
const material = new THREE.MeshBasicMaterial({color: 0xffff00, //材质颜色//   side: THREE.BackSide,// 仅有反面可见side: THREE.DoubleSide, //两面可见transparent: true, // 开启透明opacity: 0.5, //透明度
});
const flat = new THREE.Mesh(geometry, material); // 网格对象
export { flat };

4. 自定义矩形平面

一个矩形平面,可以至少通过两个三角形拼接而成,而且两个三角形是紧密贴合的,所以会存在两个相同的坐标点。
注意:为了让两个三角形的正反面显示一致,每一个三角形顶点的的顺序应该保持一致!!
在这里插入图片描述
在这里插入图片描述

import * as THREE from "three";//创建一个空的几何体对象
const geometry = new THREE.BufferGeometry();
//顶点数据
const vertices = new Float32Array([0, 0, 0, //顶点1坐标80, 0, 0, //顶点2坐标80, 80, 0, //顶点3坐标0, 0, 0, //顶点4坐标   和顶点1位置相同80, 80, 0, //顶点5坐标  和顶点3位置相同0, 80, 0, //顶点6坐标
]);// 创建属性缓冲区对象: 3个为一组,表示一个顶点的xyz坐标
const attribute = new THREE.BufferAttribute(vertices, 3);
geometry.attributes.position = attribute; // 设置几何体attributes属性的位置属性// 网格模型:
const material = new THREE.MeshBasicMaterial({color: 0xffff00, //材质颜色//   side: THREE.BackSide,// 仅有反面可见side: THREE.DoubleSide, //两面可见transparent: true, // 开启透明opacity: 0.5, //透明度
});
const flat = new THREE.Mesh(geometry, material); // 网格对象
export { flat };

也可以使用几何体顶点索引数据geometry.index来实现
在这里插入图片描述

import * as THREE from "three";//创建一个空的几何体对象
const geometry = new THREE.BufferGeometry();
//顶点数据
const vertices = new Float32Array([0, 0, 0, //顶点1坐标80, 0, 0, //顶点2坐标80, 80, 0, //顶点3坐标0, 80, 0, //顶点6坐标
]);// Uint16Array类型数组创建顶点索引数据
const indexes = new Uint16Array([// 下面索引值对应顶点位置数据中的顶点坐标0, 1, 2, 0, 2, 3,
]);
// 索引数据赋值给几何体的index属性
geometry.index = new THREE.BufferAttribute(indexes, 1); //1个为一组// 创建属性缓冲区对象: 3个为一组,表示一个顶点的xyz坐标
const attribute = new THREE.BufferAttribute(vertices, 3);
geometry.attributes.position = attribute; // 设置几何体attributes属性的位置属性// 网格模型
const material = new THREE.MeshBasicMaterial({color: 0xffff00, //材质颜色//   side: THREE.BackSide,// 仅有反面可见side: THREE.DoubleSide, //两面可见transparent: true, // 开启透明opacity: 0.5, //透明度
});
const flat = new THREE.Mesh(geometry, material); // 网格对象
export { flat };

如果将材质更换成其他受光照影响的材质,比如MeshLambertMaterial,则无法正常显示平面,因为受光照影响的材质,需要给几何体设置顶点法线

// 每个顶点的法线数据和顶点位置数据一一对应
const normals = new Float32Array([0,0,1, //顶点1法线( 法向量 )0,0,1, //顶点2法线0,0,1, //顶点3法线0,0,1, //顶点4法线
]);
// 设置几何体的顶点法线属性.attributes.normal
geometry.attributes.normal = new THREE.BufferAttribute(normals, 3);
// 网格模型:
const material2 = new THREE.MeshLambertMaterial({color: 0xffff00, //材质颜色//   side: THREE.BackSide,// 仅有反面可见side: THREE.DoubleSide, //两面可见transparent: true, // 开启透明opacity: 0.5, //透明度
});

在场景中添加光源:

  //环境光const ambientLight = new THREE.AmbientLight(0xffffff, 0.4);scene.add(ambientLight);// 平行光const directionalLight = new THREE.DirectionalLight(0xffffff, 1);// 设置光源的方向:通过光源position属性和目标指向对象的position属性计算directionalLight.position.set(10, 15, 25);// 方向光指向对象网格模型directionalLight.target = flat;

5. 内置原始几何体

请添加图片描述

import * as THREE from "three";
// 立方体
const geometry1 = new THREE.BoxGeometry(8, 8, 8);
// 球体
const geometry2 = new THREE.SphereGeometry(10);const material1 = new THREE.MeshLambertMaterial({color: 0x00ffff,wireframe: true, //线条模式渲染mesh对应的三角形数据
});
const material2 = new THREE.MeshLambertMaterial({color: 0xffffff,wireframe: true, //线条模式渲染mesh对应的三角形数据
});
const box = new THREE.Mesh(geometry1, material1);
const sphere = new THREE.Mesh(geometry2, material2);
// 位置平移
sphere.translateX(-15);
box.translateX(-15);// 克隆一个box对象
const box2 = box.clone();
// 克隆几何体材质,并重新设置的材质和几何体属性
box2.material = box.material.clone();
box2.material.color.set(0xff0000);
box2.translateY(15);
// 缩小尺寸
box2.scale.set(0.5, 0.5, 0.5);
export {  sphere, box, box2 };

https://threejs.org/docs/index.html?q=geo#api/zh/geometries/BoxGeometry

添加循环动画:

  // 渲染循环function render() {box.rotateY(0.01); // 旋转动画sphere.rotateY(-0.01);// 同步box2和box的角度,不管box姿态角度怎么变化,box2始终保持同步box2.rotation.copy(box.rotation);renderer.render(scene, camera);requestAnimationFrame(render);}render();

🔍【基础】Three.js的零基础入门篇(附案例代码)
🔍【基础】Three.js中添加操作面板,GUI可视化调试(附案例代码)
🔍【基础】Three.js加载纹理贴图、加载外部gltf格式文件

相关文章:

【基础】Three.js 自定义几何体和复制几何体

通过自定义顶点数据&#xff0c;可以创建任意的几何体。像threejs的长方体BoxGeometry、球体SphereGeometry等几何体都是基于BufferGeometry类构建的&#xff0c;它表示一个没有任何形状的空几何体。 1. 自定义点模型 通过javascript 类型化数组 Float32Array创建一组xyz坐标…...

如何使用ChatGPT进行高效的对话生成与优化

目录 一、对话生成的基础原理 二、如何优化对话生成的流畅性与上下文关联性 1. 提示词优化&#xff1a;明确上下文和期望目标 示例&#xff1a;提示词优化 2. 调整生成参数&#xff1a;控制生成长度与内容多样性 示例&#xff1a;调整生成参数 3. 上下文管理&#xff1a…...

MySQL系列—8.存储结构

目录 1.系统表空间 ibdata 2.通用表空间 .ibd 3.独立表空间 4.Undo 表空间 5.临时表空间 6.Redo Log File 1.系统表空间 ibdata 系统表空间由参数innodb_data_file_path定义路径、初始化大小、自动扩展策略 如&#xff1a; innodb_data_file_path/dayta/mysql/ibdata1:…...

vue2、vue3生成二维码

Vue2版&#xff1a; 工具&#xff1a;使用 qrcodejs插件来生成二维码 安装&#xff1a;npm install qrcodejs2 qrcodejs官网地址&#xff1a; https://davidshimjs.github.io/qrcodejs/https://davidshimjs.github.io/qrcodejs/ 代码示例&#xff1a; <template><…...

Spring Cloud全解析:熔断之Hystrix线程隔离导致的问题

Hystrix线程隔离 在微服务框架中&#xff0c;可能一个服务需要调用多个微服务&#xff0c;在tomcat中运行时&#xff0c;tomcat只是分配了100个线程&#xff0c;由于多个服务之间调用的时间消耗过长&#xff0c;可能会导致线程耗尽&#xff0c;而在Hystrix中存在线程隔离&…...

网络编程项目(云词典项目)

目录 一、功能要求 服务器 用户客户端 二、演示效果 1.登录、注册功能 2. 查单词功能 3.查看历史纪录功能 三、项目代码 1.头文件 2.服务器 3.用户端 一、功能要求 仿照云词典的原理&#xff0c;实现云词典功能&#xff0c;用户可以查询输入的单词的英文解释&…...

Java Spring Boot 项目中的密码加密与验证开发案例手册

本手册主要针对Java项目中的账号密码加密与验证进行详细的步骤讲解和代码示例。适用于开发登录认证、用户管理等功能的场景。文档包含工具类的创建、数据库配置、服务层和控制器层的集成等常见操作。 1. 常用加密操作 在实现安全的登录功能时&#xff0c;密码加密与验证是不可…...

VueSax-解决Vue3报错问题,并支持typescript

以下为坑点 根据官方提示&#xff0c;本人在vue3typescript的项目中添加了vuesax的组件依赖 根据正常的导入依赖思路编写代码&#xff0c;发现typescript一直报 查询vuesax的目录文件发现存在ts文件&#xff0c;于是乎觉得是自己的问题&#xff0c;就查阅gpt与网上资料&#x…...

回归预测 | Matlab基于贝叶斯算法优化XGBoost(BO-XGBoost/Bayes-XGBoost)的数据回归预测+交叉验证

回归预测 | Matlab基于贝叶斯算法优化XGBoost(BO-XGBoost/Bayes-XGBoost)的数据回归预测交叉验证 目录 回归预测 | Matlab基于贝叶斯算法优化XGBoost(BO-XGBoost/Bayes-XGBoost)的数据回归预测交叉验证效果一览基本介绍程序设计参考资料 效果一览 基本介绍 Matlab实现基于贝叶…...

[数据集][目标检测]电动车入梯进电梯电单车入梯检测数据集VOC+YOLO格式7106张3类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;7106 标注数量(xml文件个数)&#xff1a;7106 标注数量(txt文件个数)&#xff1a;7106 标注…...

大数常用API

package API;public class BigNum {//如果普通的long和double的精度不足以满足要求&#xff0c;那么可以使用java.math包中的两个类//BigInteger和BigDecimal//前者实现任意精度的整数运算&#xff0c;后者实现任意精度的浮点数运算//BigInteger add(BigInteger other)//BigInt…...

Gartner发布ASCA自动化安全控制评估创新洞察:三年后40%的综合安全厂商都将提供ASCA功能

复杂的安全控制网络、技能差距和快速变化的攻击技术使维持技术安全控制的最佳配置的问题更加复杂。安全和风险管理领导者可以通过自动化安全控制评估来改善他们的安全状况。 主要发现 技术安全控制配置错误是与安全漏洞相关的长期问题。薄弱的安全默认值、配置漂移、为减少误报…...

使用lspci命令获取加速卡型号

文章目录 前言一、lspci -nn 获取具体厂商及设备ID二、使用步骤三、使用3080Ti再查询一下 前言 新到的实验机器和加速卡&#xff0c;安装好之后发现lspci命令没有显示型号&#xff0c;这里记录下使用 Vendor ID和Device ID 通过网页查询获取加速卡具体型号的过程。 一、lspci …...

php代码实例强制下载文件代码例子

php代码实例强制下载文件代码例子 $filename $_GET[file]; //Get the fileid from the URL // Query the file ID $query sprintf("SELECT * FROM tableName WHERE id %s",mysql_real_escape_string($filename)); $sql mysql_query($query); if(mysql_num_rows…...

Opencv中的直方图(3)直方图比较函数compareHist()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 比较两个直方图。 函数 cv::compareHist 使用指定的方法比较两个密集或两个稀疏直方图。 该函数返回 d ( H 1 , H 2 ) d(H_1, H_2) d(H1​,H2​…...

压力测试(内存、磁盘、网络、cpu)

压力测试 1. 内存压力测试工具stressmemtester 2. 磁盘压力测试工具fio (Flexible I/O Tester)dd (Data Duplicator) 3. 网络压力测试工具iperf3speedtest-cli 4. CPU压力测试工具stress-ng 为了满足更详细的需求&#xff0c;以下是针对内存、磁盘和网络压力测试工具的更深入介…...

ArcGIS JSAPI 高级教程 - ArcGIS Maps SDK for JavaScript - 原生代码实现动态扩散效果

ArcGIS JSAPI 高级教程 - ArcGIS Maps SDK for JavaScript - 原生代码实现动态扩散效果 核心代码完整代码&#xff1a;在线示例 ArcGIS Maps SDK for JavaScript 从 4.29 开始增加 RenderNode 类&#xff0c;可以添加数据以及操作 FBO&#xff08;ManagedFBO&#xff09;&#…...

Java 设计模式-代理模式

目录 概述 一. 什么是代理模式 1. 举例说明 二. 代理模式作用 1. 保护代理 2. 增强功能 3. 代理交互 4. 远程代理&#xff1a; 三. 代理模式3个角色 四. 静态代理 1. 代码示例&#xff1a; 五. JDK动态代理 1. 代码示例&#xff1a; 六. CGLIB 动态代理 1.代码示…...

CTF靶场之BUUCTF介绍

最后开始关注CTF&#xff0c;我们先了解一下什么CTF:CTF&#xff08;Capture The Flag&#xff09;中文一般译作夺旗赛&#xff0c;在网络安全领域中指的是网络安全技术人员之间进行技术竞技的一种比赛形式,最后以夺取FLAG为成功。 从网上找了一个免费的靶场——BUUCTF&#xf…...

学会分析问题,画出分析图,解释问题过程,找出规律 ;整数数组分为左右2个部分,左边位奇数右边偶数

// 整数数组左边是奇数右边是偶数.cpp : Defines the entry point for the console application. //#include "stdafx.h" #include<stdio.h> void swap(int& a,int& b) {int tempa;ab;btemp; } int main(int argc, char* argv[]) {int a[7]{1,2,3,4,5,…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

基础测试工具使用经验

背景 vtune&#xff0c;perf, nsight system等基础测试工具&#xff0c;都是用过的&#xff0c;但是没有记录&#xff0c;都逐渐忘了。所以写这篇博客总结记录一下&#xff0c;只要以后发现新的用法&#xff0c;就记得来编辑补充一下 perf 比较基础的用法&#xff1a; 先改这…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

免费PDF转图片工具

免费PDF转图片工具 一款简单易用的PDF转图片工具&#xff0c;可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件&#xff0c;也不需要在线上传文件&#xff0c;保护您的隐私。 工具截图 主要特点 &#x1f680; 快速转换&#xff1a;本地转换&#xff0c;无需等待上…...