Three.js 基础纹理贴图

本文简介

带尬猴,我嗨德育处主任


尽管 Three.js 文档已经比较详细了,但对于刚接触 Three.js 的工友来说,最麻烦的还是不懂如何组合。Three.js 的功能实在太多了,初学者很容易被大量的新概念冲晕。

本文主要讲解入门 Three.js 必须接触的基础贴图功能。本文只讲解常用的属性,学会了常用的属性设置就知道如何查阅文档使用其他属性了~



基础贴图

基础贴图用到的是基础材质 THREE.MeshBasicMaterialTHREE.TextureLoader

THREE.MeshBasicMaterial 是一个不受光照影响的材质,它可以直接给物体设置颜色,也可以将图片贴到物体表面。

THREE.TextureLoaderTHREE 提供的一个纹理加载器,通过它可以加载一些素材纹理。


在开始之前,先把画布必须项创建好。画布必须项包括:场景、相机、渲染器。如果忘了的话可以查看 《『Three.js』起飞!》

file

<div id="canvasBox"></div><script type="module">import * as THREE from "./js/Three/src/Three.js"import { OrbitControls } from './js/Three/examples/jsm/controls/OrbitControls.js'// 创建场景const scene = new THREE.Scene()// 创建相机const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)camera.position.set(1, 1, 5)camera.lookAt(scene.position)// 创建辅助坐标系const axesHelper = new THREE.AxesHelper(5)scene.add(axesHelper)// 创建渲染器const renderer = new THREE.WebGLRenderer()renderer.setSize(window.innerWidth, window.innerHeight)document.getElementById('canvasBox').appendChild(renderer.domElement)// 创建轨道控制器const controls = new OrbitControls(camera, renderer.domElement)controls.enableDamping = true// 循环执行function animate() {controls.update()renderer.render( scene, camera )requestAnimationFrame( animate )}// 执行动画函数animate()
</script>

除了创建场景、相机和渲染器之外,我还创建了辅助坐标系 AxesHelper 和轨道控制器 OrbitControls,方便观察。


加载纹理

要使用纹理,需要做以下几步:

  1. 创建一个物体,用来承载纹理
  2. 引入纹理加载器 THREE.TextureLoader,并加载纹理 (load() 方法)
  3. 将纹理添加给基础材质 THREE.MeshBasicMaterial

由于前面已经创建了基础的画布所需项,所以这里会省略这部分代码

file

// 省略部分代码...// Three提供的纹理加载器
const textureLoader = new THREE.TextureLoader()
// 导入纹理贴图基础贴图
const chungeLoader = textureLoader.load('./assets/images/chunge_flower.png')// 创建立方体
const geometry = new THREE.BoxGeometry(1, 1, 1)
const material = new THREE.MeshBasicMaterial({map: chungeLoader // 纹理贴图
})
const cube = new THREE.Mesh(geometry, material)
scene.add(cube)

THREE.MeshBasicMaterialmap 属性可以设置纹理贴图。


正反面渲染

前面的例子我们创建的立方体,如果此时我们把图贴到平面上,默认情况下它只显示正面。


本例用到下面这张图片

file


  1. 创建一个平面
  2. 贴图

file

// 省略部分代码...// Three提供的纹理加载器
const textureLoader = new THREE.TextureLoader()
// 导入纹理贴图基础贴图
const chungeLoader = textureLoader.load('./assets/images/chunge_flower.png')// 创建一个圆形
const circleGeometry = new THREE.CircleGeometry(0.5, 32)
const material = new THREE.MeshBasicMaterial({map: chungeLoader // 贴图
})
const circle = new THREE.Mesh(circleGeometry, material)
scene.add(circle)

如果此时希望正方面都有贴图效果,可以将 side 设置为 THREE.DoubleSide

side 的默认值是 THREE.FrontSide。其他选项有THREE.BackSide, THREE.DoubleSide 和 THREE.TwoPassDoubleSide。

file

// 省略部分代码...// Three提供的纹理加载器
const textureLoader = new THREE.TextureLoader()
// 导入纹理贴图基础贴图
const chungeLoader = textureLoader.load('./assets/images/chunge_flower.png')// 创建一个圆形
const circleGeometry = new THREE.CircleGeometry(0.5, 32)
const material = new THREE.MeshBasicMaterial({map: chungeLoader, // 贴图side: THREE.DoubleSide // 正反面都贴图
})
const circle = new THREE.Mesh(circleGeometry, material)
scene.add(circle)

纹理偏移

在加载完纹理之后,可以设置纹理的 offset 属性进行纹理偏移。


