【基础】Three.js加载纹理贴图、加载外部gltf格式文件

news2024/11/13 18:40:06

请添加图片描述

1. 模型使用纹理贴图

const geometry = new THREE.BoxGeometry(10, 10, 10);
  const textureLoader = new THREE.TextureLoader(); // 创建纹理贴图加载器
  const texture = textureLoader.load("/crate.gif"); // 加载纹理贴图
  const material = new THREE.MeshLambertMaterial({
    map: texture,
    side: THREE.DoubleSide, //两面可见
  });

2. 加载外部gltf格式

GLTF(GL Transmission Format)是一种高效、开放的3D文件格式,专为Web和移动端实时渲染而设计。GLTF文件格式旨在传输3D模型数据,具有快速加载、渲染效率高、支持丰富的材质和动画等优点,被称为“3D领域的JPEG”。

GLTF文件结构:
.gltf(JSON文件): 描述模型的主要结构,包括几何体、材质、动画、场景等。
.bin(二进制文件): 存储顶点数据、法线、UV坐标等二进制数据。
纹理(.png, .jpg): 存储模型使用的纹理贴图。
.glb(单文件格式): GLB是GLTF的二进制版本,将所有数据(JSON、二进制和纹理)合并到一个文件中,方便传输和使用。

可以用Blender软件导出绘制好的三维模型,也可以打开和预览gltf格式文件模型

注意: 纹理贴图和gltf格式存放在public目录下

  // 创建GLTFLoader实例
  const loader = new GLTFLoader();

  // 加载.gltf文件
  loader.load("/models/Parrot.glb", function (gltf) {
    const model = gltf.scene;
    // 修改模型的位置
    model.position.set(0, 15, 0); // 设置为(x, y, z),可根据需要调整
    // 修改模型的旋转
    model.rotation.set(Math.PI / 4, Math.PI / 4, 0); // 设置旋转角度(弧度),如(x, y, z)
    // 修改模型的缩放
    model.scale.set(0.2, 0.2, 0.2); // 设置缩放比例 (x, y, z)
    scene.add(model);
  });

3. 光源辅助查看

1.点光源辅助查看:
PointLightHelper( light : PointLight, sphereSize : Float, color : Hex )
light – 要模拟的光源.
sphereSize – (可选的) 球形辅助对象的尺寸. 默认为 1.
color – (可选的) 如果没有赋值辅助对象将使用光源的颜色.

const pointLight = new THREE.PointLight( 0xff0000, 1, 100 );
pointLight.position.set( 10, 10, 10 );
scene.add( pointLight );

const sphereSize = 1;
const pointLightHelper = new THREE.PointLightHelper( pointLight, sphereSize );
scene.add( pointLightHelper );

2.平行光源辅助查看:
DirectionalLightHelper( light : DirectionalLight, size : Number, color : Hex )
light-- 被模拟的光源.
size – (可选的) 平面的尺寸. 默认为 1.
color – (可选的) 如果没有设置颜色将使用光源的颜色.

const light = new THREE.DirectionalLight( 0xFFFFFF );
const helper = new THREE.DirectionalLightHelper( light, 5 );
scene.add( helper );

4. 案例代码

在这里插入图片描述

<template>
  <div class="wrapper">
    <div ref="threeRef"></div>
  </div>
</template>
<script setup lang="ts">
// 引入three.js
import * as THREE from "three";
// 引入扩展库OrbitControls.js
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
// 引入dat.gui.js的一个类GUI
import { GUI } from "three/addons/libs/lil-gui.module.min.js";
import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";

import { onMounted, ref } from "vue";
const threeRef = ref();
// 模型1
const createMesh1 = () => {
  const geometry = new THREE.BoxGeometry(10, 10, 10);
  const textureLoader = new THREE.TextureLoader(); // create a texture loader.
  const texture = textureLoader.load("/crate.gif"); // load a texture

  const material = new THREE.MeshLambertMaterial({
    // color: 0xff0000,
    map: texture,
    side: THREE.DoubleSide, //两面可见
  });

  return new THREE.Mesh(geometry, material);
};
// 模型2
const createMesh2 = () => {
  const geometry = new THREE.BoxGeometry(3, 3, 3);
  const textureLoader = new THREE.TextureLoader(); // create a texture loader.
  const texture = textureLoader.load("/grid.png"); // load a texture
  texture.repeat.set(2, 2); // 设置纹理的重复次数
  texture.rotation = Math.PI / 4; // 旋转纹理(以弧度为单位)
  texture.center.set(0.5, 0.5); // 设置旋转的中心
  texture.center.set(0.5, 0.5); // 设置旋转的中心
  const material = new THREE.MeshStandardMaterial({
    map: texture,
  });
  return new THREE.Mesh(geometry, material);
};

