背景:如今很多应用场景会需要显示3D的场景,例如商品展示、在线试衣、选车时替换车身颜色,等等。
市面上有很多CAD设计软件满足不同需求场景的设计需求,如游戏、建筑、产品包装设计、3D打印等。这么多中的商业软件和文件格式,如果要开发不同的预览系统,是工作量很大的。
glTF是一种通用3D发布格式,有了它之后,其他应用可以通过导出为glTF格式,来实现内容的发布,而不需要开发很多不同格式的展示系统。
glTF是一个JSON文件,设计材质图案替换的最主要结构,大致有:mesh, material, texture, image。可以参考glTF的官网文档了解相关内容。
像针对车身换色,产品包装图案修改等需要动态改变展示内容的场景,可以通过更改glTF中的material来完成。
如,基于 https://gltf-viewer.donmccurdy.com/使用的threejs, GLTFLoader和TextureLoader,可以通过如下的更改完成。
var changedMaterials = {"material1": fileobj1, "material2": fileobj2}; // from caller side traverseMaterials(this.content, (node) => { const textureLoader = new TextureLoader(); if(changedMaterias[node.name]) { console.log('Change Material ' + node.name ); var textureFile = changedMaterias[node.name]; (function(file) { var reader = new FileReader(); reader.onload = function(e) { var imgData = e.target.result; var map = textureLoader.load(imgData); map.flipY = false; if (node.map) { // copy repeat and offset, for meshoptmizer models map.repeat.copy(node.map.repeat); map.offset.copy(node.map.offset); } node.map = map; node.needsUpdate = true; }; reader.readAsDataURL(file); })(textureFile); } else { console.log('Material ' + node.name + ' not changed.'); } });
一个限制:
glTF的标准规定了引擎至少需要实现两个UV坐标。所以市面上很多的glTF引擎都无法显示多个UV Mapping的模型。例如threejs,只会显示两个,而且第二个只针对AO (Ambient Occlusion)才会使用。
Client implementations must support at least two UV texture coordinate sets, one vertex color, and one joints/weights set.
在此限制下,如果你要为多个表面替换内容,需要将它们map到一个同一个UV Coordinate上。而不能像在CAD系统中,为多个material指定多个texture image并指定material使用的UV Map。
意味着如果你想要替换多个表面的图形,你可以:
a) 定义一个整体材质分配到多个面; 将多个面的图形合成为一个图;然后用大图替换整体材质的图片。
b) 分别为每个面定义材质;将每个面分别unwrap到整个UV coordinate中,并缩放到整个UV coordinate大小;将每个面的材质分别替换为需要的图片。
当然,还是有支持多个UV Map的引擎的。一个支持多个UV Mapping的引擎,是Sketchfab的实现。
一个例子(包含了6个UV coordinate):https://sketchfab.com/3d-models/cube-with-6-uv-mapping-71aac715d45642089906b2b68e100927