学习threejs,使用MeshFaceMaterial面材质容器

👨‍⚕️ 主页: gis分享者
👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅!
👨‍⚕️ 收录于专栏:threejs gis工程师


文章目录

  • 一、🍀前言
    • 1.1 ☘️THREE.MeshFaceMaterial
  • 二、🍀使用MeshFaceMaterial面材质容器
    • 1. ☘️实现思路
    • 2. ☘️代码样例


一、🍀前言

本文详细介绍如何基于threejs在三维场景中使用MeshFaceMaterial面材质容器,亲测可用。希望能帮助到您。一起学习,加油!加油!

1.1 ☘️THREE.MeshFaceMaterial

THREE.MeshFaceMaterial是一个材质容器,用于为几何体的每个面分配不同的材质。
代码示例:

// 创建材质数组,并为每个面指定不同的材质
const faceMaterialArray = [];
faceMaterialArray.push(new THREE.MeshBasicMaterial({ color: 0x009e60 }));
faceMaterialArray.push(new THREE.MeshBasicMaterial({ color: 0x0051ba }));
faceMaterialArray.push(new THREE.MeshBasicMaterial({ color: 0xffd500 }));
faceMaterialArray.push(new THREE.MeshBasicMaterial({ color: 0xff5800 }));
faceMaterialArray.push(new THREE.MeshBasicMaterial({ color: 0xc41e3a }));
faceMaterialArray.push(new THREE.MeshBasicMaterial({ color: 0xffffff }));// 注意:对于立方体,由于每个面由两个三角形组成,因此我们需要为每个面指定两个相同的材质。
// 但为了简化示例,这里只为每个“可见”面指定了一个材质,另一个三角形面将使用相同的材质。// 实例化MeshFaceMaterial
const faceMaterial = new THREE.MeshFaceMaterial(faceMaterialArray);// 创建几何体并应用材质
const cubeGeom = new THREE.BoxGeometry(3, 3, 3);
const cube = new THREE.Mesh(cubeGeom, faceMaterial);// 将几何体添加到场景中(这里假设已经有一个场景对象scene)
scene.add(cube);

替代方案:
在 Three.js 中,MeshFaceMaterial 是一个历史遗留的材质类,用于为几何体(Geometry)的每个面(Face)分配不同的材质。不过,自 Three.js r125+ 版本后,随着 Geometry 类被废弃并逐步替换为 BufferGeometry,MeshFaceMaterial 也已被弃用。
BufferGeometry + 多材质

  • (1) 使用多材质组(groups)
    将几何体划分为多个材质组,每组对应一个材质。
const geometry = new THREE.BufferGeometry();
const material1 = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const material2 = new THREE.MeshBasicMaterial({ color: 0x00ff00 });// 假设几何体有 6 个面(立方体)
geometry.groups.push({ start: 0, count: 3, materialIndex: 0 }, // 前3个顶点用材质0{ start: 3, count: 3, materialIndex: 1 }  // 后3个顶点用材质1
);// 创建网格时传入材质数组
const mesh = new THREE.Mesh(geometry, [material1, material2]);
  • (2) 使用多材质组(groups)
    通过顶点颜色或纹理坐标实现面级差异化效果。
// 顶点颜色示例
const colors = new Float32Array([1, 0, 0, // 顶点1颜色(红)1, 0, 0, 1, 0, 0, 0, 1, 0, // 顶点4颜色(绿)0, 1, 0, 0, 1, 0
]);
geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));const material = new THREE.MeshBasicMaterial({ vertexColors: true });
const mesh = new THREE.Mesh(geometry, material);

二、🍀使用MeshFaceMaterial面材质容器

1. ☘️实现思路

  • 1、初始化renderer渲染器。
  • 2、初始化Scene三维场景scene。
  • 3、初始化camera相机,定义相机位置 camera.position.set,设置相机方向camera.lookAt。
  • 4、创建THREE.SpotLight聚光灯光源spotLight,设置聚光灯光源位置和投影,scene场景加入spotLight。
  • 5、加载几何模型:创建二维平面网格对象plane,设置plane的旋转角度和位置,scene场景加入plane。定义数组变量mats,mats添加六个THREE.MeshBasicMaterial基础材质作为立方体的六个面材质,六个基础材质设置为不同颜色。传入mats参数创建MeshFaceMaterial面材质容器faceMaterial。创建THREE.Mesh网格group,x、y、z方向循环使用faceMaterial材质创建27个小立方体cube,设置cube位置,group添加cube。scene场景添加group。定义render方法,实现立方体魔方group的旋转动画。具体代码参考下面代码样例。
  • 6、加入gui控件,控制group的旋转速度。加入stats监控器,监控帧数信息。

