当前位置: 首页 > news >正文

第三部分-纹理与贴图——14. 纹理基础

14. 纹理基础

1. 概述

纹理(Texture)是将图像映射到 3D 物体表面的技术,用于增加物体的细节和真实感。Three.js 支持多种纹理类型和加载方式。

┌─────────────────────────────────────────────────────────────┐ │ 纹理体系 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 纹理类型 │ │ ├── Texture:基础纹理 │ │ ├── CanvasTexture:Canvas 纹理 │ │ ├── VideoTexture:视频纹理 │ │ ├── CubeTexture:立方纹理 │ │ ├── DataTexture:数据纹理 │ │ └── CompressedTexture:压缩纹理 │ │ │ │ 纹理属性 │ │ ├── wrapS / wrapT:包裹模式 │ │ ├── magFilter / minFilter:过滤模式 │ │ ├── anisotropy:各向异性 │ │ └── encoding:颜色编码 │ │ │ └─────────────────────────────────────────────────────────────┘

2. 纹理加载

2.1 TextureLoader

import*asTHREEfrom'three';// 创建加载器consttextureLoader=newTHREE.TextureLoader();// 加载纹理consttexture=textureLoader.load('texture.jpg');// 带回调的加载textureLoader.load('texture.jpg',(texture)=>{console.log('纹理加载成功',texture);},(progress)=>{console.log('加载进度',(progress.loaded/progress.total)*100+'%');},(error)=>{console.error('加载失败',error);});// 应用到材质constmaterial=newTHREE.MeshStandardMaterial({map:texture});

2.2 纹理属性配置

consttexture=textureLoader.load('texture.jpg');// 包裹模式texture.wrapS=THREE.RepeatWrapping;// 水平方向重复texture.wrapT=THREE.RepeatWrapping;// 垂直方向重复// 重复次数texture.repeat.set(2,2);// 水平和垂直各重复2次// 偏移texture.offset.set(0.5,0.5);// 偏移纹理坐标// 旋转texture.rotation=Math.PI/4;// 旋转45度texture.center.set(0.5,0.5);// 旋转中心// 过滤模式texture.magFilter=THREE.LinearFilter;// 放大过滤texture.minFilter=THREE.LinearMipmapLinearFilter;// 缩小过滤// 各向异性(提高倾斜视角的清晰度)texture.anisotropy=16;// 最大16// 颜色空间texture.encoding=THREE.sRGBEncoding;// sRGB 编码// 生成 mipmaptexture.generateMipmaps=true;

3. 包裹模式(Wrapping)

3.1 包裹模式类型

模式说明
ClampToEdgeWrapping边缘拉伸(默认)
RepeatWrapping重复平铺
MirroredRepeatWrapping镜像重复
// 重复平铺constrepeatTexture=textureLoader.load('pattern.jpg');repeatTexture.wrapS=THREE.RepeatWrapping;repeatTexture.wrapT=THREE.RepeatWrapping;repeatTexture.repeat.set(4,4);// 镜像重复constmirrorTexture=textureLoader.load('pattern.jpg');mirrorTexture.wrapS=THREE.MirroredRepeatWrapping;mirrorTexture.wrapT=THREE.MirroredRepeatWrapping;mirrorTexture.repeat.set(4,4);// 边缘拉伸(默认)constclampTexture=textureLoader.load('pattern.jpg');clampTexture.wrapS=THREE.ClampToEdgeWrapping;clampTexture.wrapT=THREE.ClampToEdgeWrapping;

4. 过滤模式(Filtering)

4.1 过滤模式类型

放大过滤(magFilter):

模式说明
LinearFilter线性插值(平滑)
NearestFilter最近邻(像素化)

缩小过滤(minFilter):

模式说明
NearestFilter最近邻
LinearFilter线性插值
NearestMipmapNearestFilter最近邻 mipmap
LinearMipmapNearestFilter线性 mipmap,最近邻
NearestMipmapLinearFilter最近邻 mipmap,线性
LinearMipmapLinearFilter线性 mipmap,线性插值(默认,质量最高)
// 像素风纹理constpixelTexture=textureLoader.load('pixel.png');pixelTexture.magFilter=THREE.NearestFilter;pixelTexture.minFilter=THREE.NearestFilter;// 高质量纹理consthighQualityTexture=textureLoader.load('highres.jpg');highQualityTexture.magFilter=THREE.LinearFilter;highQualityTexture.minFilter=THREE.LinearMipmapLinearFilter;

5. CanvasTexture

将 HTML Canvas 作为纹理。

