使用外部链接将纹理应用于WebGL中的3D模型



我刚刚学会了如何使用.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。以下是我正在使用的加载器:

MTL加载器:链接

OBJloader:链接

我也使用 ThreeJS 库:

三JS:链接

编辑: 多亏了贾夫,问题解决了!这是那些想看的人的结果:https://code.sololearn.com/WWY9cXN6OVBX/

MTLLoader 有一个名为setTexturePath的方法,您可以使用它来设置从中加载纹理的基本路径。由于您使用的是文件的外部源(保管箱(,因此可能还必须调用setCrossOrigin(true)。我附上了一个使用这些方法来加载纹理的注释示例。

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

  • 通常你会把你的纹理放在与 MTL 文件或子目录,以便您可以直接引用它们(如 只是Earth.pngtextures/Earth.png(。
  • 如果您使用的是 mipmap,则纹理尺寸必须为 例如,2 的幂 (2048 x 1024(。您的图像不是并且是 加载时自动调整大小。这样做会更有效 事先手动调整其大小。
  • 纹理为 5689 x 2844 像素。这对于纹理来说非常大 你可能应该减少它。某些移动设备甚至可能没有 能够使用大于 2048 x 2048 的纹理。

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>

相关内容

  • 没有找到相关文章