Javascript 使用外部链接将纹理应用于WebGL中的三维模型

Javascript 使用外部链接将纹理应用于WebGL中的三维模型,javascript,3d,three.js,webgl,textures,Javascript,3d,Three.js,Webgl,Textures,我刚刚学习了如何使用.mtl文件(和.obj文件)在WebGL中将纹理应用于我的3D模型。当图像保存在我的电脑上时,应用纹理效果非常好。下面是my.mtl文件的示例: newmtl Earth_MATERIAL Ns 96.078431 Ka 1.000000 1.000000 1.000000 Kd 0.640000 0.640000 0.640000 Ks 0.000000 0.000000 0.000000 Ke 0.000000 0.000000 0.000000 Ni 1.000000

我刚刚学习了如何使用.mtl文件(和.obj文件)在WebGL中将纹理应用于我的3D模型。当图像保存在我的电脑上时,应用纹理效果非常好。下面是my.mtl文件的示例:

newmtl Earth_MATERIAL
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.000000 0.000000 0.000000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 1

map_Kd Earth.png
这很有效。但是,我想发布我的模拟,因此我必须以某种方式参考图像。我的第一个想法是将图像上传到DropBox并使用该链接,但这不起作用:

...
map_Kd https://dl.dropbox.com/s/t4cm3vzsbx21crc/Earth.png?dl=0
运行此代码时出现的错误是:

错误:WebGL警告:texImage2D:元素为只读,因此无法上载


要加载纹理和模型,我使用MTLloader和OBJloader。以下是我正在使用的装载机:

MTLloader:

对象加载程序:

我还使用ThreeJS库:

ThreeJS:

编辑:
多亏了Jave,问题解决了!以下是希望看到的结果:

MTLLoader有一个名为的方法,您可以使用该方法设置加载纹理的基本路径。由于您正在使用文件的外部源(dropbox),您可能还必须调用
setCrossOrigin(true)
。我附上了一个使用这些方法加载纹理的注释示例

您可能需要考虑的一些事项:

  • 通常,您会将纹理放在与 mtl文件或子目录,以便您可以直接引用它们(如 只需
    Earth.png
    textures/Earth.png
  • 如果您使用的是纹理尺寸,则必须 例如,2的幂(2048 x 1024)。你的形象不是也不是 加载时自动调整大小。这样做会更有效率 事先手动调整大小
  • 您的纹理为5689 x 2844像素。这对于纹理来说非常大 你可能应该减少它。有些移动设备甚至可能不会 能够使用大于2048 x 2048的纹理
const canvas=document.getElementById(“canvas”);
const scene=new THREE.scene();
常数照相机=新的三个透视照相机(45,1,1,10);
const renderer=new THREE.WebGLRenderer({canvas});
const light=新的3.AmbientLight();
场景。添加(灯光);
摄像机位置设置(0,0,6);
常量网格=新的三点网格(新的三点SphereBufferGeometry(1,32,32));
场景。添加(网格);
函数更新(){
scene.rotation.y=0.001*performance.now();
渲染器。渲染(场景、摄影机);
requestAnimationFrame(更新);
}
更新();
//这只是从包含mtl数据的div创建一个数据url,实际上并不必要,但它将使示例更类似于加载文件。
const data=document.getElementById(“mtlplaceholder”).textContent;
const dataurl=“数据:文本/普通;base64”+btoa(数据);
const loader=new THREE.MTLLoader();
//要加载与mtl文件不在同一文件夹中的纹理文件,我们需要使用正确的基本路径调用setTexurePath。请注意,每个纹理都必须在同一个基本url上可用,从dropbox共享时可能不是这种情况。
//完整的URL是https://dl.dropbox.com/s/t4cm3vzsbx21crc/Earth.png
loader.setTexturePath(“https://dl.dropbox.com/s/t4cm3vzsbx21crc/");
//要使用纹理的跨原点加载,请调用setCrossOrigin(true):
loader.setCrossOrigin(真);
//最后。加载mtl文件(在本例中,“文件”是上面创建的dataurl):
loader.load(dataurl,res=>{
//MTLLoader.load创建一个MTLLoader.MaterialCreator,以获取实际的材质,我们必须使用所需材质的名称调用create。
//如果使用的是OBJLoader,请改用预加载,然后使用OBJLoader.setMaterials。
const loadedMat=res.create(“土料”);
//最后,我们在网格上设置材质。
mesh.material=荷载最大值;
},e=>console.log(“error”,e))

新材料
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.0000000.0000000.000000
克朗0.0000000.0000000.000000
倪1.000000
d 100万
照明1
map_Kd Earth.png

发布负责加载纹理的代码部分(如果正在使用3d库,则发布3d库)。我使用MTLloader和OBJloader。以下是我正在使用的加载程序:MTLloader:OBJloader:这正是我要找的!使用objLoader也可以很好地工作,非常感谢!你是我的英雄:-)