moistCash
moistCash

Reputation: 29

How to export multiple varying 3d scenes with GLTFExporter in react-three-fiber

I'm trying to create multiple 3d models of a cube varying in the texture used on the faces of each using react-three-fiber. I would like them exported as gltf files.

I have been using this --- Exporting scene in GLTF format from react-three-fiber --- as a guideline. I have the ref component and callback, however I'm not sure how to call GLTFExporter with, say, a button, so that it exports a cube with different faces every time (until the options from a given directory runs out). I also have one scene I am able to export as example for now.

Ideally, I would like to have a directory for the different cubes, and the GLTFExporter "button" would access a different folder from there with the different faces each time.

Upvotes: 0

Views: 736

Answers (1)

Don McCurdy
Don McCurdy

Reputation: 12000

A bit different than the solution you suggested, but a similar option would be to first export the scene from GLTFExporter and then generate permutations of the glTF file afterward:

import { WebIO } from '@gltf-transform/core';
import { KHRONOS_EXTENSIONS } from '@gltf-transform/extensions';

const exporter = new THREE.GLTFExporter();

// NOTE: three.js r135 will change method signature here...
//   scene, onLoad, options → scene, onLoad, onError, options
exporter.parse(scene, (glb) => createVariations(glb), {binary: true});

async function createVariations (glb) {
  const io = new WebIO().registerExtensions(KHRONOS_EXTENSIONS);
  const document = io.readBinary(glb);
  
  // assign a blank texture to all materials' base color
  const texture = document.createTexture();
  for (const material of document.getRoot().listMaterials()) {
    material.setBaseColorTexture(texture);
  }

  for (const textureURL of MY_TEXTURE_URLS) {
    // load each texture and attach it.
    const image = await fetch(textureURL).then((r) => r.arrayBuffer());
    texture.setImage(image).setMimeType('image/png'); // or 'image/jpeg'


    // write this variant of the GLB
    const variantGLB = io.writeBinary(document); // → ArrayBuffer
  }
}

The same thing could be done offline in a script, using NodeIO instead of WebIO.

Upvotes: 2

Related Questions