Three.js 基础纹理贴图

news2025/1/12 12:06:13

本文简介

带尬猴,我嗨德育处主任


尽管 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.coloradmin.cn/o/1137403.html

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

相关文章

BES2700 蓝牙协议之RFCOMM通道使用方法

是否需要申请加入数字音频系统研究开发交流答疑群(课题组)?可加我微信hezkz17, 本群提供音频技术答疑服务 BES2700 RFCOMM通道使用方法 RFCOMM_CHANNEL_NUM 枚举定义了一系列的通道号码,并为每个通道号码指定了一个具体的名称。以下是其中一些通道的中文含义: RFCOMM_CHAN…

解决Windows出现找不到mfcm90u.dll无法打开软件程序的方法

今天&#xff0c;我非常荣幸能够在这里与大家分享关于mfc90u.dll丢失的5种解决方法。在我们日常使用电脑的过程中&#xff0c;可能会遇到一些软件或系统错误&#xff0c;其中之一就是mfc90u.dll丢失。那么&#xff0c;mfc90u.dll究竟是什么文件呢&#xff1f;接下来&#xff0c…

【代码随想录】算法训练计划02

1、977. 有序数组的平方 给你一个按 非递减顺序 排序的整数数组 nums&#xff0c;返回 每个数字的平方 组成的新数组&#xff0c;要求也按 非递减顺序 排序。 输入&#xff1a;nums [-4,-1,0,3,10] 输出&#xff1a;[0,1,9,16,100] 思路&#xff1a; 这题思路在于——双指针…

网工内推 | 国企,解决方案工程师,最高30k,有软考证书优先

01 中电信数智科技有限公司海南分公司 招聘岗位&#xff1a;解决方案经理&#xff08;ICT&#xff09; 职责描述&#xff1a; 1、负责调动前后端资源做好全省ICT业务的售前支撑服务工作。 2、根据实际项目需求&#xff0c;主动协同客户渠道开展ICT项目商机挖掘&#xff0c;促进…

点云处理【七】(点云配准)

点云处理 第一章 点云数据采集 1.点云配准 点云配准是将两个或多个点云数据集融合到一个统一的坐标系统中的过程。这通常是为了创建一个完整的模型或融合从不同视角采集的数据。 点云配准一般分为粗配准和精配准&#xff0c;粗配准指的是在两幅点云之间的变换完全未知的情况下…

JS加密/解密之那些不为人知的基础逻辑运算符

不多说&#xff0c;直接上干货 使用逻辑非运算符 ! 和双重逻辑非运算符 !!&#xff1a;例如 ![]、!![]、!0、!!0 和 !""、!!""。空字符串的转换&#xff1a;!"" 和 !!""。数组和对象的类型转换&#xff1a;[] []、[] - []、{} [] 和…

STM32中除零运算,为何程序不崩溃?

在 C 语言中&#xff0c;除零运算会导致异常吗&#xff1f; 在 C 语言中&#xff0c;当一个数除以零时&#xff0c;会导致除法运算错误&#xff0c;通常表现为“除以零”错误或被称为“浮点异常”&#xff08;floating-point exception&#xff09;。 对于整数除法&#xff0c…

YOLOv5源码中的参数超详细解析(3)— 训练部分(train.py)| 模型训练调参

前言:Hello大家好,我是小哥谈。YOLOv5项目代码中,train.py是用于模型训练的代码,是YOLOv5中最为核心的代码之一,而代码中的训练参数则是核心中的核心,只有学会了各种训练参数的真正含义,才能使用YOLOv5进行最基本的训练。🌈 前期回顾: YOLOv5源码中的参数超详细解析…

IC-705连接wfview

wfview是一款开源的主要针对ICOM的远程控制软件&#xff0c;可以通过USB或者无线控制电台&#xff0c;貌似还支持X6100。 IC-705支持WLAN功能&#xff0c;连接wfview非常方便。 IC-705的WLAN支持两种模式&#xff0c;一种是Station模式&#xff0c;可用于连接WI-FI路由器&#…

vue中使用xlsx插件导出多sheet excel实现方法

安装xlsx&#xff0c;一定要注意版本&#xff1a; npm i xlsx0.17.0 -S package.json&#xff1a; {"name": "hello-world","version": "0.1.0","private": true,"scripts": {"serve": "vue-c…

