Three.js--》模型材质与纹理的使用

news2024/11/20 14:18:09

目录

初识材质与纹理

修改模型材质颜色

模型添加纹理

纹理常用属性使用

纹理显示算法

设置粗糙度

纹理加载进度情况

设置环境贴图


初识材质与纹理

three.js中的材质就是几何体表面的材料。所有材质均继承自Material。ThreeJS的材质分为:基础材质、深度材质、法向量材质、琥珀材质、冯氏材质、标准材质、着色器材质、基础线材质以及虚线材质。

材质就像物体的皮肤,决定了几何体的外表。例如,材质可以定义一个几何体看起来像金属还是木板,是否透明,什么颜色等,然后添加到Mesh中才可以添加到场景中进行渲染。本章,将会带领大家熟悉Three.js中API提供的所有材质,你也会学会运用这些材质,制作精美的三维物体。

纹理的基类是 Texture,一般我们都使用这个类,通过给其属性 Image 传入一个图片从而构造出一个纹理。纹理是材质的属性,材质和几何体 Gemotry 构成 Mesh ,然后被添加到 Scene 中进行渲染。纹理决定了物体的表面该是什么样子,而材质则决定了物体具备什么样的“气质”。

修改模型材质颜色

比如我设置了一个几何体,后面如果想修改其颜色的话可以通过以下几种方式进行:

模型添加纹理

给几何体添加纹理十分简单,只需准备一张纹理图,然后参考官方文档给出的案例即可:

纹理常用属性使用

纹理的属性有很多,具体的可参看 官方文档 ,如下。接下来着重讲解几个重要的属性:

纹理偏移设置

纹理旋转设置

// 设置纹理旋转 45deg
doorColorTexture.center.set(0.5,0.5) // 设置旋转原点
doorColorTexture.rotation = Math.PI / 4

纹理重复设置

// 设置纹理重复
doorColorTexture.repeat.set(2,3)
// 设置纹理重复模式
doorColorTexture.wrapS = THREE.RepeatWrapping  // 水平无限重复
doorColorTexture.wrapT = THREE.MirroredRepeatWrapping // 垂直镜像重复

纹理显示算法

通过以下官方提供给我们的API函数,实现纹理显示的算法:

// texture纹理显示设置
doorColorTexture.minFilter = THREE.NearestFilter
doorColorTexture.magFilter = THREE.NearestFilter

// texture纹理显示设置
doorColorTexture.minFilter = THREE.LinearFilter
doorColorTexture.magFilter = THREE.LinearFilter

设置粗糙度

我们也可以给几何体设置粗糙度,让其表面变得光滑从而反射的光更明显,如下:

当然我们可以采用一些贴图网站提供给我们的素材,对某一几何体进行相关细节特征的编写,在这就不再过多赘述,后期项目中会逐一讲解,素材网站 ;素材网站 。

纹理加载进度情况

当我们的项目图像资源过大时,我们可以可视化一个加载进度的显示,通过如下方式进行:

创建一个加载管理器:

// 设置加载管理器
const loadingManager = new THREE.loadingManager()

将load后三者提供的参数放置在里面

// 设置三种情况
const event = {}
event.onLoad = () =>{ 
  console.log('图片加载成功');
}
event.onProgress = (url,num,total) =>{ 
  console.log('图片加载完成:',url);
  console.log('图片加载进度:',num);
  console.log('图片总数:',total);
  console.log('加载进度的百分比:',((num/total)*100).toFixed(2)+"%")
}
event.onError = (e) =>{ 
  console.log('图片加载出现错误');
  console.log(e);
}

// 设置加载管理器
const loadingManager = new THREE.LoadingManager(
  event.onLoad,
  event.onProgress,
  event.onError
)

// 导入纹理
const textureLoader = new THREE.TextureLoader(loadingManager)
const doorColorTexture = textureLoader.load(img)

当然我们可以将进度显示在界面上,如下:

var div = document.createElement("div")
div.style.width = "200px"
div.style.height = "200px"
div.style.position = "fixed"
div.style.right = 0
div.style.top = 0
div.style.color = "#fff"
document.body.appendChild(div)

因为我写的这个案例就一张图片,所以加载速度很快,等后期做项目素材数量多的话,这种就有明显的效果了,如下:

设置环境贴图

环境贴图就类似于将一个几何体的全身都贴上图片,让其彷佛置身在当前的空间当中,当然这里的图片你可以采用真实的类似商业街道或者乡野田园等等。

注意:使用图片的分辨率尺寸一定要保持一致,不然是不会加载出来的。

// 设置cube纹理加载器
const cubeTextureLoader = new THREE.CubeTextureLoader()
const envMapTexture = cubeTextureLoader.load([img1,img2,img3,img4,img5,img6])