2. ☘️代码样例

<!DOCTYPE html>
<html>
<head><title>学习threejs,使用MeshFaceMaterial面材质容器</title><script type="text/javascript" src="../libs/three.js"></script><script type="text/javascript" src="../libs/stats.js"></script><script type="text/javascript" src="../libs/dat.gui.js"></script><style>body {margin: 0;overflow: hidden;}</style>
</head>
<body><div id="Stats-output">
</div>
<!-- Div which will hold the Output -->
<div id="WebGL-output">
</div><!-- Js 代码块 -->
<script type="text/javascript">// 初始化function init() {var stats = initStats();// 创建三维场景var scene = new THREE.Scene();// 创建相机var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);// 创建渲染器,设置颜色和大小var renderer = new THREE.WebGLRenderer();renderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));renderer.setSize(window.innerWidth, window.innerHeight);renderer.shadowMapEnabled = false;// 创建二维平面,并设置投影var planeGeometry = new THREE.PlaneGeometry(60, 40, 1, 1);var planeMaterial = new THREE.MeshLambertMaterial({color: 0xffffff});var plane = new THREE.Mesh(planeGeometry, planeMaterial);plane.receiveShadow = true;// 设置二维平面的位置和旋转角度plane.rotation.x = -0.5 * Math.PI;plane.position.x = 0;plane.position.y = -2;plane.position.z = 0;// 场景scene添加二维平面scene.add(plane);// 设置相机位置和方向camera.position.x = -40;camera.position.y = 40;camera.position.z = 40;camera.lookAt(scene.position);// 添加聚光灯光源,设置光源位置和投影var spotLight = new THREE.SpotLight(0xffffff);spotLight.position.set(-40, 60, -10);spotLight.castShadow = true;scene.add(spotLight);// renderer渲染器绑定html要素document.getElementById("WebGL-output").appendChild(renderer.domElement);var group = new THREE.Mesh();// 添加立方体六个面材质var mats = [];mats.push(new THREE.MeshBasicMaterial({color: 0x009e60}));mats.push(new THREE.MeshBasicMaterial({color: 0x0051ba}));mats.push(new THREE.MeshBasicMaterial({color: 0xffd500}));mats.push(new THREE.MeshBasicMaterial({color: 0xff5800}));mats.push(new THREE.MeshBasicMaterial({color: 0xC41E3A}));mats.push(new THREE.MeshBasicMaterial({color: 0xffffff}));var faceMaterial = new THREE.MeshFaceMaterial(mats);// 创建27个小立方体组成大立方体for (var x = 0; x < 3; x++) {for (var y = 0; y < 3; y++) {for (var z = 0; z < 3; z++) {var cubeGeom = new THREE.BoxGeometry(2.9, 2.9, 2.9);var cube = new THREE.Mesh(cubeGeom, faceMaterial);cube.position.set(x * 3 - 3, y * 3, z * 3 - 3);group.add(cube);}}}scene.add(group);var step = 0;var controls = new function () {this.rotationSpeed = 0.02;this.numberOfObjects = scene.children.length;};var gui = new dat.GUI();gui.add(controls, 'rotationSpeed', 0, 0.5);render();function render() {stats.update();group.rotation.y = step += controls.rotationSpeed;requestAnimationFrame(render);renderer.render(scene, camera);}function initStats() {var stats = new Stats();stats.setMode(0);stats.domElement.style.position = 'absolute';stats.domElement.style.left = '0px';stats.domElement.style.top = '0px';document.getElementById("Stats-output").appendChild(stats.domElement);return stats;}}window.onload = init;
</script>
</body>
</html>

效果如下:
在这里插入图片描述

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

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

相关文章

