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

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

请添加图片描述

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 textureconst 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 texturetexture.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,0directionalLight.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场景对象Sceneconst 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


🔍【基础】Three.js的零基础入门篇(附案例代码)
🔍【基础】Three.js中添加操作面板,GUI可视化调试(附案例代码)

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Ext JS主要特点有哪些?
  • uniapp+vue3实现小程序和h5解压线上压缩包以及如何访问解压后的视频地址
  • 詳細解析軟路由與代理爬蟲池-okeyproxy
  • C++和OpenGL实现3D游戏编程【连载8】——纹理文字实现与优化
  • 元学习与机器学习
  • 精通推荐算法29:行为序列建模之MIMN— 记忆网络建模长周期行为序列
  • 视频监控系统布局策略:EasyCVR视频汇聚平台构建高效、全面的安全防线
  • ffmpeg音视频开发从入门到精通——ffmpeg日志及目录操作
  • 第143天:内网安全-权限维持自启动映像劫持粘滞键辅助屏保后门WinLogon
  • 探寻 IP 代理地址繁多之因
  • 【WPF】WPF学习之【二】布局学习
  • Spring Boot 部署(jar包)
  • 手机TF卡格式化后数据恢复:方法、挑战与预防措施
  • KRTS网络模块:UDP通信
  • MQ-7一氧化碳传感器详解(STM32)
  • [译]Python中的类属性与实例属性的区别
  • 【5+】跨webview多页面 触发事件(二)
  • dva中组件的懒加载
  • gulp 教程
  • isset在php5.6-和php7.0+的一些差异
  • select2 取值 遍历 设置默认值
  • Terraform入门 - 3. 变更基础设施
  • UMLCHINA 首席专家潘加宇鼎力推荐
  • 纯 javascript 半自动式下滑一定高度,导航栏固定
  • 从0到1:PostCSS 插件开发最佳实践
  • 对话:中国为什么有前途/ 写给中国的经济学
  • 试着探索高并发下的系统架构面貌
  • 微信小程序开发问题汇总
  • 微信小程序填坑清单
  • 问题之ssh中Host key verification failed的解决
  • 我是如何设计 Upload 上传组件的
  • “十年磨一剑”--有赞的HBase平台实践和应用之路 ...
  • 3月7日云栖精选夜读 | RSA 2019安全大会:企业资产管理成行业新风向标,云上安全占绝对优势 ...
  • # 计算机视觉入门
  • #前后端分离# 头条发布系统
  • #我与Java虚拟机的故事#连载18:JAVA成长之路
  • (2024最新)CentOS 7上在线安装MySQL 5.7|喂饭级教程
  • (31)对象的克隆
  • (CPU/GPU)粒子继承贴图颜色发射
  • (k8s)Kubernetes本地存储接入
  • (定时器/计数器)中断系统(详解与使用)
  • (免费领源码)Java#Springboot#mysql农产品销售管理系统47627-计算机毕业设计项目选题推荐
  • (转)Java socket中关闭IO流后,发生什么事?(以关闭输出流为例) .
  • (转)Mysql的优化设置
  • (转)创业家杂志:UCWEB天使第一步
  • .NET MVC第三章、三种传值方式
  • .NET 中 GetHashCode 的哈希值有多大概率会相同(哈希碰撞)
  • .NET教程 - 字符串 编码 正则表达式(String Encoding Regular Express)
  • /dev/sda2 is mounted; will not make a filesystem here!
  • @Not - Empty-Null-Blank
  • @property python知乎_Python3基础之:property
  • [ 网络通信基础 ]——网络的传输介质(双绞线,光纤,标准,线序)
  • [@Controller]4 详解@ModelAttribute
  • [android] 天气app布局练习
  • [BZOJ 1032][JSOI2007]祖码Zuma(区间Dp)