我正在通过JSON文件引入几何和材质。大多数情况下,这个效果很好,除了现在我正在尝试引入纹理贴图。从我所知道的情况来看,THREE.ObjectLoader会从加载的纹理中去除任何图像信息,因此材质无法访问图像源。 我已经尝试了几件事情,但它们都导致相同的结果:如果我使用纹理贴图重新创建材质并将其应用于加载的对象,对象将消失。threejs - 将具有纹理贴图的材质应用于通过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'); });
我已经试过以上的多次迭代和所有的结果指向相同的结果:如果我添加一个映射到我的材料如果我省略了材质的贴图属性,则导入的对象会更改材质(可以看到新的颜色和其他属性)。
我在这里看到几条道路: 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),则导入的几何图形将呈红色,并显示材质的颜色。
对长查询的道歉,我想确保我记录我的企图。我希望我已经完成了复杂的事情,因为我肯定错过了一些关于为什么我的对象会消失的简单信息,如果我尝试添加具有纹理的材质。 谢谢。
只是为了验证,THREE.ObjectLoader目前还不支持:https://github.com/mrdoob/three.js/issues/4967。不过,我应该能够以某种方式将纹理贴图贴到几何图形上!这是一个解决这个问题的请求:https://github.com/denzp/three.js/commit/c069ec1b26014b55bc961846feaf7f7554fc2bb2 构建这个版本后,loadmanager报告正在加载的图片,但是我得到了其他错误:THREE.WebGLRenderer: WEBGL_compressed_texture_pvrtc扩展名不支持three.js(第24404行)和TypeError:无效的'instanceof'操作数THREE.ImmediateRenderObject three.js(第21582行) – 2015-02-10 15:35:44