本例用到下面这张图片

file


05

// 省略部分代码...// Three提供的纹理加载器
const textureLoader = new THREE.TextureLoader()
// 导入纹理贴图基础贴图
const chungeLoader = textureLoader.load('./assets/images/chunge_flower.png')// 纹理偏移
chungeLoader.offset.set(0.1, -0.5)// 创建一个圆形
const circleGeometry = new THREE.CircleGeometry(0.5, 32)
const material = new THREE.MeshBasicMaterial({map: chungeLoader, // 贴图side: THREE.DoubleSide // 正反面都贴图
})
const circle = new THREE.Mesh(circleGeometry, material)
scene.add(circle)

其中,以下代码等价于 chungeLoader.offset.set(0.1, -0.5)

chungeLoader.offset.x = 0.1
chungeLoader.offset.y = -0.5

x轴方向是正数时,纹理向右偏移;负数则向左偏移。

y轴方向是正数时,纹理向下偏移;负数则向上偏移。


旋转纹理

加载完纹理后,可以通过修改 rotation 属性旋转纹理。

旋转纹理要注意以下几点:

  1. 通过 rotation 旋转纹理
  2. 旋转时,是以弧度为单位。角度转弧度比较直观的公式是:角度度数 * Math.PI / 180
  3. 通过 center 设置旋转中心点

如果不设置旋转中心点,默认是以左上角为中心点进行旋转。

file

// 省略部分代码...// Three提供的纹理加载器
const textureLoader = new THREE.TextureLoader()
// 导入纹理贴图基础贴图
const chungeLoader = textureLoader.load('./assets/images/chunge_flower.png')// 旋转贴图
chungeLoader.rotation = 45 * Math.PI / 180// 创建一个圆形
const circleGeometry = new THREE.CircleGeometry(0.5, 32)
const material = new THREE.MeshBasicMaterial({map: chungeLoader, // 贴图side: THREE.DoubleSide // 正反面都贴图
})
const circle = new THREE.Mesh(circleGeometry, material)
scene.add(circle)

本例将贴图旋转了45度,如果希望以元素的中心点作为旋转中心点,可以将 center 设置成 (0.5, 0.5),此时x轴和y轴都是以元素的中心点作为旋转中心点了。

file

// 省略部分代码...// 旋转贴图
chungeLoader.rotation = 45 * Math.PI / 180
// 设置旋转中心点
chungeLoader.center.set(0.5, 0.5)

重复渲染

设置纹理的 repeat 属性可以控制重复渲染的次数。通过 wrapSwrapT 可以分别设置水平方向和垂直方向的的重复渲染模式。

wrapSwrapT 默认值是 THREE.ClampToEdgeWrapping,即纹理边缘将被推到外部边缘的纹素。 其它的两个选项分别是 THREE.RepeatWrappingTHREE.MirroredRepeatWrapping

THREE.RepeatWrapping 是正常的重复,THREE.MirroredRepeatWrapping 是镜像重复。

接下来拿『春哥』练练手。

file

// 省略部分代码...// Three提供的纹理加载器
const textureLoader = new THREE.TextureLoader()
// 导入纹理贴图基础贴图
const chungeLoader = textureLoader.load('./assets/images/chunge_flower.png')// 水平重复3次,垂直重复2次
chungeLoader.repeat.set(3, 2)
chungeLoader.wrapS = THREE.RepeatWrapping // 水平重复
chungeLoader.wrapT = THREE.MirroredRepeatWrapping // 垂直镜像重复// 创建立方体
const geometry = new THREE.BoxGeometry(1, 1, 1)
const material = new THREE.MeshBasicMaterial({map: chungeLoader // 纹理贴图
})
const cube = new THREE.Mesh(geometry, material)
scene.add(cube)

灰度纹理

如果你想把花背景隐藏掉,可以使用灰度纹理。

此时需要2张图。

file

file

黑白这张图是一个蒙版层,和PS的图层蒙版是一个道理。

黑色表示要完全隐藏的部分,白色表示要完成显示的部分。如果用灰色,会根据灰色的深浅设置一个半透明的效果。

使用 alphaMap 可以设置灰度纹理层,同时还要将 transparent 设置为 true 才有效。

file