// 添加光源
const createDictionLight = (target) => {
  // 平行光
  const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
  // 设置光源的方向:通过光源position属性和目标指向对象的position属性计算
  directionalLight.position.set(10, 15, 25);
  // 方向光指向对象网格模型mesh,可以不设置,默认的位置是0,0,0
  directionalLight.target = target;
  return directionalLight;
};

// 添加渲染器
const createRenderer = (dom: HTMLElement) => {
  const renderer = new THREE.WebGLRenderer({
    antialias: true, // 设置锯齿属性,为了获得更好的图像质量
  });

  // 定义threejs输出画布的尺寸(单位:像素px)
  renderer.setSize(window.innerWidth, window.innerHeight);
  // 为了适应不同的硬件设备屏幕,设置设备像素比
  renderer.setPixelRatio(window.devicePixelRatio);
  // 插入到任意HTML元素中
  dom.append(renderer.domElement);

  return renderer;
};
// 响应式窗口处理
const onResize = (camera, renderer) => {
  window.onresize = function () {
    // 更新相机纵横比
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    // 更新渲染器的大小
    renderer.setSize(window.innerWidth, window.innerHeight);
  };
};

// 添加操作面板
const createGui = (mesh, light) => {
  // 实例化一个gui对象
  const gui = new GUI();

  //设置操作面板位置
  gui.domElement.style.right = "0px";
  gui.domElement.style.width = "300px";

  //添加光照强度,并使用name重命名,step设置步长
  gui.add(light, "intensity", 0, 2.0).name("平行光强度").step(0.1);

  // 添加颜色
  gui
    .addColor(
      {
        color: 0xff0000,
      },
      "color"
    )
    .name("颜色")
    .onChange(function (value) {
      mesh.material.color.set(value);
    });
};
// 添加了一个相机控制插件,实现平移、旋转和缩放/推拉相以从任何角度查看场景
// 改变的实际上时相机的位置,并不是物体
const createControls = (scene, camera, renderer) => {
  const controls = new OrbitControls(camera, renderer.domElement);
  // 这个插件允许您
  controls.addEventListener("change", function () {
    renderer.render(scene, camera); //执行渲染操作
  });
};

const init = () => {
  //! 1.创建场景
  // 创建3D场景对象Scene
  const scene = new THREE.Scene();
  scene.background = new THREE.Color("#c1c5d8"); // 设置场景颜色

  // 物体
  const mesh1 = createMesh1();
  mesh1.position.set(0, 0, 0);
  scene.add(mesh1); // 将模型添加到场景中

  const mesh2 = createMesh2();
  mesh2.position.set(0, 8, 0);
  scene.add(mesh2);

  //! 2.创建相机
  // 30:视场角度, width / height:Canvas画布宽高比, 1:近裁截面, 3000:远裁截面
  const camera = new THREE.PerspectiveCamera(
    75,
    window.innerWidth / window.innerHeight,
    1,
    3000
  );
  camera.position.set(10, 10, 10); // 相机位置
  camera.lookAt(mesh1.position); //指向mesh对应的位置
  camera.lookAt(mesh2.position); //指向mesh对应的位置

  // !AxesHelper:辅助观察的坐标系
  // const axesHelper = new THREE.AxesHelper(20);
  //  scene.add(axesHelper);

  //渲染
  const renderer = createRenderer(threeRef.value);
  renderer.render(scene, camera);

  // 添加光源
  const dictionLight = createDictionLight(mesh1);
  // 将光源添加到场景中
  scene.add(dictionLight);
  // 查看平行光
  const helper = new THREE.DirectionalLightHelper(dictionLight, 5);
  scene.add(helper);

  //环境光:没有特定方向,整体改变场景的光照明暗
  const ambientLight = new THREE.AmbientLight(0xffffff, 0.4);
  scene.add(ambientLight);

  // 设置相机控件轨道控制器
  createControls(scene, camera, renderer);
  // !  创建循环动画,使物体可以动起来
  function rotateRender() {
    renderer.render(scene, camera); //执行渲染操作
    mesh1.rotateY(0.01); //每次绕y轴旋转0.01弧度
    mesh2.rotateX(0.01);
    requestAnimationFrame(rotateRender); //请求再次执行渲染函数render,渲染下一帧
  }

  // 创建GLTFLoader实例
  const loader = new GLTFLoader();

  // 加载.gltf文件
  loader.load("/models/Parrot.glb", function (gltf) {
    const model = gltf.scene;
    // 修改模型的位置
    model.position.set(0, 15, 0); // 设置为(x, y, z),可根据需要调整
    // 修改模型的旋转
    model.rotation.set(Math.PI / 4, Math.PI / 4, 0); // 设置旋转角度(弧度),如(x, y, z)
    // 修改模型的缩放
    model.scale.set(0.2, 0.2, 0.2); // 设置缩放比例 (x, y, z)
    scene.add(model);
  });

  rotateRender();
  // 添加操作面板
  createGui(mesh2, dictionLight);
  onResize(camera, renderer);
};

