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

学习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>

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

相关文章:

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

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.MeshFaceMaterial 二…...

Git 实战指南:本地客户端连接 Gitee 全流程

本文将以 Gitee(码云)、系统Windows 11 为例,详细介绍从本地仓库初始化到远程协作的全流程操作 目录 1. 前期准备1.1 注册与配置 Gitee1.2 下载、安装、配置客户端1.3 配置公钥到 Gitee2. 本地仓库操作(PowerShell/Git Bash)2.1 初始化本地仓库2.2 关联 Gitee 远程仓库3. …...

Spring Cloud 中的服务注册与发现: Eureka详解

1. 背景 1.1 问题描述 我们如果通过 RestTamplate 进行远程调用时&#xff0c;URL 是写死的&#xff0c;例如&#xff1a; String url "http://127.0.0.1:9090/product/" orderInfo.getProductId(); 当机器更换或者新增机器时&#xff0c;这个 URL 就需要相应地变…...

通过 SVG 使用 AI 生成理想图片:技术实现与实践指南

文章目录 1. SVG 与 AI 的结合&#xff1a;技术价值2. 技术原理&#xff1a;AI 如何生成 SVG&#xff1f;3. 实现步骤&#xff1a;从需求到图形3.1 定义需求3.2 使用 AI 生成 SVG3.3 验证与调整 4. 代码解析&#xff1a;实现科技感的关键4.1 渐变背景4.2 网格线条4.3 发光六边形…...

【AI学习从零至壹】Pytorch神经⽹络

Pytorch神经⽹络 神经网络简介神经元激活函数 神经网络神经⽹络的⼯作过程前向传播(forward) 反向传播(backward)训练神经⽹络 Pytorch搭建并训练神经⽹络神经⽹络构建和训练过程数据预处理构建模型优化器&提取训练数据训练样本 神经网络简介 神经元 在深度学习中&#x…...

设计模式-对象创建

对象创建 前言1. Factory Method1.1 模式介绍1.2 模式代码1.2.1 问题代码1.2.2 重构代码 1.3 模式类图1.4 要点总结 2. Abstract Factory2.1 模式介绍2.2 模式代码2.2.1 问题代码2.2.2 重构代码 2.3 模式类图2.4 要点总结 3. Prototype3.1 模式介绍3.2 模式代码3.3 模式类图3.4…...

谈谈你对前端工程化的理解,它包含哪些方面

大白话谈谈你对前端工程化的理解&#xff0c;它包含哪些方面 前端工程化其实就是把前端开发变得更规范、更高效、更易于维护的一套方法和流程。就好比你盖房子&#xff0c;不能随便瞎盖&#xff0c;得有设计图纸、施工标准、分工合作&#xff0c;前端工程化也是类似的道理。 项…...

JSON数据格式介绍

2.5 JSON 2.5.1.JSON格式的用途 在开发中凡是涉及到『跨平台数据传输』&#xff0c;JSON格式一定是首选 2.5.2.JSON格式的说明 1.JSON数据两端要么是{}&#xff0c;要么是[] {}定义JSON对象[]定义JSON数组 2.JSON对象的格式是&#xff1a;json {key:value,key:value,...,ke…...

java的WeakHashMap可以用来做缓存使用?强软弱虚四种引用对比

在 Java 中&#xff0c;引用&#xff08;Reference&#xff09;机制用于管理对象的生命周期和垃圾回收。Java 提供了四种类型的引用&#xff1a;强引用&#xff08;Strong Reference&#xff09;、软引用&#xff08;Soft Reference&#xff09;、弱引用&#xff08;Weak Refer…...

【AVRCP】Notification PDUs 深入解析与应用

目录 一、Notification PDUs 概述 二、GetPlayStatus:同步查询播放状态 2.1 命令功能与应用场景 2.2 请求格式(CT → TG) 2.3 响应格式(TG → CT) 2.4 注意事项 2.5 协议实现示例(伪代码) 三、RegisterNotification:异步事件订阅 3.1 命令概述 3.2 命令格式 …...