// 创建球物体
const sphereGeometry = new THREE.SphereGeometry(1,20,20)
// 球模型渲染几何体
const material = new THREE.MeshStandardMaterial({
  metalness:0.7, // 设置金属材质
  roughness:0.1, // 设置光滑度
  envMap:envMapTexture
})
const mesh = new THREE.Mesh(sphereGeometry,material)
scene.add(mesh)

当然我们也可以给环境添加背景,这样让整个样式更加的真实,如下:

// 给场景添加背景
scene.background = envMapTexture

当然你也可以不用给材料设置envMap属性,也可以进行如下设置给当前所有的页面添加相同背景

当然我们也不一定非要需要6张图片去实现,一张全景图也能实现3d可视化效果,这种方式就是类似于一张世界地图呈现在你面前,而当它不是以平面图片给你展示而是以一个球体给你展示的时候,你也能感受到3d的效果,全景图的实现类似就是这样:

import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader'
// 添加hdr环境图
const rgbeLoader = new RGBELoader()
rgbeLoader.loadAsync("/src/public/2.hdr").then((texture)=>{
  texture.mapping = THREE.EquirectangularReflectionMapping
  scene.background = texture
  scene.environment = texture
})

ok,材质与纹理的使用就讲到这,具体可以参考官网,给出本文的代码笔记:

import * as THREE from 'three';
// 导入轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
// import img from '../public/木质纹理.jpg'
// import img1 from '../public/1.jpg'
// import img2 from '../public/2.jpg'
// import img3 from '../public/3.jpg'
// import img4 from '../public/4.jpg'
// import img5 from '../public/5.jpg'
// import img6 from '../public/6.jpg'
// import img7 from "../public/1.hdr"
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader'
// 添加hdr环境图
const rgbeLoader = new RGBELoader()
rgbeLoader.loadAsync("/src/public/2.hdr").then((texture)=>{
  texture.mapping = THREE.EquirectangularReflectionMapping
  scene.background = texture
  scene.environment = texture
})

// 1.创建场景
const scene = new THREE.Scene();
// 2.创建相机
const camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000)
// 设置x、y、z轴坐标,即设置相机位置
camera.position.set(0,0,10)
// 将相机添加到场景之中
scene.add(camera)
// 3.添加物体,创建几何体
// const geometry = new THREE.BoxGeometry(3,3,3)

// var div = document.createElement("div")
// div.style.width = "200px"
// div.style.height = "200px"
// div.style.position = "fixed"
// div.style.right = 0
// div.style.top = 0
// div.style.color = "#fff"
// document.body.appendChild(div)

// // 设置三种情况
// const event = {}
// event.onLoad = () =>{ 
//   console.log('图片加载成功');
// }
// event.onProgress = (url,num,total) =>{ 
//   console.log('图片加载完成:',url);
//   console.log('图片加载进度:',num);
//   console.log('图片总数:',total);
//   let value = ((num/total)*100).toFixed(2)+"%"
//   div.innerHTML = value
//   console.log('加载进度的百分比:',((num/total)*100).toFixed(2)+"%")
// }
// event.onError = (e) =>{ 
//   console.log('图片加载出现错误');
//   console.log(e);
// }

// // 设置加载管理器
// const loadingManager = new THREE.LoadingManager(
//   event.onLoad,
//   event.onProgress,
//   event.onError
// )

// // 导入纹理
// const textureLoader = new THREE.TextureLoader(loadingManager)
// const doorColorTexture = textureLoader.load(img)

// // 设置纹理偏移
// doorColorTexture.offset.x = 0.5
// doorColorTexture.offset.y = 0.5
// doorColorTexture.offset.set(0.5,0,5)
// // 设置纹理旋转 45deg
// doorColorTexture.center.set(0.5,0.5) // 设置旋转原点
// doorColorTexture.rotation = Math.PI / 4
// // 设置纹理重复
// doorColorTexture.repeat.set(2,3)
// // 设置纹理重复模式
// doorColorTexture.wrapS = THREE.RepeatWrapping  // 水平无限重复
// doorColorTexture.wrapT = THREE.MirroredRepeatWrapping // 垂直镜像重复

// texture纹理显示设置
// doorColorTexture.minFilter = THREE.NearestFilter
// doorColorTexture.magFilter = THREE.NearestFilter
// doorColorTexture.minFilter = THREE.LinearFilter
// doorColorTexture.magFilter = THREE.LinearFilter

// 设置cube纹理加载器
// const cubeTextureLoader = new THREE.CubeTextureLoader()
// const envMapTexture = cubeTextureLoader.load([img1,img2,img3,img4,img5,img6])

