对于数量较多的模型,为了减少尺寸,我们采用没有贴图的模型文件,然后在程序里做统一贴图。
对于房子等建筑物,需要房顶和立面采用不同的材质贴图,甚至房子底部需要删除。
实现的思路是遍历所有面,根据方向确定是否为房顶或房子底部,修改贴图和UV数据。
关键代码如下:
// 修改房顶这一面的贴图,删除房子底部 function changeFaceMaterial(child, materials, index) { child.material = materials; child.geometry = (new THREE.Geometry()).fromBufferGeometry(child.geometry); puteBoundingBox(); var max = child.geometry.boundingBox.max, min = child.geometry.boundingBox.min; var offset = new THREE.Vector2(0 - min.x, 0 - min.y); var range = new THREE.Vector2(max.x - min.x, max.y - min.y); var faces = child.geometry.faces; // 遍历所有面,根据方向确定是否为房顶 for (var i = 0; i < faces.length; i++) { var el = faces[i]; // 顶部法线方向向上 if(el.normal.z == 1) { // 三角形顶点 var v1 = child.geometry.vertices[el.a], v2 = child.geometry.vertices[el.b], v3 = child.geometry.vertices[el.c]; // 替换掉该面的UV映射数据,否则对于不规则形状贴图会不正常 child.geometry.faceVertexUvs[0][i]= [ new THREE.Vector2((v1.x + offset.x) / range.x, (v1.y + offset.y) / range.y), new THREE.Vector2((v2.x + offset.x) / range.x, (v2.y + offset.y) / range.y), new THREE.Vector2((v3.x + offset.x) / range.x, (v3.y + offset.y) / range.y) ]; // 修改房顶材质 el.materialIndex = index; } // 底部法线方向向下 if(el.normal.z == -1) { // 删除房子底部的面 faces.splice(i, 1); // 对应的UV数据也需要删除 child.geometry.faceVertexUvs[0].splice(i, 1); i--; } } child.geometry.uvsNeedUpdate = true; }
源码下载:http://www.okbase.net/file/item/34755
免责声明:好库网所展示的信息由买卖双方自行提供,其真实性、准确性和合法性由信息发布人负责。好库网不提供任何保证,并不承担任何法律责任。