A comprehensive debugging and performance monitoring system for WebGPU demos, designed to help identify performance bottlenecks and analyze rendering behavior without impacting runtime performance.
The debugging system consists of two main components:
WebGPUDebugger: Core debugging class with all timing and analysis functionalityThis separation keeps the main demo classes clean while providing powerful debugging capabilities.
Once a WebGPU demo is running, you can access debugging features through the global webgpuDemo object:
// Show all available commands
webgpuDemo.help()
// Quick performance check
webgpuDemo.debugQuick()
// Start continuous monitoring
webgpuDemo.startMonitoring()
Additional utilities are available via webgpuDebugUtils:
// Quick setup
webgpuDebugUtils.quickDebug()
// Start monitoring with defaults
webgpuDebugUtils.startQuickMonitoring()
// Create performance alerts
const stopAlert = webgpuDebugUtils.createPerformanceAlert(20) // 20ms threshold
debugTiming()Comprehensive frame performance breakdown with detailed table output.
⚠️ Warning: Uses console.table() which can impact performance.
webgpuDemo.debugTiming()
debugTimingLite()Lightweight single-line timing information - performance friendly.
webgpuDemo.debugTimingLite()
// Output: ⚡ Frame: 2.45ms | Reset: 0.12ms | Behaviors: 0.34ms | ...
debugQuick()Ultra-quick performance summary for continuous monitoring.
webgpuDemo.debugQuick()
// Output: 🚀 2.5ms | 12 objects | 2.1ms avg
debugPerformanceBar()Visual performance breakdown using emoji bar charts.
webgpuDemo.debugPerformanceBar()
debugRenderOrder()Detailed render order and uniform offset analysis with tables.
⚠️ Warning: Uses console.table() which can impact performance.
debugRenderOrderLite()Lightweight render order summary.
webgpuDemo.debugRenderOrderLite()
// Output: 👁️ Visible: 8 objects | 🙈 Hidden: 2 objects
debugAll()Lightweight comprehensive debug information (recommended).
debugAllDetailed()Comprehensive debug with detailed tables (slower).
startMonitoring(intervalMs?)Start continuous performance monitoring.
webgpuDemo.startMonitoring(500) // Monitor every 500ms
stopMonitoring()Stop continuous monitoring.
toggleMonitoring()Pause/resume monitoring without stopping the timer.
debugTransparency()Comprehensive transparency sorting and culling analysis for all objects in the scene.
webgpuDemo.debugTransparency()
Shows:
debugTransparencyLite()Lightweight transparency summary.
webgpuDemo.debugTransparencyLite()
// Output: 🔮 Transparency: 3 transparent, 5 opaque, 3 no-cull
debugTransparentCulling()Test transparent material culling behavior with various material configurations.
webgpuDemo.debugTransparentCulling()
Tests culling modes for:
Set up automatic alerts when frame times exceed thresholds:
const stopAlert = webgpuDebugUtils.createPerformanceAlert(16.67) // 60fps threshold
// Automatically stops after calling stopAlert()
Record performance data over time for analysis:
const session = new webgpuDebugUtils.DebugSession()
session.start(100) // Record every 100ms
// ... let it run ...
session.stop()
session.analyze() // Get statistical analysis
const data = session.export() // Export raw data
Get performance data programmatically:
const snapshot = webgpuDebugUtils.getPerformanceSnapshot()
if (snapshot) {
console.log(`Frame time: ${snapshot.frameTime}ms`)
console.log(`Objects: ${snapshot.objectCount}`)
}
| Method Type | Performance Impact | Use Case |
|---|---|---|
*Lite() methods |
Minimal | Frequent debugging, continuous monitoring |
debugQuick() |
Minimal | Real-time monitoring |
debug*() with tables |
High | Detailed analysis, one-time debugging |
Use lightweight methods for frequent debugging
webgpuDemo.debugQuick() // ✅ Good for frequent use
webgpuDemo.debugTiming() // ❌ Avoid in loops/frequent calls
Continuous monitoring with appropriate intervals
webgpuDemo.startMonitoring(1000) // ✅ Good for general monitoring
webgpuDemo.startMonitoring(16) // ❌ Too frequent, impacts performance
Clean up monitoring
webgpuDemo.stopMonitoring() // Always stop when done
The system measures these key performance metrics:
❌ No WebGPU demo instance found. Make sure a demo is running.
Solution: Ensure a WebGPU demo is loaded and initialized. The webgpuDemo global is only available after demo initialization.
❌ No timing data
Solution: Wait for at least one frame to render. Timing data is only available after the first render call.
If debugging methods are impacting performance:
*Lite() versions of methodsconsole.table() methods (debugTiming(), debugRenderOrder())Demo classes implement this interface to expose necessary data:
interface WebGPUDebugTarget {
lastFrameTiming: FrameTimingData | null;
smoothedFrameTime: number;
canvasWidth: number;
canvasHeight: number;
isInitialized: boolean;
sceneState?: SceneState;
resourceManager?: ResourceManager;
camera?: Camera;
}
interface FrameTimingData {
resetRingBuffers: number;
applyBehaviors: number;
updateTransforms: number;
renderPassSetup: number;
renderLoop: number;
totalRenderFunction: number;
objectCount: number;
debugInfo?: Array<{
id: number;
name: string;
visible: boolean;
offset: number;
}>;
}
// Quick check
webgpuDemo.debugQuick()
// Start background monitoring
webgpuDemo.startMonitoring(1000)
// Check detailed breakdown when needed
webgpuDemo.debugTimingLite()
// Record a session
const session = new webgpuDebugUtils.DebugSession()
session.start(50) // High frequency for detailed analysis
// Run your test scenario...
// (interact with demo, change settings, etc.)
session.stop()
session.analyze() // Get statistics
// Set up alerts for different scenarios
const renderAlert = webgpuDebugUtils.createPerformanceAlert(16.67) // 60fps
const targetAlert = webgpuDebugUtils.createPerformanceAlert(8.33) // 120fps
// Run your demo...
// Clean up
renderAlert()
targetAlert()
When adding new debugging features:
WebGPUDebugger