// 创建球物体
const sphereGeometry = new THREE.SphereGeometry(1,20,20)
// 球模型渲染几何体
const material = new THREE.MeshStandardMaterial({
  metalness:0.7, // 设置金属材质
  roughness:0.1, // 设置光滑度
  // envMap:envMapTexture
})
const mesh = new THREE.Mesh(sphereGeometry,material)
scene.add(mesh)
// // 给场景添加背景
// scene.background = envMapTexture
// 给场景所有的物体添加默认的环境贴图
// scene.environment = envMapTexture


// // 网格模型渲染几何体
// const material = new THREE.MeshStandardMaterial({
//   color:'#fffff00',
// })
// const mesh = new THREE.Mesh(geometry,material)
// scene.add(mesh)


// 4.初始化渲染器
const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth,window.innerHeight)
document.body.appendChild(renderer.domElement)

// // 添加一个平行光
// const directionalLight = new THREE.DirectionalLight(0xffffff,1)
// // 设置光源方向
// directionalLight.position.set(8,10,5)
// // 方向光指向对象网格模型Mesh,即照射的对象,可以不设置,默认的位置是0,0,0
// directionalLight.target = mesh
// scene.add(directionalLight)

// 添加一个环境光
const ambient = new THREE.AmbientLight(0xffffff,0.9)
scene.add(ambient)

// // 创建一个点光源
// const pointLight = new THREE.PointLight(0xffffff,1.0)
// // 设置点光源位置
// pointLight.position.set(0,5,0)
// scene.add(pointLight)
// // 可视化点光源
// const pointLightHelper = new THREE.PointLightHelper( pointLight, 0.1 );
// scene.add(pointLightHelper)

// // 添加坐标轴辅助器
// const axesHelper = new THREE.AxesHelper(5) // 数值代表线的长度
// scene.add(axesHelper) // 添加到场景之中

// 创建轨道控制器
const controls =  new OrbitControls(camera,renderer.domElement)
// 设置控制器阻尼,让控制器更有真实效果,但必须在动画循环里调用 .update()
controls.enableDamping = true

export function render(){
  // 每次循环渲染时调用stats更新方法,来刷新时间
  controls.update()
  renderer.render(scene,camera) // 周期性执行相机的渲染功能,更新canvas画布上的内容
  requestAnimationFrame(render) // 接下来渲染下一帧的时候就会调用render函数
}
// 先开始就渲染一下
render()

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

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

相关文章

Linux(centos 7) 环境安装MySQL5.7

mysql安装包 链接:百度网盘 请输入提取码 提取码:b8w4 环境准备 安装好的centos 7系统 root 用户登录Linux 在根目录下创建/soft目录 上传mysql安装包到/soft目录,结果如下 准备完毕 安装 根据现有序号挨个安装 rpm 包,依…

“聪明车”接驳“智慧路”—— 智能网联车驶上新赛道

去年底,智己L7首批200台Beta体验版下线交付。 智能网联车,“新赛道”上疾驶着“新终端”。“聪明车”如何更好接驳“智慧路”?全国两会现场,不少代表委员聚焦于这一话题展开热议,出谋划策。 “只有把‘终端’牢牢掌握在…

06 - 2 分层架构模式(Layered Arch)

层 层的定义 层:软件的逻辑单元每一层都有特定的功能组件被分配到不同的层 何谓分层 将系统按照职责拆分和组织上层依赖于直接下层 下层不可以依赖于上层不可以跃层访问(理想状况) 经典分层架构 OSI 7 层架构 CS 两层架构Client&…

生动形象的傅里叶变换解析!

使用联想链条和几何直观,辅以从实际需求衍生概念的思考模式,详解什么是傅立叶变换,为什么要做傅立叶变换等,帮助记忆和理解,目的当然是标题所说:让你永远忘不了傅里叶变换这个公式。另,这篇博客…

MySQL之Server层的内存结构

前言 本文已收录在MySQL性能优化原理实战专栏,点击此处浏览更多优质内容。 前面的文章我们介绍了InnoDB存储引擎的一些内存、内存磁盘的结构以及工作原理,今天我们就来看一下关于MySQL Server层的一些内存结构。 目录 一、Binlog Cache1.1 Binlog Cache工…

jvm之远程调试

写在前面 工作中,有时会出现测试环境有问题,本地却正常的情况,此时我们就可以通过JVM提供的远程调用的功能,实现在本地debug调试测试环境代码。 1:例子1直接运行class 首先我们来定义类: package com.f…

Blender 形变类修改器:曲线

