Three.js 纹理贴图 - 环境贴图 - 纹理贴图 - 透明贴图 - 高光贴图

文章目录

  • Three.js 纹理贴图
    • 纹理贴图 map属性
      • 纹理贴图的映射方式 texture.Mapping
      • 纹理加载器 THREE.TextureLoader
        • 监听单个材质
        • 监听多个材质 - LoadingManager类
      • 1. 颜色贴图与材质的颜色
      • 2.渲染效果:UV坐标 - 描述纹理贴图的坐标
        • 自定义顶点UV`geometry.attributes.uv`
      • 纹理对象Texture阵列 - texture.wrapS、texture.wrapT与texture.repeat
      • 案例:矩形Mesh+背景透明png贴图
      • 案例:uv动画 - 纹理对象的偏移属性offset
        • 纹理贴图阵列 + UV动画
    • 环境贴图
      • 添加环境贴图 mesh材质的envMap属性
      • 使用立方体纹理加载器CubeTextureLoader加载环境贴图
    • 透明贴图 mesh的alphaMap属性 / 高光贴图 mesh的specularMap属性/光照贴图 mesh的lightMap属性/环境遮挡贴图 mesh的aoMap属性

Three.js 纹理贴图

  • 纹理贴图加载器TextureLoader.load()方法加载一张图片,返回一个纹理对象Texture
  • 立方体纹理加载器CubeTextureLoader.load()方法加载6张图片,返回一个立方体纹理对象CubeTexture立方体纹理对象CubeTexture的父类是纹理对象Texture

网格材质 Mesh的贴图属性

属性描述其他
map:Texture材质的颜色贴图使用范围:除MeshPhysicalMaterial
envMap : Texture环境贴图
alphaMap:透明贴图
alpha贴图是一张灰度纹理,用于控制整个表面的透明度。
需要开启材质的透明度属性
specularMap : Texture高光贴图用于控制对象表面的高光反射强度和位置,通常使用灰度图像来表示不同的反射强度值。可以通过reflectivity属性设置反射强度

纹理贴图 map属性

纹理贴图的映射方式 texture.Mapping

属性默认值:texture.Mapping = THREE.UVMapping
属性含义:如何将纹理题图应用到几何体表面

  • mapping 是一种将纹理贴到几何体表面上的技术
  • cube mapping 则是一种将纹理贴到立方体表面上的技术。
属性值描述使用
THREE.UVMapping UV贴图将二维纹理映射到三维物体表面的过程。在 Three.js 中,每个几何体都有一个 UV 坐标系,和几何体表面上的三角形网格一一对应。UV 坐标系中的每个点都映射到纹理图像上的一个像素,用来确定几何体表面的纹理贴图。U,V 坐标用来应用映射,要求是单个纹理。
一般与网格材质的map属性配合使用。
THREE.CubeReflectionMapping 立方体反射映射该映射模式将环境贴图作为一个立方体贴图,将六个面分别映射到对应的立方体面上,以模拟立方体环境映射和反射效果。cubeTexture.mapping的默认值
THREE.CubeRefractionMapping 立方体折射映射使用一个立方体贴图来表示环境光的折射,可以用来模拟环境光和镜面反射等效果该映射模式与 THREE.CubeReflectionMapping 类似,但是它模拟的是折射效果,环境贴图中的物体看作透明的,经过物体的折射后反射到表面上。
THREE.EquirectangularReflectionMapping 圆柱反射映射将环境贴图作为一个全景图片,将图片映射到球体或半球体上,以模拟球形环境映射和反射效果。类似cube mapping,只不过不是用立方体贴图,而是使用单个贴图?

可以配合材质的envMap属性使用
THREE.EquirectangularRefractionMapping 圆柱折射映射该映射模式与 THREE.EquirectangularReflectionMapping 类似,但是模拟的是折射效果,即将环境贴图中的物体看作透明的,经过物体的折射后反射到表面上。可以配合材质的envMap属性使用

纹理加载器 THREE.TextureLoader

