尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

three.js 纹理系统深度解析:Texture 基类完整参考与源码级实践指南

three.js 纹理系统深度解析:Texture 基类完整参考与源码级实践指南 three.js 纹理系统深度解析Texture 基类完整参考与源码级实践指南【免费下载链接】three.jsJavaScript 3D Library.项目地址: https://gitcode.com/GitHub_Trending/th/three.jsTexture 是 three.js 中所有纹理类型的基类承载了图像数据在 GPU 上的采样、过滤、坐标变换与色彩空间管理。本文以 Texture API 参考 为主体骨架结合 src/textures/Texture.js 与 src/textures/TextureSource.js 的源码实现系统梳理 Texture 的构造参数、全部属性、方法与事件帮助你写出正确、高效、可预测的纹理代码。Texture 是什么继承体系与数据/定义分离设计Texture 是所有纹理的基类继承自EventDispatcher其类型继承链为EventDispatcher → Texture。所有的纹理类型——如DataTexture、CanvasTexture、CubeTexture、VideoTexture、DepthTexture、CompressedTexture、DataArrayTexture、Data3DTexture等——都直接或间接继承自它见 src/textures 目录下的类声明例如 CubeTexture.js、DataTexture.js。从源码结构看Texture 与渲染相关的最核心设计是数据源与纹理定义解耦Texture持有的是纹理的定义如何采样filter、如何平铺wrap、如何变换 UVoffset/repeat/rotation、用何种格式存储format/type/colorSpace真正的像素数据存放在 TextureSource.js 的TextureSource实例中构造函数内通过this.source new TextureSource( image )创建见 Texture.js。这种解耦的典型收益是同一份数据源可以被多个 Texture 共享例如精灵表spritesheet场景中多个纹理引用同一张图片却各自拥有不同的 offset/repeat 等变换。从TextureSource源码可以看到它额外维护了dataReady、version与needsUpdate逻辑用于控制数据是否真正被上传到 GPUdataReady false时只分配显存不传输数据见 TextureSource.js。一处关键约束贯穿整个纹理生命周期纹理首次被使用后其尺寸dimensions、format 与 type 不能再修改。如需更改只能先调用dispose()释放旧纹理再创建一个新实例。构造函数与默认参数详解构造函数签名完整形式见 Texture.jsnew Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, colorSpace )各参数均带默认值。在工程实践中你几乎不会直接实例化裸Texture而更常用其子类或加载器但了解这套参数正是理解子类构造器与加载流程的钥匙参数含义默认值对应常量image持有纹理数据的图像对象Texture.DEFAULT_IMAGEnull—mapping纹理如何被映射到物体上Texture.DEFAULT_MAPPINGUVMappingUVMapping 300wrapS水平方向U的环绕方式ClampToEdgeWrappingClampToEdgeWrapping 1001wrapT垂直方向V的环绕方式ClampToEdgeWrappingClampToEdgeWrapping 1001magFilter放大过滤方式LinearFilterLinearFilter 1006minFilter缩小过滤方式LinearMipmapLinearFilterLinearMipmapLinearFilter 1008format像素格式RGBAFormatRGBAFormat 1023type数据类型UnsignedByteTypeUnsignedByteType 1009anisotropy各向异性过滤采样数Texture.DEFAULT_ANISOTROPY1—colorSpace色彩空间NoColorSpaceNoColorSpace 上述各常量的数值定义均可在 src/constants.js 中核实例如UVMapping 300见 L508、RGBAFormat 1023见 L763、NoColorSpace 见 L1301映射/环绕/过滤/色彩空间四组常量以不同数值区间区分。构造函数内部依次为所有属性初始化默认值其中最值得注意的几点id通过模块级计数器自增生成并只读Object.defineProperty( this, id, { value: _textureId } )Texture.jsisArrayTexture的初始值取决于 image 的depthimage image.depth image.depth 1Texture.js静态默认值DEFAULT_IMAGE null、DEFAULT_MAPPING UVMapping、DEFAULT_ANISOTROPY 1定义于类声明之后Texture.js。基于默认值的工程化初始化写法因为大部分默认值已足够常用日常代码往往只显式传入少数参数// 等价于 new THREE.TextureLoader().load(...) 底层最终创建的配置 const texture new THREE.Texture( image ); // 之后按需覆盖采样、平铺与色彩空间设置 texture.wrapS THREE.RepeatWrapping; texture.wrapT THREE.RepeatWrapping; texture.colorSpace THREE.SRGBColorSpace; // 颜色贴图务必标注属性全集按职责分组逐项解析原文档的属性条目较多这里按数据来源 → GPU 上传 → 采样 → 格式 → 坐标变换 → 生命周期六个维度分组解读保证每条属性语义与默认值完整保留。1. 图像数据相关.source : TextureSource构造后只读引用纹理的数据定义。一份数据源可被多个纹理共享精灵表场景中同一图片来源配上不同变换即是典型用例Texture.js。.image : Object持有纹理数据的图像对象本质是source.data的 getter/setter 代理Texture.js。.width、.height、.depth只读纹理像素宽、高、深。注意它们是 getter实现在source.getSize()中能自动兼容HTMLVideoElement取videoWidth/videoHeight、VideoFrame取displayWidth/displayHeight以及普通图像对象见 TextureSource.js。.mipmaps : Array用户自定义的 mipmap 数组。若自行准备多级 mipmap应同时把generateMipmaps置为false。2. GPU 上传与像素处理.needsUpdate : boolean默认false触发上传的关键开关。通过 setter 实现——置true会让version自增并将source.needsUpdate置true渲染器据此在下一帧上传纹理到 GPU 并重设纹理参数Texture.js。.version : number只读从0起统计needsUpdate被置true的次数。.flipY : boolean默认true上传时是否沿垂直轴翻转。注意使用ImageBitmap时该属性无效需在创建 bitmap 阶段createImageBitmap的imageOrientation: flipY配置。.premultiplyAlpha : boolean默认false上传时是否将 alpha 预乘进 RGB 通道。同样对ImageBitmap无效需在 bitmap 创建时配置。.unpackAlignment : number默认4内存中每行像素起始位置的对齐要求合法值为1字节对齐、2偶数倍字节、4字对齐、8双字边界对应 WebGLglPixelStoreiTexture.js。.generateMipmaps : boolean默认true是否自动生成 mipmap手动生成 mipmap 时应置false。WebGL 渲染器只有在格式允许RGBA 及未压缩格式且过滤需要时才会真正生成判定逻辑见 src/renderers/webgl/WebGLTextures.js 附近的texture.generateMipmaps分支。.updateRanges : Array仅更新纹理的子区域或特定行时使用通过addUpdateRange()追加。WebGLTextures会在上传前对 range 排序合并避免重复更新相邻区域见 src/renderers/webgl/WebGLTextures.js 的相关逻辑。3. 采样与过滤.magFilter默认LinearFilter当纹素覆盖超过一个像素纹理被放大时如何采样。.minFilter默认LinearMipmapLinearFilter当纹素覆盖不足一个像素纹理被缩小时如何采样。.anisotropy : number默认Texture.DEFAULT_ANISOTROPY 1沿纹素密度最高轴向的采样数。值越高斜面/透视下的模糊越少代价是采样开销增大。两组 filter 可选值相同取值为以下六个常量之一NearestFilter、NearestMipmapNearestFilter、NearestMipmapLinearFilter、LinearFilter、LinearMipmapNearestFilter、LinearMipmapLinearFilter。若minFilter不含 Mipmap 变体即不是...Mipmap...系列则generateMipmaps实际不会生效。三者相关的常量数值均见 src/constants.js。4. 格式、类型与色彩空间.format : number默认RGBAFormat纹理像素格式。除RGBAFormat外还有AlphaFormat、RGBFormat、RedFormat、RedIntegerFormat、RGFormat、RGIntegerFormat、RGBIntegerFormat、RGBAIntegerFormat、DepthFormat、DepthStencilFormat以及各类压缩格式S3TC/PVRTC/ETC1 等——压缩格式常量数值与 OpenGL 扩展值一致src/constants.js。.internalFormat : string默认nullGPU 上的实际存储格式。默认由format与type组合推导例如UnsignedByteType RGBAFormat配合 sRGB 传输可得到SRGB8_ALPHA8浮点组合得到RGBA16F/RGBA32F等推导表见 src/renderers/webgl/WebGLTextures.js 的getInternalFormat()。该属性允许手动覆盖默认推导结果。.type : number默认UnsignedByteType数据位深类型。可选ByteType、ShortType、UnsignedShortType、IntType、UnsignedIntType、FloatType、HalfFloatType、UnsignedShort4444Type、UnsignedShort5551Type等src/constants.js。浮点/半浮点纹理常用于 HDR 数据与后处理中间缓冲。.normalized : boolean默认false是否使用归一化的 16 位整型格式采样时归一化到[0, 1]或[-1, 1]视有符号/无符号而定。.colorSpace : string默认NoColorSpace颜色贴图应标注为SRGBColorSpacesrgb或LinearSRGBColorSpacesrgb-linear。format type决定存储位型colorSpace 决定渲染时的色彩转换与内部格式的 sRGB 变体选择转换依据见 src/renderers/webgl/WebGLTextures.js 中的ColorManagement.getTransfer( colorSpace )分支。5. UV 坐标变换offset/repeat/rotation/center.offset : Vector2默认(0,0)单次重复起始偏移U/V 两方向典型范围0.0 ~ 1.0。.repeat : Vector2默认(1,1)纹理在表面重复次数。任一向大于 1 时需同步把对应 wrap 设为RepeatWrapping或MirroredRepeatWrapping才能得到平铺效果。.center : Vector2默认(0,0)即左下角旋转的参考中心(0.5, 0.5)表示纹理中心。.rotation : number默认0绕中心旋转的弧度正值逆时针。.matrix : Matrix3UV 变换矩阵。.matrixAutoUpdate : boolean默认true是否由上述 offset/repeat/rotation/center 自动推导更新matrix。手动直接指定矩阵时置false。.updateMatrix()依据 offset、repeat、rotation、center 调用Matrix3#setUvTransform重建变换矩阵Texture.js。.transformUv( uv )用纹理的 UV 变换矩阵作用于给定 UV 向量并按 wrapS/wrapT 语义对越界坐标做回绕/钳制/镜像处理最后在flipY为true时翻转 V完整实现见 Texture.js。注意仅当mapping UVMapping时才执行变换。6. 生命周期、管理与杂项.dispose()释放 GPU 侧资源并触发dispose事件见下文方法节。.onUpdate : function默认null纹理更新时如needsUpdate置真并被使用后触发的回调。.needsPMREMUpdate : boolean、.pmremVersion : number只读默认0PMREM预滤波 mipmap 辐射环境贴图再生成标记。置needsPMREMUpdate true会使pmremVersion自增仅对 render target 纹理有意义Texture.js。.renderTarget默认null、.isRenderTargetTexture只读默认false纹理所属渲染目标的反向引用及标记。.isArrayTexture只读默认按 image depth 推断是否按纹理数组处理。.channel : number默认0选择纹理要映射到的 UV 属性0→uv、1→uv1、2→uv2、3→uv3。.mapping : number默认UVMapping映射模式集合为UVMapping、CubeReflectionMapping、CubeRefractionMapping、EquirectangularReflectionMapping、EquirectangularRefractionMapping、CubeUVReflectionMappingsrc/constants.js。默认UVMapping即用物体 UV 坐标贴图。.id只读、.uuid只读、.name标识与命名。uuid由generateUUID()生成toJSON序列化依赖 uuid 作为查重键。.userData : Object自定义数据容器不要存函数引用因为 clone 时通过JSON.parse(JSON.stringify(...))深拷贝见 Texture.js函数会被丢弃。.isTexture : boolean只读默认true类型探测标志子类各自再添加如isDataTexture、isVideoTexture等同风格标志。另外wrapS/wrapT均默认ClampToEdgeWrapping定义水平/垂直方向即 UV 中的 U/V的环绕方式与平铺配合的取值矩阵为取值常量数值行为RepeatWrapping1000超出范围时重复取样ClampToEdgeWrapping1001钳制到边缘像素MirroredRepeatWrapping1002镜像重复取样三个静态默认常量.DEFAULT_ANISOTROPY、.DEFAULT_IMAGE、.DEFAULT_MAPPING分别默认1、null、UVMapping。方法复制、序列化与更新.clone() : Texturenew this.constructor().copy( this )返回同构造器的新实例并复制全部取值。.copy( source : Texture ) : Texture从源纹理拷贝所有属性。值得注意的实现细节userData走 JSON 深拷贝、mipmaps走slice(0)浅拷贝数组、source引用直接共享而copy结束会把needsUpdate置true以强制上传Texture.js。.setValues( values : Object )批量设置属性。对Vector2/Vector3/Matrix3类型属性调用其.copy其余直接赋值遇到undefined值或不存在属性会发出告警Texture.js。MeshBasicMaterial等的map: {...}对象式传参最终即走此方法。.toJSON( meta : Object | string ) : Object序列化为 JSON。meta 可省略或传字符串此时为根对象否则写入meta.textures[uuid]去重缓存产物包含 metadataversion: 4.7、uuid、image、mapping、wrap、filter、format、type、colorSpace 等完整字段Texture.js。对应解析端为ObjectLoader#parse。.addUpdateRange( start : number, count : number )/.clearUpdateRanges()向updateRanges添加一段{ start, count }更新区间或清空全部区间Texture.js。适用于只改动贴图首几行等局部更新的场景可显著节省上传带宽。.dispose()dispatchEvent( { type: dispose } )即释放 GPU 资源并广播dispose事件Texture.js。应用在不再使用该纹理时显式调用这是 WebGL 应用中避免纹理泄漏的必要手段。事件与渲染器侧的联动.dispose当纹理被释放后触发事件对象为Object。典型用法是配合WebGLRenderer.capabilities或renderer.dispose()前统一释放场景内纹理。将needsUpdate、version、source.version串联起来就能看清 three.js 的纹理失效机制Texture#needsUpdatesetter 递增texture.version与source.needsUpdateWebGL 侧通过比较texture.version ! textureProperties.__version决定是否重新上传与设置纹理参数见 src/renderers/webgl/WebGLTextures.js 中多处textureProperties.__version ! texture.version判断。因此修改图片数据后必须把texture.needsUpdate true否则渲染器不会察觉数据变化。实战从加载器到子类的典型用法最常用的纹理创建入口是TextureLoader底层最终构建出一个Texture实例并自动根据图片 URL 推断编码。手动创建与子类的典型示例import * as THREE from three; // 1) 图片加载推荐交由 TextureLoader 管理 image 与 needsUpdate const map new THREE.TextureLoader().load( textures/uv_grid_opengl.jpg ); map.colorSpace THREE.SRGBColorSpace; // 颜色贴图标注 sRGB map.wrapS map.wrapT THREE.RepeatWrapping; // 配合 repeat 平铺 map.repeat.set( 2, 2 ); map.anisotropy 8; // 改善斜面观感 // 2) CanvasTexture画布可直接渲染构造时自动置 needsUpdate true // 见 src/textures/CanvasTexture.js#L39 const canvas document.createElement( canvas ); const canvasTex new THREE.CanvasTexture( canvas ); // 3) DataTexture从 TypedArray 原始数据构造默认 NearestFilter、不生成 mipmap // 见 src/textures/DataTexture.js#L32-L60 const data new Uint8Array( 256 * 256 * 4 ); const dataTex new THREE.DataTexture( data, 256, 256, THREE.RGBAFormat, THREE.UnsignedByteType ); dataTex.needsUpdate true; // 修改 data 后务必触发上传 // 4) 每帧修改后的更新惯例 map.needsUpdate true;DataTexture 子类内部实现印证了文档的默认值行为其magFilter/minFilter默认均为NearestFilter且generateMipmaps默认关闭DataTexture.js、DataTexture.js——因为无插值的原始数据噪声图、查找表等通常不需要 mipmap。其他常用子类各有针对性的默认差异均继承自 Texture 骨架CubeTexturesrc/textures/CubeTexture.js接收 6 面图像数组默认mapping CubeReflectionMapping且flipY false天空盒/环境贴图不应上下翻转见 L58。VideoTexturesrc/textures/VideoTexture.jsminFilter默认LinearFilter、不生成 mipmap优先借助requestVideoFrameCallback在每新帧触发needsUpdate true不支持时退化为update()轮询dispose()时取消帧回调。文档同时提示WebGPURenderer 下应把colorSpace设为SRGBColorSpace。CompressedTexture / DataArrayTexture / Data3DTexture / DepthTexture等分别承载压缩格式、2D 纹理数组、3D 体积数据与深度/深度模板格式语义差异集中于format、image结构及isArrayTexture类标志。涉及渲染目标后处理、程序化纹理与视频动态内容的官方可运行示例可在 examples/webgl_materials_texture_canvas.html、examples/webgl_video_panorama_equirectangular.html、examples/webgl_tsl_earth.html 等文件中找到Texture/DataTexture/VideoTexture的组合使用方式。小结与最佳实践清单颜色贴图务必标注colorSpace SRGBColorSpace数据贴图法线、粗糙度等保持NoColorSpace或按需LinearSRGBColorSpace。修改像素数据image 或 data 缓冲后必须needsUpdate true否则version不递增、渲染器不会重新上传。首次使用后尺寸/format/type 不可变需要变更就dispose()后重建。repeat 1时把wrapS/wrapT设为RepeatWrapping或MirroredRepeatWrapping否则看不到平铺。大面积贴图可借助addUpdateRange()只更新局部行减少每帧上传量。不再使用的纹理调用dispose()需要时监听dispose事件做资源收尾。动画纹理视频、实时 canvas的更新机制最终都收敛到置needsUpdate→version→ WebGL 重新上传这一条链路理解它即可预测所有子类的刷新行为。源码索引基类实现src/textures/Texture.js数据源实现src/textures/TextureSource.js常量定义mapping/wrap/filter/format/type/colorSpacesrc/constants.jsGPU 侧上传与参数推导src/renderers/webgl/WebGLTextures.js子类示例DataTexture.js、CanvasTexture.js、VideoTexture.js、CubeTexture.js、DepthTexture.js序列化解析端ObjectLoader#parsesrc/loaders/ObjectLoader.js【免费下载链接】three.jsJavaScript 3D Library.项目地址: https://gitcode.com/GitHub_Trending/th/three.js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表