onMounted(() => {
  init();
});
</script>
<style scoped></style>

案例纹理图片:位置放在/public
https://github.com/mrdoob/three.js/blob/dev/examples/textures/crate.gif
在这里插入图片描述
案例gltf文件: 位置放在/public/models
https://github.com/mrdoob/three.js/blob/dev/examples/models/gltf/Parrot.glb

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

运维问题0001:MM模块-MIGO收货报错“消息号 M7036 对于采购订单********无收货可能”

1、问题解析&#xff1a; 该报错为SAP标准报错类型,针对公司不同配置/业务设计/校验逻辑&#xff0c;导致该问题原因比较多。 常见的问题总结如下&#xff1a; 1&#xff09;输入的PO信息有问题&#xff08;例如&#xff1a;PO输入错误/PO删除状态/PO冻结状态/PO已完成收货等…

HCIE认证要学多久?3个方面决定HCIE学习时长

HCIE认证作为华为公司推出的顶级专业认证&#xff0c;已经成为网络技术领域内的一个标杆。 它不仅象征着专业技能的高峰&#xff0c;也是许多IT专业人士职业发展的重要里程碑。 HCIE作为华为高级认证虽然可以不需要满足任何条件直接报考&#xff0c;但掌握必要的知识内容必不可…

MySQL复习2

高级查询 准备 create database greatselect; use greatselect;drop table if exists class; create table class (cid int(11) not null auto_increment,caption varchar(32) not null,primary key (cid) )engine innoDB AUTO_INCREMENT5 default charset utf8;create tab…

报考条件、材料、流程?关于CISP认证,你必须要了解这些

信息安全一直是一个火热的话题&#xff0c;在近两年又被推上了高峰。对此&#xff0c;相关认证也不例外。 很多朋友都想get一本安全方向的证书&#xff0c;在广大安全方向的认证中&#xff0c;CISP可谓是发展迅猛&#xff0c;并越来越广为人知&#xff0c;也越来越受到IT从业者…

python Bokeh库学习记录

First steps 2: 添加和自定义渲染器 在之前的入门指南中&#xff0c;你使用了Bokeh的figure()函数来绘制折线图。 在本节中&#xff0c;你将使用不同的渲染函数来创建各种其他类型的图表。你还将自定义你的图像外观。 渲染不同的图形符号 Bokeh的绘图界面支持多种不同的图形…

古典显示格式解一偏微分方程并绘制结果的彩色图

解如下偏微分方程 以上公式的Latex代码 \begin{cases}\frac{\partial u}{\partial t}a\frac{\partial ^2u}{\partial x^2}\,\,,0<x<1,t>0\\u\left( x,0 \right) 4x\left( 1-x \right) \,\,,0\leqslant x\leqslant 1\\u\left( 0,t \right) u\left( 1,t \right) 0 ,t\g…

补题篇--codeforces

传送门&#xff1a;Problem - G - Codeforces 题意&#xff1a; 思路&#xff1a; 注意&#xff1a; n 的范围很小&#xff0c;大概率考察状态压缩 因此这个题可以考虑用 状压dp f[i][j] 表示状态为 i 的选法&#xff0c;以第 j 首歌为结尾的播放列表中的歌曲总数 f[ i | …

生活方式对人健康影响非常大 第三篇

身体健康因素中 生活方式占到60% 赶紧去调整自己哪错了 上游的生活方式管理 是药三分毒 药物会影响身体肝肾功能,代谢 所以你要去找上游到底是我哪错了 短板越多 个健康状态越差 饮食管理是生活方式管理中难度最大的 原则1:与基因相对应相平衡 只吃素 会导致大脑萎…