Fabric.js 图案笔刷

本文简介 带尬猴&#xff0c;我是德育处主任 Fabric.js 有图案画笔功能&#xff0c;这个功能可以简单理解成“刮刮卡”效果。 如果只是看 Fabric.js 文档可能还不太明白 图案画笔 PatternBrush 是如何使用。 本文将讲解如何配置这款画笔的基础属性。 图案画笔&#xff08;笔…

UG\NX二次开发 连接曲线、连结曲线 UF_CURVE_auto_join_curves

文章作者:里海 来源网站:王牌飞行员_里海_里海NX二次开发3000例,里海BlockUI专栏,C\C++-CSDN博客 简介 UG\NX二次开发 连接曲线、连结曲线 UF_CURVE_auto_join_curves 效果 代码 #include "me.hpp" extern DllExport void ufusr(char* param, int* returnC…

TypeScript之索引签名

1. 索引签名 在 TypeScript 中&#xff0c;索引签名是一种定义对象类型的方式&#xff0c;它允许我们使用字符串或数字作为索引来访问对象的属性。 索引签名最主要的作用就是允许我们动态地添加或访问对象的属性&#xff0c;通过使用索引签名&#xff0c;我们可以在编译时无法…

2023年CSP-S赛后总结(2023CSP-S题解+游记)

目录 T1 题目描述 输入格式 输出格式 代码 T2 题目描述 输入格式 输出格式 题目描述 输入格式 输出格式 题意翻译 代码 T3 题目背景 题目描述 输入格式 输出格式 代码 T4 题目描述 输入格式 输出格式 代码 总结 游记 DAY1 DAY0 DAY-1 T1 题目描述…

P-MOS管开关机控制电路(手动按键控制和自动采样信号触发控制)

1. 手动(按键)控制 这种控制适合与消费电子&#xff0c;家庭消费电子领域&#xff0c;用户人为地手动按动机械按键控制P-MOS管导通与断开。例如&#xff1a;电动牙刷、儿童玩具等等&#xff0c;很多都会用到一个按钮控制产品的开关机&#xff0c;调档等等。 1.1 RH6030_JX触摸…

029.Python面向对象_类补充_属性(方法)相关

我 的 个 人 主 页&#xff1a;&#x1f449;&#x1f449; 失心疯的个人主页 &#x1f448;&#x1f448; 入 门 教 程 推 荐 &#xff1a;&#x1f449;&#x1f449; Python零基础入门教程合集 &#x1f448;&#x1f448; 虚 拟 环 境 搭 建 &#xff1a;&#x1f449;&…

Qt之菜单栏、工具栏、状态栏介绍及工具栏QAction的动态增删显示实现方式

目的 端应用程序或者编辑器基本都支持工具栏快捷功能的动态增删&#xff0c;即通过在菜单栏上打钩就可以在工具栏上看到相应功能的快捷按钮&#xff0c;取消打钩则在工具栏上就移除了该功能的快捷按钮。那么Qt如何实现这个功能&#xff0c;本篇目的就是记录实现此功能的方法及思…

cmd 命令关闭占用端口

工作中还是偶尔会遇到端口号被占用的情况&#xff0c;之前也有写过另一种关闭方式&#xff0c;但是发现没有命令方便&#xff0c;所以记录一下。 1、 查看 8081 端口占用的 pid 。 命令&#xff1a;netstat -ano |findstr 8081 由上图可知&#xff0c;占用 8081 端口的进程 id…

折叠式菜单怎么做编程,初学编程系统化教程初级1上线

中文编程系统化教程&#xff0c;不需英语基础&#xff0c;学习链接——入门篇课程 https://edu.csdn.net/course/detail/39036中文编程系统化教程&#xff0c;不需英语基础&#xff0c;学习链接—— 初级1课程 https://edu.csdn.net/course/detail/39061 ——————————…

C语言输出以下图案

图案&#xff1a; * * * * * * * * * * * * * * * * * * * * * * * * * 完整代码&#xff1a; /* 输出以下图案 * * * * * * * * * * * * * * * * * * * * * * * * * */ #include<stdio.h>int main(){//图案的行数int n5;for (int i 0; i < n; i){//每一行开头空格…