目录 形变类修改器1. 测试一:减少环切数量1.1 调整物体原点1.2 让两个物体原点重合1.3 添加曲线修改器1.4 融并边 2. 测试二:曲线的方向2.1 查看曲线的方向(曲线法向显示)2.2 在3D空间调整曲线 3. 测试三:空间位置的影…

【Minecraft开服教学】使用 MCSM 面板一键搭建我的世界服务器 并使用内网穿透公网远程联机

文章目录 前言1.Mcsmanager安装2.创建Minecraft服务器3.本地测试联机4. 内网穿透4.1 安装cpolar内网穿透4.2 创建隧道映射内网端口 5.远程联机测试6. 配置固定远程联机端口地址6.1 保留一个固定TCP地址6.2 配置固定TCP地址 7. 使用固定公网地址远程联机 转载自远程穿透文章&…

C语言中链表经典面试题目

🐶博主主页:ᰔᩚ. 一怀明月ꦿ ❤️‍🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C 🔥座右铭:“不要等到什么都没有了,才下…

MySQL之Change Buffer详解

前言 本文已收录在MySQL性能优化原理实战专栏,点击此处浏览更多优质内容。 上一篇文章一文带你了解MySQL数据库InnoDB_Buffer_Pool(点击跳转)我们学习了InnoDB Buffer Pool的工作原理,其作用是减少MySQL读取数据时直接与磁盘打交道…

百趣代谢组学党参远志散对记忆障碍大鼠学习能力和肠道菌群的影响

文章标题:Effects of Dangshen Yuanzhi Powder on learning ability and gut microflora in rats with memory disorde 发表期刊:Journal of Ethnopharmacology 影响因子:5.195 作者单位:山西中医药大学 百趣提供服务&#xf…

什么是元宇宙数字展厅?元宇宙前景如何 ?

元宇宙是一个近年来备受关注的概念,它被认为是未来数字世界的新形态。元宇宙是一个虚拟的、数字化的世界,它可以模拟现实世界的各种物理、社会和经济系统,同时也可以融合人工智能、虚拟现实等前沿技术,为用户提供更加丰富、多样化…

钴基双金属氧化物储能材料的高效制备和电化学应用

一、引言 钴金属氧化物作为一类典型的储能材料,既可以用于锂离子电池负极材料,又可以用于超级电容器电极材料,因而备受关注 。在作为锂离子电池负极材料时,具有较高的理论比容量,但充放电体积变化较大、材料导电性较差…

十、MyBatis的缓存

文章目录 十、MyBatis的缓存10.1 MyBatis的一级缓存场景1:判断同一个sqlSession是否查询1级缓存,答案:会查询1级缓存场景2:判断不同sqlSession是否查询1级缓存,答案:不会查询1级缓存场景3:判断相…

企业服务管理(ESM)工具

什么是企业服务管理 企业服务管理 (ESM) 是 IT 服务管理(ITSM)原则的延伸,旨在为人力资源 (HR)、法律、设施、营销和财务等业务团队提供更好的服务。ITSM 是 IT 团队管理向客户提供端到端 IT 服务的方式。ESM 的一个例子是建立一个可供整个组织所有团队使用的服务台…

LED显示屏周边设备

LED显示屏市场也呈多元化发展,异型屏、灯条屏、透明屏、小间距等应用新产品的出现无疑不是一种技术创新。以上创新技术的应用,对LED显示屏周边设备生产企业也提出了更高要求。因此,周边设备对推动整个LED显示屏的产业发展起着举足轻重、不可或…

【Linux-进程通信1】管道

🌈进程间通信介绍 🍄进程间通信目的 在操作系统中,每个进程都是独立运行的,它们有自己的地址空间和资源,它们不能直接访问其他进程的资源。然而,在现代计算机系统中,很少有一个进程能够独立完成…

yolov5读取单通道图像会怎样?

通过上图打印可知输入是固定3通道,那么意味着在读取图像中会对图像进行处理。 opencv在默认情况下会读取3个通道的图像,如果是灰度图会将图层复制三次(BGR缺省,BGR),因此读出来的图片是三通道。

xcode打包导出ipa

转载:xcode打包导出ipa 众所周知,在开发苹果应用时需要使用签名(证书)才能进行打包安装苹果IPA,作为刚接触ios开发的同学,只是学习ios app开发内测,并没有上架appstore需求,对于苹果…

【Mybatis】Mybatis之xml开发—用户角色权限关联案例

目录 要求:使用xml开发完成需求查询。 数据库 需求 要求:使用xml开发完成需求查询。 数据库 -- 用户表 create table sys_user(user_id int primary key auto_increment comment 用户ID,user_name varchar(50) comment 用户名,password varchar(32)…