// 创建 Canvasconstcanvas=document.createElement('canvas');canvas.width=512;canvas.height=512;constctx=canvas.getContext('2d');// 绘制内容ctx.fillStyle='#ff6600';ctx.fillRect(0,0,canvas.width,canvas.height);ctx.fillStyle='#ffffff';ctx.font='Bold 40px Arial';ctx.fillText('Three.js',canvas.width/2-100,canvas.height/2);// 创建纹理constcanvasTexture=newTHREE.CanvasTexture(canvas);// 动态更新纹理functionupdateCanvasTexture(){ctx.fillStyle=`hsl(${Date.now()%360}, 100%, 50%)`;ctx.fillRect(0,0,canvas.width,canvas.height);canvasTexture.needsUpdate=true;}constmaterial=newTHREE.MeshStandardMaterial({map:canvasTexture});

6. VideoTexture

将视频作为纹理。

// 创建 video 元素constvideo=document.createElement('video');video.src='video.mp4';video.loop=true;video.muted=true;video.autoplay=true;video.play();// 创建视频纹理constvideoTexture=newTHREE.VideoTexture(video);videoTexture.minFilter=THREE.LinearFilter;videoTexture.magFilter=THREE.LinearFilter;constmaterial=newTHREE.MeshStandardMaterial({map:videoTexture});

7. DataTexture

从原始数据创建纹理。

// 创建数据constwidth=512;constheight=512;constsize=width*height;constdata=newUint8Array(size*4);// RGBAfor(leti=0;i<size;i++){conststride=i*4;constvalue=Math.floor(Math.random()*256);data[stride]=value;// Rdata[stride+1]=value;// Gdata[stride+2]=value;// Bdata[stride+3]=255;// A}constdataTexture=newTHREE.DataTexture(data,width,height,THREE.RGBAFormat);dataTexture.needsUpdate=true;

8. 纹理数组

consttextureLoader=newTHREE.TextureLoader();consttextures=[textureLoader.load('texture1.jpg'),textureLoader.load('texture2.jpg'),textureLoader.load('texture3.jpg')];// 切换纹理letcurrentTextureIndex=0;material.map=textures[currentTextureIndex];material.needsUpdate=true;

9. 完整示例

import*asTHREEfrom'three';import{OrbitControls}from'three/examples/jsm/controls/OrbitControls.js';constscene=newTHREE.Scene();scene.background=newTHREE.Color(0x111122);constcamera=newTHREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);camera.position.set(5,5,8);camera.lookAt(0,0,0);constrenderer=newTHREE.WebGLRenderer({antialias:true});renderer.setSize(window.innerWidth,window.innerHeight);document.body.appendChild(renderer.domElement);constcontrols=newOrbitControls(camera,renderer.domElement);controls.enableDamping=true;// 辅助对象constaxesHelper=newTHREE.AxesHelper(5);scene.add(axesHelper);constgridHelper=newTHREE.GridHelper(10,20);scene.add(gridHelper);// 光源constambientLight=newTHREE.AmbientLight(0x404040,0.5);scene.add(ambientLight);constdirectionalLight=newTHREE.DirectionalLight(0xffffff,1);directionalLight.position.set(5,10,7);scene.add(directionalLight);// 纹理加载器consttextureLoader=newTHREE.TextureLoader();// 创建棋盘格纹理(CanvasTexture)constcanvas=document.createElement('canvas');canvas.width=512;canvas.height=512;constctx=canvas.getContext('2d');constsize=64;for(leti=0;i<canvas.width;i+=size){for(letj=0;j<canvas.height;j+=size){ctx.fillStyle=((i+j)/size)%2===0?'#ff6600':'#ffffff';ctx.fillRect(i,j,size,size);}}constcheckerTexture=newTHREE.CanvasTexture(canvas);// 立方体constgeometry=newTHREE.BoxGeometry(2,2,2);constmaterial=newTHREE.MeshStandardMaterial({map:checkerTexture});constcube=newTHREE.Mesh(geometry,material);cube.castShadow=true;cube.receiveShadow=true;scene.add(cube);// 平面constplaneGeometry=newTHREE.PlaneGeometry(6,6);constplaneMaterial=newTHREE.MeshStandardMaterial({color:0x336699,side:THREE.DoubleSide});constplane=newTHREE.Mesh(planeGeometry,planeMaterial);plane.rotation.x=-Math.PI/2;plane.position.y=-1.5;plane.receiveShadow=true;scene.add(plane);// GUI 控制importGUIfrom'lil-gui';constgui=newGUI();// 纹理属性控制consttextureFolder=gui.addFolder('纹理属性');textureFolder.add(checkerTexture,'wrapS',{ClampToEdgeWrapping:THREE.ClampToEdgeWrapping,RepeatWrapping:THREE.RepeatWrapping,MirroredRepeatWrapping:THREE.MirroredRepeatWrapping}).name('水平包裹').onChange(()=>checkerTexture.needsUpdate=true);textureFolder.add(checkerTexture,'wrapT',{ClampToEdgeWrapping:THREE.ClampToEdgeWrapping,RepeatWrapping:THREE.RepeatWrapping,MirroredRepeatWrapping:THREE.MirroredRepeatWrapping}).name('垂直包裹').onChange(()=>checkerTexture.needsUpdate=true);textureFolder.add(checkerTexture.repeat,'x',0.1,4).name('水平重复').onChange(()=>checkerTexture.needsUpdate=true);textureFolder.add(checkerTexture.repeat,'y',0.1,4).name('垂直重复').onChange(()=>checkerTexture.needsUpdate=true);textureFolder.add(checkerTexture.offset,'x',-2,2).name('水平偏移').onChange(()=>checkerTexture.needsUpdate=true);textureFolder.add(checkerTexture.offset,'y',-2,2).name('垂直偏移').onChange(()=>checkerTexture.needsUpdate=true);textureFolder.add(checkerTexture,'rotation',0,Math.PI*2).name('旋转').onChange(()=>checkerTexture.needsUpdate=true);textureFolder.open();// 动画functionanimate(){requestAnimationFrame(animate);cube.rotation.x+=0.005;cube.rotation.y+=0.01;controls.update();renderer.render(scene,camera);}animate();window.addEventListener('resize',onWindowResize,false);functiononWindowResize(){camera.aspect=window.innerWidth/window.innerHeight;camera.updateProjectionMatrix();renderer.setSize(window.innerWidth,window.innerHeight);}

