fix(editor): decompress compressed textures on GLB export (#435)
three r184's GLTFExporter throws 'setTextureUtils() must be called' when a scene contains KTX2/basis-compressed textures. Wire up WebGPUTextureUtils (matching the app's WebGPURenderer) so compressed textures are decompressed during GLB export. decompress() is called without the live renderer on purpose: it resizes whatever renderer it is given and never restores it, which would corrupt the visible canvas. Omitting it lets three create and dispose its own throwaway renderer for the blit. Reworked from #435 (anton-pascal); switches WebGL->WebGPU utils and avoids the live-renderer resize gotcha surfaced in review. Co-authored-by: Open Pascal <open@pascal.app>
This commit is contained in:
@@ -7,6 +7,7 @@ import type { Mesh, Object3D } from 'three'
|
||||
import { GLTFExporter } from 'three/examples/jsm/exporters/GLTFExporter.js'
|
||||
import { OBJExporter } from 'three/examples/jsm/exporters/OBJExporter.js'
|
||||
import { STLExporter } from 'three/examples/jsm/exporters/STLExporter.js'
|
||||
import * as WebGPUTextureUtils from 'three/examples/jsm/utils/WebGPUTextureUtils.js'
|
||||
|
||||
export function ExportManager() {
|
||||
const scene = useThree((state) => state.scene)
|
||||
@@ -43,6 +44,18 @@ export function ExportManager() {
|
||||
// Default: GLB export (existing behavior)
|
||||
const exporter = new GLTFExporter()
|
||||
|
||||
// Compressed (KTX2/basis) textures must be decompressed during export or
|
||||
// three r184's GLTFExporter throws "setTextureUtils() must be called".
|
||||
// The app renders with WebGPURenderer, so use the WebGPU texture utils.
|
||||
// We intentionally do NOT pass the live renderer: decompress() resizes
|
||||
// whatever renderer it's given (and never restores it), which would
|
||||
// corrupt the visible canvas. Omitting it lets three spin up and dispose
|
||||
// its own throwaway renderer for the blit instead.
|
||||
exporter.setTextureUtils({
|
||||
decompress: (texture, maxTextureSize) =>
|
||||
WebGPUTextureUtils.decompress(texture, maxTextureSize),
|
||||
})
|
||||
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
exporter.parse(
|
||||
exportScene,
|
||||
|
||||
Reference in New Issue
Block a user