Three.js入门(四)——顶点UV坐标、纹理贴图

创建纹理贴图

通过纹理贴图加载器TextureLoaderload()方法加载一张图片可以返回一个纹理对象Texture,纹理对象Texture可以作为模型材质颜色贴图.map属性的值

const geometry = new THREE.PlaneGeometry(200, 100); 
//纹理贴图加载器TextureLoader
const texLoader = new THREE.TextureLoader();
// .load()方法加载图像,返回一个纹理对象Texture
const texture = texLoader.load('./earth.jpg');
const material = new THREE.MeshLambertMaterial({
    // 设置纹理贴图:Texture对象作为材质map属性的属性值
    map: texture,//map表示材质的颜色贴图属性
});

材质的颜色贴图属性.map设置后,模型会从纹理贴图上采集像素值,这时候一般来说不需要再设置材质颜色.color.map贴图之所以称之为颜色贴图就是因为网格模型会获得颜色贴图的颜色值RGB。

颜色贴图map和color属性颜色值会混合。如果没有特殊需要,设置了颜色贴图.map,不用设置color的值,color默认白色0xffffff。

自定义顶点UV坐标

顶点UV坐标geometry.attributes.uv和顶点位置坐标geometry.attributes.position是一一对应的,

UV顶点坐标你可以根据需要在0~1之间任意设置,具体怎么设置,要看你想把图片的哪部分映射到Mesh的几何体表面上

const uvs = new Float32Array([
    0, 0, 
    0.5, 0, 
    0.5, 0.5, 
    0, 0.5, 
]);

// 设置几何体attributes属性的位置normal属性
geometry.attributes.uv = new THREE.BufferAttribute(uvs, 2); //2个为一组,表示一个顶点的纹理坐标

纹理对象Texture阵列

 // 设置阵列模式
      texture.wrapS = THREE.RepeatWrapping;
      texture.wrapT = THREE.RepeatWrapping;
      // uv两个方向纹理重复数量
      texture.repeat.set(3, 3); //注意选择合适的阵列数量

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

UV动画

 const texture = textureLoader.load(
        "https://appasset.xverse.cn/1/breathpoint/4fc376a802e24dd6a061619e27ea8213/Oworld_game.png"
      );
      texture.offset.x += 0.5; //纹理U方向偏移
      texture.offset.y += 0.5; //纹理U方向偏移
      // 设置阵列模式
      texture.wrapS = THREE.RepeatWrapping;
      texture.wrapT = THREE.RepeatWrapping;
      // uv两个方向纹理重复数量
      texture.repeat.set(3, 3); //注意选择合适的阵列数量

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要实现线路流动和建筑物纹理流动,需要使用Three.js中的ShaderMaterial和自定义的着色器代码。下面是一个简单的示例代码: HTML: ``` <div id="container"></div> ``` JavaScript: ```javascript // 创建场景和渲染器 var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); var renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); document.getElementById('container').appendChild(renderer.domElement); // 添加灯光 var ambientLight = new THREE.AmbientLight(0xffffff, 0.5); scene.add(ambientLight); var pointLight = new THREE.PointLight(0xffffff, 0.5); pointLight.position.set(10, 10, 10); scene.add(pointLight); // 创建建筑物和线路材质 var buildingGeometry = new THREE.BoxGeometry(1, 1, 1); var buildingMaterial = new THREE.MeshPhongMaterial({ color: 0xCCCCCC, shininess: 10 }); var lineMaterial = new THREE.LineBasicMaterial({ color: 0x00FF00 }); var time = 0; // 自定义着色器代码 var vertexShader = ` uniform float time; varying vec2 vUv; void main() { vUv = uv; vec3 position = position; position.x += sin(position.z * 10.0 + time) * 0.1; position.y += sin(position.z * 20.0 + time) * 0.1; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } `; var fragmentShader = ` uniform float time; uniform sampler2D texture; varying vec2 vUv; void main() { vec2 uv = vUv; uv.x += sin(uv.y * 10.0 + time) * 0.1; uv.y += sin(uv.x * 20.0 + time) * 0.1; gl_FragColor = texture2D(texture, uv); } `; // 创建着色器材质 var shaderMaterial = new THREE.ShaderMaterial({ uniforms: { time: { value: 0 }, texture: { value: new THREE.TextureLoader().load('https://threejs.org/examples/textures/uv_grid_opengl.jpg') } }, vertexShader: vertexShader, fragmentShader: fragmentShader }); // 添加建筑物和线路 for (var i = 0; i < 10; i++) { var building = new THREE.Mesh(buildingGeometry, buildingMaterial); building.position.set(i - 5, 0, 0); scene.add(building); var lineGeometry = new THREE.Geometry(); lineGeometry.vertices.push(new THREE.Vector3(i - 5, -0.5, 0), new THREE.Vector3(i - 5, -0.5, -5)); var line = new THREE.Line(lineGeometry, lineMaterial); scene.add(line); } // 渲染循环 function render() { requestAnimationFrame(render); time += 0.1; shaderMaterial.uniforms.time.value = time; renderer.render(scene, camera); } render(); ``` 这个示例代码中,我们创建了一个包含10个方块和10条线路的场景。我们使用了一个自定义的着色器代码来实现建筑物和线路的流动效果。建筑物使用了Phong材质,线路使用了LineBasicMaterial。 在自定义的着色器代码中,我们使用了一个uniform变量time来控制时间流逝。在顶点着色器中,我们根据时间调整建筑物的位置。在片元着色器中,我们根据时间调整纹理UV坐标来实现纹理的流动效果。 如果你需要进一步了解ShaderMaterial和自定义着色器代码的使用,可以参考Three.js的官方文档。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值