zoukankan      html  css  js  c++  java
  • three.js UV映射简述

    今天郭先生来说一说uv映射,什么是uv映射?uv映射就是将二维的贴图映射到对象的一个面(或者多个面)上。说到这个问题,我们就不得不了解一下Geometry的点、面和uv的结构。我们以BoxGeometry为例。

    new THREE.BoxGeometry(20, 20, 20); //创建一个边长为20的正方体。

    我们可以发现一个长方体由八个点和12个三角面组成,就拿0-1-2-3这个面来看,两个面的face3分别是:

    也就是faces[0]对应顶点0-2-1,faces[1]对应顶点2-3-1,这个顺序可以记一下。
    Face3里面有一个很重要的属性materialIndex,这个索引是当使用数组材质的时候指定使用哪个材质作为当前Face3的材质,对于BoxGeometry来说,前面的两个三角面的materialIndex为0,后面的两个为1,上面两个为2,下面的两个为3,左面两个为4,右面的两个为5,即使数组中只有两个材质,那么也是按照这个顺序(既只显示前后两个面)。

    再说说uv映射,一个纹理图的原点在其左下方,坐标为(0,0),右下方为(1,0),左上方为(0,1),右上方为(1,1)

    在Geometry中,faceVertexUvs决定了uv映射的关系,如下如就是uv映射关系

    我们可以看出第一个三角面对应一个二维点数组[new THREE.Vector2(0,1), new THREE.Vector2(0,0), new THREE.Vector2(1, 1)],他默认将face3[0]的第一个点对应纹理的第一个点,face3[0]的第二个点对应纹理的第二个点,,face3[0]的第三个点对应纹理的第三个点,最后的到的如下图,

     

    我们稍微改变一下[new THREE.Vector2(0.25,0.75), new THREE.Vector2(0.25,0.25), new THREE.Vector2(0.75, 0.75)],看看会发生什么,

    就变成这个样子了,原因看下图

    接下来我们以数组材质的方式和单张纹理图的方式说一下如何将6个面赋予不同的贴图(默认六个面是相同的贴图)。

    1. 数组材质的方式

    这种方法十分简单,只需要创建6个贴图材质即可

    var geom = new THREE.BoxGeometry(20, 20, 20);
    var mate1 = new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('/static/images/animal/kaola.png')});
    var mate2 = new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('/static/images/animal/mao.png')});
    var mate3 = new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('/static/images/animal/quan.png')});
    var mate4 = new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('/static/images/animal/shi.png')});
    var mate5 = new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('/static/images/animal/tuboshu.png')});
    var mate6 = new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('/static/images/animal/xiongmao.png')});
    
    var mesh = new THREE.Mesh(geom, [mate1, mate2, mate3, mate4, mate5, mate6]);
    scene.add(mesh);

    2. 单张纹理图

    如下图所示,将六个面的纹理贴图绘制到一张

    var geom = new THREE.BoxGeometry(20, 20, 20);
    var mate = new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('/static/images/animal/an-uv.png')});
    var mesh = new THREE.Mesh(geom, mate);
    geom.faceVertexUvs[0][0] = [new THREE.Vector2(0,1), new THREE.Vector2(0,0.66), new THREE.Vector2(0.5, 1)];
    geom.faceVertexUvs[0][1] = [new THREE.Vector2(0,0.66), new THREE.Vector2(0.5,0.66), new THREE.Vector2(0.5, 1)];
    geom.faceVertexUvs[0][2] = [new THREE.Vector2(0.5,1), new THREE.Vector2(0.5,0.66), new THREE.Vector2(1, 1)];
    geom.faceVertexUvs[0][3] = [new THREE.Vector2(0.5,0.66), new THREE.Vector2(1,0.66), new THREE.Vector2(1, 1)];
    geom.faceVertexUvs[0][4] = [new THREE.Vector2(0,0.66), new THREE.Vector2(0,0.33), new THREE.Vector2(0.5, 0.66)];
    geom.faceVertexUvs[0][5] = [new THREE.Vector2(0,0.33), new THREE.Vector2(0.5,0.33), new THREE.Vector2(0.5, 0.66)];
    geom.faceVertexUvs[0][6] = [new THREE.Vector2(0.5,0.66), new THREE.Vector2(0.5,0.33), new THREE.Vector2(1, 0.66)];
    geom.faceVertexUvs[0][7] = [new THREE.Vector2(0.5,0.33), new THREE.Vector2(1,0.33), new THREE.Vector2(1, 0.66)];
    geom.faceVertexUvs[0][8] = [new THREE.Vector2(0,0.33), new THREE.Vector2(0,0), new THREE.Vector2(0.5, 0.33)];
    geom.faceVertexUvs[0][9] = [new THREE.Vector2(0,0), new THREE.Vector2(0.5,0), new THREE.Vector2(0.5, 0.33)];
    geom.faceVertexUvs[0][10] = [new THREE.Vector2(0.5,0.33), new THREE.Vector2(0.5,0), new THREE.Vector2(1, 0.33)];
    geom.faceVertexUvs[0][11] = [new THREE.Vector2(0.5,0), new THREE.Vector2(1,0), new THREE.Vector2(1, 0.33)];
    
    scene.add(mesh);

    他们的结果同下图。这里faceVertexUvs数组的第一维度是材质的索引,第二维度才是面的uv贴图映射关系,由于只有一个材质,所以这里的索引都是0。

    这节说了一下uv的使用,下一节说一说关于它的小应用。

    转载请注明地址:郭先生的博客

  • 相关阅读:
    树链剖分 (模板) 洛谷3384
    ST表 (模板) 洛谷3865
    IOI 2005 River (洛谷 3354)
    IOI 2005 River (洛谷 3354)
    poj1094 Sorting It All Out
    poj1094 Sorting It All Out
    spfa(模板)
    HAOI 2006 受欢迎的牛 (洛谷2341)
    HAOI 2006 受欢迎的牛 (洛谷2341)
    洛谷1850(NOIp2016) 换教室——期望dp
  • 原文地址:https://www.cnblogs.com/vadim-web/p/13517244.html
Copyright © 2011-2022 走看看