电脑内存不足怎么办?

常规解决方法盘点 关闭后台程序&#xff1a;按下【Ctrl Shift Esc】组合键打开任务管理器&#xff0c;在 “进程” 选项卡里&#xff0c;把当前不用的程序统统 “结束任务” &#xff0c;像那些自动更新的软件、常驻后台的播放器&#xff0c;关了能释放不少内存。比如音乐软…

Excel中国式排名,3种方法!

大家好&#xff0c;我是小鱼。 什么是中国式排名呢&#xff1f; 举个例子比如说公司一共有10名员工进行成绩考核&#xff0c;如果9个人考核成绩都是90分&#xff0c;你是89分&#xff0c;按照国际惯用的排名法则&#xff1a;9 个人考核成绩并列第一&#xff0c;你第10名&…

deepseek+kimi做ppt教程记录

1.首先注册deepseek和kimi deepseek官网&#xff1a;https://chat.deepseek.com/ kimi官网&#xff1a;https://kimi.moonshot.cn/ 以下以一篇工作总结报告为例 2.使用deepseek生成ppt大纲 让deepseek生成kimi生成ppt所需要的内容时&#xff0c;需要注意提示词内容&#xff0c;…

前端无限滚动内容自动回收技术详解:原理、实现与优化

文章目录 一、核心需求与技术挑战1.1 无限滚动的问题症结1.2 自动回收的三大目标 二、技术实现原理2.1 虚拟滚动核心机制2.2 关键技术指标 三、完整实现方案3.1 基础HTML结构3.2 CSS关键样式3.3 JavaScript核心逻辑3.3.1 滚动控制器3.3.2 动态尺寸处理 四、性能优化策略4.1 内存…

【训练细节解读】文本智能混合分块(Mixtures of Text Chunking,MoC)引领RAG进入多粒度感知智能分块阶段

RAG系统在处理复杂上下文时,传统和语义分块方法的局限性,文本分块的质量限制了检索到的内容,从而影响生成答案的准确性。尽管其他算法组件有所进步,但分块策略中的增量缺陷仍可能在一定程度上降低整体系统性能。如何直接量化分块质量?如何有效利用大型语言模型(LLMs)进行…

Jmeter下载及环境配置

Jmeter下载及环境配置 java环境变量配置配置jdk环境变量检查是否配置成功JMeter下载 java环境变量配置 访问地址&#xff1a; https://www.oracle.com/cn/java/technologies/downloads/ 注意&#xff1a;需要自己注册账号 下载完成&#xff0c;解压后的目录为&#xff1a; …

coze ai assistant Task 2

创建一个智能体&#xff1a;夸夸机器人 https://www.coze.cn/store/agent/7480939060010713138?bot_idtrue 改为豆包系列-豆包角色扮演 添加bingWebSearch搜索 添加前&#xff1a; 添加后&#xff1a; 改为工具调用&#xff1a; 添加知识库 使用长期记忆 结合自己的需求&…

Unity基于C#+UGUI解决方案,制作每日签到系统(本地存储签到数据)

一、需求介绍:基于本地存储系统制作一个每日签到系统界面,相关签到界面如下图所示,点击“签到有礼”按钮后就会跳转到“每日登录礼”这个界面,点击“立即签到”按钮之后,按钮就会置灰,而且按钮的文字会变成“等待明日”。 二、制作界面显示相关功能,需要在Unity中新建一…

多线程(超详细) (ε≡٩(๑>₃<)۶ 一心向学)

多线程目录 一、认识线程 1、概念&#xff1a; 1) 线程是什么 2) 线程为什么存在 3) 进程与线程的区别 二、创建线程 1、方法1&#xff1a;继承Thread类 2、方法2&#xff1a;实现 Runnable 接口 3、方法3&#xff1a;匿名内部类创建 Thread 子类对象 4、方法4&#…

SpringBoot——Maven篇

Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的工具。它具有许多特性&#xff0c;其中一些重要的特性包括&#xff1a; 1. 自动配置&#xff1a;Spring Boot 提供了自动配置的机制&#xff0c;可以根据应用程序的依赖和环境自动配置应用程序的各种组件&#xff…

中文大语言模型提示工程:解锁AI力量的密钥(完整优化版)

