ThreeJS-3D教学十-有宽度的line
webgl中线是没有宽度的,现实的应用中一般做法都是将线拓宽成面来绘制。默认threejs的线宽是无法调节的,需要用有厚度的线 THREE.Line2。
先看效果图:

看下代码:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><style>body {width: 100%;height: 100%;}* {margin: 0;padding: 0;}.label {font-size: 20px;color: #000;font-weight: 700;}</style>
</head>
<body>
<div id="container"></div>
<script type="importmap">{"imports": {"three": "../three-155/build/three.module.js","three/addons/": "../three-155/examples/jsm/"}}
</script>
<script type="module">
import * as THREE from 'three';
import Stats from 'three/addons/libs/stats.module.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { GPUStatsPanel } from 'three/addons/utils/GPUStatsPanel.js';
import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';
import { Line2 } from 'three/addons/lines/Line2.js';
import { LineMaterial } from 'three/addons/lines/LineMaterial.js';
import { LineGeometry } from 'three/addons/lines/LineGeometry.js';
let stats, labelRenderer, gpuPanel;
let camera, scene, renderer, controls;
const group = new THREE.Group();
const matLines = [];
let once = true;
init();
initHelp();
initLight();
axesHelperWord();
animate();let data1 = [{x: -50,y: 50,z: 0},{x: 50,y: 50,z: 0},{x: 50,y: -50,z: 0},{x: -50,y: -50,z: 0},{x: -50,y: 50,z: 0}
];let data2 = [{x: -50,y: 0,z: 0},{x: 50,y: 1,z: 0}
];let data3 = [{x: -25,y: 25,z: 0},{x: 25,y: 25,z: 0},{x: 25,y: -25,z: 0},{x: -25,y: -25,z: 0},{x: -25,y: 25,z: 0}
];let positions1 = [];
let positions2 = [];
let positions3 = [];
let colors = [];
let l = data1.length;let color = new THREE.Color();data1.map((v, i) => {positions1.push(v.x, v.y, v.z);color.setHSL(i / l, 1.0, 0.5);colors.push(color.r, color.g, color.b);
});data2.map((v, i) => {positions2.push(v.x, v.y, v.z);color.setHSL(i / l, 1.0, 0.5);colors.push(color.r, color.g, color.b);
});data3.map((v, i) => {positions3.push(v.x, v.y, v.z);
});draw(positions1, colors);
draw(positions2, colors);
drawSolidLine(positions3, '#f00');function draw(positions, colors) {let geometry = new LineGeometry();// 虚线const matLine = new LineMaterial({// 只有白色 可以显示出渐变色的效果color: 0xffffff,linewidth: 10,vertexColors: THREE.VertexColors, // 单独设置顶点颜色//resolution: // renderer.render 时加上这个属性dashed: true,dashSize: 1,gapSize: 1,defines: {USE_DASH: ''}});let line = new Line2(geometry, matLine);line.scale.set(1, 1, 1);line.visible = true;scene.add(line);matLines.push(matLine);geometry.setPositions(positions);geometry.setColors(colors);line.computeLineDistances();
}function drawSolidLine(positions, color) {let geometry = new LineGeometry();// 虚线const matLine = new LineMaterial({// 只有白色 可以显示出渐变色的效果color: color,linewidth: 10,// vertexColors: THREE.VertexColors, // 单独设置顶点颜色// resolution: // renderer.render 时加上这个属性dashed: false});let line = new Line2(geometry, matLine);line.scale.set(1, 1, 1);line.visible = true;line.rotateX(Math.PI / 3);scene.add(line);matLines.push(matLine);geometry.setPositions(positions);line.computeLineDistances();
}function init() {camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 10, 2000 );camera.up.set(0, 1, 0);camera.position.set(60, 40, 60);camera.lookAt(0, 0, 0);scene = new THREE.Scene();scene.background = new THREE.Color( '#ccc' );renderer = new THREE.WebGLRenderer( { antialias: true } );renderer.setPixelRatio( window.devicePixelRatio );renderer.setSize( window.innerWidth, window.innerHeight );document.body.appendChild( renderer.domElement );labelRenderer = new CSS2DRenderer();labelRenderer.setSize( window.innerWidth, window.innerHeight );labelRenderer.domElement.style.position = 'absolute';labelRenderer.domElement.style.top = '0px';labelRenderer.domElement.style.pointerEvents = 'none';document.getElementById( 'container' ).appendChild( labelRenderer.domElement );controls = new OrbitControls( camera, renderer.domElement );// 设置最大最小视距controls.minDistance = 20;controls.maxDistance = 1000;window.addEventListener( 'resize', onWindowResize );stats = new Stats();stats.setMode(1); // 0: fps, 1: msdocument.body.appendChild( stats.dom );gpuPanel = new GPUStatsPanel( renderer.getContext() );stats.addPanel( gpuPanel );stats.showPanel( 0 );scene.add( group );
}function initLight() {const AmbientLight = new THREE.AmbientLight(new THREE.Color('rgb(255, 255, 255)'));scene.add( AmbientLight );
}function initHelp() {// const size = 100;// const divisions = 5;// const gridHelper = new THREE.GridHelper( size, divisions );// scene.add( gridHelper );// The X axis is red. The Y axis is green. The Z axis is blue.const axesHelper = new THREE.AxesHelper( 100 );scene.add( axesHelper );
}function axesHelperWord() {let xP = addWord('X轴');let yP = addWord('Y轴');let zP = addWord('Z轴');xP.position.set(50, 0, 0);yP.position.set(0, 50, 0);zP.position.set(0, 0, 50);
}function addWord(word) {let name = `<span>${word}</span>`;let moonDiv = document.createElement( 'div' );moonDiv.className = 'label';// moonDiv.textContent = 'Moon';// moonDiv.style.marginTop = '-1em';moonDiv.innerHTML = name;const label = new CSS2DObject( moonDiv );group.add( label );return label;
}function onWindowResize() {camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();renderer.setSize( window.innerWidth, window.innerHeight );
}function animate() {requestAnimationFrame( animate );// 这里请注意 // 把渲染窗口尺寸分辨率传值给材质LineMaterial的resolution属性// resolution属性值会在着色器代码中参与计算if (matLines.length && once) {matLines.forEach(matLine => {matLine.resolution.set(window.innerWidth, window.innerHeight); // resolution of the viewport});once = false;}stats.update();controls.update();labelRenderer.render( scene, camera );renderer.render( scene, camera );
}
</script>
</body>
</html>相关文章:
ThreeJS-3D教学十-有宽度的line
webgl中线是没有宽度的,现实的应用中一般做法都是将线拓宽成面来绘制。默认threejs的线宽是无法调节的,需要用有厚度的线 THREE.Line2。 先看效果图: 看下代码: <!DOCTYPE html> <html lang"en"> <he…...
安装Elasticsearch步骤(包含遇到的问题及解决方案)
注:笔者是在centos云服务器环境下安装的Elasticsearch 目录 1.安装前准备 2.下载Elasticsearch 3.启动Elasticsearch 非常容易出问题 第一次运行时,可能出现如下错误: 一、内存不足原因启动失败 二、使用root用户启动问题 三、启动ES自…...
网络编程面试笔试真题
网络编程笔试面试真题 1、关于Linux系统中多线程的信号处理,说法中不正确的是? A:在线程环境霞,产生的信号是传递给整个进程的 B:一般情况下,信号会随机给进程的一个线程 C:对某个信号处理函数…...
MySQL官方文档如何查看,MySQL中文文档
这里写自定义目录标题 MySQL官方文档如何查看MySQL中文文档 MySQL官方文档如何查看 MySQL官网地址:https://dev.mysql.com/doc/ 比如这里我要找InnoDB架构 MySQL中文文档 MySQL 5.1中文文档地址:https://www.mysqlzh.com/...
第七章:最新版零基础学习 PYTHON 教程—Python 列表(第四节 -如何在 Python 中查找列表的长度)
列表是 Python 日常编程不可或缺的一部分,所有 Python 用户都必须学习,了解其实用程序和操作是必不可少的,而且总是有好处的。因此,本文讨论了找到第一个这样的实用程序。使用Python 的列表中的元素。 目录 在 Python 中查找列表的长度...
XPS虽没流行,但还在使用!在Windows 10中打开XPS文件的最佳方法
当Windows Vista发布时,微软推出了XPS格式,这是PDF的替代品。XPS文件格式并不是什么新鲜事,但从未获得过多大的吸引力。 因此,XPS(XML Paper Specification)文件是微软对Adobe PDF文件的竞争对手。尽管XPS…...
23 种设计模式详解(C#案例)
🚀设计模式简介 设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时…...
@SpringBootApplication配置了scanBasePackages导致请求一直404,分析下原因
出现RequestMapping注解的Controller类可能是因为SpringBootApplication注解中配置了scanBasePackages导致的请求一直返回404错误。 SpringBootApplication注解是Spring Boot的核心注解之一,它用于启动Spring Boot应用程序。这个注解实际上是一个组合注解ÿ…...
{大厂漏洞 } OA产品存在SQL注入
0x01 漏洞介绍 江苏叁拾叁-OA是由江苏叁拾叁信息技术有限公司开发的一款OA办公平台,主要有知识管理,工作流程,沟通交流,辅助办公,集成解决方案,应用支撑平台,基础支撑等功能。 该系统也与江苏叁…...
6-8 舞伴问题 分数 15
void DancePartner(DataType dancer[], int num) {LinkQueue maleQueue SetNullQueue_Link();LinkQueue femaleQueue SetNullQueue_Link();// 将男士和女士的信息分别加入对应的队列for (int i 0; i < num; i) {if (dancer[i].sex M){EnQueue_link(maleQueue, dancer[i]…...
samba服务器的功能是什么
Samba服务器是一个开源的网络文件共享服务,其主要功能是在不同操作系统之间实现文件和打印机共享。它最常用于将Linux/Unix系统与Windows系统互联,但也支持其他操作系统。 以下是Samba服务器的主要功能: 文件共享:Samba允许用户在…...
MSQL系列(五) Mysql实战-索引最左侧匹配原则分析及实战
Mysql实战-索引最左侧匹配原则分析及实战 前面我们讲解了索引的存储结构,BTree的索引结构,以及索引最左侧匹配原则,Explain的用法,今天我们来实战一下 最左侧匹配原则 1.联合索引最左侧匹配原则 联合索引有一个最左侧匹配原则 …...
react|redux状态管理
react|redux状态管理 参考官网:https://cn.redux-toolkit.js.org/tutorials/quick-start 状态管理使用流程 1、安装: npm install react-redux reduxjs/toolkit2、创建store.js 通过configureStore的hook对reducer(或slice)进行…...
Python之旅----判断语句
布尔类型和比较运算符 布尔类型 布尔类型的定义 布尔类型的字面量: True 表示真(是、肯定) False 表示假 (否、否定) 也就是布尔类型进行判断,只会有2个结果:是或否 定义变量存储布尔类型…...
【JavaEE】文件操作和IO
1 什么是文件? 针对硬盘这种持久化存储的I/O设备,当我们想要进行数据保存时,往往不是保存成一个整体,而是独立成一个个的单位进行保存,这个独立的单位就被抽象成文件的概念 2 文件路径 文件路径就是指咱们文件系统中…...
python使用dataset快速使用SQLite
目录 一、官网地址 二、安装 三、 快速使用 一、官网地址 GitHub - pudo/dataset: Easy-to-use data handling for SQL data stores with support for implicit table creation, bulk loading, and transactions. 二、安装 pip install dataset 如果是mysql,则…...
Python 练习100实例(21-40)
Python 练习实例21 题目:猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天…...
“创新启变 聚焦增长”极狐(GitLab)媒体沟通会,共话智能时代软件开发新生态
10 月 18 日 北京 昨日,全球领先 AI 赋能 DevSecOps 一体化平台极狐(GitLab) 在北京举办了主题为“创新启变 聚焦增长”的媒体沟通会。极狐(GitLab) CEO 柳钢就“中国企业数字化转型、软件研发、技术自主可控等热点问题,以及 AI 大模型时代下,…...
【ChatGLM2-6B】在只有CPU的Linux服务器上进行部署
简介 ChatGLM2-6B 是清华大学开源的一款支持中英双语的对话语言模型。经过了 1.4T 中英标识符的预训练与人类偏好对齐训练,具有62 亿参数的 ChatGLM2-6B 已经能生成相当符合人类偏好的回答。结合模型量化技术,用户可以在消费级的显卡上进行本地部署&…...
Xilinx IP 10 Gigabit Ethernet Subsystem IP
Xilinx IP 10 Gigabit Ethernet Subsystem IP 10 Gb 以太网子系统在 10GBASE-R/KR 模式下提供 10 Gb 以太网 MAC 和 PCS/PMA,以提供 10 Gb 以太网端口。发送和接收数据接口使用 AXI4 流接口。可选的 AXI4-Lite 接口用于内部寄存器的控制接口。 • 设计符合 10 Gb 以太网规范…...
聊天记录会消失?这款开源工具让数据永远属于你
聊天记录会消失?这款开源工具让数据永远属于你 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/WeChatMsg …...
融智学三大基本定律——信息世界的根本法则体系:为跨模态知识处理、人机协同等前沿领域提供原理支撑
融智学三大基本定律——信息世界的根本法则体系摘要:融智学三大基本定律构成信息处理的核心理论体系。第一定律(实部序位关系唯一守恒)确立本质信息的稳定性;第二定律(实部序位同义并列对应转换)实现多元表…...
【个人推荐】一些好用的录音转写工具
因为助教课备课的缘故,需要录制讲座的音频以整理知识点。一次讲座的音频内容很长,即使3x速快进播放依然很耗费时间,因此录音转写的需求浮现了出来。于是闲暇之余探索了下市面上的录音转写工具,浅浅记录下体验。 下面主要推荐三款…...
Go性能剖析pprof工具使用
Go语言凭借其高效的并发模型和简洁的语法,成为众多开发者的首选。随着项目规模扩大,性能问题逐渐显现。如何快速定位性能瓶颈?Go内置的pprof工具正是解决这一问题的利器。本文将带你深入了解pprof的核心功能,助你轻松优化代码性能…...
SSM+Vue大学生兼职网站源码+论文
代码可以查看文章末尾⬇️联系方式获取,记得注明来意哦~🌹 分享万套开题报告任务书答辩PPT模板 作者完整代码目录供你选择: 《SpringBoot网站项目》1800套 《SSM网站项目》1500套 《小程序项目》1600套 《APP项目》1500套 《Python网站项目》…...
AI正冲击金融岗!高薪职业如何守住饭碗?金融人转行AI指南
AI技术正全面冲击金融行业,初级分析师、风控专员、客服等中低端认知劳动密集型岗位面临被替代风险。但高端投行、深度研究、资源型和创新型岗位短期内仍安全。金融人转型AI有独特优势,如数据敏感性、业务理解力等。转型路径包括AI应用专家、金融科技产品…...
IQR四分位数法是什么?
一、核心概念:四分位数与IQR1. 四分位数(Quartiles)将一组有序数据(从小到大排列)划分为4个相等部分的三个关键分割点,分别记为:Q1(第一四分位数,25%分位数)&…...
菊水PBZ40电源协议详解:从‘*IDN?’到波形设置,一份给硬件测试新人的避坑指南
菊水PBZ40电源协议实战手册:从基础指令到复杂波形配置的工程指南 第一次接触菊水PBZ40可编程电源时,面对满屏的协议指令和参数配置,不少硬件测试工程师都会感到无从下手。这台看似简单的设备,实际上隐藏着许多需要特别注意的细节…...
2025届学术党必备的六大AI科研工具推荐
Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek AI写作软件,是人工智能技术于内容创作领域的具体运用,正一步步改变传…...
CTF实战:手把手教你用fastcoll工具复现MD5碰撞攻击(附Python验证脚本)
CTF实战:手把手教你用fastcoll工具复现MD5碰撞攻击(附Python验证脚本) 在网络安全竞赛和渗透测试中,MD5碰撞攻击是一个经典且实用的技术点。本文将带你从零开始,完整复现MD5碰撞攻击的全过程,包括工具使用、…...
