我多次使用图像作为纹理,一次通过material组件,另一次使用自定义组件。在后者我使用THREE.TextureLoader()
导致应用程序加载图像两次。我打赌还有另一种方式。
HTML
<!-- Assets -->
<a-assets>
<img id="my-map" src="path/to/map.jpg">
<a-asset-item id="my-model" src=path/to/model.gltf""></a-asset-item>
</a-assets>
<!-- Entities -->
<a-box material="src: #my-map">
<a-entity gltf-model="src: #my-model" custom-component="mymap: #my-map">
JS
// custom-component extract
schema: { mymap: { type: 'map' } }
init: function()
{
let mesh = this.el.getObject3D('mesh')
mesh.traverse( function( child )
{
if ( child.isMesh )
{
let TextureLoader = new THREE.TextureLoader()
let mymap = TextureLoader.load( data.mymap )
child.material = new THREE.MeshPhongMaterial({ map: mymap })
child.material.needsUpdate = true;
}
})
}
如何在自定义组件中使用相同的图像资源而不加载两次?
答案 0 :(得分:1)
您正在使用mesh.traverse()
,每个mesh
的孩子都会调用您的函数一次。如果你的网格中有两个孩子,它会调用TextureLoader.load()
两次。只需从traverse()
中取出加载调用,您就会看到只加载一次图像。
let mesh = this.el.getObject3D('mesh')
let TextureLoader = new THREE.TextureLoader()
let mymap = TextureLoader.load( data.mymap )
mesh.traverse( function( child )
{
if ( child.isMesh )
{
child.material = new THREE.MeshPhongMaterial({ map: mymap })
child.material.needsUpdate = true;
}
})
答案 1 :(得分:0)
经过一些研究挖掘ThreeJs代码后,我发现TextureLoader
依赖于ImageLoader
(请参阅here),在加载新图片之前,它会查看THREE.Cache
查看图片是否已加载(参见here)。
在AFrame中将图片加载为img
不会将其存储在THREE.Cache
中,因此图片已加载两次。但是,如果您将图片加载为a-asset-item
,那么。
因此无需在javascript中更改任何内容。只需使用a-asset-item
代替img
即可。
有关详细信息,请参阅AFrame documentation