WEB 3D技术 three.js 线框几何体

本文 我们说一下 线框几何体

想将一个几何体 以线框形式展现 threeJS中 有两种类可以实现
第一种 WireframeGeometry
在这里插入图片描述
这种几何体 其实就类似于 将材质中的 wireframe 开启 这种方法 之前我们也用过

还有一种 就是 EdgesGeometry 边缘几何体
在这里插入图片描述
我们先将代码写成这样

import './style.css'
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";//创建相机
const camera = new THREE.PerspectiveCamera(45, //视角 视角越大  能看到的范围就越大window.innerWidth / window.innerHeight,//相机的宽高比  一般和画布一样大最好0.1,1000
);
const scene = new THREE.Scene();
const gltfLoader = new GLTFLoader();
gltfLoader.load("/gltf/scene.gltf",(gltf) => {gltf.scene.traverse((child) => {if (child.isMesh) {child.frustumCulled = false;child.castShadow = true;child.material.emissive = child.material.color;child.material.emissiveMap = child.material.map;}});scene.add(gltf.scene);}
);//c创建一个canvas容器  并追加到 body上
const renderer = new THREE.WebGLRenderer(0);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);//设置相机位置   这里 我们设置Z轴  大家可以试试  S Y 和 Z  都是可以的
camera.position.z = 5;
//设置相机默认看向哪里   三个 0  代表 默认看向原点
camera.lookAt(0, 0, 0);
//将内容渲染到元素上
renderer.render(scene, camera);
const controls = new OrbitControls(camera, renderer.domElement);function animate() {controls.update();requestAnimationFrame(animate);/*cube.rotation.x += 0.01;cube.rotation.y += 0.01;*/renderer.render(scene, camera);
}
animate();

gltf/scene.gltf 是我项目中的一个 gltf 3D资源文件
在这里插入图片描述
现在 我希望用边缘几何体 将这个3D元素 拆解显示
那么 先这样改一下

const gltfLoader = new GLTFLoader();
gltfLoader.load("/gltf/scene.gltf",(gltf) => {gltf.scene.traverse((child) => {if (child.isMesh) {child.frustumCulled = false;child.castShadow = true;child.material.emissive = child.material.color;child.material.emissiveMap = child.material.map;let geometry = child.geometry;let edgesGeometry = new THREE.EdgesGeometry(geometry);}});scene.add(gltf.scene);}
);

threeJS中 LineSegments 可以生成线段
在这里插入图片描述
但是 现在 我们需要先用 LineBasicMaterial 创建一个线段的材质
在这里插入图片描述
整个复制 然后 我们只需要里面的 color 颜色属性
在这里插入图片描述
都弄好之后 我们就可以通过 LineSegments 生成一个线框几何体 然后将他add到场景中了
整体代码如下