纹理加载器:new THREE.TextureLoader( manager : LoadingManager )
参数:加载器使用的 loadingManager,默认值为THREE.DefaultLoadingManager
继承链:Loader → TextureLoader
返回值:返回创建的纹理加载器TextureLoader.

纹理对象的属性和方法

属性名和方法名描述
texture.offset:Vector2贴图单次重复中的起始偏移量(偏移贴图在Mesh上位置),分别表示U和V。

加载纹理- 得到纹理对象
textureLoader.load ( url : String, onLoad : (texture)=>{}, onProgress : Function, onError : Function ) : Texture
返回值:新的纹理对象texture,该纹理对象可以用于材质创建
注意点:异步加载,第三个参数在后续版本好像被遗弃了可以用undefined暂时占位

监听单个材质
import tile from "./assets/tile.jpg";

// 初始化一个加载器
const loader = new THREE.TextureLoader();

// 加载一个资源
loader.load(
    // 【参数1】资源URL
    tile,

    // 【参数2】onLoad回调
    function ( texture ) {
        // 【才材质加载成功后执行】
        const material = new THREE.MeshBasicMaterial( {
            map: texture
         } );
    },
 
    // 【参数3】目前暂不支持onProgress的回调
    undefined,

    // 【参数4】onError回调,
    function ( err ) {
        console.error( '材质加载失败' );
    }
)
监听多个材质 - LoadingManager类

语法:LoadingManager(onLoad:Function,onProgress:Function,, onError:Function,)
说明:处理并跟踪已加载和待处理的数据。
参数
onLoad:所有加载器加载完成后,将调用此函数。
onProgress: 当每个项目完成后,将调用此函数。
onError: 当一个加载器遇到错误时,将调用此函数。

// 设置加载管理器
const loadingManager = new THREE.LoadingManager(
  function() {
    console.log('图片加载完成')
  },
  function(url, loaded, total) {
    console.log(`图片加载中,本次加载的材质${url},第 ${loaded}/${total} 个材质`)
  },
  function(err) {
    console.log('图片加载失败', err)
  }
)

// Three提供的纹理加载器
const textureLoader = new THREE.TextureLoader(loadingManager)

// 导入纹理贴图基础贴图
const imgTexture1 = textureLoader.load('../assets/images/140.jpg')
const imgTexture2 = textureLoader.load('../assets/images/141.jpg')

执行输出

图片加载中,本次加载的材质../assets/images/140.jpg,第 1/2 个材质
图片加载中,本次加载的材质../assets/images/141.jpg,第 2/2 个材质
图片加载完成

1. 颜色贴图与材质的颜色

在vur中的引入方式
方式1.先import引入然后作为参数传递给load
方式2.将图片存储在public公共文件夹下

// 方式1
import map from "./assets/map.jpg";
const texLoader = new THREE.TextureLoader();
const texture = texLoader.load(map)

// 方式2
import panda from "/panda.png";
const material = new THREE.MeshLambertMaterial({
  map:texLoader.load( panda),
});
// 这种写法也可以
const material = new THREE.MeshLambertMaterial({
  map:texLoader.load('../public/panda.png'),
});

// 加载失败会报错,这里参数只是字符串
const texture = texLoader.load('./assets/map.jpg')

public里的文件不会处理,直接复制到打包文件。文件中的绝对地址也不会解析所以可以将图片放到public中。.开头的地址会被理解为相对地址,webpack会解析地址加载图片,这里不知道是不是load的参数没有被理解为相对地址去解析,所以才会报错?

vue中引入图片失败的原因及解决办法

材质的颜色贴图属性.map设置后,模型会从纹理贴图上采集像素值,这时候一般来说不需要再设置材质颜色.color

颜色贴图mapcolor属性颜色值会混合。如果没有特殊需要,设置了颜色贴图.map就不用设置·color

2.渲染效果:UV坐标 - 描述纹理贴图的坐标

