Threejs_06 多材质的实现

Threejs 同一个几何体如何实现多材质呢?

多材质的实现

1.使用索引绘制一个几何体

//创建几何体(三角形)
const geometry = new THREE.BufferGeometry();

//使用索引绘制  (两个共用的)
const vertices = new Float32Array([
  -1.0, -1.0, 0.0, 1.0, -1.0, 0.0, 1.0, 1.0, 0.0, -1.0, 1.0, 0,
]);
//创建顶点属性
geometry.setAttribute("position", new THREE.BufferAttribute(vertices, 3));
//创建索引
const indices = new Uint16Array([0, 1, 2, 2, 3, 0]);
//创建索引属性
geometry.setIndex(new THREE.BufferAttribute(indices, 1));

2. 设置顶点组(为了方便应用材质)

// 设置2个顶点组 形成两个材质 顶点0开始 添加3个顶点 用的是第一个材质(第三个参数)
geometry.addGroup(0, 3, 0);
geometry.addGroup(3, 3, 1); //顶点3开始 添加三个顶点 第二个材质

3.创建两个材质

//创建材质
const material = new THREE.MeshBasicMaterial({
  color: 0x00ff00,
  // wireframe: true,
  // side: THREE.DoubleSide,
});
const material1 = new THREE.MeshBasicMaterial({
  color: 0xff0000,
  // wireframe: true,
});

4. 构建几何体

const plane = new THREE.Mesh(geometry, [material, material1]);
//现在就有两个材质了
scene.add(plane);

 

多材质绘制立方体

1. 做一个立方体的物料

// 创建一个集合体  (立方体)
const cubegeometry = new THREE.BoxGeometry(1, 1, 1);

2. 做立方体六个面的六个材质

// 创建材质 (16进制颜色)
const cubematerial0 = new THREE.MeshBasicMaterial({
  color: 0x00ff00,
  //线框
  // wireframe: true,
});
const cubematerial1 = new THREE.MeshBasicMaterial({
  color: 0xff0000,
});
const cubematerial2 = new THREE.MeshBasicMaterial({
  color: 0x0000ff,
});
const cubematerial3 = new THREE.MeshBasicMaterial({
  color: 0xffff00,
});
const cubematerial4 = new THREE.MeshBasicMaterial({
  color: 0x00ffff,
});
const cubematerial5 = new THREE.MeshBasicMaterial({
  color: 0xff00ff,
});

3. 创建立方体

// 创建网格体
const cube = new THREE.Mesh(cubegeometry, [
  cubematerial0,
  cubematerial1,
  cubematerial2,
  cubematerial3,
  cubematerial4,
  cubematerial5,
]);
//移动一下
cube.position.set(2, 0, 0);
// 添加到场景中
scene.add(cube);

  

一个六面六个不同材质的立方体就做好了。

 所有代码

//1.一个物体可以设置多个材质嘛

//1.设置定点组
//2 多个

//导入 threejs
import * as THREE from "three";
//导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
//导入lil.gui
// import * as dat from "dat.gui";  // 旧
import { GUI } from "three/examples/jsm/libs/lil-gui.module.min.js";

// 创建场景
const scene = new THREE.Scene();
// 创建相机
const camera = new THREE.PerspectiveCamera(
  45, // 视角
  window.innerWidth / window.innerHeight, // 宽高比 窗口的宽高进行设置的
  0.1, // 近平面   相机最近最近能看到的物体
  1000 // 远平面   相机最远能看到的物体
);
// 创建渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染器的大小  (窗口大小)
renderer.setSize(window.innerWidth, window.innerHeight);
// 将渲染器的dom元素添加到body中
document.body.appendChild(renderer.domElement);

// 创建一个集合体  (立方体)
const cubegeometry = new THREE.BoxGeometry(1, 1, 1);
console.log(cubegeometry);
// 创建材质 (16进制颜色)
const cubematerial0 = new THREE.MeshBasicMaterial({
  color: 0x00ff00,
  //线框
  // wireframe: true,
});
const cubematerial1 = new THREE.MeshBasicMaterial({
  color: 0xff0000,
});
const cubematerial2 = new THREE.MeshBasicMaterial({
  color: 0x0000ff,
});
const cubematerial3 = new THREE.MeshBasicMaterial({
  color: 0xffff00,
});
const cubematerial4 = new THREE.MeshBasicMaterial({
  color: 0x00ffff,
});
const cubematerial5 = new THREE.MeshBasicMaterial({
  color: 0xff00ff,
});
// 创建网格体
const cube = new THREE.Mesh(cubegeometry, [
  cubematerial0,
  cubematerial1,
  cubematerial2,
  cubematerial3,
  cubematerial4,
  cubematerial5,
]);
//移动一下
cube.position.set(2, 0, 0);
// 添加到场景中
scene.add(cube);

// //创建几何体(三角形)
// const geometry = new THREE.BufferGeometry();

