From 25dc8d01732628a597c40fe4ccab7e75662da2fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Beaufort?= Date: Wed, 7 May 2025 11:29:21 +0200 Subject: [PATCH 1/2] Prevent image flash when switching between texture formats --- sample/volumeRenderingTexture3D/main.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sample/volumeRenderingTexture3D/main.ts b/sample/volumeRenderingTexture3D/main.ts index b5a4c0fc..86748556 100644 --- a/sample/volumeRenderingTexture3D/main.ts +++ b/sample/volumeRenderingTexture3D/main.ts @@ -130,10 +130,11 @@ const uniformBuffer = device.createBuffer({ }); let volumeTexture: GPUTexture | null = null; +let isVolumeTextureReady = false; // Fetch the image and upload it into a GPUTexture. async function createVolumeTexture(format: GPUTextureFormat) { - volumeTexture = null; + isVolumeTextureReady = false; const { blockLength, bytesPerBlock, dataPath, feature } = brainImages[format]; const width = 180; @@ -172,6 +173,8 @@ async function createVolumeTexture(format: GPUTextureFormat) { { bytesPerRow: bytesPerRow, rowsPerImage: blocksHigh }, [width, height, depth] ); + await device.queue.onSubmittedWorkDone(); + isVolumeTextureReady = true; } await createVolumeTexture(params.textureFormat); @@ -260,7 +263,7 @@ function frame() { const commandEncoder = device.createCommandEncoder(); const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor); - if (volumeTexture) { + if (isVolumeTextureReady) { bindGroupDescriptor.entries[2].resource = volumeTexture.createView(); const uniformBindGroup = device.createBindGroup(bindGroupDescriptor); passEncoder.setPipeline(pipeline); From 4db04361a22c9fad99304a2e41e98a1e977ac04b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Beaufort?= Date: Thu, 8 May 2025 07:42:18 +0200 Subject: [PATCH 2/2] Address gregg's feedback --- sample/volumeRenderingTexture3D/main.ts | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/sample/volumeRenderingTexture3D/main.ts b/sample/volumeRenderingTexture3D/main.ts index 86748556..a6e75d78 100644 --- a/sample/volumeRenderingTexture3D/main.ts +++ b/sample/volumeRenderingTexture3D/main.ts @@ -130,11 +130,10 @@ const uniformBuffer = device.createBuffer({ }); let volumeTexture: GPUTexture | null = null; -let isVolumeTextureReady = false; // Fetch the image and upload it into a GPUTexture. async function createVolumeTexture(format: GPUTextureFormat) { - isVolumeTextureReady = false; + volumeTexture = null; const { blockLength, bytesPerBlock, dataPath, feature } = brainImages[format]; const width = 180; @@ -151,13 +150,6 @@ async function createVolumeTexture(format: GPUTextureFormat) { status.textContent = ''; } - volumeTexture = device.createTexture({ - dimension: '3d', - size: [width, height, depth], - format: format, - usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST, - }); - const response = await fetch(dataPath); // Decompress the data using DecompressionStream for gzip format @@ -166,15 +158,20 @@ async function createVolumeTexture(format: GPUTextureFormat) { const decompressedArrayBuffer = await new Response( decompressedStream ).arrayBuffer(); - const byteArray = new Uint8Array(decompressedArrayBuffer); + + volumeTexture = device.createTexture({ + dimension: '3d', + size: [width, height, depth], + format: format, + usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST, + }); + device.queue.writeTexture( { texture: volumeTexture }, - byteArray, + decompressedArrayBuffer, { bytesPerRow: bytesPerRow, rowsPerImage: blocksHigh }, [width, height, depth] ); - await device.queue.onSubmittedWorkDone(); - isVolumeTextureReady = true; } await createVolumeTexture(params.textureFormat); @@ -263,7 +260,7 @@ function frame() { const commandEncoder = device.createCommandEncoder(); const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor); - if (isVolumeTextureReady) { + if (volumeTexture) { bindGroupDescriptor.entries[2].resource = volumeTexture.createView(); const uniformBindGroup = device.createBindGroup(bindGroupDescriptor); passEncoder.setPipeline(pipeline);