是什么:顶点UV坐标可以在0~1.0之间任意取值,纹理贴图左下角对应的UV坐标是(0,0),右上角对应的坐标(1,1)。
在这里插入图片描述
作用:从纹理贴图上提取UV坐标范围的像素映射到网格模型Mesh的几何体表面上。

// 默认情况会自动提取
import panda from "../public/panda.png";

const geometry = new THREE.BoxGeometry(100, 100,100);
const texLoader = new THREE.TextureLoader();
const texture = texLoader.load(panda )
const material = new THREE.MeshLambertMaterial({
  map:texture,
});
const mesh = new THREE.Mesh(geometry, material);
console.log(geometry.attributes.uv)

在这里插入图片描述

自定义顶点UVgeometry.attributes.uv

geometry.attributes.position描述几何体的顶点坐标
geometry.attributes.uv 描述纹理贴图的坐标
位置关系是一一对应的,每一个顶点位置对应一个纹理贴图的位置

根据纹理坐标将纹理贴图的对应位置裁剪映射到几何体的表面上。

const geometry = new THREE.BufferGeometry();
const vertices = new Float32Array([
    0, 0, 0, //顶点1坐标
    100, 0, 0, //顶点2坐标
    0, 100, 0, //顶点3坐标
]);
geometry.attributes.position = new THREE.BufferAttribute(vertices, 3);
const uv = new Float32Array([
    0, 0, //顶点1对应位置的纹理坐标uv
    1, 0, //顶点2对应位置的纹理坐标uv
    0, 1, //顶点3对应位置的纹理坐标uv
]);
geometry.attributes.uv = new THREE.BufferAttribute(uv, 2);

在这里插入图片描述

纹理对象Texture阵列 - texture.wrapS、texture.wrapT与texture.repeat

阵列就是不断的重复,如果使用一个规则的图形,load只需要加载一小部分,然后通过阵列完全显示,加快贴图加载的速度。

属性名描述参考值
texture.wrapS:number定义了纹理贴图在水平方向上将如何包裹,在UV映射中对应于U可选纹理常量中的包裹模式三个选项,默认是THREE.ClampToEdgeWrapping
texture.wrapT :number纹理贴图在垂直方向上将如何包裹,在UV映射中对应于V
texture.repeat:Vector2决定纹理在表面的重复次数,两个方向分别表示U和V-

包裹模式的可选值

包裹模式描述
THREE.RepeatWrapping纹理将简单地重复到无穷大
THREE.ClampToEdgeWrapping纹理中的最后一个像素将延伸到网格的边缘
THREE.MirroredRepeatWrapping在每次重复时将进行镜像
import tile from "./assets/tile.jpg";
// 1.创建地面
const geometry = new THREE.PlaneGeometry(300, 250);

// 2.加载纹理对象
const texLoader = new THREE.TextureLoader();
const texture = texLoader.load(tile)

//3.开启阵列,设置阵列模式
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
// uv两个方向纹理重复数量
texture.repeat.set(8,8);
const material = new THREE.MeshLambertMaterial({
  map:texture,
});

在这里插入图片描述

案例:矩形Mesh+背景透明png贴图

想要png贴图完全透明的部分不显示,需要将材质的transparent属性打开。

// 矩形平面网格模型设置背景透明的png贴图
import direction from "./assets/direction .jpg";
const geometry = new THREE.PlaneGeometry(60, 60); //默认在XOY平面上
const textureLoader = new THREE.TextureLoader();
const material = new THREE.MeshBasicMaterial({
    map: textureLoader.load(direction ),        
    transparent: true, //使用背景透明的png贴图,注意开启透明计算 
});
const mesh = new THREE.Mesh(geometry, material);
mesh.rotateX(-Math.PI / 2);

案例:uv动画 - 纹理对象的偏移属性offset

偏移之后的左边部分被截掉,右边的剩余部分为图片最后1px无限重复

// 渲染循环
function render() {
    texture.offset.x +=0.001;//设置纹理动画:偏移量根据纹理和动画需要,设置合适的值
    renderer.render(scene, camera);
    requestAnimationFrame(render);
}
render();

