From fc2d9fe610ebc41dab24e168b44e7c074bd101fa Mon Sep 17 00:00:00 2001 From: Noah Lyons Date: Fri, 29 May 2026 18:20:20 -0400 Subject: [PATCH] Handle missing HDR canvas format in particles sample --- sample/particles/main.ts | 45 ++++++++++++++++++++++++++++++++++++---- sample/util.ts | 2 +- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/sample/particles/main.ts b/sample/particles/main.ts index 89237ff6..6a7ffdbe 100644 --- a/sample/particles/main.ts +++ b/sample/particles/main.ts @@ -3,7 +3,7 @@ import { GUI } from 'dat.gui'; import particleWGSL from './particle.wgsl'; import probabilityMapWGSL from './probabilityMap.wgsl'; -import { quitIfWebGPUNotAvailableOrMissingFeatures } from '../util'; +import { fail, quitIfWebGPUNotAvailableOrMissingFeatures } from '../util'; const numParticles = 50000; const particlePositionOffset = 0; @@ -28,14 +28,48 @@ const context = canvas.getContext('webgpu'); const devicePixelRatio = window.devicePixelRatio; canvas.width = canvas.clientWidth * devicePixelRatio; canvas.height = canvas.clientHeight * devicePixelRatio; -const presentationFormat = 'rgba16float'; +const hdrPresentationFormat: GPUTextureFormat = 'rgba16float'; +let presentationFormat: GPUTextureFormat = hdrPresentationFormat; +let hasHDRCanvasFormat = true; -function configureContext() { +try { context.configure({ device, format: presentationFormat, - toneMapping: { mode: simulationParams.toneMappingMode }, + toneMapping: { mode: 'standard' }, }); +} catch (error) { + hasHDRCanvasFormat = false; + presentationFormat = navigator.gpu.getPreferredCanvasFormat(); + + try { + context.configure({ + device, + format: presentationFormat, + }); + } catch (fallbackError) { + fail( + `Unable to configure the WebGPU canvas. The HDR format '${hdrPresentationFormat}' is not supported by this browser, and configuring the preferred canvas format '${presentationFormat}' also failed.\n\n${fallbackError}` + ); + } + + console.warn( + `Canvas texture format '${hdrPresentationFormat}' is not supported by this browser. Falling back to '${presentationFormat}'.`, + error + ); +} + +function configureContext() { + const configuration: GPUCanvasConfiguration = { + device, + format: presentationFormat, + }; + + if (hasHDRCanvasFormat) { + configuration.toneMapping = { mode: simulationParams.toneMappingMode }; + } + + context.configure(configuration); hdrFolder.name = getHdrFolderName(); } @@ -336,6 +370,9 @@ function getHdrFolderName() { if (!hdrMediaQuery.matches) { return "HDR settings ⚠️ Display isn't compatible"; } + if (!hasHDRCanvasFormat) { + return "HDR settings ⚠️ Browser doesn't support HDR canvas"; + } if (!('getConfiguration' in GPUCanvasContext.prototype)) { return 'HDR settings'; } diff --git a/sample/util.ts b/sample/util.ts index 10522835..0e245af0 100644 --- a/sample/util.ts +++ b/sample/util.ts @@ -181,7 +181,7 @@ export function quitIfWebGPUNotAvailableOrMissingFeatures( } /** Fail by showing a console error, and dialog box if possible. */ -const fail = (() => { +export const fail = (() => { type ErrorOutput = { show(msg: string): void }; function createErrorOutput() {