Three 之 three.js (webgl)shader 中 Texture 贴图 uv 坐标的相关简单说明,并简单测试 UV 重复旋转偏移效果
Three 之 three.js (webgl)shader 中 Texture 贴图 uv 坐标的相关简单说明,并简单测试 UV 重复旋转偏移效果
目录
Three 之 three.js (webgl)shader 中 Texture 贴图 uv 坐标的相关简单说明,并简单测试 UV 重复旋转偏移效果
一、简单介绍
二、纹理坐标系统
三、纹理贴图(代码实例 Texture repeat 重复)
1、使用纹理对象贴图
2、UV坐标与顶点坐标的关系
四、其他
1、Texture 在 Three js 中的属性 和 方法
一、简单介绍
Three js 开发的一些知识整理,方便后期遇到类似的问题,能够及时查阅使用。
本节介绍, three 开发网页 3D 场景,three.js (webgl)shader 中 贴图 uv 坐标的相关说明,并简单测试UV旋转偏移效果,如果有不足之处,欢迎指出,或者你有更好的方法,欢迎留言。
二、纹理坐标系统
uv 其实就是纹理坐标,因为xyz已经被顶点坐标占用了,所以uvw就用来表示纹理坐标。它时候贴图影射到模型表面的依据,把表面的点与平面上的像素对应起来,一般取值在0~1;
u:图片在显示器水平的坐标
v:垂直方向
w:垂直于显示器表面
一般情况只是在表面贴图,就涉及不到w,所以常称为uv。
uv 纹理坐标设定与贴图规则
当opengl对一个四方形进行贴图时,会定义纹理贴图坐标,一串数组。
当纹理映射启动后绘图时,必须为OpenGL ES提供其他数据,即顶点数组中各顶点的纹理坐标。纹理坐标定义了图像的哪一部分将被映射到多边形。它的工作方式有点奇怪。
下面看下在android平台下Opengl纹理系统坐标,左下角为原点。
三、纹理贴图(代码实例 Texture repeat 重复)
1、使用纹理对象贴图
Texture ThreeJS本身做了封装,贴图十分方便,你可以在中文网站上直接查看教程或对象方法。
const w=h=64,textureW=textureH=64;var geometry = new THREE.PlaneBufferGeometry(w, h); //矩形平面// TextureLoader创建一个纹理加载器对象,可以加载图片作为几何体纹理var textureLoader = new THREE.TextureLoader();// 执行load方法,加载纹理贴图成功后,返回一个纹理对象TexturetextureLoader.load('./p.jpg', function (texture) {texture.wrapS = THREE.RepeatWrapping;texture.wrapT = THREE.RepeatWrapping;// texture.repeat.set(2, 2);var material = new THREE.MeshLambertMaterial({map: texture, //设置颜色贴图属性值}); //材质对象Materialvar mesh = new THREE.Mesh(geometry, material); //网格模型对象Meshscene.add(mesh); //网格模型添加到场景中//纹理贴图加载成功后,调用渲染函数执行渲染操作render();
代码说明:
纹理对象Texture本身是有UV旋转偏移方法的,但是如果调整纹理UV,用本身自带方法就需要频繁重新贴图,详细解析如下:
2、UV坐标与顶点坐标的关系
原始贴图,它的纹理坐标和顶点坐标对应情况,它们是一一对应的,大概是下图绘制的效果
四、简单 Texture UV 旋转偏移
通过旋转和偏移的值构建一个矩阵,用ThreeJS自带的矩阵库,因为它只有三维和四维的,所以把uv坐标写成了三维,即齐次坐标;
通过取得BufferGeometry的顶点坐标,再去计算原始的UV坐标。不过要注意的只有是或继承BufferGeometry 的对象才能取得uv、position信息;
最后通过矩阵转换每一点UV坐标,设置为BufferGeometry的UV。
//geometry可以通过mesh对象取得,pos是保存顶点坐标的数组let pos = geometry.getAttribute("position").array;let uv = [];const startP = [pos[0],pos[1]];//UV偏移不能太大,一般在0到1之间const offsetU = 0.05,offsetV = 0.02,rotation = Math.PI/4;let m = new THREE.Matrix3();m.setUvTransform( -offsetU, -offsetV, 1, 1, rotation, 0, 0 );//取得正常情况下的UV坐标for (let index = 0; index*3 < pos.length; index++) {if(index === 0) uv.push(...[0,0,1]);else{const currentP = [pos[index*3],pos[index*3+1]]uv.push(...[Math.abs((currentP[0]-startP[0])/w),Math.abs((currentP[1]-startP[1])/h),1]);}}let uvAttr = new THREE.BufferAttribute(new Float32Array(uv) , 3) ;uvAttr = m.applyToBufferAttribute (uvAttr);geometry.attributes.uv = uvAttr;
这么简单的代码就可以实现UV旋转偏移,但是我们一般会把它封装成函数,通过页面上的Input调整offsetU, offsetV,rotation的值。上面几行的代码,效果如下:
四、其他
1、Texture 在 Three js 中的属性 和 方法
属性
名称 | 描述 |
id | 此纹理实例的唯一编号。 |
uuid | 此对象实例的UUID。这会自动分配,所以不应该编辑。 |
name | 对象的名称,可以重复,默认值为空字符串 |
image |
一个Image对象,通常使用 ImageUtils 或 ImageLoader 类来创建。 Image对象可以包括图像 (比如 PNG, JPG, GIF, DDS), 视频 (e.g., MP4, OGG/OGV), 或者六幅图像的集合用于一个立方体贴图。 要使用视频作为一个纹理, 你需要把一个HTML5视频元素作为纹理图像的源, 并在视频播放时不断更新这个纹理-VideoTexture类会自动处理。 |
mipmap | 用户指定的mipmap数组(可选) |
mapping |
如何将图像应用到对象。默认为 UV贴图(THREE.UVMapping)类型,这里U,V 坐标用来应用映射,要求是单个纹理。 |
wrapS |
缺省为 THREE.ClampToEdgeWrapping, 表示边缘被夹到纹理单元(texels)的外边界。 THREE.ClampToEdgeWrapping:夹边。超过1.0的值被固定为1.0。超过1.0的其它地方的纹理, 沿用最后像素的纹理。用于当叠加过滤时,需要从0.0到1.0精确覆盖且没有模糊边界的纹理。 其他两个选项是: 在渲染具有诸如砖墙之类纹理的物体时,如果使用包含一整张砖墙的纹理贴图会占用较多的内存, 通常只需载入一张具有一块或多块砖瓦的较小的纹理贴图, 再把它按照重叠纹理寻址模式在物体表面映射多次,就可以达到和使用整张砖墙贴图同样的效果。 或者v处纹理被镜像翻转。 |
wrapT |
缺省为 THREE.ClampToEdgeWrapping, 表示边缘被夹到纹理单元(texels)的外边界。 其他两个选项是 THREE.RepeatWrapping 和 THREE.MirroredRepeatWrapping。 1024,2048,…)时工作。每个维度的值不一定是相同的,但每一个维度都必须是2的幂次方。 这是WebGL的限制,不是Three.js的。 |
magFilter |
该属性定义当一个纹理单元(texel)覆盖多个像素点时纹理如何采样。 缺省为 THREE.LinearFilter,表示获取4个最近的纹理单元执行双向线性插值计算(显示效果好)。 另外的选项是 THREE.NearestFilter, 表示使用最近的texel(性能优)。 |
minFilter |
该属性定义当一个纹理单元(texel)不足以覆盖单个像素点时纹理如何采样。缺省为 THREE.LinearMipMapLinearFilter, 表示使用多级纹理贴图(mipmapping)以及一个三线性滤波器。 其他选项是: THREE.NearestFilter:最近滤镜。在纹理基层上执行最邻近过滤。 THREE.NearestMipMapNearestFilter:选择最临近的mip层,并执行最临近的过滤。 THREE.NearestMipMapLinearFilter:在mip层之间执行线性插补,并执行最临近的过滤。 THREE.LinearFilter:在纹理基层上执行线性过滤。 THREE.LinearMipMapNearestFilter:选择最临近的mip层,并执行线性过滤。 THREE.LinearMipMapLinearFilter:在mip层之间执行线性插补,并执行线性过滤。 |
anisotropy |
表示纹理的各向异性。沿纹理单元密度最高方向的轴线所取样本数。默认情况下,这个值为1。 较高的值比基础MipMap要更清晰,但需要更多的采样。 使用renderer.getMaxAnisotropy()方法来找到GPU最大有效各向异性值; 这个值通常是2的幂次方。 |
format |
缺省纹理格式为THREE.RGBAFormat。其他格式有: THREE.UnsignedByteType:无符号8位整形值(1个字节) THREE.ByteType:带符号8位整形值(1个字节) THREE.ShortType:带符号16位整形值(2个字节) THREE.UnsignedShortType:无符号16未整形值(2个字节) THREE.IntType:带符号32位整形值(4个字节) THREE.UnsignedIntType:无符号32位整形值(4个字节) THREE.FloatType:单精度浮点型(4个字节) THREE.HalfFloatType:半浮点型 |
offset |
在U和V方向上,纹理在模型表面上重复绘制时的偏移。通常范围是0.0 到 1.0。注意: offset属性是一个便捷修饰符,仅影响Texture对模型上第一组UV的应用。 如果纹理用作需要额外UV集的贴图(例如,大多数库存材料的aoMap或lightMap), 则必须手动分配这些UV以获得所需的偏移量。 |
repeat |
纹理在整个表面上重复多少次,在每个方向U和V上。如果在任一方向上repeat设置为大于1, 则相应的Wrap参数也应设置为 THREE.RepeatWrapping或THREE.MirroredRepeatWrapping 以实现所需的平铺影响。注意: repeat属性是一个便捷修饰符, 仅影响Texture对模型上第一组UV的应用。如果纹理用作需要额外UV集的贴图 (例如,大多数库存材料的aoMap或lightMap),则必须手动分配这些UV以实现所需的重复。 |
rotation | 纹理围绕中心点旋转多少,以弧度表示。正值是逆时针的。缺省值是0。 |
center | 旋转发生的点。值(0.5,0.5)对应于纹理的中心。默认值是(0,0),左下角。 |
matrixAutoUpdate |
是否更新纹理的UV-变换.matrix从纹理特性.offset,.repeat, .rotation和.center。 默认情况下为真。如果直接指定uv-transform矩阵,则将其设置为false。 |
matrix |
纹理的uv转换矩阵。从质地特性渲染更新.offset,.repeat, .rotation和.center当纹理 的.matrixAutoUpdate属性为true。当.matrixAutoUpdate属性为false时, 可以手动设置此矩阵。默认值是单位矩阵。 |
generateMipmaps |
是否为纹理生成mipmap(如果可能)。默认情况下为真。如果您手动创建mipmap, 请将其设置为false。 |
premultiplyAlpha | 在默认情况下,这是PNG图像的标准。如果RGB值已被预乘alpha,则设置为true。 |
flipY | 默认为真。翻转图像的Y轴以匹配WebGL纹理坐标空间。 |
unpackAlignment |
默认值为4。指定内容中每个像素行起点的对齐要求。有效值有 1 (字节对齐byte-alignment), 2 (行起点按偶数字节对齐), 4 (字对齐word-alignment), 和 8(行起点按双字对齐)。 参阅:glPixelStorei 以了解更多信息。 |
encoding |
编码方式。默认设置为 THREE.LinearEncoding,但是支持 sRGB, RGBE, RGBM, RGBD, LogLuv 和 Gamma。 重要:如果纹理中的这个值在材料已用后被改变, 则需要触发一个Material.needsUpdate操作,以便该值在着色器中得到实现。 |
version | 从0开始计算needsUpdate更新次数 |
onUpdate |
一个回调函数,当纹理被更新时调用(例如,当needsUpdate被设置为true并且纹理 被使用时)。 |
needsUpdate | 将其设置为true以在下次使用纹理时触发更新。对于设置换行模式尤为重要。 |
方法
名称 | 描述 |
.updateMatrix () | 更新纹理的UV-变换.matrix从纹理特性.offset,.repeat, .rotation和.center。 |
.clone( texture : Texture ) | 制作纹理的副本。请注意,这不是“深层复制”,图像是共享的。 |
.toJSON( meta ) | meta - 包含元数据的可选对象。将材质转换为three.js JSON格式。 |
.dispose () | 使用一个’dispose’事件类型来调用 EventDispatcher.dispatchEvent 方法(自定义事件类)。 |
.transformUv ( uv ) | 根据此纹理的.offset,.repeat, .wrapS,.wrapT和.flipY属性的值转换uv 。 |
Three 之 three.js (webgl)shader 中 Texture 贴图 uv 坐标的相关简单说明,并简单测试 UV 重复旋转偏移效果相关推荐
- python中画折线图要用什么库_python画最最简单的折线图
原博文 2018-05-03 14:58 − # encoding=utf-8import matplotlib.pyplot as pltfrom pylab import * #支持中文mpl.r ...
- 【Three.js】shader特效之能量盾
shader特效之能量盾 前言 效果噪点图 主要代码 index.html depth-fs.js depth-vs.js shield-fs.js shield-vs.js 相关项目 前言 效果噪点 ...
- Unity shader图集Atlas下的UV坐标归一化转换
unity中如果图片打入了图集中,在shader中取到的uv坐标默认是图集中的坐标,如果需要shader做一些类似流光的效果,需要转换成常用的0-1区间的归一化uv坐标,转换方法如下: 步骤一: C# ...
- threejs(webgl)-shader入门教程(1)
1.shader基本使用 2.shader粒子 shader是什么? shader是一个用GLSL编写的小程序,也就是着色器语言,我们可以通过shader来编写顶点着色器和片元着色器,在WEBGL编程 ...
- WebGL+shader实现素描效果渲染
转自:点击打开链接 实现一个这样的渲染效果,主要的步骤包括: 准备模型和场景 通过 WebGL (Three.js) 导入场景 实现 Shader 以表现接近素描的效果 在最重要的第 3 步中,我们要 ...
- 在WebGL场景中进行棋盘操作的实验
这篇文章讨论如何在基于Babylon.js的WebGL场景中,建立棋盘状的地块和多个可选择的棋子对象,在点选棋子时显示棋子的移动范围,并且在点击移动范围内的空白地块时向目标地块移动棋子.在这一过程中要 ...
- 原生WebGL场景中绘制多个圆锥圆柱
前几天解决了原生WebGL开发中的一个问题,就是在一个场景中绘制多个几何网格特征不同的模型,比如本文所做的绘制多个圆锥和圆柱在同一个场景中,今天抽空把解决的办法记录下来,同时也附上代码.首先声明,圆柱 ...
- 在WebGL场景中管理多个卡牌对象的实验
这篇文章讨论如何在基于Babylon.js的WebGL场景中,实现多个简单卡牌类对象的显示.选择.分组.排序,同时建立一套实用的3D场景代码框架.由于作者美工能力有限,所以示例场景视觉效果可能欠佳,本 ...
- 狗和披萨:使用TensorFlow.js在浏览器中实现计算机视觉
目录 起点 托管说明 MobileNet v1 运行物体识别 终点线 下一步是什么?绒毛动物? 下载TensorFlowJS示例-6.1 MB TensorFlow + JavaScript.现在,最 ...
- 使用TensorFlow.js在浏览器中进行深度学习入门
目录 设置TensorFlow.js 创建训练数据 检查点 定义神经网络模型 训练AI 测试结果 终点线 内存使用注意事项 下一步是什么?狗和披萨? 下载TensorFlowJS示例-6.1 MB T ...
最新文章
- 经典 Python参数传递采用的肯定是“传对象引用”的方式。相当于传值和传引用的一种综合。如果函数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值--相当于通过“传引用”来传递对象
- Python 之父谈 Python
- python下载的文件放在哪里的-python实现下载文件的三种方法
- 想学python怎么学习_新手如何自学python课程?
- 获取其他线程的数据用 queue, 多进程Q
- 想学习java,如果学不会java怎么办?
- 服务器后还有一系列留后门,服务器留隐蔽后门
- 监控和调整Linux网络协议栈的图解指南:接收数据
- delphi如何获得select得到的信息_如何建立闭环的笔记体系
- GridView里面的Item高度设置
- FoxMail7.2信纸设置(适用于7.0及以上版本)
- 一套简单的进销存管理系统源码
- 怎么创建电脑的无线网络连接服务器,怎么开通无线网络
- assume用法及意思_assume的用法和例句
- 翻牌记忆类H5游戏的春天
- 哔哩哔哩 2019秋招编程题---脸滚键盘
- CPP2022-07-循环结构01
- github新手入门
- Android应用在新浪微博授权提示:文件不存在 C8998 的解决方法
- Perl之Spreadsheet::WriteExcel