THREE.js学习笔记8——Textures

news/2025/1/17 20:27:25/文章来源:https://www.cnblogs.com/xxxiCJQ/p/18676320

这个小节主要学习纹理,Texture
纹理是覆盖几何形状表面的图像,不同类型的纹理具有多种不同的效果。
这些纹理(尤其是金属性和粗糙度)遵循PBR原则

  • 基于物理的渲染
  • 许多技术往往遵循现实生活中的方向以获得现实的结果
  • 成为现实渲染的标准
  • 许多软件、引擎和库都在使用它

如何加载纹理?
首先引入一张图片,图片确保在public目录下,以便被正确解析

const wukong = new Image();
wukong.onload = () => {console.log("图片已加载");
};
wukong.src = "/assets/wukong.png";

然后将这张图片转化为Texture

const wukong = new Image();
const texture = new THREE.Texture(wukong);
wukong.onload = () => {texture.needsUpdate = true;
};
wukong.src = "/assets/wukong.png";
const material = new THREE.MeshBasicMaterial({//   color: 0xff0000,map: texture,
});

渲染结果
1
或者使用textureLoader
为什么会有白色默认颜色和我的材质相叠加?

const textureLoader = new THREE.TextureLoader();
const texture = textureLoader.load("/assets/wukong.png");

textureLoader.load()函数中,除了第一个路径参数,还有其它三个参数,准确的说是三个回调函数

  • 加载成功-当图像加载成功时
  • 进行时-加载进行时
  • 加载错误-如果出现问题
const textureLoader = new THREE.TextureLoader();
const texture = textureLoader.load("/assets/rustyLake.png",() => {console.log("加载成功");},() => {console.log("正在运行");},() => {console.log("加载失败");}
);

同时,我们可以使用LoadingManager来看见所有的loading progress它们loading的进度

const loadingManager = new THREE.LoadingManager();
const textureLoader = new THREE.TextureLoader(loadingManager);
const loadingManager = new THREE.LoadingManager();
//通过不同的回调函数,来看见加载的过程,处理加载失败
loadingManager.onStart = () => {console.log("加载开始");
};
loadingManager.onLoad = () => {console.log("加载完成");
};
loadingManager.onProgress = () => {console.log("正在加载");
};

纹理以不同的方式被拉伸或挤压以覆盖在几何上,这被称为UV unwrapping.
每个点在平面(通常是正方形)上都有一个2D坐标,就是在这个几何模型的展开图上有一个屏幕的坐标。
这些UV坐标由 Three.js生成。
如果我们创建自己的几何体,则必须指定 UV 坐标
如果我们使用 3D 软件制作几何体,您还自己做
UV 展开。
我们可以在geography.attribution.uv中看到这些UV unwrapping

const geometry = new THREE.BoxGeometry(1, 1, 1);
console.log(geometry.attributes.uv);

我们可以通过使用repeat属性来重复纹理
它是具有xy属性的Vector 2
默认情况下,纹理不会重复,最后一个像素会被拉伸。我们可以用THREE.RepeatWrapping中的来改变这一点。改变wrapSwrapT

texture.repeat.x = 2;
texture.wrapT = THREE.RepeatWrapping;
texture.wrapS = THREE.RepeatWrapping;
//或者对称重复
texture.wrapT = THREE.MirroredRepeatWrapping;
texture.wrapS = THREE.MirroredRepeatWrapping;

同时,也可以将材质偏移,旋转

texture.offset.x = 0.5;
texture.offset.y = 0.5;
//现在的旋转中心是(0,0)这个坐标
texture.rotation = Math.PI * 0.25;
//我们同时也可以修改旋转中心的坐标
texture.center.x = 0.5;
texture.center.y = 0.5;

FILTERING AND MIPMAPPING

有些时候,当我们看向顶面或缩小方块时,会看到模糊的材质。这是因为Mipmapping会一次又一次地创建半个较小版本的材质(上一材质的四分之一大小),直到我们得到1x1像素的材质,所有这些材质都会被发送到GPU,当我们没有显示一整个面,GPU就会选择一些较小的材质来填充剩余的部分,达到当前模型位置下最合适的材质纹理。
所有这些都已经由Three.jsGPU处理,但我们可以选择不同的算法,有两种类型的过滤算法。
Minification Filters

  • THREE.NearestFilter
  • THREE.NearestMipmapNearestFilter
  • THREE.NearestMipmapLinearFilter
  • THREE.LinearFilter
  • THREE.LinearMipmapNearestFilter
  • THREE.LinearMipmapLinearFilter(default)

这些常量用于纹理的minFilter属性,它们定义了当被纹理化的像素映射到大于1纹理元素(texel)的区域时,将要使用的纹理缩小函数。

//NearestFilter会得到一种尖锐缩小的结果
texture.minFilter = THREE.NearestFilter;
texture.magFilter = THREE.NearestMipmapNearestFilter;

如果说我们的材质贴图很小,但是材质方块很大,以至于材质贴上去就变得模糊时,可以使用NearestFilter来将材质变得清晰而尖锐,同时,使用NearestFilter也会让性能变得更好。
如果我们使用 THREE.NearestFilter 在 minFilter 上,我们不需要Mipmapping
我们可以使用texture.generateMipmaps = false来关闭它。