// 省略部分代码...// Three提供的纹理加载器
const textureLoader = new THREE.TextureLoader()
// 导入纹理贴图基础贴图
const chungeLoader = textureLoader.load('./assets/images/chunge_flower.png')
// 导入蒙版贴图
const chungeAlphaTexture = textureLoader.load('./assets/images/chunge_alpha.png')// 创建立方体
const geometry = new THREE.BoxGeometry(1, 1, 1)
const material = new THREE.MeshBasicMaterial({map: chungeLoader, // 纹理贴图alphaMap: chungeAlphaTexture, // 设置透明纹理层transparent: true // 允许材质透明
})
const cube = new THREE.Mesh(geometry, material)
scene.add(cube)

从上图可以看到,花背景已经被隐藏掉了。

如果此时将 side 设置成 THREE.DoubleSide 就可以双面展示了。

file



代码仓库

⭐ 基础纹理贴图



推荐阅读

👍《Three.js 起飞!》

👍《Three.js 辅助坐标轴》

👍《Three.js 场景 Scene》

👍《Three.js 几个简单的入门动画(新手篇)》

👍《Three.js 这样写就有阴影效果啦》

👍《Three.js 性能监视器 Stats》

代码仓库

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

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

相关文章

JVM基础:字节码文件详解①

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、Java虚拟机的组成二、字节码文件的组成2.1 为什么要了解字节码文件&#xff1f;2.2 如何“窥探”字节码文件的奥秘&#xff1f;2.2.1 使用工具打开字节码文件2.…

进程间通信(匿名管道、命名管道、消息队列、共享内存、信号量、信号、Socket)

文章目录 一、什么是进程间通信二、管道1.匿名管道(pipe)a).创建匿名管道b).管道的读写规则c).匿名管道的特点 2.有名管道(FIFO)a).创建命名管道b).命名管道的特点c).基于命名管道的进程间通信&#xff08;服务端/客户端&#xff09; 三、消息队列四、共享内存1.什么是共享内存…

react高阶成分(HOC)例子效果

使用React函数式组件写了一个身份验证的一个功能&#xff0c;示例通过高阶组件实现的一个效果展示&#xff1a; import React, { useState, useEffect } from react;// 定义一个高阶组件&#xff0c;它接受一个组件作为输入&#xff0c;并返回一个新的包装组件 const withAuth…

(C++进阶)正则表达式

目录 一、概念 1、简介 2、字符规则 二、常用函数 1、std::regex_match 2、std::regex_search 3、std::regex_replace 三、std::smatch 一、概念 1、简介 正则表达式&#xff08;Regular Expression&#xff09;&#xff0c;通常简写为RegExp或Regex&#xff0c;是一种…

装了mac os 14.0 sonoma 在腾讯会议投屏时候,无法设置麦克风权限问题

愿意&#xff1a;界面上直接空白的&#xff0c;无法手动或自动弹出要配置授权的软件 解决思路&#xff1a; 给 TCC.db 增加1条权限记录 添加到数据库里 /usr/bin/sqlite3 ~/Library/Application\ Support/com.apple.TCC/TCC.db "INSERT INTO main.access (service, cli…

windows PC virtualBox 配置

效果&#xff1a; oracle vitualbox 可以访问通PC主机&#xff0c;可以访问外网: 注意&#xff0c;如果docker0网络地址&#xff0c;和PC主机的网络地址冲突了&#xff0c;需要变更docker的网络地址&#xff1a; root/home/mysqlPcap/anti-tamper $ cat /etc/docker/daemon.js…

YOLOv5算法改进(21)— 添加CA注意力机制 + 更换Neck网络之BiFPN + 更换损失函数之EIoU

前言:Hello大家好,我是小哥谈。通过上节课的学习,相信同学们一定了解了组合改进的核心。本节课开始,就让我们结合论文来对YOLOv5进行组合改进(添加CA注意力机制+更换Neck网络之BiFPN+更换损失函数之EIoU),希望同学们学完本节课可以有所启迪,并且后期可以自行进行YOLOv5…

GPT与创作:革命性的合作还是失业的噩梦?

作为一个从事互联网行业的从业者&#xff0c;我经常听到关于GPT的争议性言论。百度的​1​、CSDN的​2​&#xff0c;以及各种AI助手&#xff0c;这些工具在创作领域掀起了一场革命。但是&#xff0c;人们担心广泛使用GPT是否会导致人们失业&#xff0c;甚至挑战互联网公司的存…

【MySQL数据库重点】第二节:MySQL基础知识(基本操作)

目录 一&#xff1a;数据库的操作 1.显示数据库 2.创建数据库 3.使用数据库 4.删除数据库 二&#xff1a;常用数据类型 1.数值类型&#xff1a;整型和浮点型 2.字符串类型 3.日期类型 三&#xff1a;表的操作 1.查看表结构 2.创建表 3.删除表 一&#xff1a;数据库…

