threejs-将具有纹理贴图的材质应用于通过THREE.ObjectLoader加载的对象

路易斯·E·福格

我通过JSON文件引入几何和材料。在大多数情况下,这很好用,除非现在我也尝试引入纹理贴图。据我所知,THREE.ObjectLoader从加载的纹理中去除了任何图像信息,因此,材质无法访问图像源。我已经尝试了几件事,但是所有这些都会导致相同的结果:如果我重新创建带有纹理贴图的材质并将其应用于已加载的对象,则该对象会消失。

为了确保某些东西可以工作,我创建了一个带有多维数据集和材质的简单场景。这很好用:

var textureDiff = THREE.ImageUtils.loadTexture( "img/brick_diffuse.jpg" ); 
textureDiff.wrapS = THREE.RepeatWrapping; 
textureDiff.wrapT = THREE.RepeatWrapping; 
textureDiff.repeat.set( 2, 2 );

var textureBump = THREE.ImageUtils.loadTexture( "img/brick_bump.jpg" ); 
textureBump.wrapS = THREE.RepeatWrapping; 
textureBump.wrapT = THREE.RepeatWrapping; 
textureBump.repeat.set( 2, 2 );

var material = new THREE.MeshPhongMaterial({map: textureDiff, bumpMap: textureBump});

var geometry = new THREE.BoxGeometry( 2, 2, 2 ); 

var cube = new THREE.Mesh( geometry, material ); 
cube.name = "myCube";
cube.position.set( 0, 1, 0 );
cube.castShadow = true;
cube.receiveShadow = true;
scene.add( cube );

我得到一个带有砖纹理的立方体。伟大的!我什至可以混合其顺序,例如,用简单的材质添加多维数据集,将其添加到场景中,按名称查找多维数据集,然后用新材质替换它。所有这些都可以。

乍看之下,通过THREE.ObjectLoader加载对象的工作。对象在那里,并且它们的材料颜色指示在生成JSON的应用程序中分配给它们的材料。如果查询该方法中加载的对象,则几乎所有我期望的并存储在文件中的特征都在那里。但是当我查看对象的材质时,贴图槽为空。因此,我查看了THREE.ObjectLoader的源代码,并从中收集了可能未加载材质纹理贴图的信息。ObjectLoader顺应了MaterialLoader,后者似乎没有处理纹理贴图的逻辑。

因此,我尝试也处理来自解析的JSON场景对象的材料。在这里,我得到的结构与我在JSON文件中的结构相同。我浏览了材质,纹理和图像,并以此创建了一系列新的材质。如果我询问新的材质数组,则贴图将包含带有图像的纹理对象。我尝试以几种方式加载纹理:

首先,通过在上面的测试中使用ImageUtils:

scene.children[i].material.map =  THREE.ImageUtils.loadTexture('img/brick_diffuse.jpg');

其次,通过实际构建所有内容,首先加载图像,然后制作纹理,然后制作材料,然后将其应用于对象(这里是材料构造代码)。在这种情况下,如果删除地图,则导入的对象将变为红色:

var loaderImg = new THREE.ImageLoader();
// load a image resource 
loaderImg.load( // resource URL 
    'img/brick_diffuse.jpg', 
    // Function when resource is loaded 
    function ( image ) { // do something with it // like drawing a part of it on a canvas 
console.log("image loaded!");

texture = new THREE.Texture({
    image : image,
    wrapS : THREE.RepeatWrapping,
    wrapT : THREE.RepeatWrapping,
    repeat : [1,1]
});

material = new THREE.MeshPhongMaterial({
    color: new THREE.Color('rgb(0,0,255)'),
    map: texture

    });

//add material to object    
scene.children[i].material = material;                          
},

function ( xhr ) { console.log( (xhr.loaded / xhr.total * 100) + '% loaded' ); }, 
// Function called when download errors 
function ( xhr ) { console.log( 'An error happened' ); } );

我已经尝试了上面的多次迭代,所有结果都指向相同的结果:如果将地图添加到创建的材质中,则不会出现该对象,如果省略材质的map属性,则导入的对象会发生变化材料(可以看到新的颜色和其他属性)。

我在这里看到几条路:1.只需使用经过解析的JSON场景,就不用考虑THREE.ObjectLoader了,遍历文件中的所有对象,获取它们的关联材料,等等,一点一点地构造它。2.扩展THREE.MaterialLoader以进入并实际加载图像。3.稍加注意。

我在这里看到了几个类似问题的问题,但似乎没有明确的答案。我还尝试了某些答案中建议的其他方法,但我总是遇到一个丢失的对象。

