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

news/2025/3/18 18:23:38/

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


文章目录


一、🍀前言

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

FaceMaterialfont_10">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);

FaceMaterialfont_76">二、🍀使用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.ppmy.cn/news/1580125.html

相关文章

便携版:随时随地,高效处理 PDF 文件

PDF-XChange Editor Plus 便携版是一款功能强大且极其实用的 PDF 阅读与编辑工具。它不仅支持快速浏览 PDF 文件&#xff0c;还提供了丰富的编辑功能&#xff0c;让用户可以轻松处理 PDF 文档。经过大神优化处理&#xff0c;这款软件已经变得十分轻便&#xff0c;非常适合需要随…

汽车PKE无钥匙进入系统一键启动系统定义与原理

汽车智能钥匙&#xff08;PKE无钥匙进入系统&#xff09;一键启动介绍 系统定义与原理 汽车无钥匙进入系统&#xff0c;简称PKE&#xff08;Passive Keyless Entry&#xff09;&#xff0c;该系统采用了RFID无线射频技术和车辆身份编码识别系统&#xff0c;率先应用小型化、小…

Linux中Tomcat、idea和MySQL的安装

一、tomcat安装 1.上传安装文件&#xff0c;并解压缩到 /opt/tomcat 2.进入解压目录 /bin &#xff0c;启动Tomcat&#xff0c; ./startup.sh 3. 开放端口 8080 4.测试是否成功&#xff0c;访问http://linuxip:8080 二、IDEA2020安装 1.上传安装文件到 /opt/idea&#xff0c;…

【cuda学习日记】8.1 GPU加速库 --cuSPARSE

8.1.1 cuSPARSE概念 cuSPARSE是一个线性代数库&#xff0c;内含很多通用的稀疏线性代数函数。 稠密存储方式&#xff08;dense&#xff09; 把矩阵中的每个元素都存储起来&#xff0c;不管它是否为零。 坐标稀疏矩阵格式&#xff08;COO&#xff09; 坐标稀疏矩阵格式&am…

Redis,从数据结构到集群的知识总结

Redis基础部分 2. 数据结构 redis底层使用C语言实现&#xff0c;这里主要分析底层数据结构 2.1 动态字符串(SDS) 由于C底层的字符串数组一旦遇到’\0’就会认为这个字符串数组已经结束&#xff0c;意味着无法存储二进制数据&#xff08;如图片、音频等&#xff09;&#xff…

Java0317初尝试与报错

支付模块&#xff1a;27min讲了打开神秘开关 在前面讲了Data&#xff0c;NoArgsConstructor&#xff0c;AllArgsConstructor lombok技术 报错1 package com.itheima.demo; public class GoldCard extends Card { Override public void cost(double money){ //消费八折 setM…

高效手机检测:视觉分析技术的优势

在当今社会&#xff0c;手机已成为人们日常生活和工作中不可或缺的工具。然而&#xff0c;在某些特定场合&#xff0c;如考场、工作场所等&#xff0c;手机的使用却可能带来负面影响。因此&#xff0c;如何有效监测和防止在这些场合偷用手机的行为&#xff0c;成为了一个亟待解…

Python游戏开发自学指南:从入门到实践(第四天)

Python不仅适用于数据分析、Web开发和自动化脚本&#xff0c;还可以用于游戏开发&#xff01;虽然Python不是传统意义上的游戏开发语言&#xff0c;但其简洁的语法和丰富的库使其成为初学者学习游戏开发的绝佳选择。本文将为你提供一份全面的Python游戏开发自学指南&#xff0c…