从过拟合到强化学习:机器学习核心知识全解析

Langchain系列文章目录 01-玩转LangChain&#xff1a;从模型调用到Prompt模板与输出解析的完整指南 02-玩转 LangChain Memory 模块&#xff1a;四种记忆类型详解及应用场景全覆盖 03-全面掌握 LangChain&#xff1a;从核心链条构建到动态任务分配的实战指南 04-玩转 LangChai…...

【MySQL基础-9】深入理解MySQL中的聚合函数

在数据库操作中&#xff0c;聚合函数是一类非常重要的函数&#xff0c;它们用于对一组值执行计算并返回单个值。MySQL提供了多种聚合函数&#xff0c;如COUNT、SUM、AVG、MIN和MAX等。这些函数在数据分析和报表生成中扮演着关键角色。本文将深入探讨这些聚合函数的使用方法、注…...

Lora 中 怎么 实现 矩阵压缩

Lora 中 怎么 实现 矩阵压缩 1. 导入必要的库 import torch import re from datasets import Dataset from transformers import AutoTokenizer, AutoModelForCausalLM, TrainingArguments, Trainer, \get_cosine_schedule_with_warmup, EarlyStoppingCallback from peft...

MATLAB 控制系统设计与仿真 - 27

状态空间的标准型 传递函数和状态空间可以相互转换&#xff0c;接下来会举例如何有传递函数转成状态空间标准型。 对角标准型 当 G(s)可以写成&#xff1a; 即&#xff1a; 根据上图可知&#xff1a; 约当标准型 当 G(s)可以写成&#xff1a; 即&#xff1a; 根据上图…...

linux 命令 cp

cp 是 Linux 中用于复制文件和目录的命令&#xff0c;基本功能是将源文件或目录复制到目标位置 基本语法 cp [选项] 源文件 目标文件 cp [选项] 源文件1 源文件2 ... 目标目录 常用选项 选项说明-i交互模式&#xff08;覆盖前询问确认&#xff09;-r 或 -R递归复制目录&#…...

从FFmpeg命令行到Rust:多场景实战指南

FFmpeg作为功能强大的多媒体处理工具&#xff0c;被广泛应用于视频编辑、格式转换等领域。然而&#xff0c;直接使用FFmpeg的命令行界面&#xff08;CLI&#xff09;可能会遇到以下挑战&#xff1a; 命令复杂度高&#xff1a;FFmpeg的命令行参数众多且复杂&#xff0c;初学者可…...

蓝桥杯高频考点——进制转换

进制转换 二进制转十进制代码演示 十六进制转十进制代码演示 十进制转K进制代码演示 任意进制之间的转换代码演示 二进制转十进制 代码演示 // 定义函数 calc&#xff0c;用于将字符转换为对应的数值 int calc(char c) {// 若字符 c 大于等于 9&#xff08;注&#xff1a;此处…...

【算法百题】专题七_分治快排_专题八_分治归并

文章目录 前言分治快排题&#xff1a;043. [颜⾊分类&#xff08;medium&#xff09;](https://leetcode.cn/problems/sort-colors/description/)分析 044. [快速排序&#xff08;medium&#xff09;](https://leetcode.cn/problems/sort-an-array/description/)分析 045. [快速…...

DOM4J解析XML, 修改xml的值

1. 引入pom依赖 <dependency><groupId>org.dom4j</groupId><artifactId>dom4j</artifactId><version>2.1.3</version> </dependency> 2. 解析xml, 修改xml节点的值 import org.apache.commons.io.IOUtils; import org.dom4…...

3.16[A]FPGA

FPGA的工作原理是通过配置存储器中的数据来控制可编程逻辑单元和互连资源&#xff0c;从而实现用户定义的逻辑功能。用户可以通过硬件描述语言&#xff08;HDL&#xff09;编写代码&#xff0c;然后通过综合、映射、布局布线等步骤生成配置数据&#xff0c;最后将这些数据加载到…...

