GLB Export in a Service Context

Hello awesome BJS team and community! We are looking to import a GLB, make some changes and export a GLB in a service context (Node JS using Playwright to provide a WebGL context). We are seeing significant differences between the time required to export a GLB in a browser context and a service context. For example we have one case where we can export a GLB is 8s in a playground that takes about 47 seconds in Node JS. We wonder if this is due to lack of access to GPU hardware acceleration in the service context (AWS Fargate). From looking at the code, we notice that, in order to get the binary data for a texture, it appears that Babylon makes a call to this: WebGLRenderingContext.readPixels() - Web APIs | MDN which seems to read data from the GPU. I can imagine that this call will be much slower in a container with no GPU as it would rely on software rendering. With that background we have three questions:

  1. As you can see in this PG (by commenting in each call to importScene), GLB export time seems to scale linearly with increasing texture size. Is this expected?
  2. Can you confirm access to GPU hardware acceleration is required for optimal export performance?
  3. Given that we do not care about rendering anything, e.g. generating screenshots, do you have any recommendations on how to improve performance of GLB export in a service context? Null engine does not work in our experience because texture loading seems to require a WebGL context.

Hey!

  1. Yes as we need to read texture data
  2. THAT BEING SAID :slight_smile: We read the texture to export the UV texture transform coordinates. If you don’t need it you can probably disable that part (Adding @Drigax to keep me honest)
  3. I feel like that getting rid of texture access should be your way to go
1 Like

We read the texture to export the UV texture transform coordinates. If you don’t need it you can probably disable that part

Yup, as long as you’re exporting in a way that we can represent via the KHR_texture_Transform extension i.e:

  1. Translation only
  2. W texture Rotation only with no pivot change. (or combined with uniform scaling)
  3. Scaling only

We can export without needing to resample / render the texture

@Deltakosh @Drigax Hey guys,

So we’ve been able to figure out a solution that we believe will work. We strip out all the textures on the glb model and run it through Babylon and make our changes, then do an export. This happens really fast, as we no longer have to wait for the super long texture exports. We then manually manipulate the gltf JSON and add the textures back in manually.

HOWEVER, it required us to modify the Babylon code, as uv attributes are getting stripped within the glTFExporter.ts file. We had to remove this snippet from the setPrimitiveAttributesAsync function:

if (attributeKind === VertexBuffer.UVKind || attributeKind === VertexBuffer.UV2Kind) {
    if (glTFMaterial && !this._glTFMaterialExporter._hasTexturesPresent(glTFMaterial)) {
        continue;
    }
}

Obviously removing that check is not ideal, but can an option be added to the export functions (GLTF2Export class) to not strip out the uvs?

1 Like

I believe so. @Drigax works for you?

If @Drigax agrees, you can probably do a PR :slight_smile:

1 Like

Sure, that sounds like a great idea. Would you like to add a flag somewhere along the lines of “ExportUnusedUVs” to the IExportOptions | Babylon.js Documentation?

1 Like

Yes, that sounds perfect! Would you like me to make a pull request?

Sure!

1 Like

@Drigax PR created! Added exportUnusedUVs property to the IExportOptions interface by ericbroberic · Pull Request #10290 · BabylonJS/Babylon.js · GitHub

1 Like