ThreeJs入门18-纹理的重复和纹理的回环

3,354 阅读2分钟

「这是我参与2022首次更文挑战的第22天,活动详情查看:2022首次更文挑战

示例代码采用three.js-r73版本: cdnjs.cloudflare.com/ajax/libs/t…

yuque_diagram.jpg

我们已经学会了纹理的基本使用,以及如何解决跨域问题。这一些我们学习一下关于纹理更加复杂的使用方式。

纹理重复

  • 在一个平面上,可以有很多重复的纹理,我们来让界面上展示重复的纹理。

纹理重复的使用

  • 师傅念经,大师兄很头疼,我们让它更头疼些。就像下面这样

image.png

  • 我们使用的图片是下面这张

image.png

function createGUI() {
    var ParamObj = function () {
        this.repeat = 1;
        this.wrap = 1;
    }
    param = new ParamObj();
    const gui = new dat.GUI();
    gui.add(param, "repeat", 1, 5).name('纹理重复')
    gui.add(param, "wrap", 1, 3).name('纹理环绕').step(1)
}

// 改变纹理
function changeTexture() {
    if (texture != null) {
     		// 纹理重复
        texture.repeat.x = texture.repeat.y = param.repeat
    }
}

function animation() {
    changeTexture()
    renderer.render(scene, camera);
    requestAnimationFrame(animation);
    update()
}
  • texture.repeat:纹理将在表面上,分别在U、V方向重复多少次。
  • 通过修改纹理重复次数,让我们的纹理进行重复
  • 但是展示的效果却不是我们想要的

image.png

  • 纹理图片缩小,成了一种拉丝的状态,这是为什么呢
    • 这是因为纹理回环导致的(后面我们再讲)
    • 我们先设置纹理回环为重复的
var texture
function initObject() {
    // 创建平面几何体
    var geometry = new THREE.PlaneGeometry(512, 512);
    // 获取纹理,内部使用ImageLoader来实现
    var loader = new THREE.TextureLoader();
    loader.setCrossOrigin("Anonymous");  // 解决跨域问题
    texture = loader.load("textures/image.png");
    // 设置纹理回环为重复的
    texture.wrapS = texture.wrapT = THREE.RepeatWrapping
    // 使用纹理进行材质创建
    var material = new THREE.MeshBasicMaterial({ map: texture })
    var mesh = new THREE.Mesh(geometry, material);
    scene.add(mesh)
}
  • 这样我们的效果就达到了

image.png

纹理重复需要注意的问题

  • 我们把重复值的范围设置为(-100,100),看下最大值和最小值的显示状况
  • 重复值太大,会造成密集恐惧症

image.png

  • 重复值是负数,纹理就会倒过来

image.png

  • 重复值取(-1到0和0到1)范围内,会被裁减

image.png

纹理回环

  • 重复纹理的方式叫纹理回环
  • threejs给了几个纹理回环常量供我们使用
    • 简单重复
    • 边缘拉伸
    • 镜像重复

简单重复

THREE.RepeatWrapping = 1000;

image.png

边缘拉伸

THREE.ClampToEdgeWrapping = 1001;

image.png

镜像重复

THREE.MirroredRepeatWrapping = 1002;

image.png

通过gui动态改变回环参数

function createGUI() {
    var ParamObj = function () {
        this.repeat = 1;
        this.wrap = 1000;
    }
    param = new ParamObj();
    const gui = new dat.GUI();
    gui.add(param, "repeat", -100, 100).name('纹理重复')
    gui.add(param, "wrap", 1000, 1002).name('纹理环绕').step(1)
}

function changeTexture() {
    if (texture != null) {
        texture.repeat.x = texture.repeat.y = param.repeat
        texture.wrapS = texture.wrapT = param.wrap
      	// 更新纹理
        texture.needsUpdate = true
    }
}

codepen示例代码

总结

这一节我们主要讲了以下内容:

  • 纹理重复的使用
  • 纹理重复需要注意的纹理
  • 纹理回环的分类
    • 简单重复
    • 边缘拉伸
    • 镜像重复
  • gui动态修改参数