How to call BABYLON.CubeTexture.CreateFromPrefilteredData with cached .env files?

hi,

I have an app that downloads env files and store in cache:

        const blob = await res.blob();

        // Store the blob in browser's temp storage (Cache API)
        const cache = await caches.open("env-blob-cache");
        const cacheUrl = `/env-cache/${filename}`;
        await cache.put(cacheUrl, new Response(blob, { headers: { "Content-Type": blob.type } }));

Then I’d like to use this file in CreateFromPrefilteredData. Copilot suggested to override Tools.LoadFile:

if (!(window as any).__env_cache_hooked) {
  (window as any).__env_cache_hooked = true;
  const origLoadFile = BABYLON.Tools.LoadFile;
  BABYLON.Tools.LoadFile = function (
    url: string,
    onSuccess: (data: string | ArrayBuffer, responseURL?: string) => void,
    onProgress?: (data: any) => void,
    offlineProvider?: BABYLON.IOfflineProvider,
    useArrayBuffer?: boolean,
    onError?: (request?: BABYLON.WebRequest, exception?: any) => void
  ): BABYLON.IFileRequest {
    if (url.startsWith("/env-cache/")) {
      console.log("Loading environment from cache:", url);
      caches.open("env-blob-cache").then(cache => {
        cache.match(url).then(response => {
          if (response) {
            console.log("Found in cache:", url);
            // Always return ArrayBuffer for .env files
            response.arrayBuffer().then(buffer => {
              console.log("Returning cached ArrayBuffer for:", url);
              onSuccess(buffer, url);
            });
          } else {
            if (onError) onError(undefined, "Not found in cache: " + url);
          }
        });
      });
      // Return a dummy IFileRequest object with required properties
      return {
        abort: () => { /* no-op */ },
        onCompleteObservable: {
          add: () => {},
          remove: () => {},
          hasObservers: () => false,
          clear: () => {},
        } as unknown as BABYLON.Observable<any>
      };
    }
    // Otherwise, fallback to original loader
    return origLoadFile.call(
      BABYLON.Tools,
      url,
      onSuccess,
      onProgress,
      offlineProvider,
      useArrayBuffer,
      onError
    );
  };
}

But CreateFromPrefilteredData still fails with error: Not a babylon environment map.

I think you could get the blob back from the cache and create a url from the blob with var blobURL = URL.createObjectURL(blob); and load from there ?

1 Like

That doesn’t work. URL.createObjectURL(…) creates something like “http://localhost:8888/07014591-ce72-4ee8-99e3-aa7a18075464”, passing that to CreateFromPrefilteredData results in error: Failed to load environment texture: Cannot load cubemap because files were not defined, or the correct loader was not found.

You can use nee CubeTexture… instead and precise the forcedExtension to .env in this case

Thanks, that works