// //使用索引绘制  (两个共用的)
// const vertices = new Float32Array([
//   -1.0, -1.0, 0.0, 1.0, -1.0, 0.0, 1.0, 1.0, 0.0, -1.0, 1.0, 0,
// ]);
// //创建顶点属性
// geometry.setAttribute("position", new THREE.BufferAttribute(vertices, 3));
// //创建索引
// const indices = new Uint16Array([0, 1, 2, 2, 3, 0]);
// //创建索引属性
// geometry.setIndex(new THREE.BufferAttribute(indices, 1));

// // 设置2个顶点组 形成两个材质 顶点0开始 添加3个顶点 用的是第一个材质(第三个参数)
// geometry.addGroup(0, 3, 0);
// geometry.addGroup(3, 3, 1); //顶点3开始 添加三个顶点 第二个材质

// //创建材质
// const material = new THREE.MeshBasicMaterial({
//   color: 0x00ff00,
//   // wireframe: true,
//   // side: THREE.DoubleSide,
// });
// const material1 = new THREE.MeshBasicMaterial({
//   color: 0xff0000,
//   // wireframe: true,
// });

// const plane = new THREE.Mesh(geometry, [material, material1]);
// //现在就有两个材质了
// scene.add(plane);

// 设置相机的位置
camera.position.z = 5;
// 为了看到z轴
camera.position.y = 2;
// 设置x轴
camera.position.x = 2;
//设置相机的焦点 (相机看向哪个点)
camera.lookAt(0, 0, 0);

//添加世界坐标辅助器  (红色x轴,绿色y轴,蓝色z轴)一个线段 参数为 线段长度
const axesHelper = new THREE.AxesHelper(5);
//添加到场景之中
scene.add(axesHelper);

// 添加轨道控制器 (修改侦听位置)  一般监听画布的事件  不监听document.body
const controls = new OrbitControls(camera, renderer.domElement);
// 这里传递阻塞掉了 会导致无法点击
// const controls = new OrbitControls(camera, document.body);

// // 设置带阻尼的旋转
// controls.enableDamping = true;
// // 设置阻尼系数
// controls.dampingFactor = 0.01;
// // 自动旋转
// controls.autoRotate = false;

//渲染函数
function animate() {
  controls.update();
  //请求动画帧
  requestAnimationFrame(animate);
  //旋转网格体
  // cube.rotation.x += 0.01;
  // cube.rotation.y += 0.01;
  //渲染
  renderer.render(scene, camera);
}
animate();
//渲染

// 监听窗口的变化 重新设置渲染器的大小 画布自适应窗口
window.addEventListener("resize", () => {
  // 重新设置渲染器的大小
  renderer.setSize(window.innerWidth, window.innerHeight);
  // 重新设置相机的宽高比
  camera.aspect = window.innerWidth / window.innerHeight;
  // 重新计算相机的投影矩阵
  camera.updateProjectionMatrix();
});



//1.gui控制按钮
let eventObj = {
  Fullscreen: function () {
    // 全屏 (画布)
    // renderer.domElement.requestFullscreen();
    // 全屏 (document.body)  可以看到写入的按钮
    document.body.requestFullscreen();
  },
  exitFullscreen: function () {
    // 退出全屏
    document.exitFullscreen();
  },
};

//创建gui实例
const gui = new GUI();
//添加按钮  第一个参数为对象实例  第二个参数为对象中属性名称
gui.add(eventObj, "Fullscreen").name("全屏");
//退出按钮
gui.add(eventObj, "exitFullscreen").name("退出全屏");

//2.gui控制立方体的位置
// gui.add(cube.position, "x", -5, 5).name("立方体x轴位置");

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

js高效函数库Lodash.js

Lodash 是一个 JavaScript 的实用工具库,提供了许多实用且高效的函数,可以简化 JavaScript 编程中的常见任务。 Lodash具有高性能、模块化和易用性等特点,表现一致性以及可扩展,下面将介绍一些 Lodash 的重要特性和用法&#xff1…

CRM按行业细分的重要性

很多企业和销售会诟病CRM系统不够贴合行业、功能也不够细分和实用。因为各行各业的业务千差万别,所以功能完备、使用满意度高的CRM一定是与不同行业业务场景高度匹配的,是深度行业化的。因此行业化是CRM发展的重要趋势之一,为什么CRM一定要走…

庖丁解牛:NIO核心概念与机制详解 05 _ 文件锁定

文章目录 Pre概述锁定文件 (lock)Code文件锁定和可移植性 Pre 庖丁解牛:NIO核心概念与机制详解 01 庖丁解牛:NIO核心概念与机制详解 02 _ 缓冲区的细节实现 庖丁解牛:NIO核心概念与机制详解 03 _ 缓冲区分配、包装和…

2005B 2.4W AB类音频功率放大器应用领域

2005B 2.4W AB类音频功率放大器应用领域:1、便携式DVD;2、笔记本电脑;3、插卡音箱 / USB音箱;4、液晶电视 / 液晶显示器等等。 2005B是一颗单通道AB类音频功率放大器。在5V 电源供电,THDN10%,4欧姆负载上可…

尽快调整心态,切莫自讨苦吃

