Three.js如何加载本地资源?

Three.js如何加载本地资源?

2023年6月25日发(作者:)

如何加载本地资源?动机模型资源往往⽐较⼤,数据内容变动不⼤,可重复利⽤率不⾼。频繁请求⽐较浪费⽹络资源,加载到本地可以既可以节约请求,充分利⽤资源,并且可以节省⽤户下载时间,提⾼⽤户体验。那么怎么做才能实现我们的需求呢?⽅案(1)存考虑⽤indexDB将⼤量数据储存在客户端,这样可以减少从服务器获取数据,直接从本地获取数据。IndexedDB 不仅可以储存字符串,还可以储存⼆进制数据(ArrayBuffer 对象和 Blob 对象)。完全可以满⾜我们的需求。(2)取取的关键在于如何从本地数据库中加载资源⽽不是直接加载⽹络资源。这两者有何不同呢?我们注意到,以GLTFLoader为例: let manager = new gManager(); let gltfloader = new ader(manager); (url, obj => {

}, progress => {

}, err => {

})这⾥的url⼀般是⼀个⽹络地址。如果我们将数据存储在本地,不会有这样有⼀个URL。那么该怎么加载存储在本地的资源呢?这就是本⽂主要探索的⽬的。原理处理的关键还在于LoadingManager那⾥,官⽅⽂档上有这样⼀个⽰例://

将⽂件拖⼊⽹页时创建的Blob或File对象。var blobs = {'': blob1, '': blob2, '': blob3};var manager = new gManager();//

使⽤URL回调初始化加载管理器。var objectURLs = [];Modifier( ( url ) => { url = ObjectURL( blobs[ url ] ); ( url ); return url;} );//

像通常⼀样加载,然后撤消blob URLvar loader = new ader( manager );( '', (gltf) => { ( ); h( ( url ) => ObjectURL( url ) );});搞懂了这个例⼦,我们就知道怎么加载本地资源了。⾸先,blobs对象⾥存模型名称类型和该模型的⼆进制数据。我们把前⾯的资源名称类型姑且认为就是本地资源地址,我们的⽬的就是将它转为loader能识别的url。objectURLs存转换后的url。//

这是⼲嘛的?Modifier(() => {})// ://

查看LoadingManager的源码可以看到:Modifier = function ( transform ) { urlModifier = transform; return this;};// setURLModifier的回调,就是⾃定义修改URL的函数。但是manager拿着我们定义url的函数把它赋值给urlModifier有什么⽤呢?继续回到那个例⼦,接下来执⾏了⽅法( '', (gltf) => {

});也就是说,经过上⼀步,⾃定义设置url函数后,该loader已经可以直接读取名称类型就可以成功加载本地资源了,那么肯定就是在⽅法⾥做了⽂章,查看源码GLTFLoader的load⽅法(别被那么多吓到,我们只看我们⽤到的):// : function ( url, onLoad, onProgress, onError ) { ... //

其实GLTFLoader是继承FileLoader这个类的,我们需要继续到这个类中找答案 var loader = new ader( r ); ...}继续查看FileLoader的load⽅法的源码:// : function ( url, onLoad, onProgress, onError ) { if ( url === undefined ) url = ''; if ( !== undefined ) url = + url; //

关键就在这⾥了,绕来绕去,⼜回到manager⾥了,原来url在manager的resolveURL⽅法被处理了。 url = eURL( url ); ......}回到:// :eURL = function ( url ) { if ( urlModifier ) { return urlModifier( url ); } return url;};也就是说我们⾃定义url函数返回的url必须是loader能读取的url。除了常规的⽹络url还可以是blob url等。看看上⾯例⼦是怎么为本地资源⾃定义url的。补充Blob URL / Object URL是⼀种伪协议,允许Blob和File对象⽤作图像,下载⼆进制数据链接等的URL源。Blob URL或Object-URL与Blob或File对象⼀起使⽤。例如,不能处理Image对象的原始字节数据,因为它不知道如何处理它。它需要例如图像(⼆进制数据)通过URL加载。这适⽤于任何需要URL作为源的东西。不⽤上传⼆进制数据,⽽是通过URL提供回来,最好使⽤额外的本地步骤来直接访问数据⽽⽆需通过服务器。对于编码为Base-64的字符串的Data-URI也是更好的选择。Data-URI的问题是每个char在JavaScript中占⽤两个字节。最重要的是,由于Base-64编码增加了33%。Blob是纯粹的⼆进制字节数组,它不像Data-URI那样具有任何重要的开销,这使得它们处理速度越来越快。objectURL = ObjectURL(object);ObjectURL() 静态⽅法会创建⼀个 DOMString,其中包含⼀个表⽰参数中给出的对象的URL。这个 URL 的⽣命周期和创建它的窗⼝中的 document 绑定。这个新的URL 对象表⽰指定的 File 对象或 Blob 对象。ObjectURL(objectURL);ObjectURL() 静态⽅法⽤来释放⼀个之前已经存在的、通过调⽤ ObjectURL() 创建的 URL 对象。当你结束使⽤某个 URL 对象之后,应该通过调⽤这个⽅法来让浏览器知道不⽤在内存中继续保留对这个⽂件的引⽤了。你可以在 sourceopen 被处理之后的任何时候调⽤ revokeObjectURL()。这是因为 createObjectURL() 仅仅意味着将⼀个媒体元素的 src 属性关联到⼀个 MediaSource 对象上去。调⽤revokeObjectURL() 使这个潜在的对象回到原来的地⽅,允许平台在合适的时机进⾏垃圾收集。其实在也定义了resolveURL⽅法并且在ffer和xture都有调⽤//

看来loader加载某些特殊类型资源,除了⽀持常规的⽹络url,还要⽀持base64地址和blob url。function resolveURL( url, path ) { // Invalid URL if ( typeof url !== 'string' || url === '' ) return ''; // Absolute URL ,,// if ( /^(https?:)?/( url ) ) return url; // Data URI if ( /^data:.*,.*$/( url ) ) return url; // Blob URL if ( /^blob:.*$/( url ) ) return url; // Relative URL return path + url;}......ffer = function ( bufferIndex ) { ...... return new Promise( function ( resolve, reject ) { //

这⾥ ( resolveURL( , ), resolve, undefined, function () { reject( new Error( 'ader: Failed to load buffer "' + + '".' )); }); });}xture = function ( textureIndex ) { ...... return e( sourceURI ).then( function ( sourceURI ) { var loader = ( sourceURI ); if (!loader ) { loader = textureExtensions[ _TEXTURE_DDS ] ? ions[ _TEXTURE_DDS ].ddsLoader : textureLoader; } return new Promise( function ( resolve, reject ) { //

这⾥ ( resolveURL( sourceURI, ), resolve, undefined, reject ); }); }).then( function ( texture ) { if ( isObjectURL === true ) { ObjectURL( sourceURI ); } = false; if ( !== undefined ) = ; if ( pe in MIME_TYPE_FORMATS ) { = MIME_TYPE_FORMATS[ pe ]; } var samplers = rs || {}; var sampler = samplers[ r ] || {}; ter = WEBGL_FILTERS[ ter ] || Filter; ter = WEBGL_FILTERS[ ter ] || MipMapLinearFilter; = WEBGL_WRAPPINGS[ ] || Wrapping; = WEBGL_WRAPPINGS[ ] || Wrapping; return texture; });}

发布者:admin,转转请注明出处:http://www.yc00.com/web/1687678308a30837.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信