请添加图片描述

纹理贴图阵列 + UV动画

开启阵列之后,左边偏移消失的地方会拼接到右边偏移之后多出来的地方(首尾相连)

import * as THREE from "three";
import panda from "/panda.png";

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
  45,
  window.innerWidth / window.innerHeight, 
  1,
  8000
);
camera.position.set(300,300,300)

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);

const geometry = new THREE.PlaneGeometry(200, 200);
const loader = new THREE.TextureLoader();
const texture = loader.load(panda)
// 设置U方向阵列模式
texture.wrapS = THREE.RepeatWrapping;
// u方向纹理重复数量
texture.repeat.x=2;
const material = new THREE.MeshBasicMaterial( {
  map: texture
} );
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

const ambient = new THREE.AmbientLight(0xffffff,3)
scene.add(ambient);

document.body.appendChild(renderer.domElement);
// 渲染循环
function render() {
    texture.offset.x +=0.1;
    renderer.render(scene, camera);
    requestAnimationFrame(render);
}
render();

请添加图片描述

环境贴图

环境贴图是一类用于模拟环境反射光照的一种 3D 技术

为什么叫天空盒
OpenGL中天空盒的思想就是绘制一个大的立方体,然后将观察者放在立方体的中心,当相机移动时,这个立方体也跟着相机一起移动,这样相机就永远不会运动到场景的边缘。

在这里插入图片描述

添加环境贴图 mesh材质的envMap属性

给模型设置环境贴图后,可以将将光反射的环境部分映射到模型上(类似镜子将人反射在镜子上面)。

使用下图作为环境贴图
请添加图片描述
这里一定要将设置envMap.mapping,不然模型就是一片黑色,这里设置成THREE.EquirectangularReflectionMappingTHREE.EquirectangularRefractionMapping都可以。

// 这里的图片都在public文件夹下
const geometry = new THREE.PlaneGeometry(200, 200);
const loader = new THREE.TextureLoader();
const texture = loader.load("/assets/door.png") 
const material = new THREE.MeshBasicMaterial({
  map: texture,
});
loader.load("/assets/test.jpg",(envMap)=>{
  envMap.mapping = THREE.EquirectangularReflectionMapping;
  material.envMap = envMap;
})

const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

在这里插入图片描述

使用一个全景图作为环境贴图

loader.load("/assets/test.jpg",(envMap)=>{
  envMap.mapping = THREE.EquirectangularReflectionMapping;
  scene.background = envMap; // 将全景图设置为scen的背景
  scene.environment = envMap;
  material.envMap = envMap; // 设置为环境贴图后,可以在模型上看见光反射的环境
})

使用立方体纹理加载器CubeTextureLoader加载环境贴图

语法:new CubeTextureLoader( manager : LoadingManager )
参数:加载器使用的 loadingManager,默认值为THREE.DefaultLoadingManager
继承链:Loader → CubeTextureLoader
返回值:返回创建的立方体纹理加载器CubeTextureLoader.
描述:立方体纹理加载器CubeTextureLoader.load()方法加载6张图片,返回一个立方体纹理对象CubeTexture

loader.setPath 设置基础路径

// 加载环境贴图
// 加载周围环境6个方向贴图
// 上下左右前后6张贴图构成一个立方体空间

const loader = new THREE.TextureLoader();
const texture = loader.load("/assets/door1.png")
const alphaMap = loader.load("/assets/mask.png")
const urls = [
  '/assets/tile.jpg', x轴正方向  p:正positive  n:负negative
  '/assets/tile.jpg', x轴负方向  p:正positive  n:负negative
  '/assets/tile.jpg', y轴正方向
  '/assets/tile.jpg', y轴负方向
  '/assets/tile.jpg', z轴正方向
  '/assets/tile.jpg', z轴负方向
]
let textureCube = new THREE.CubeTextureLoader().load(urls);
scene.background = textureCube;
const material = new THREE.MeshBasicMaterial({
  map: texture,
  envMap:textureCube,
});

