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:
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?
Can you confirm access to GPU hardware acceleration is required for optimal export performance?
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.
THAT BEING SAID 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)
I feel like that getting rid of texture access should be your way to go
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?
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?
@dongqui I just saw this. Using playwright or puppeteer works great when running on a server. Even when the server doesn’t have a GPU, chromium uses a software renderer and almost everything works flawlessly. The one area where we found things to be super slow was doing any sort of export. That was due to the textures being included in the model we wanted to export, and because it was running on a software renderer, took absolutely forever to export. For that part, we needed to strip out all the textures and then reapply them after the babylon export to get it to work.
If you’re just looking to do something like capturing a screenshot, then you probably don’t need to deal with that last part. Hope that helps!