const gltfLoader = new GLTFLoader();
gltfLoader.load("/gltf/scene.gltf",(gltf) => {gltf.scene.traverse((child) => {if (child.isMesh) {child.frustumCulled = false;child.castShadow = true;child.material.emissive = child.material.color;child.material.emissiveMap = child.material.map;let geometry = child.geometry;let edgesGeometry = new THREE.EdgesGeometry(geometry);const material = new THREE.LineBasicMaterial( {color: 0xffffff} );let edges = new THREE.LineSegments(edgesGeometry, material);// 添加倒场录scene.add(edges);}});scene.add(gltf.scene);}
);

但是运行之后 你会发现 两个几何体重合了
在这里插入图片描述
我们这里 可以将这个线框几何体 移动一下
在这里插入图片描述
然后 我们线框几何体就前面去了
在这里插入图片描述
但是 这里 我们明显发现 我们原来的3D元素 是有旋转的 但是线框几何体没有
这边 我们可以通过世界举证 解决这个问题

我们这样写

const gltfLoader = new GLTFLoader();
gltfLoader.load("/gltf/scene.gltf",(gltf) => {gltf.scene.traverse((child) => {if (child.isMesh) {child.frustumCulled = false;child.castShadow = true;child.material.emissive = child.material.color;child.material.emissiveMap = child.material.map;let geometry = child.geometry;let edgesGeometry = new THREE.EdgesGeometry(geometry);const material = new THREE.LineBasicMaterial( {color: 0xffffff} );let edges = new THREE.LineSegments(edgesGeometry, material);// 添加倒场录child.updateMatrixWorld(true, true);edges.matrix.copy(child.matrixWorld);edges.matrix.decompose(edges.position, edges.quaternion, edges.scale, edges.rotation);scene.add(edges);}});scene.add(gltf.scene);}
);

decompose 会同步他们的旋转 位置等属性
但是 我们这里 好像是用顶点旋转做的
在这里插入图片描述
那直接简单粗暴 我们直接也旋转它

在这里插入图片描述
直接改 rotation 属性
在这里插入图片描述
然后 前面也说了 还有一种 WireframeGeometry 线框几何体的方式
直接将

let edgesGeometry = new THREE.EdgesGeometry(geometry);

换成

let edgesGeometry = new THREE.WireframeGeometry(geometry);

因为他也是 可以直接传入原几何体对象 然后生成几何体内容 通过材质 LineSegments
就可以用了的

const gltfLoader = new GLTFLoader();
gltfLoader.load("/gltf/scene.gltf",(gltf) => {gltf.scene.traverse((child) => {if (child.isMesh) {child.frustumCulled = false;child.castShadow = true;child.material.emissive = child.material.color;child.material.emissiveMap = child.material.map;let geometry = child.geometry;const material = new THREE.LineBasicMaterial( {color: 0xffffff} );let edgesGeometry = new THREE.WireframeGeometry(geometry);let edges = new THREE.LineSegments(edgesGeometry, material);// 添加倒场录child.updateMatrixWorld(true, true);edges.matrix.copy(child.matrixWorld);edges.matrix.decompose(edges.position, edges.quaternion, edges.scale, edges.rotation);scene.add(edges);}});//scene.add(gltf.scene);}
);

在这里插入图片描述
这种 看着就会乱很多 因为整体都是 三角形构成的

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【深度学习每日小知识】Data Augmentation 数据增强

数据增强是通过对原始数据进行各种转换和修改来人工生成附加数据的过程,旨在增加机器学习模型中训练数据的大小和多样性。这对于计算机视觉领域尤为重要,因为图像经常被用作输入数据。 计算机视觉中的数据增强 数据增强的主要目标是解决过拟合问题&…

使用迭代优化递归程

王有志,一个分享硬核Java技术的互金摸鱼侠加入Java人的提桶跑路群:共同富裕的Java人 今天我们将会分析上篇文章中递归算法存在的问题,并通过迭代去优化。 递归存在的问题 上一篇中,我们计算了序号10以内的斐波那契数。今天为了清…

【Leetcode】236.二叉树的最近公共祖先

一、题目 1、题目描述 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。” 示例1…

商品秒杀总结

秒杀模块编写思维总结 分为两种模式一个是限时购买,一个是限裤购买。 我们这里使用的是指定时间段下面的限库购买 单独使用一个库来存储数据,下面有两张表,一张表是具体的商品,一张表是订单。用户下的订单数据都要放到redis 中…

【Linux】journalctl和dmesg日志的区别

journalctl 和 dmesg 是两个在 Linux 系统中查看日志信息的工具,它们提供了不同层次和角度的系统日志。 journalctl: journalctl 是 systemd-journald 服务的一个前端,用于检查和查询系统日志。它使用 systemd 的日志系统,将日志信…

每日coding

今天无意点进一个回文串的题目,对于回文串我第一印象就用双指针,但是确实没写出来,看了评论区题解,绝大多数都是用dp来做的,但是找到一个用双指针做的,刚好延续思路,先把题目贴出来。 5、最长回…

64、图片预处理:Normalize

上一篇介绍了图像预处理中 resize 和 crop 的概念,在仓库的 python 预处理函数中,在 resize 和 crop之后,还有几个预处理的过程:一个是归一化,另外就是transpose 和reshape。 这一节就介绍一下,为什么在推理之前还需要对图像进行归一化。 归一化(Normalization) 在深…

Python用法:if __name__ == “__main__“的作用

文章目录 前言一、__name__是什么二、if __ name__ == __ main__语句的使用1.tempconv.py2.calc.py三、存在的问题查看__name__属性:四、总结前言 与C语言不同,Python是一种解释型脚本语言,在执行之前不同要将所有代码先编译成中间代码,Python程序运行时是从模块顶行开始,…

Nacos使用MySQL8时区问题导致启动失败

文章目录 配置下mysql的时区方式一 (永久)方式二(临时) 由于mysql8需要配置时区,如果不配置时区,nacos就连不上mysql,从而也就无法登录nacos自带的图形化界面 配置下mysql的时区 方式一 (永久) 直接修改配置文件&…

关于“Python”的核心知识点整理大全63

目录 20.2.11 使用 Git 跟踪项目文件 1. 安装Git 2. 配置Git 3. 忽略文件 .gitignore 注意 4. 提交项目 20.2.12 推送到 Heroku 注意 20.2.13 在 Heroku 上建立数据库 20.2.14 改进 Heroku 部署 1. 在Heroku上创建超级用户 注意 注意 20.2.11 使用 Git 跟踪项目文件…

Vue3-37-路由-组件内的路由守卫 onBeforeRouteLeave 和 onBeforeRouteUpdate

简介 组件内的路由守卫,实际上就是两个 API 方法。 他们与普通的守卫不同的是 : 他们是写在组件内的,在组件中监听路由的变化,不是全局的,比较灵活。 以下是两个 API 的功能说明:onBeforeRouteLeave() : 守…

Java中的序列化方法探索

.为什么要序列化 对象不序列化,能直接存储吗? 在 Java 中,序列化是将对象的状态信息转换为可以存储或传输的形式(例如,转换为字节流)的过程。在对象数据需要在网络上传输或需要在磁盘上持久化存储时&#…

指针的含义、表示、规范、存储、运用

指针的含义、表示、规范、存储、运用 指针的含义指针的表示指针的规范先声明再定义声明和定义一起表示错误表示 指针的存储理解一个变量的存储过程和原理理解一个指针的存储过程和原理理解多个指针的存储过程和原理 指针的运用 指针的含义 表示某个变量或数据所在的内存地址 注…

使用tailscale访问对端局域网上的其他设备

当tailscale客户端应用程序直接安装在组织中的每个客户端、服务器和虚拟机上时,Tailscale 效果最佳。这样,流量就会被端到端加密,并且无需配置即可在物理位置之间移动机器。 但是,在某些情况下,你不能或不想在每台设备…

Linux第18步_安装“Ubuntu系统下的C语言编GCC译器”

Ubuntu系统没有提供C/C的编译环境,因此还需要手动安装build-essential软件包,它包含了 GNU 编辑器,GNU 调试器,和其他编译软件所必需的开发库和工具。本节用于重点介绍安装“Ubuntu系统下的C语言编译器GCC”和使用。 1、在安装前…

图片纹理贴图

/* * 当需要给图形赋予真实颜色的时候&#xff0c;不太可能为没一个顶点指定一个颜色&#xff0c;通常会采用纹理贴图 * 每个顶点关联一个纹理坐标 (Texture Coordinate) 其它片段上进行片段插值 * */#include <iostream> #define STBI_NO_SIMD #define STB_IMAGE_IMPLE…

SQL窗口函数

一 什么是SQL窗口函数&#xff1f; SQL窗口函数说的是在查询现有的结果集的特定“窗口”&#xff08;即数据集的一个分区或整个结果集&#xff09;再作处理统计&#xff08;排序&#xff0c;聚合统计&#xff0c;如count,sum等&#xff09;&#xff0c;最简单的理解就是执行两…

Vim 用法详解

一、命令C&#xff1a;删除–>剪切–>进入插入模式 c命令详解&#xff1a; C or c$表示修改当前行上光标后面的部分. 进入编辑状态. c0 or c^表示从光标处到当前行行首的部分进行修改&#xff0c;^代表首个非空格处。 cc OR S修改当前行. 进入编辑状态. cw从光标所在…

【嵌入式移植】1、Ubuntu系统准备

Ubuntu系统准备 虚拟机与Ubuntu安装下载Ubuntu创建虚拟机系统配置 虚拟机与Ubuntu安装 嵌入式移植通常使用Linux操作系统的环境&#xff0c;使用Linux下的交叉编译工具链对BootLoader、kernel以及应用程序进行编译&#xff0c;然后下载运行。当然也可以通过各类IDE或者Windows…

从文本(.txt)文件中读取数据时出现中文乱码

前言 当需要从记事本中读取数据时&#xff0c;发现读取的数据会出现中文乱码&#xff0c;我尝试了C和C读取文件&#xff0c;发现都是这样。 乱码原因 文本文件的保存默认使用UTF-8编码方式&#xff0c;而VS编译器的编码方式是GBK&#xff0c;所以不同的编码方式导致了乱码。…