收藏
回答

threejs-miniprogram引入gltf或者glb模型在gltf-loader报错,怎搞?

我是用了官方推荐的模板案例,可以正常加载


但是当替换成我这边自己的glb或者gltf文件的时候,直接报错

我从网上搜到,说是要在gltf-loader.js里把

var URL = window.URL || window.webkitURL;

改成

var URL = {};

但是又报了新的错误

请问要如何解决啊?先谢过

回答关注问题邀请回答
收藏

7 个回答

  • 刘亚男
    刘亚男
    2022-10-23

    最近开发也遇到了同样的问题,看了看源码,是因为gltf-loader.js中引用了Blob和URL两个Web API,但小程序是不支持的。官方提供的demo之所以可以加载那个机器人,是因为他的模型不包含纹理(Texture)数据。而只有在加载加载纹理的时候,才会调用这两个不支持的API。

    不要使用Blob、URL的polyfill,因为createObjectURL这个api不能被polyfill。

    其实加载Texture只是一段内存buffer数据。除了createObjectURL,还可以用base64。我简单改了代码,可以参考下这里的代码


    2022-10-23
    有用 2
    回复 1
    • 教不坏_小葮发
      教不坏_小葮发
      发表于移动端
      2022-11-23
      你好,同样的问题。怎么联系你
      2022-11-23
      回复
  • Null
    Null
    2022-02-28

    URL和blob需要模拟;建议使用gltf模型,glb纹理都需要blob

    // Blob文件
    export default class $Blob {
      constructor(parts, options) {
        this.parts = parts;
        this.options = options;
    
    
        // 目前仅适配如下
        // var blob = new Blob([bufferView], { type: source.mimeType });
        // sourceURI = URL.createObjectURL(blob);
    
    
        // var base64 = ArrayBufferToBase64(bufferView);
        // var url = `data:${options.type};base64,${base64}`;
      }
    }
    // url文件
    import Blob from './Blob';
    import { encode as ArrayBufferToBase64 } from './base64-arraybuffer';
    
    
    export default class $URL {
      createObjectURL(obj) {
        if (obj instanceof Blob) {
          // TODO: use wasm to improve decode performance
          // 经测试主要耗时在于字符串拼接,使用assemblyscript的字符串拼接比js拼接慢非常多
    
    
          // 组长找到更好的方式,使用wx.fileSystemManager写入临时文件来获取url,但是需要手动管理临时文件
    
    
          // const t = Date.now();
          const base64 = ArrayBufferToBase64(obj.parts[0]);
          const url = `data:${obj.options.type};base64,${base64}`;
          // console.log('createObjectURL', Date.now() - t);
          return url;
        }
    
    
        return '';
      }
    
    
      revokeObjectURL() {}
    }
    // base64-arraybuffer文件
    /*
     * base64-arraybuffer
     * https://github.com/niklasvh/base64-arraybuffer
     *
     * Copyright (c) 2012 Niklas von Hertzen
     * Licensed under the MIT license.
     */
    
    
    var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
    
    
    // Use a lookup table to find the index.
    var lookup = new Uint8Array(256);
    for (var i = 0; i < chars.length; i++) {
      lookup[chars.charCodeAt(i)] = i;
    }
    
    
    // 有点慢
    // export function encode(arraybuffer) {
    //   var bytes = new Uint8Array(arraybuffer),
    //     i,
    //     len = bytes.length,
    //     base64 = '';
    
    
    //   for (i = 0; i < len; i += 3) {
    //     base64 += chars[bytes[i] >> 2];
    //     base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
    //     base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
    //     base64 += chars[bytes[i + 2] & 63];
    //   }
    
    
    //   if (len % 3 === 2) {
    //     base64 = base64.substring(0, base64.length - 1) + '=';
    //   } else if (len % 3 === 1) {
    //     base64 = base64.substring(0, base64.length - 2) + '==';
    //   }
    
    
    //   return base64;
    // }
    
    
    // 快一点
    export function encode(arrayBuffer) {
      var base64 = '';
    
    
      var bytes = new Uint8Array(arrayBuffer);
      var byteLength = bytes.byteLength;
      var byteRemainder = byteLength % 3;
      var mainLength = byteLength - byteRemainder;
    
    
      var a, b, c, d;
      var chunk;
    
    
      // Main loop deals with bytes in chunks of 3
      for (var i = 0; i < mainLength; i = i + 3) {
        // Combine the three bytes into a single integer
        chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];
    
    
        // Use bitmasks to extract 6-bit segments from the triplet
        a = (chunk & 16515072) >> 18; // 16515072 = (2^6 - 1) << 18
        b = (chunk & 258048) >> 12; // 258048   = (2^6 - 1) << 12
        c = (chunk & 4032) >> 6; // 4032     = (2^6 - 1) << 6
        d = chunk & 63; // 63       = 2^6 - 1
    
    
        // Convert the raw binary segments to the appropriate ASCII encoding
        base64 += chars[a] + chars[b] + chars[c] + chars[d];
      }
    
    
      // Deal with the remaining bytes and padding
      if (byteRemainder == 1) {
        chunk = bytes[mainLength];
    
    
        a = (chunk & 252) >> 2; // 252 = (2^6 - 1) << 2
    
    
        // Set the 4 least significant bits to zero
        b = (chunk & 3) << 4; // 3   = 2^2 - 1
    
    
        base64 += chars[a] + chars[b] + '==';
      } else if (byteRemainder == 2) {
        chunk = (bytes[mainLength] << 8) | bytes[mainLength + 1];
    
    
        a = (chunk & 64512) >> 10; // 64512 = (2^6 - 1) << 10
        b = (chunk & 1008) >> 4; // 1008  = (2^6 - 1) << 4
    
    
        // Set the 2 least significant bits to zero
        c = (chunk & 15) << 2; // 15    = 2^4 - 1
    
    
        base64 += chars[a] + chars[b] + chars[c] + '=';
      }
    
    
      return base64;
    }
    
    
    export function decode(base64) {
      var bufferLength = base64.length * 0.75,
        len = base64.length,
        i,
        p = 0,
        encoded1,
        encoded2,
        encoded3,
        encoded4;
    
    
      if (base64[base64.length - 1] === '=') {
        bufferLength--;
        if (base64[base64.length - 2] === '=') {
          bufferLength--;
        }
      }
    
    
      var arraybuffer = new ArrayBuffer(bufferLength),
        bytes = new Uint8Array(arraybuffer);
    
    
      for (i = 0; i < len; i += 4) {
        encoded1 = lookup[base64.charCodeAt(i)];
        encoded2 = lookup[base64.charCodeAt(i + 1)];
        encoded3 = lookup[base64.charCodeAt(i + 2)];
        encoded4 = lookup[base64.charCodeAt(i + 3)];
    
    
        bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
        bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
        bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
      }
    
    
      return arraybuffer;
    }
    
    
    


    2022-02-28
    有用 1
    回复
  • LiuLiang
    LiuLiang
    2022-02-24

    兄弟们 我也遇到了 解决了

    报错了是 “Blob is not defined”

    解决方案:

    glb模型建的不对 ,找UI同学重新生成了模型,某种规格的,就可以了,代码没有改动就能渲染glb模型了。

    2022-02-24
    有用 1
    回复 5
    • 北瓜
      北瓜
      2022-03-28
      具体是啥规格?
      2022-03-28
      回复
    • 雨点
      雨点
      2022-03-28
      同问
      2022-03-28
      回复
    • 自由飞翔
      自由飞翔
      2022-07-17
      同问,能不能具体说一下需要什么规格
      2022-07-17
      回复
    • 多多
      多多
      2022-10-20
      同问,能不能具体说一下需要什么规格
      2022-10-20
      回复
    • : bq
      : bq
      2022-12-16
      听君一席话,如听一席话
      2022-12-16
      1
      回复
  • !
    2022-03-01

    同问

    2022-03-01
    有用
    回复
  • vincent
    vincent
    2022-01-12


    2022-01-12
    有用
    回复
  • Vic陈焱林
    Vic陈焱林
    2021-12-17

    同问

    2021-12-17
    有用
    回复
  • Forever
    Forever
    2020-12-22

    你是在小程序环境下的canvas开发小游戏吗?

    2020-12-22
    有用
    回复 7
    • Rick
      Rick
      2020-12-22
      我是在小程序环境下,想使用threejs去加载glb的文件,就比如想加载一个鼠标的glb文件,实现360度旋转,不知道怎么搞的我的这个帖子被转移到小游戏这边了
      2020-12-22
      回复
    • A  ^﹏^
      A ^﹏^
      2021-03-25
      解决了吗,同问,也是在小程序环境下加载了自己的gltf文件,报URL错误,和你上面改的一样,现在报这个。。。有啥办法吗
      2021-03-25
      回复
    • lpw
      lpw
      2021-04-15回复A ^﹏^
      解决了么,同样的问题
      2021-04-15
      回复
    • A  ^﹏^
      A ^﹏^
      2021-04-22回复lpw
      我截图的play报错,是下载的demo相关代码没注释,注释掉就好了。小程序不支持Blob。换个小点的gltf文件demo加载试试。应该可以。
      2021-04-22
      回复
    • 千里
      千里
      2021-05-18回复lpw
      大佬 解决了嘛,同问
      2021-05-18
      回复
    查看更多(2)
登录 后发表内容
问题标签