文章目录 **引言&#xff1a;AI时代的"咒语"革命****一、为什么中文提示工程是技术深水区&#xff1f;****1.1 中文的"模糊美学"挑战****1.2 文化认知鸿沟****1.3 分词歧义陷阱** **二、中文提示工程六脉神剑&#xff08;附实战代码&#xff09;****2.1 结…

C++中虚析构函数的作用是什么?为什么基类需要虚析构函数?

C中虚析构函数的作用是什么&#xff1f;为什么基类需要虚析构函数&#xff1f; 在C中&#xff0c;虚析构函数&#xff08;virtual destructor&#xff09;的作用是确保在通过基类指针或引用删除派生类对象时&#xff0c;能够正确调用派生类的析构函数&#xff0c;从而避免资源…

【C++项目实战】校园公告搜索引擎:完整实现与优化指南

&#x1f3ac; 个人主页&#xff1a;谁在夜里看海. &#x1f4d6; 个人专栏&#xff1a;《C系列》《Linux系列》《算法系列》 ⛰️ 道阻且长&#xff0c;行则将至 目录 &#x1f4da;一、项目概述 &#x1f4d6;1.项目背景 &#x1f4d6;2.主要功能 &#x1f4d6;3.界面展…

大数据技术之Spark优化

第 1 章 Spark 性能调优 问:spark 优化 第一句:我们可以从性能,算子,shuffle 过程以及 jvm 四个方面展开优化。 1 常规性能调优 1.1 常规性能调优一:最优资源配置 Spark 性能调优的第一步,就是为任务分配更多的资源,在一定范围内,增加资源的分配与性能的提升是成正…

【 Manus平替开源项目】

文章目录 Manus平替开源项目1 OpenManus1.1 简介1.2 安装教程1.3 运行 2 OWL2.1 简介2.2 安装教程2.3 运行 3 OpenHands&#xff08;原OpenDevin&#xff09;3.1 简介3.2 安装教程和运行 Manus平替开源项目 1 OpenManus 1.1 简介 开发团队: MetaGPT 核心贡献者&#xff08;5…

《Java SQL 操作指南:深入理解 Statement 用法与优化》

在 Java 数据库编程中&#xff0c;Statement 是用于执行 SQL 语句的接口&#xff0c;允许程序与数据库进行交互。本文将详细介绍 Statement 的基本概念、常见用法以及 PreparedStatement 和 CallableStatement 等相关接口。 1. Statement 基本介绍 Statement 接口继承了 AutoC…

FFMPEG录制远程监控摄像头MP4

手绘效果图 上图是录制功能的HTML前端页面&#xff0c;录制功能和解码视频放在一起。录制功能关键是录制(开始录制按钮)、停止录像按钮。当点击“录制”的时候则会开始录制MP4文件, 当点击停止的时候就会停止录制MP4。经过录制后&#xff0c;则会生成MP4,并放到我的RV1126的/tm…

数据类型及sizeof,进制转换

其实数据类型可以讲很多内容&#xff0c;这里看情况需要讲多久吧。 本篇基本都是理论。 目录 数据类型的分类 基本数据类型 构造数据类型 指针类型 空类型 计算数据类型或变量所占用的内存字节数 基本语法 进制转换 二进制 二进制的概念 二进制与十进制的转换 十六进…

网络安全之tcpdump工具

引言 wireshark是一款非常不错的抓包软件&#xff0c;在图形化界面占绝对统治地位&#xff1b;尽管其在字符界面下有些许选项可供使用&#xff0c;但终究不太方便&#xff0c;下面我再介绍一款NB的终端抓包工具 tcpdump 1、混杂模式 linux的网卡有混杂模式一说&#xff0c;当开…

建筑管理(2): 施工承包模式,工程监理,质量监督

文章目录 一. 施工承包模式1. 施工总承包模式1.1 施工总承包的特点1.2 施工总承包模式中的承包方 2. 平行承包模式3. 联合体与合作体承包模式 二. 工程监理1. 强制实行监理的工程范围1.1 国家重点建设工程1.2 大中型公用事业工程(重点)1.3 成片开发建设的住宅小区工程1.4 必须实…