透明贴图 mesh的alphaMap属性 / 高光贴图 mesh的specularMap属性/光照贴图 mesh的lightMap属性/环境遮挡贴图 mesh的aoMap属性

  • 透明贴图:alpha贴图是一张灰度纹理,用于控制整个表面的透明度。
  • 高光贴图:用于控制对象表面的高光反射强度和位置,通常使用灰度图像来表示不同的反射强度值。
  • 光照贴图:用于控制对象表面的光照强度和位置,通常使用灰度图像来表示不同的光照强度值。光照贴图可以让对象表面看起来更加真实,增强细节和立体感。
  • 环境光遮蔽贴图(AO贴图):用于控制对象表面在环境光下的遮蔽程度,通常使用灰度图像来表示不同的遮蔽程度值。
贴图类型黑色白色灰色
透明贴图alphaMap不透明区域完全透明不同程度的半透明
高光贴图specularMap不反射区域最大反射强度区域不同程度反射强度区域
光照贴图lightMap无光照五颜六色的光
环境遮蔽贴图aoMap完全被遮蔽没有遮蔽不同程度的遮蔽

案例代码
代码只显示某一贴图,测试时可以修改为不同贴图的设置属性,使用下图测试效果。在这里插入图片描述

const texture = loader.load("/assets/door.png")
const alphaMap = loader.load("/assets/transparent.png")
let planeMaterial = new THREE.MeshBasicMaterial({
  color: 0xffffff,
  map: texture,
  transparent: true, // 允许透明
  // 透明度贴图
  alphaMap: alphaMap,
  reflectivity: 0.5,  //设置反射强度
});

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java 数据抓取

大家好我是苏麟 , 今天聊聊数据抓取 . 大家合理使用 注意,爬虫技术不能滥用,干万不要给别人的系统造成压力、不要侵犯他人权益! 数据抓取 实质上就是java程序模拟浏览器进行目标网站的访问,无论是请求目标服务器的接口还是请求目标网页内容…

python基础——池

池的介绍: 提前创建进程池,防止创建的进程数量过多导致系统性能受到影响,在系统执行任务时,系统会使用池中已经创建进程/线程,从而防止资源的浪费,创建的进程/线程可以让多个进程使用,从而降低…

Unity技术手册-UGUI零基础详细教程-Canvas详解

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 👉关于作者 专注于Android/Unity和各种游…

备战蓝桥杯---数据结构与STL应用(入门4)

本专题主要是关于利用优先队列解决贪心选择上的“反悔”问题 话不多说,直接看题: 下面为分析: 很显然,我们在整体上以s[i]为基准,先把士兵按s[i]排好。然后,我们先求s[i]大的开始,即规定选人数…

电源模块欠压保护点测试方法分享 纳米软件

电源欠压保护原理 欠压保护是指当电源电压低于一定值时,电源的保护功能会及时断开电路,避免设备受到损坏。电源欠压保护一般是通过一个或多个传感器来检测电压,当电压低于设定值时就会触发电源的保护功能,断开电路,保护…

Git--07--GitExtension

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、GitExtension下载GitExtension官网下载教程 二、GitExtension安装三、GitExtension配置四、GitExtension使用 一、GitExtension下载 官网下载: http…

Docker中安装MySql的遇到的问题

目录 一、mysql查询中文乱码问题 1. 进入mysql中进行查看数据库字符集 2. 修改 my.cnf 中的配置 3. 重启mysql容器,使得容器重新加载配置文件 4. 测试结果 二、主从同步中遇到的问题 2.1 Slave_IO_Running:Connecting 的解决方案 1. 确定宿主机防火墙开放my…

嵌入式学习第十四天!(结构体、共用体、枚举、位运算)