【书生大模型实战营】进阶岛 第6关 MindSearch 快速部署

文章目录 【书生大模型实战营】进阶岛 第6关 MindSearch 快速部署MindSearch 部署到Github Codespace 和 Hugging Face Space创建开发机 & 环境配置MindSearch下载及环境配置获取硅基流动API Key作业 - 基础任务在Github codespaces 启动 MindSearch通过 Github Codespace …

spring框架4 - bean加载

本节内容&#xff1a;beanFactory.getBean("user"); Testvoid testGetBean() {Gun gun beanFactory.getBean("m416", Gun.class);log.info("gun{}", gun);} public <T> T getBean(String name, Class<T> requiredType) throws Bea…

2024年威胁暴露管理两大新趋势

文章目录 前言一、威胁暴露管理的两大新类别二、EAP:减少对CVSS的依赖三、AEV:锁定现实威胁四、CTEM实施面临的挑战与应对策略五、主动风险管理的新时代前言 2024年,安全运营(SecOps)领域迎来重大变革。根据Gartner最新发布的《安全运营技术成熟度曲线》报告,持续威胁暴…

一款人脸识别的芯片内部

三年前在一家3D人脸识别的芯片公司&#xff0c;先后做过两个稍具规模的芯片项目&#xff0c;因为各种原因&#xff0c;这些最终都没有上市&#xff0c;成为沉寂在实验室的产物。但是这些芯片的总体设计都颇具匠心&#xff0c;自己在当时也很有触动&#xff0c;现在拿出一点来供…

揭秘难以复现Bug的解决之道:堆栈分析实战

目录 引言 友情提示难以复现的Bug之痛 寄存器(SP、LR)详解 SP寄存器&#xff1a;堆栈的指路明灯LR寄存器&#xff1a;函数调用与异常处理的桥梁 问题分析与解决流程揭秘 保存现场分析堆栈数据 堆栈结构入栈顺序 案例 J-Link工具 常用命令保存RAM数据到本地 分析栈基本信息 分…

【最新华为OD机试E卷】最大报酬(100分)-多语言题解-(Python/C/JavaScript/Java/Cpp)

🍭 大家好这里是春秋招笔试突围 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-E/D卷的三语言AC题解 💻 ACM金牌🏅️团队| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 🍿 最新华为OD机试D卷目录,全、新、准,题目覆盖率达 95% 以上,…

【Python】企业排名、地域分布与词云分析可视化

目录 数据处理 Pyecharts 各国数量 分布地图 数量占比 城市分布 营业收入 利润转化 数据处理 2021世界五百强企业数据&#xff0c;包含公司名称、公司链接、营业收入(百万美元)、利润(百万美元)、国家等信息。数据集下载&#xff1a;Python企业排名、地域分布与词云分…

opencv-python 图像增强十七:泊松图像融合

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、概述二&#xff0c;实现&#xff1a; 前言 在深入探讨图像处理与计算机视觉领域的过程中&#xff0c;我们不禁对图像融合技术的精妙与实用性感到着迷。图像…

物联网之云平台架构

一&#xff0c;一个典型的物联网云平台 一个典型的物联网&#xff08;IoT&#xff09;云平台需要实现多个功能&#xff0c;以支持物联网设备的接入、数据处理、设备管理、实时控制等需求。 &#xff08;一&#xff09;核心功能 1&#xff0c;设备接入与管理&#xff1a; - 设…

【达梦数据库】DBeaver连接达梦数据库

打开 DBeaver&#xff0c;新建驱动管理器 新建驱动管理器&#xff0c;配置信息如下 添加库文件&#xff0c;jar包使用项目上使用的jdbc驱动包即可&#xff0c;找到本地maven仓库jar位置进行添加。 <dependency><groupId>com.dameng</groupId><artifact…

打开配置好的gee的jupyter Lab环境

目录 打开anconda 打开箭头下的cmd环境&#xff0c;输入jupyter lab

Spring MVC 八股文

目录 重点 SpringMVC的工作原理 Spring MVC 拦截器 Spring MVC 的拦截器和 Filter 过滤器有什么差别&#xff1f; 基础 什么是SpringMVC SpringMVC的优点 Spring MVC的核心组件 Spring MVC的常用注解由有哪些 Controller 注解有什么用 重点 SpringMVC的工作原理 1、客…