wait和sleep是否会触发锁的释放以及 CPU 资源的释放?

wait和sleep Object.wait()方法&#xff0c;会释放锁资源以及 CPU 资源。 Thread.sleep()方法&#xff0c;不会释放锁资源&#xff0c;但是会释放 CPU 资源。 wait 方法 wait()方法是让一个线程进入到阻塞状态&#xff0c;而这个方法必须要写在一个Synchronized 同步代码块里面…

Dubbo 路由及负载均衡性能优化

作者&#xff1a;vivo 互联网中间件团队- Wang Xiaochuang 本文主要介绍在vivo内部针对Dubbo路由模块及负载均衡的一些优化手段&#xff0c;主要是异步化缓存&#xff0c;可减少在RPC调用过程中路由及负载均衡的CPU消耗&#xff0c;极大提升调用效率。 一、概要 vivo内部Java…

工厂干洗店洗鞋店系统,校园洗护小程序来了

洗鞋店小程序&#xff0c;干洗店软件&#xff0c;洗护行业小程序,上门取衣小程序,预约干洗小程序,校园干洗店小程序,工厂干洗店小程序,干洗店小程序开发&#xff0c;成品软件开发 洗衣工厂软件、功能强大&#xff01; 包含以下主要功能&#xff1a; * 用户选择洗护用品&#x…

OS的Alarm定时器调度机制

调度表触发的任务在编译时就被静态定义&#xff0c;任务的触发时间和执行顺序是固定的。这种方式适用于已知的、固定的任务触发模式&#xff0c;例如周期性任务或事件驱动任务。而使用 Alarm 机制触发的任务具有更大的灵活性。Alarm 允许在运行时动态地设置和修改任务的触发时间…

计算机网络--第一次作业

1、比较电路交换、报文交换和分组报文交换优缺点 电路交换 电路交换是以电路连接为目的的交换方式&#xff0c;通信之前要在通信双方之间建立一条被双方独占的物理通道&#xff08;由通信双方之间的交换设备和链路逐段连接而成&#xff09;。 优点&#xff1a; ①由于通信线路为…

薛定谔的猫重出江湖?法国初创公司AliceBob研发猫态量子比特

总部位于巴黎的初创公司Alice&Bob使用超导芯片的两个相反的量子态&#xff08;他们称之为“猫态量子比特”芯片&#xff09;来帮助开发量子计算的不同自旋方式。&#xff08;图片来源&#xff1a;网络&#xff09; 有的人认为&#xff0c;构建量子计算机的模块模仿了著名的…

链动2+1全新9.0版本 无限链动收益

一个平台能否长期存活取决于它是否有一个支撑其持续发展的商业模式。蜂群精选深谙用户心理&#xff0c;对链动21模式进行改造&#xff0c;创新出一种同时具备裂变能力和高效吸引用户留存的新玩法。 链动21模式在整个架构上都是完整的&#xff0c;可以说是一个非常出色的营销模式…

ruoyi-plus创建模块、自动生成代码

ruoyi-plus自动生成代码 1、创建模块 复制其他部分的resouce过来 修改yml文件 2 修改Nacos 2.1 修改数据库文件 复制其他数据库的链接 &#xff0c;改为自己新建的数据库名字 修改为自己要生成的数据库 新建数据库的yaml文件 3 重启docker的ruoyi-gen服务 docker re…

新手向:如何考虑将数据库技术和大数据框架结合使用?

结合的意义/应用场景与功能分摊 结合场景 大规模数据处理&#xff1a;当数据量巨大&#xff0c;超出传统数据库的处理能力时&#xff0c;大数据框架可以高效地处理这些数据&#xff0c;而传统数据库可以为应用程序提供实时或交互式查询。 混合工作负载&#xff1a;企业通常需…

ClickHouse快速了解

简介 ClickHouse是一个开源列式数据库管理系统&#xff08;DBMS&#xff09;&#xff0c;用于在线分析处理&#xff08;OLAP&#xff09;&#xff1a; 列式存储&#xff1a;与传统的行式数据库不同&#xff0c;ClickHouse以列的形式存储数据&#xff0c;这使得在分析大量数据时…

敏感词过滤--golang

目录 1. 建立敏感词数据库表2. 定时任务&#xff0c;读数据并建立敏感词树2.1 开启定时任务2.2 读数据并建立敏感词树 3. 使用 思路&#xff1a; 将敏感词都存到数据库表中定时读取数据到内存中&#xff0c;构建敏感词前缀树写工具方法&#xff0c;使用内存中的前缀树判断消息…