ssh转发笔记

工作中又学到了&#xff0c;大脑转不过来 现有主机A&#xff0c;主机B&#xff0c;主机C A能访问B&#xff0c;B能访问C&#xff0c;A不能访问C C上80端口有个服务&#xff0c;现在A想访问这个服务&#xff0c;领导让用ssh转发&#xff0c;研究半天没找到理想的语句&#xf…...

使用OBS进行webRTC推流参考

参考腾讯云官方文档&#xff1a; 云直播 OBS WebRTC 推流_腾讯云 说明非常详细&#xff0c;分为通过WHIP和OBS插件的形式进行推流。 注意&#xff1a;通过OBS插件的形式进行推流需要使用较低的版本&#xff0c;文档里有说明&#xff0c;需要仔细阅读。...

(链表)面试题 02.07. 链表相交

给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结构中不存在环。 注意&#xff0c;函数返回结果后&#xff…...

Python----数据可视化(Pyecharts三:绘图二:涟漪散点图,K线图,漏斗图,雷达图,词云图,地图,柱状图折线图组合,时间线轮廓图)

1、涟漪特效散点图 from pyecharts.globals import SymbolType from pyecharts.charts import EffectScatter from pyecharts.faker import Faker from pyecharts import options as opts from pyecharts.globals import ThemeType # 绘制图表 es (EffectScatter(init_optsop…...

正则表达式:贪婪匹配与非贪婪匹配

正则表达式:贪婪匹配与非贪婪匹配 非贪婪匹配 .*?这三个字符的组合就是非贪婪匹配&#xff0c;意思是匹配任意字符直到遇到第一个后面指定的字符&#xff0c;比如.*?_就表示匹配任意字符直到碰到下划线&#xff0c;还可以组合^来表示从头匹配&#xff0c;比如^.*?_就是从头…...

IP风险度自检,互联网的安全“指南针”

IP地址就像我们的网络“身份证”&#xff0c;而IP风险度则是衡量这个“身份证”安全性的重要指标。它关乎着我们的隐私保护、账号安全以及网络体验&#xff0c;今天就让我们一起深入了解一下IP风险度。 什么是IP风险度 IP风险度是指一个IP地址可能暴露用户真实身份或被网络平台…...

数据结构与算法-图论-拓扑排序

前置芝士 概念 拓扑排序&#xff08;Topological Sorting&#xff09;是对有向无环图&#xff08;DAG&#xff0c;Directed Acyclic Graph&#xff09;的顶点进行排序的一种算法。它将图中的所有顶点排成一个线性序列&#xff0c;使得对于图中的任意一条有向边 (u, v)&#x…...

Gan网络公式了解

Gan网络 生成器和判别器是亦敌亦友的关系 对于生成模型&#xff0c;损失函数很难定义->所以我们可以将生成模型的输出交给判别模型进行处理&#xff0c;来分辨好坏。 生成器的损失是通过判别器的输出来计算的&#xff0c;而判别器的输出是一个概率值&#xff0c;我们可以通过…...

解决linux mysql命令 bash: mysql: command not found 的方法

首先得知道mysql命令或mysqladmin命令的完整路径 比如mysql的路径是&#xff1a; /usr/local/mysql/bin/mysql&#xff0c;我们则可以这样执行命令&#xff1a; ln -s /usr/local/mysql/bin/mysql /usr/bin © 著作权归作者所有,转载或内容合作请联系作者 喜欢的朋友记得点…...

微服务存在的问题及解决方案

微服务存在的问题及解决方案 1. 存在问题 1.1 接口拖慢 因为一个接口在并发时&#xff0c;正好执行时长又比较长&#xff0c;那么当前这个接口占用过多的 Tomcat 连接&#xff0c;导致其他接口无法即时获取到 Tomcat 连接来完成请求&#xff0c;导致接口拖慢&#xff0c;甚至…...