1. 结构体: 1. 结构体类型定义: 嵌入式学习第十三天!(const指针、函数指针和指针函数、构造数据类型)-CSDN博客 2. 结构体变量的定义: 嵌入式学习第十三天!(const指针、函数指针和…

推荐一个好用的旧版本软件安装包下载地址

最近要下载旧版本的mysql和postman,发现官网和其他博客里边提供的地址,要不都非常难找到相应的下载链接,要不就是提供的从别的地方复制过来的垃圾教程,甚至有的下载还要积分,反正是最后都没下载成功,偶然发…

安全通道堵塞识别摄像机

当建筑物的安全通道发生堵塞时,可能会给人员疏散和救援带来重大隐患。为了及时识别和解决安全通道堵塞问题,专门设计了安全通道堵塞识别摄像机,它具有监测、识别和报警功能,可在第一时间发现通道堵塞情况。这种摄像机通常安装在通…

Mysql-索引创建,索引失效案例

索引创建建议 1 什么情况下需要创建索引? 频繁出现在where 条件字段,order排序,group by分组字段select 频繁查询的列,考虑是否需要创建联合索引(覆盖索引,不回表)多表join关联查询&#xff0…

【PyRestTest】高级使用

本节主要涉及PyRestTest的高级特征的详细使用,主要指:generators(生成器), variable binding(变量绑定), data extraction(数据提取), content validators(文本验证) 它们是如何组合在一起的? 模板和上下文 测试和基准测试可以使用变量来模板化动态配置。使用基础的…

OSPF排错

目录 实验拓扑图 实验要求 实验排错 故障一 故障现象 故障分析 故障解决 故障二 故障现象 故障分析 故障解决 故障三 故障现象 故障分析 故障解决 故障四 故障现象 故障分析 故障解决 故障五 故障现象 故障分析 故障解决 故障六 故障现象 故障分析 …

区块链游戏解说:什么是 SecondLive

数据源:SecondLive Dashboard 作者:lesleyfootprint.network 什么是 SecondLive SecondLive 是元宇宙居民的中心枢纽,拥有超过100 万用户的蓬勃社区。它的主要使命是促进自我表达,释放创造力,构建梦想中的平行宇宙…

【HTML】自定义属性(data)

自定义属性 data: 的用法(如何设置,如何获取) ,有何优势? data-* 的值的获取和设置,2种方法: 传统方法 getAttribute() 获取 data- 属性值; setAttribute() 设置 data- 属性值getAttribute() 获取 data- 属性值; setAttribute()…

腾讯云SSL证书在阿里云添加域名DNS解析

场景说明 在阿里云申请并备案了域名,这个域名理论上可以在任何服务器上进行绑定。应用服务器部署到腾讯云,并在腾讯云申请了SSL证书,从而完成HTTPS转化。那么问题来了,腾讯提供的免费版SSL证书是一年有效期,到期后就需…

Cadence——布线部分相关教程

(一)PCB布线叠层与阻抗设计 PCB布线要区分有阻抗和无阻抗这个是根据频率和速率来区分,一般达100M以上就是有阻抗,单端信号一般是五十欧姆,差分信号一般一百欧姆 叠成是多层板由不同的介质压合而成,介质是&…

SD-WAN技术:网络升级的智慧选择

在移动办公、云计算技术和多元化的应用交付方式不断普及的今天,企业网络正变得越来越错综复杂,充满了不可预测性。为了跟上这一网络发展的步伐,IT部门需要深刻反思网络建设的方式,而定义软件广域网(SD-WAN)…

Ubuntu系统硬盘分区攻略(磁盘分区、RAID磁盘阵列、RAID阵列、固态硬盘分区、机械硬盘分区、swap分区、swap交换分区)

文章目录 分区需求分区方案分区顺序相关疑问swap分区不是应该放在最后吗?我安装系统分区的时候,上面有available devices,下面有create software raid(md),我该用哪个?我available devices下面有个893G的固态&#xff…

C++数据结构与算法——链表

C第二阶段——数据结构和算法,之前学过一点点数据结构,当时是基于Python来学习的,现在基于C查漏补缺,尤其是树的部分。这一部分计划一个月,主要利用代码随想录来学习,刷题使用力扣网站,不定时更…