【ThreeJS基础教程-材质纹理篇】3.1 纹理知识进阶

纹理知识进阶

  • 学习ThreeJS的捷径
  • 如何用一张地板砖贴图制作出地板砖效果
  • 旋转纹理
  • 移动纹理
  • 纹理旋转与移动的应用
    • 简单的光圈效果
    • 简单的流水效果
    • WebGL项目优化技巧:没必要的细节可以用纹理直接代替
  • 下一篇预告

学习ThreeJS的捷径

本段内容会写在0篇以外所有的,本人所编写的Threejs教程中

对,学习ThreeJS有捷径
当你有哪个函数不懂的时候,第一时间去翻一翻文档
当你有哪个效果不会做的时候,第一时间去翻一翻所有的案例,也许就能找到你想要的效果
最重要的一点,就是,绝对不要怕问问题,越怕找找别人问题,你的问题就会被拖的越久

如果你确定要走WebGL/ThreeJS的开发者路线的话,以下行为可以让你更快的学习ThreeJS

  1. 没事就把所有的文档翻一遍,哪怕看不懂,也要留个印象,至少要知道Threejs有什么
  2. 没事多看看案例效果,当你记忆的案例效果足够多时,下次再遇到相似问题时,你就有可能第一时间来找对应的案例,能更快解决你自己的问题
  3. 上述案例不只是官网的案例,郭隆邦技术博客,跃焱邵隼,暮志未晚等站点均有不少优质案例,记得一并收藏
    http://www.yanhuangxueyuan.com/ 郭隆邦技术博客
    https://www.wellyyss.cn/ 跃焱邵隼
    http://www.wjceo.com/ 暮志未晚
    这三个站点是我最常逛的站点,推荐各位有事没事逛一下,看看他们的案例和写法思路,绝对没坏处

如何用一张地板砖贴图制作出地板砖效果

【ThreeJS基础教程-材质纹理篇】3.1 纹理知识进阶_第1张图片
图片来源于网络,如有侵权请联系我

首先我们准备一张瓷砖的贴图

还记得之前写过的草地吗?我们以同样的方式,把瓷砖贴图贴给plane

    function addMesh(){

        let texture = new THREE.TextureLoader().load('./ls.jpg');

        let geometry = new THREE.PlaneGeometry(10,10).rotateX(-Math.PI/2);

        let material = new THREE.MeshBasicMaterial({
            map:texture
        });
        let mesh = new THREE.Mesh(geometry,material);

        scene.add(mesh);
    }

但是,这样给人的感觉只是一块瓷砖,而不是地板
【ThreeJS基础教程-材质纹理篇】3.1 纹理知识进阶_第2张图片

这里我们要介绍纹理的第一个属性 wrap(包裹模式),warp有两个属性,wrapT和wrapS,S对应水平方向的图像,如何对应到物体的uv上,S对应uv的U,T对应垂直方向上,T对应uv的V

官方提供了三种包裹模式
THREE.RepeatWrapping :重复模式
THREE.ClampToEdgeWrapping:延伸模式
THREE.MirroredRepeatWrapping:镜像重复模式,每次重复时会镜像纹理

我们想要地板效果,就不能使用默认的延伸模式,而应该使用重复或镜像模式,同时,我们也应该为纹理设置其重复次数

texture.repeat : Vector2 ,x轴对应uv的u方向上重复几次,y对应uv的v方向上重复几次

这里说起来可能会比较麻烦,但是我们实际用一下,就直接可以明白了

    function addMesh(){

        let texture = new THREE.TextureLoader().load('./ls.jpg');
        texture.wrapT = texture.wrapS = THREE.RepeatWrapping;
        texture.repeat.set(10,10);

        let geometry = new THREE.PlaneGeometry(10,10).rotateX(-Math.PI/2);

        let material = new THREE.MeshBasicMaterial({
            map:texture
        });
        let mesh = new THREE.Mesh(geometry,material);

        scene.add(mesh);
    }

修改后的效果
【ThreeJS基础教程-材质纹理篇】3.1 纹理知识进阶_第3张图片
这里我们设定了让它重复10次

我们还可以换成让它镜像重复

        texture.wrapT = texture.wrapS = THREE.MirroredRepeatWrapping;

【ThreeJS基础教程-材质纹理篇】3.1 纹理知识进阶_第4张图片
在实际的设计中,我们的贴图都是由设计来出的,上面的贴图来源于网络,在视觉观感上可能会比较差,而我们作为程序开发,大多数都不具备良好的审美,所以不用去计较贴图是否好看

旋转纹理