texture.minFilter = THREE.NearestFilter;
texture.generateMipmaps = false;

TEXTURE FORMAT AND OPTIMISATION

材质的格式和优化,当我们在创建材质时,要考虑三个参数
  • The weight
  • The size (or the resolution)
  • The data

有些时候,用户们会下载材质,我们可以选择不同文件类型的材质和确认用户使用体验的文件大小

  • .jpg——会压缩画质,通常文件更小
  • .png——会较少的压缩画质,通常文件更大

材质纹理的每个像素都会存储在GPU上,而不管图像的到底有多大。但是GPU有存储限制,同时mipmapping又增加了要存储的像素的数量,所以作为开发人员要尝试尽可能减小图像的大小。
因为mipmapping会持续细分到1*1像素大小的材质,所以我们找的原材质大小的宽高都应该是2的n次方
同时材质纹理是支持透明度的,但我们不能在.jpg中使用透明度,如果我们想有一个结合了coloralpha的纹理,我们最好使用.png文件。
有些时候我们也可以在同一个材质中使用不同通道的值,像红,绿,蓝和alpha通道

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

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

相关文章

快速傅里叶变换总结

基本概念 对于求和式 \(\sum a_ix^i\),如果是有限项相加,称为多项式,记作 \[f(x)=\sum_{i=0}^n a_ix^i。 \]其中最高次项的次数为 \(n\),为 \(n\) 次多项式。 用 \(n+1\) 个点可以唯一地确定一个 \(n\) 次多项式,这一过程可以参考 拉格朗日插值。 引入 给定多项式 \(f(x),…

寒假学习1

老年人评估系统 初步整理web端思路先写了第一张信息表并搭建基本框架并编写了老年人信息添加功能

1.17安卓测试

今天在idea进行安卓虚拟机测试成功,昨天的错误是因为版本不兼容 启动虚拟机运行测试

【Azure APIM】升级中国区APIM服务 stv1 到 stv2 遇见错误

Invalid parameter: This Migration API option is not supported or is temporarily disabled due to internal issues. Please visit https://aka.ms/apim-migrate-stv2 to see other migration options.问题描述 在执行Azure API Management服务升级的操作中 (从 stv1 升级到…

高频面题: 你们线上 QPS 多少?你 怎么知道的?

本文原文链接 文章很长,且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录 博客园版 为您奉上珍贵的学习资源 : 免费赠送 :《尼恩Java面试宝典》 持续更新+ 史上最全 + 面试必备 2000页+ 面试必备 + 大厂必备 +涨薪必备 免费赠送 :《尼恩技术圣经+高并发系列PDF》 ,帮你 …

【Java安全】CB链详细分析

免责申明: 本公众号所分享内容仅用于网络安全技术讨论,切勿用于违法途径,所有渗透都需获取授权,违者后果自行承担,与本号及作者无关,请谨记守法.环境配置 pom.xml添加: <dependency> <groupId>commons-beanutils</groupId> <artifactId>commo…

17-php相关知识

1、安装最新版phpstudy集成工具并创建一个网站,编写php代码输出网站信息(phpinfo)利用小皮创建一个名叫pikachu的网站,根目录为pikachu源码存放的目录在根目录下的test目录中创建info.php文件(内容为<?php phpinfo;?>)浏览器访问该地址,输出pikachu网站对应的ph…

ljnljn的春秋杯冬季赛wp(1.17)

杂项 1、See anything in these pics? 压缩包里有个码,确认是aztec码这个是压缩包密码,解压出一张图片 binwalk找到多个图片,foremost分离 1:JPEG image data, JFIF standard 1.01 2:PNG image, 360 x 450, 8-bit grayscale, non-interlaced 3:TIFF image data, big-endian…

金融行业构建高效知识库:策略与实践

在金融行业,信息的准确性和时效性至关重要。随着业务范围的扩大和产品线的丰富,金融机构面临着前所未有的知识管理挑战。一个高效、易用的内部知识库不仅能够提升员工工作效率,还能增强客户服务质量,促进业务创新。本文将提供一套快速搭建金融行业内部知识库的指南,并简要…

智慧医疗的知识库:赋能医疗创新与患者服务

智慧医疗的发展正深刻改变着医疗行业的面貌,从精准医疗到远程诊疗,从健康管理到疾病预防,技术的革新带来了前所未有的机遇。然而,随着医疗数据的爆炸式增长和医疗知识的不断更新,如何高效管理并利用这些知识成为智慧医疗发展的关键。本文将对智慧医疗内部知识库进行深入剖…

如何对需求分析进行测试(阅读《有效需求分析》触发的思考)

我的初步理解 1. 明确满意条件定义任务的满意条件(验收条件),确保开发目标清晰可衡量。2. 提供Checklist制定Checklist,明确必填项和关键检查点,确保任务完成的完整性和一致性。3. 需求与特性的关联需求归属:明确当前用户需求属于哪个特性(Feature),并了解该特性下的其…

在绩效管理中采用OKR的优势

现代的绩效管理体系剔除旧的年度绩效管理系统,以获取此现代系统的好处,该系统可基于连续的反馈进行频繁的绩效评估系统。 OKR绝对清晰地说明了需要优先考虑的事项以及如何帮助公司取得成功。 透明度和与组织目标的一致性可确保员工符合组织目标,并更有动力和参与度基于OKR的…