我刚学会了如何使用.mtl文件(和.obj文件)在WebGL中将纹理应用于我的3D模型。当图像保存在我的计算机上时,应用纹理效果很好。以下是我的.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:link
OBJloader:link
我也使用ThreeJS Library:
ThreeJS:link
编辑: 由于Jave,问题解决了!以下是希望查看的人的结果:https://code.sololearn.com/WWY9cXN6OVBX/
答案 0 :(得分:0)
MTLLoader有一个名为setTexturePath
的方法,您可以使用该方法设置加载纹理的基本路径。由于您使用文件的外部源(dropbox),因此您可能还需要调用setCrossOrigin(true)
。我附上了一个使用这些方法加载纹理的注释示例。
您可能需要考虑的一些事项:
Earth.png
或textures/Earth.png
)。
const canvas = document.getElementById("canvas");
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, 1, 1, 10);
const renderer = new THREE.WebGLRenderer({ canvas });
const light = new THREE.AmbientLight();
scene.add(light);
camera.position.set(0, 0, 6);
const mesh = new THREE.Mesh(new THREE.SphereBufferGeometry( 1, 32, 32 ));
scene.add(mesh);
function update(){
scene.rotation.y = 0.001 * performance.now();
renderer.render(scene, camera);
requestAnimationFrame(update);
}
update();
//This is just creating a data-url from the div containing the mtl-data, it is not really neccessary, but it will make the example more similiar to loading a file.
const data = document.getElementById("mtlplaceholder").textContent;
const dataurl = "data:text/plain;base64," + btoa(data);
const loader = new THREE.MTLLoader();
//To load texture files not in the same folder as the mtl-file, we need to call setTexurePath with the proper base path. Note that every texture will have to be available at this same base url, which might not be the case when shared from dropbox.
//The complete URL is https://dl.dropbox.com/s/t4cm3vzsbx21crc/Earth.png
loader.setTexturePath("https://dl.dropbox.com/s/t4cm3vzsbx21crc/");
//To use cross-origin loading of textures, call setCrossOrigin(true):
loader.setCrossOrigin(true);
//Finally. load the mtl file (in this case the "file" is the dataurl created above):
loader.load(dataurl, res => {
//MTLLoader.load creates a MTLLoader.MaterialCreator, to get the actual material we have to call create with the name of the material we want.
//If you are using the OBJLoader, use preload instead and then objloader.setMaterials.
const loadedMat = res.create("Earth_MATERIAL");
//Finally, we set the material on the mesh.
mesh.material = loadedMat;
}, e => console.log("error", e));
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/92/three.js"></script>
<script src="https://rawgit.com/mrdoob/three.js/53838a2/examples/js/loaders/MTLLoader.js"></script>
<canvas id="canvas" width="400" height="400"></canvas>
<div id="mtlplaceholder" style:"white-space:pre">
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
</div>