是不是当前的图形有点不太好看,那么我们转一下它吧

    function addMesh(){

        let texture = new THREE.TextureLoader().load('./ls.jpg');
        texture.wrapT = texture.wrapS = THREE.MirroredRepeatWrapping;
        texture.repeat.set(10,10);
        texture.rotation = Math.PI/4;

        let geometry = new THREE.PlaneGeometry(10,10).rotateX(-Math.PI/2);

        let material = new THREE.MeshBasicMaterial({
            map:texture
        });
        let mesh = new THREE.Mesh(geometry,material);

        scene.add(mesh);
    }

【ThreeJS基础教程-材质纹理篇】3.1 纹理知识进阶_第5张图片

移动纹理

除了旋转,我们还可以移动纹理

	    function addMesh(){

        let texture = new THREE.TextureLoader().load('./ls.jpg');
        texture.wrapT = texture.wrapS = THREE.MirroredRepeatWrapping;
        texture.repeat.set(10,10);
        texture.rotation = Math.PI/4;
        texture.offset.set(0.8,0.8);

        let geometry = new THREE.PlaneGeometry(10,10).rotateX(-Math.PI/2);

        let material = new THREE.MeshBasicMaterial({
            map:texture
        });
        let mesh = new THREE.Mesh(geometry,material);

        scene.add(mesh);
    }

【ThreeJS基础教程-材质纹理篇】3.1 纹理知识进阶_第6张图片
你有发现移动的痕迹吗?

纹理旋转与移动的应用

简单的光圈效果

既然我们能对纹理进行操作了,那么,我们就可以利用操作纹理来做一些特别的效果,比如说一个旋转的图形

    let texture;
    function addMesh(){

        texture = new THREE.TextureLoader().load('./light.png');
        texture.center.set(0.5,0.5);

        let geometry = new THREE.PlaneGeometry(10,10).rotateX(-Math.PI/2);

        let material = new THREE.MeshBasicMaterial({
            map:texture,
            transparent:true
        });
        let mesh = new THREE.Mesh(geometry,material);

        scene.add(mesh);
    }
    function render(){
        renderer.render(scene,camera);
        requestAnimationFrame(render);
        texture.rotation += 0.01;
    }

图片是用ps做的
【ThreeJS基础教程-材质纹理篇】3.1 纹理知识进阶_第7张图片
我们只需要对texture做相应处理,就可以做出一个旋转的圆环效果

【ThreeJS基础教程-材质纹理篇】3.1 纹理知识进阶_第8张图片
这个就是最简单的一种动态光圈效果,根据图片的质量不同,我们也能做出效果更好的动态光圈

简单的流水效果


(图片来源于百度,如有侵权请联系我)

简单的水流效果

    let texture;
    function addMesh(){

        texture = new THREE.TextureLoader().load('./water.png');
		//记得开启重复模式
        texture.wrapT = texture.wrapS = THREE.RepeatWrapping;

        let geometry = new THREE.PlaneGeometry(10,10).rotateX(-Math.PI/2);

        let material = new THREE.MeshBasicMaterial({
            map:texture
        });
        let mesh = new THREE.Mesh(geometry,material);

        scene.add(mesh);
    }
    function render(){
        renderer.render(scene,camera);
        requestAnimationFrame(render);
        texture.offset.x += 0.001;
    }

【ThreeJS基础教程-材质纹理篇】3.1 纹理知识进阶_第9张图片

这里笔者没有gif图,就放一张静态图上来,在render中让贴图每一帧行走0.001就可以实现水流流动的感觉

笔者这里也没有使用完美重合的水流图,所以在流动过程中可以看到很明显的图片分界线,这种图片一般由设计人员来寻找或制作

同理,使用箭头贴图,可以制作箭头流动的效果

WebGL项目优化技巧:没必要的细节可以用纹理直接代替

有那么一类物体,在我们的项目中不需要展示细节,但是它却拥有很复杂的外观结构,比如说我们想在屋子里放一台笔记本电脑
如果给笔记本电脑完整的建模,那么多键盘的键位的细节都做的很精致很清楚,屏幕微小的高度差也被看的清清楚楚。。。然后把这个模型用在一个大型的场景中,我们会发现,在大型场景下,我们最多只能看到这个物体是个笔记本,而很多人不会去刻意去看笔记本的模型做的细节,而是更关注大型场景

这个时候,我们使用一张贴图来替代笔记本的键盘建模,直接使用两个box来做成笔记本,给屏幕的box贴一张图,给键盘的box再贴一张图,两张图+两个box,比起精致的建模来说,可以省去大量的建模时间以及点线面空间

总结一下就是:在做程序用的模型时,没必要的细节可以用纹理直接代替 ,以节省点线面数量

下一篇预告

初识MeshStandardMaterial

你可能感兴趣的:(ThreeJS,WebGL,材质,贴图,前端)