我在threejs r70上,已经在本地和远程服务器,Chrome和Firefox上尝试过。

最后,我尝试了这两件事:

 var textureDiff = THREE.ImageUtils.loadTexture( "img/Cork.png" ); 
    textureDiff.wrapS = THREE.RepeatWrapping; 
    textureDiff.wrapT = THREE.RepeatWrapping; 
    textureDiff.repeat.set( 2, 2 ); 

    var material = new THREE.MeshPhongMaterial({
        color:new THREE.Color('rgb(255,0,0)'),
        map: textureDiff
        });

    var geometry = new THREE.BoxGeometry( 2, 2, 2 );            
    var mmm = new THREE.Mesh(geometry, material );
    scene.add(mmm);

2.在这里,如果改为使用导入对象的几何形状来制作新的网格,则网格消失:

var textureDiff = THREE.ImageUtils.loadTexture( "img/Cork.png" ); 
    textureDiff.wrapS = THREE.RepeatWrapping; 
    textureDiff.wrapT = THREE.RepeatWrapping; 
    textureDiff.repeat.set( 2, 2 );

    var geometry = new THREE.BoxGeometry( 2, 2, 2 ); 

    var material = new THREE.MeshPhongMaterial({
        color:new THREE.Color('rgb(255,0,0)'),
        map: textureDiff
        });

    var mmm = new THREE.Mesh(scene.children[i].geometry, material );
    scene.add(mmm);

如果我确实注释掉了地图(// map:textureDiff),则导入的几何图形为红色,并具有材质的颜色。

很抱歉,我想确保对自己的尝试进行记录。我希望我已经使事情复杂化了,因为我肯定会丢失一条简单的信息,说明如果尝试添加具有纹理的材质,为什么我的物体会消失。谢谢。

路易斯·E·福格

我正在处理的问题有几个相关的子问题:1. threejs r70中的THREE.ObjectLoader不支持材质贴图加载。2.我的JSON不包含任何面顶点uvs。

为了解决第一个问题,我查看了源代码和请求请求,并发现了对对象加载器修改由于这些更改未编译到库中,因此我构建了一个混合的threejs,使用此pull请求中的版本替换了当前的版本ObjectLoader。

为了解决第二个问题,我将网格面顶点uvs从我的应用程序添加到正在写入的json文件中。

现在,pull请求已与threejs的dev分支合并

感谢@denzp的修改,感谢@mrdoob(和其他贡献者)对threejs的出色工作。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Threejs 将裁剪应用于对象的特定区域

来自分类Dev

THREEJS-将材质分配给对象时,无法将jpg作为材质贴图属性加载

来自分类Dev

Threejs纹理

来自分类Dev

Threejs从场景中删除所有对象

来自分类Dev

three.js ObjectLoader是否可以加载纹理?

来自分类Dev

在ThreeJS中更新纹理贴图

来自分类Dev

将纹理应用于threejs模型时出现奇怪的线条(“接缝”)

来自分类Dev

只需将材质分配给加载的 .OBJ - ThreeJS

来自分类Dev

DAE文件未在Threejs中加载多纹理

来自分类Dev

ThreeJS字体未加载

来自分类Dev

加载模型-threejs

来自分类Dev

ThreeJS OBJMTLLoader在纹理可用之前渲染对象

来自分类Dev

ThreeJS不同形状的对象纹理无法正常工作

来自分类Dev

ThreeJS OBJMTLLoader在纹理可用之前渲染对象

来自分类Dev

为什么通过GLTFLoader加载的Threejs克隆组行为异常?

来自分类Dev

threejs获取对象中心

来自分类Dev

threejs遍历对象onClick

来自分类Dev

ThreeJS对象的位置/旋转

来自分类Dev

如何使用threejs为对象应用平面着色

来自分类Dev

Threejs 2000纹理瓶颈

来自分类Dev

Threejs中的纹理格式

来自分类Dev

无法将 Threejs EventDispatcher 附加到自定义对象

来自分类Dev

ThreeJS:使用Matrix4更新现有对象

来自分类Dev

Threejs旋转对象,带有设备方向控制

来自分类Dev

ThreeJS ObjectLoader-无法读取未定义的属性“ fog”

来自分类Dev

Threejs-在着色器材质上应用简单的纹理

来自分类Dev

Threejs-在着色器材质上应用简单的纹理

来自分类Dev

Three.js 将重复纹理应用于 JSON 场景对象

来自分类Dev

在Threejs中将对象加载为Geometry而不是BufferGeometry