退休多年的老龄人的本“人民体验官”闲得无聊,怕被闲出更多病痛,更怕被闲死,所以天天上网坚持职业新闻人的老习惯——上网读新闻,并以一孔之见置评,旨在抛砖引玉。 11月8日,本“人民体验官 ”在推广人民日…

python 自动化福音,30行代码手撸ddt模块

用 python 做过自动化的小伙伴,大多数都应该使用过 ddt 这个模块,不可否认 ddt 这个模块确实挺好用,可以自动根据用例数据,来生成测试用例,能够很方便的将测试数据和测试用例执行的逻辑进行分离。 接下来就带大家一起…

2023年亚太杯数学建模亚太赛ABC题思路资料汇总贴

下文包含:2023年亚太杯数学建模亚太赛A- C题思路解析、选题建议、代码可视化及如何准备数学建模竞赛(23号发) C君将会第一时间发布选题建议、所有题目的思路解析、相关代码、参考文献、参考论文等多项资料,帮助大家取得好成绩。2…

深度学习人体跌倒检测 -yolo 机器视觉 opencv python 计算机竞赛

0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 **基于深度学习的人体跌倒检测算法研究与实现 ** 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🥇学长这里给一个题目综合评分(每项满…

不必购买Mac,这款国产设计工具能轻松替代Sketch!

介绍 即时设计是新一代可以直接在浏览器中使用的设计工具,具有Sketch和实时协作功能。与本地Sketch相比,增加了实时协作功能,即时设计可以看作是在线Sketch,两个工具可以简单粗暴地总结为一个公式: 即时设计Sketch云…

快手运营的必备的10个工具

一、引言 快手作为短视频领域的佼佼者,为众多创作者提供了广阔的舞台。要想在快手运营中取得成功,掌握一些必备的工具是必不可少的。本文将为您介绍快手运营的10个必备工具,帮助您提高工作效率,优化内容创作。 二、工具推荐 1. …

CRM系统定制开发价格

我们都知道,CRM系统对企业有着很大的帮助。但是市面上大多数CRM系统都是标准化的,无法满足那些产品线复杂,或者有着特殊需求的企业。这个时候,就需要对CRM系统进行二次开发。那么,CRM系统二次开发的价格是多少&#xf…

充电桩负载测试需要检测哪些项目

充电桩负载测试在进行充电桩负载测试时,需要检测以下几个项目: 充电速度:测试充电桩的充电速度,包括直流充电桩的最大输出功率和交流充电桩的充电功率,以确定其是否符合标准要求。充电效率:测试充电桩的充电…

实时监控电脑屏幕的软件丨同时查看12台电脑屏幕

Hello 大家好 又见面啦 今天给大家推荐两款比较实用的监控电脑使用情况、屏幕的软件! 软件一 实时性能监控 从软件名就可以看出来,这是一款电脑性能监测工具。它可以实时监测内存、CPU、磁盘占用情况,也能一键结束进程,给电脑提…

Python UI自动化 —— 关键字+excel表格数据驱动

步骤: 1. 对selenium进行二次封装,创建关键字的库 2. 准备一个表格文件来写入所有测试用例步骤 3. 对表格内容进行读取,使用映射关系来对用例进行调用执行 4. 执行用例 1. 对selenium进行二次封装,创建关键字的库 from time imp…

采集淘宝天猫整店商品api(店铺列表、店铺所有商品)

返回数据:请求链接 {"items": {"shop_id": "336945718","page": "1","real_total_results": "75","total_results": "75","page_size": 10,"page_coun…

windows通过命令给文件夹或文件增加权限

给Demo001追加everyone权限 D:\cmd>cacls Demo001 /p everyone:f /e 处理的目录: D:\cmd\Demo001D:\cmd> 给Demo001下的所有文件追加everyone权限 D:\cmd>cacls Demo001 /p everyone:f /e /t 处理的目录: D:\cmd\Demo001 处理的目录: D:\cmd\Demo001\A 处理的文件:…

浅谈面向对象

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO 联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬 从某个角度说&#xff…

用公式告诉你 现货黄金投资者要不要换策略?

看过笔者相关文章的朋友都知道,其实笔者是相当不鼓励投资者更改策略的。但这并不意味着,策略不能改或者换。之所以反对更改策略,是因为很多人对自己的策略还没上手,没了解清楚就急着换策略,这是没必要的。通过下面这个…

RK3568 AD按键改成GPIO按键

authordaisy.skye的博客_CSDN博客-嵌入式,Qt,Linux领域博主 相对路径 kernel/arch/arm64/boot/dts/rockchip/ido-evb3568-v2b.dtsi 代码解析 linux,input-type <1>;//input类型 <EV_KEY>按键 即1 gpios <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>;//io脚地址…

算法--- 叶子相似的树

题目 请考虑一棵二叉树上所有的叶子&#xff0c;这些叶子的值按从左到右的顺序排列形成一个 叶值序列 。 举个例子&#xff0c;如上图所示&#xff0c;给定一棵叶值序列为 (6, 7, 4, 9, 8) 的树。 如果有两棵二叉树的叶值序列是相同&#xff0c;那么我们就认为它们是 叶相似…