-
Notifications
You must be signed in to change notification settings - Fork 32
Port to native WebGPU: 1M flights @ 75 FPS #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
teamchong
wants to merge
49
commits into
jeantimex:main
Choose a base branch
from
teamchong:teamchong/port-to-webgpu
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- Add WebGPUContext.ts for native WebGPU initialization - Replace Three.js WebGLRenderer with WebGPU device/context - Add depth texture management with resize handling - Implement error detection for unsupported browsers - Rename old App.ts to App.legacy.ts (preserve Three.js code) - Add gl-matrix for camera math (no Three.js dependency) - Add @webgpu/types for TypeScript support - Security: Use textContent to prevent XSS in error messages Targets 1M flights with 1GB GPU buffer limits.
- Add PerspectiveCamera class using gl-matrix - Add OrbitControls with mouse drag and wheel zoom - Integrate camera and controls into App.ts - Fix zoom calculation bug in OrbitControls - Remove unnecessary view matrix update in setAspect
- Add SphereGeometry generator with interleaved vertices - Add TextureLoader for WebGPU textures with flipY support - Add earth.wgsl shader with Phong lighting - Add EarthWebGPU renderer class - Integrate Earth into App.ts render loop - Add vite-env.d.ts for WGSL module types - Optimize: reuse uniform buffer per frame (avoid allocations)
- Add stars.wgsl shader with instanced billboards - Add StarsWebGPU renderer class (5000 stars) - Integrate stars into App.ts render loop - Use additive blending for twinkling effect - Camera-facing quads with circular shape - Optimize: reuse uniform buffer per frame
- Add atmosphere.wgsl shader with rim lighting - Add AtmosphereWebGPU renderer class (1.25x Earth radius) - Integrate atmosphere into App.ts render loop - Use additive blending for atmospheric glow - Fix rim lighting: use world-space normals with camera direction - Optimize: reuse uniform buffer per frame
- 88MB total (optimized with packed buffers) - Control points: 48MB (4 vec3 per flight) - Flight state: 16MB PACKED (t, speed, packedColor, packedSizeFlags) - Output buffer: 24MB (position, direction) - Memory bandwidth: 6.2 GB/s (1-3% GPU usage) - Target: <5ms compute per frame (200fps budget) - Workgroup size: 64 threads (15,625 workgroups) - Packed color: RGBA8 (8-bit per channel) - Packed size/flags: 16-bit each
- Add WGSL compute shader with Catmull-Rom curve interpolation - Create FlightManager class for buffer management and dispatch - Support 1M flights with 64-thread workgroups (15,625 workgroups) - Return flight logic with proper reflection and drift prevention - Memory: 88MB total (48MB control points, 16MB state, 32MB output) - Target: <5ms compute per frame (200fps budget)
- Add AtlasLoader for packing 8 SVGs into 4×2 texture atlas - Create planes.wgsl shader with direction-oriented billboards - Implement PlanesWebGPU renderer with atlas support - Pack texture index in FlightManager state buffer (bits 8-15) - Orient planes along flight direction (not camera-facing) - Memory: 2048×1024 atlas (~8MB), single draw call for 1M planes - Update docs with texture index packing format
- Add CurveManager for GPU-accelerated curve tessellation - Create compute shader for Catmull-Rom curve generation - Add render pipeline for line-strip rendering with gradients - Fix plane orientation to align nose with flight direction - Fix return flight direction by flipping when speed is negative - Refactor control point generation with named constants and helpers - Add lateral bulge perpendicular to great circle for curved paths Performance: 32 segments per curve, tessellated on GPU Memory: ~1MB per 1K flights for line vertices
- Add ControlsWebGPU with full dat.GUI interface matching legacy version - Implement 1M flight pre-allocation with real-time slider (1K-1M range) - Add atmosphere visibility toggle control - Fix WebGPU workgroup dispatch limits using 2D dispatch for >65K workgroups - Add flight count debouncing (100ms) to prevent rapid slider changes - Update all managers to use visibleFlightCount vs total flightCount
- Add sun position calculation based on UTC time and day of year - Implement dynamic day/night lighting in earth.wgsl shader - Add smooth terminator transition using smoothstep - Wire up all Earth controls in GUI (all now functional): * Day/Night Effect toggle * Real-time Sun toggle with continuous updates * Time slider (0-24 hours UTC) * Time display textbox (editable) * Reset Sun Position button * Day/Night brightness controls (0-100%) - Add real-time sun updates in render loop - Expand uniform buffer from 240 to 256 bytes - Match legacy lighting-based approach (no separate textures)
- Add distance field to line vertices for arc length tracking - Calculate cumulative distance in curveTessellation compute shader - Approximate arc length using 10-sample method along Catmull-Rom curve - Add dashSize and gapSize uniforms to curves shader - Implement fragment discard in gaps using modulo arithmetic - Wire up Dash Size and Gap Size controls in GUI (0-100 range) - Default to solid lines (dashSize = 0) - Update vertex attribute layout to include distance at offset 12
…, Plane Color) Adds three missing plane controls to match legacy version functionality. Animation speed multiplier applied globally in compute shader (0.01-1.0 range, default 0.1). Elevation offset renders planes above flight paths radially (0-100 range). Plane color override tints SVG gray parts with selected color (default #ff6666), enabled by default. Fixed uniform buffer alignment for vec3 (16-byte boundary) and corrected paint mask from linear 0.6939 to sRGB 0.851.
Adds plane style control to switch between SVG (textured sprites with unified color) and Pane (solid colored quads with random colors per plane). Fixed race condition where async texture loading could override Pane mode. Both loadPlaneTexture() and setAtlas() now respect current planeStyle state. Default to SVG mode matching legacy behavior.
Performance improvements for 1M flights (19 FPS → target 60 FPS): - GPU-side counter reset: New clearCounter.wgsl shader eliminates CPU-GPU sync bottleneck from writeBuffer call (PlanesWebGPU.ts:435) - Increased workgroup size: 64 → 256 threads per workgroup in visibilityCull.wgsl:49, reducing dispatch overhead from 15,625 to 3,906 workgroups for 1M flights - Added clearCounterPipeline to reset atomic counter on GPU before visibility culling pass (PlanesWebGPU.ts:394-422) - Modified cullVisibility() to dispatch clear pass before visibility pass (PlanesWebGPU.ts:432-437) Technical details: - clearCounter.wgsl: Single-thread workgroup that atomically resets counter and drawArgs.instanceCount - visibilityCull.wgsl: Increased @workgroup_size(256) and updated dispatch calculation in PlanesWebGPU.ts:446 - No new buffers allocated (reuses atomicCounterBuffer and drawArgsBuffer)
Batched curve rendering from 1M draw calls to single call using line-list topology. Performance results: - Before: 19 FPS (1M draw calls per frame) - After curves batched: 87 FPS (single draw call) - After indirect rendering: 89 FPS (GPU-driven culling) Changes: 1. Curve batching (main optimization): - curveTessellation.wgsl: Generate line-list vertex pairs (2 per segment) - CurveManager.ts: Changed topology line-strip → line-list - CurveManager.ts:326: Replaced loop with single draw call 2. Indirect rendering (minor gain): - planes.wgsl: Read from compacted visibleIndices buffer - PlanesWebGPU.ts: Enabled useIndirectRendering flag - Visibility culling compacts visible flights on GPU - DrawIndirect skips vertex shader for culled flights Technical details: - Line-list topology: Each segment = 2 vertices (vs line-strip: N+1 for N segments) - Indirect rendering adds compute overhead but saves vertex work when zoomed in - 89 FPS represents 4.7x improvement from baseline
Complete WebGPU migration documentation: - Browser support matrix (Chrome 113+, Safari 26+, Firefox 141+) - Comprehensive testing checklist (functionality, performance, visual, GUI) - Cross-browser testing instructions - Known issues and debugging steps - Performance profiling guidance CLAUDE.md updated locally (gitignored) with: - Complete WebGPU architecture documentation - Performance benchmarks (89 FPS @ 1M flights) - Compute + render pipeline details - WGSL shader architecture - Optimization strategies - Development guidelines
Implemented shader-based backface culling to hide curves on far side of Earth. Benefits: - Renders ALL curves on visible hemisphere (no missing gaps) - Culls ~50% of vertices (back side of Earth) - Maintains 87 FPS performance Implementation: - curves.wgsl: Dot product test between curve point and camera direction - Threshold: -0.1 to avoid edge artifacts - CurveManager: Passes camera position to shader each frame Result: Same performance as before but with complete curve coverage on visible side.
Extended backface culling to planes for additional performance gain. Planes now check both: 1. Distance culling (existing): within 20000 units 2. Hemisphere culling (NEW): on visible side of Earth Implementation: - flightUpdate.wgsl: Dot product test in visibility flag logic - Culls ~50% of planes on far side of Earth at full view - Works with indirect rendering (compacts visible indices) Result: 11 FPS improvement (87 → 98 FPS at 1M flights)
…unts Replace all-or-nothing curve skipping with intelligent decimation that maintains visual detail across all flight counts. At 1M flights, shows 50K curves distributed evenly (every 10th curve) with 4 segments each, achieving 95 FPS while keeping paths visible everywhere on Earth. - Add calculateLOD() helper to compute segments and decimation factor - Cap at 50K curves max for performance budget - Reduce segment count based on visible flight estimate - Distribute curves evenly using modulo decimation in shader - Refactor to eliminate code duplication between tessellate/render Performance: 95 FPS at 1M flights (vs 100 FPS with no curves)
Adjust LOD thresholds to use minimum 2 segments at very high flight counts (>800K flights). This reduces rendering workload by 50% at 1M flights while maintaining curve visibility everywhere on Earth. LOD thresholds updated: - ≤200K visible: 16 segments - ≤500K visible: 8 segments - ≤800K visible: 4 segments - >800K visible: 2 segments (straight line approximation) Performance: 104 FPS at 1M flights (vs 95 FPS with 4 segments) Visual trade-off: Curves become straight lines at extreme counts
Lower MAX_CURVES from 50K to 20K to reduce rendering workload while maintaining visual coverage across the globe. Curves remain distributed evenly at all flight counts, just with lower density at extreme scales. At 1M flights: - 20K curves shown (vs 50K previously) - 80K vertices rendered (vs 120K) - 33% reduction in rendering workload - Maintains 120 FPS performance target Trade-off: Sparser curve density but still visible everywhere
Precompute normalized camera direction on CPU once per frame instead of computing it 125K times in GPU shader (125K visible flights with 1/8 temporal stagger). Changes: - Add cameraDirection field to flight update uniforms (vec3) - Compute normalize(cameraPosition) once on CPU in FlightManager - Use precomputed direction in shader visibility check - Add UNIFORM_BUFFER_SIZE constant for maintainability - Expand uniform buffer from 32 to 48 bytes Expected performance gain: ~5-10 FPS by reducing GPU math operations
Eliminates separate tessellation pass by merging curve vertex generation into flight position update shader. Expected performance gain: +20-30 FPS by halving GPU memory reads and reducing compute overhead.
Adds GUI control to toggle between random flight colors and single color override. Random colors enabled by default. Plane color picker automatically disabled when random colors is on.
With merged shader performance gains, relaxed aggressive optimizations for better quality: - Temporal stagger: 1/8 → 1/4 (smoother animation, 250K updates/frame) - Curve budget: 20K → 50K MAX_CURVES (2.5x more curves shown) - LOD quality: 16→8→4→2 segments → 32→24→16→8 segments (4x better at high counts) - Full detail maintained up to 300K flights (previously 40K)
Changed animation speed defaults and range: - GUI default: 0.1 → 1.0 - GUI max: 1.0 → 2.0 - Flight generation: 0.05-0.2 → 0.5-1.5 (centered at 1.0)
Controls improvements: - Decreased zoom speed: 0.1 → 0.05 (2x slower scroll) - Added keyboard controls: Arrow keys (rotate), +/- (zoom) Performance optimization: - Reverted LOD segments: 32→24→16→8 → 16→8→4→2 (original) - Result: 120 FPS (33% improvement from 90 FPS) - MAX_CURVES still at 50K (2.5x more curves than original)
Earth fixes: - Fixed upside-down texture: flipY true → false - Render both sides: cullMode 'back' → 'none' Camera fixes: - Limit polar rotation: 5% to 95% (prevent looking directly at poles) - Add position safety check to prevent camera going inside Earth sphere - Fixes blackout when rotating to north/south poles
- Add footer with 'Made by jeantimex' and GitHub link - Add real-time lat/lng coordinate display - Add smooth camera zoom-in animation on startup - Fix camera position initialization (lat 12.05°, lng -26.22°) - Create OrbitControls after animation to prevent camera jump - Make atmosphere thinner (1.025x radius) and lighter (70% reduction) - Increase flight path line thickness (1.0 -> 3.0) - Adjust speed scale (GUI 0.1 = actual 1.0, GUI 1.0 = actual 10.0) - Reorder GUI controls: Flight > Path > Plane > Earth > Brightness - Set all GUI folders to open by default - Optimize camera distances for better Earth size
- Adjust atmosphere scale to 1.08 for better visibility - Use main branch shader formula with edge fade (power 2.5) - Reduce intensity to 0.7 for softer outer edges - Creates smooth gradient with transparent outer fade
- Reduce minAltitude from 30 to 10 - Reduce maxAltitude from 220 to 50 - Paths now hug Earth's curvature like main branch
- Reduce BULGE_MIN from 20% to 5% - Reduce BULGE_MAX from 40% to 15% - Reduce BULGE_INFLUENCE from 0.5 to 0.3 - Paths now hug Earth curvature instead of high arcs
- Reduce nightBrightness from 15 to 8 - Reduce dayBrightness from 80 to 50 - More subtle day/night effect
- Update sun direction calculation to use proper spherical coordinate conversion with rotation matrix (matching latLngToVector3 from main) - Add /3.0 brightness divisor to reduce overall day/night intensity - Restore control defaults to 80/15 for consistency with main - Update camera initial longitude from -26.22° to -17.55°
- Replace 4-point Catmull-Rom curves with 9-point parabolic curves - Update shader to use piecewise linear interpolation through 9 points - Generate all 9 control points: startTangent, startSurface, climbPoint1/2, cruisePeak, descentPoint1/2, endSurface, endTangent - Increase altitude values to match main (minAltitude: 30, maxAltitude: 220) - Change default flight count from 1000 to 5000 to match main - Update GUI ranges: dash/gap max 2000, plane size 5-500, animation speed max 0.5 - Fix initial dash pattern application (40/40 now renders correctly on load) - Update buffer allocation from 64 to 144 bytes per flight (9 vec4s)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Complete rewrite using native WebGPU (removed Three.js dependency). Handles 1 million simultaneous flight paths at 89 FPS.
Key Changes
Performance
Browser Support
Requires WebGPU:
Testing
See
BROWSER_COMPATIBILITY.mdfor testing checklist.Demo
2025-10-22.at.13.07.33.-.Coffee.Aardwolf.mp4
It can be up to 150 FPS, but for some reason now capped at 75 FPS
Note: Do this for fun / learning WebGPU!