10. 总结

纹理类型创建方式适用场景
TextureTextureLoader图片纹理
CanvasTextureCanvas 元素动态纹理
VideoTextureVideo 元素视频纹理
CubeTexture6张图片环境贴图
DataTexture原始数据程序化纹理
纹理属性说明
wrapS/wrapT包裹模式
repeat重复次数
offset偏移量
rotation旋转角度
magFilter/minFilter过滤模式
anisotropy各向异性
needsUpdate需要更新

http://www.cnnetsun.cn/news/2172149.html

相关文章:

  • Java发展史之Java由来
  • simple-llm-finetuner性能优化:如何在有限GPU内存下获得最佳效果
  • SAP SmartForms深度使用指南:从OTF数据到PDF,一次讲清CONVERT_OTF和CONVERT_OTF_2_PDF的区别
  • 5分钟快速上手:完全免费的本地视频字幕提取终极指南
  • KikoPlay局域网服务完全指南:网页控制、Android客户端与多设备同步
  • 产品经理和开发者的高效协作神器:Balsamiq Wireframes实战配置与团队项目搭建
  • 协议逆向工程实践:基于TEA加密算法的手机号与QQ号关联查询技术解析
  • 5分钟快速上手QtScrcpy:电脑键鼠操控安卓手机的完整指南
  • Redisson 分布式锁实现:可重入与看门狗
  • 嵌入式Linux开发板深度定制:从内核驱动到根文件系统构建实战
  • 支付宝异步通知处理库alipay-notify:安全验签与生产环境实践指南
  • Windows Cleaner:告别C盘爆红的智能系统清理神器
  • 从Arduino到STM32:用AS5600磁编码器做个角度传感器,附完整代码与精度对比
  • TMC2240 芯片数据手册解读|第七篇 步进/方向接口(Step/Direction Interface)全解析
  • Gemini 3.1 在线入口(官方镜像):为什么它被持续关注
  • 64、【Agent】【OpenCode】用户对话提示词(推理链)
  • Gemini 官方下载,安全无病毒
  • 绝地求生压枪难题怎么破?罗技鼠标宏5分钟配置指南
  • 如何快速解决Windows任务栏透明工具TranslucentTB启动失败问题:完整解决方案指南
  • ViGEmBus:Windows内核级虚拟游戏控制器驱动深度解析
  • 基于STM32单片机智能出租车计价器分时计费GPS定位蓝牙设计23-135
  • BV哔哩哔哩第三方客户端TV车机版 支持4K真彩HDR|杜比视界 精简11M安装包
  • 魔兽争霸3玩家必备:9大兼容性问题一站式解决方案
  • 基于Claude API的智能代理框架:从工具调用到生产部署全解析
  • Maya glTF插件:5步实现3D模型跨平台完美转换
  • Spark.NET:一个试图把 Django / Rails 式开发体验带回 .NET 世界的全栈 Web 框架。
  • 为 OpenClaw 智能体配置 Taotoken 作为其底层模型服务
  • 如何智能清理Windows系统:免费开源工具的高效使用指南
  • 前端开发必备:shameless工具库深度解析与实战应用
  • 变长序列数据处理:从填充掩码到动态批处理实战