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

news2024/9/20 8:07:38

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

想将一个几何体 以线框形式展现 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.coloradmin.cn/o/1370184.html

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

相关文章

删除并获得点数(动态规划)

1.状态表示 2.状态转移方程 3.初始化 f[ 0 ] arr[ 0 ] g[ 0 ] 0; 4.填表 从左往右填表,两个表同时填 5.返回值 max( f[n-1] , g[n-1] )

如何用浏览器制作二维码?多种二维码在线制作技巧

二维码现在的用途有很多,除了我们最常见的扫码支付功能之外,现在也可以用来承载视频、图片、文件等内容,将数据储存在云端,通过扫码来查看内容;还可以用于做问卷、签到、报名等用途,用来收集用户数据信息。…

聚道云软件连接器助力某餐饮管理有限公司实现人力资源信息自动化

客户介绍: 某餐饮管理有限公司是一家集餐饮连锁、餐饮管理、餐饮咨询等业务于一体的综合性餐饮企业。公司业务遍布全国多个城市,拥有众多员工。 添加图片注释,不超过 140 字(可选) 客户痛点: 员工入离职…

如何做好档案统一管理?

档案统一管理是指将一个组织或机构的所有档案资料进行集中管理和整理的一种管理方式。档案统一管理的目标是确保档案的完整性、准确性和可访问性,提高档案的利用价值和管理效率。 要做好档案统一管理,需要以下几个步骤: 1. 确定档案的分类与命…

Nginx配置反向代理实例一

Mac 安装Nginx教程 提醒一下:下面实例讲解是在Mac系统演示的; 反向代理实例一实现的效果 在浏览器地址栏输入www.testproxy.com, 跳转到系统Tomcat主页面。 反向代理准备工作 第一步:在系统的 hosts 文件进行ip和域名对应关系的配置。 …

Django入门教程|Auth登录实战

前言 目标:实现用户登录和注销功能。涉及django登录知识点,如登录的用户名密码如何验证,输出错误如何提示,当用户未登陆时访问功能页面如何让用户去登录(DjangoAuth,类似过滤器)等。 效果图 开…

Vue3导出el-table为execl文件

在开发时遇到了这样的需求,整理之后向大家分享一下,欢迎积极讨论与指正哦 因为在实现表格时使用了分页插件,在导出时只能导出本页的内容,最后选择了这样的方法: 正常显示的表格使用分页后的数据 在这里设置了id 而用…

电力监控系统在数据中心应用

摘 要:在电力系统的运行过程中,变电站作为整个电力系统的核心,在保证电力系统可靠的运行方面起着至关重要的作用,基于此需对变电站监控系统的特点进行分析,结合变电站监控系统的功能需求,对变电站电力监控系…

Linux的网络设置

一.查看网络配置 1.查看网络接口信息 - ifconfig ① 直接使用 ifconfig 命令 默认显示活动的网卡 解析: ② ifconfig 具体网卡名称 只显示具体的网卡的信息 ③ ifconfig -a 显示所有的网卡 ④ ifconfig 网卡名称 down 关闭网卡 ifdown 关闭网卡 …

GO语言笔记2-变量与基本数据类型

变量使用步骤 声明赋值使用 package main import "fmt" func main(){var age int //声明一个 int类型的变量叫ageage 18 //给变量用 赋值fmt.Println(age) //使用变量 输出变量的值 } 编译运行输出变量值 变量的四种使用方式 package main import "fmt&q…

[足式机器人]Part2 Dr. CAN学习笔记-动态系统建模与分析 Ch02-8 Bode Plot伯德图

本文仅供学习使用 本文参考: B站:DR_CAN Dr. CAN学习笔记-动态系统建模与分析 Ch02-8 Bode Plot伯德图 Bode Plot 手绘技巧与应用

在线文本转语音工具的实现

文章目录 文章最下面有工具链接!前言edge-tts库1.首先使用pip安装这个库2.写一段示例代码3.多线程 pydub库1.介绍2.示例 将他们整合起来我把他们部署到了我的服务器上,可以在线使用点我使用工具 文章最下面有工具链接! 前言 最近有文字转语…

将Llama2上下文长度扩展100倍;效率更高的SeTformer;LLM准确度基本不变加速1.56×;FreeTalker

本文首发于公众号:机器感知 将Llama2上下文长度扩展100倍;效率更高的SeTformer;LLM准确度基本不变加速1.56;FreeTalker Latte: Latent Diffusion Transformer for Video Generation 本文使用Latent Diffusion Transformer(Latte…

程序媛的mac修炼手册-- 终端(terminal)常用命令

「终端(terminal)」相当于macOS的一个 App ,它的特殊之处是,它是管理其它App的App,操作主要通过命令行界面 (CLI) 。 相比于我们日常熟悉的用户界面(User Interface,UI)&#xff0c…

go image.DecodeConfig 和image.Decode 不能同时使用吗

问题场景:在同时使用go image.DecodeConfig 和image.Decode获取图片信息时,报错提示: 无法读取图像配置 image: unknown format package mainimport ("fmt""github.com/golang/freetype""image""image/d…

GPT在地学、GIS、气象、农业、生态、环境等领域应用教程

详情点击链接:GPT在地学、GIS、气象、农业、生态、环境等领域应用教程 一开启大模型 1 开启大模型 1)大模型的发展历程与最新功能 2)大模型的算法构架与底层逻辑 3)大模型的强大功能与应用场景 4)国内外经典大模型(ChatGPT、LLaMA、Gemini、DALLE、…

【echarts】雷达图参数详细介绍

1. 详细示例 var option {tooltip: {trigger: item},radar: {startAngle: 90,//第一个指示器轴的角度,默认90indicator: [// 指示器{ name: Category A, max: 220 },// name:指示器名称{ name: Category B, max: 200 },// max:指示器的最大值,可选&…

【JAVA】throw 和 throws 的区别?

🍎个人博客:个人主页 🏆个人专栏: JAVA ⛳️ 功不唐捐,玉汝于成 目录 前言 正文 throw: throws: 区别: 作用: 使用位置: 个数: 应…

第1章 初识JavaScript

学习目标 了解JavaScript基本概念,能够说出JavaScript的作用、由来、组成和特点 熟悉常见浏览器的特点,能够说出浏览器的组成以及作用 掌握下载和安装Visual Studio Code编辑器,能够独立完成编辑器的下载和安装 掌握JavaScript代码引入方式…

【forwardRef与useImperativeHandle】

1、 2、 3、 4、代码 1、index.tsx代码 import React, {useRef, useEffect} from react import MyInput from "./InputItem";export default function Index() {const ref useRef<any>(null);useEffect(() > {ref.current?.focus();}, [])return (<&…