- Added WebGPUContext class to manage WebGPU initialization and resource creation. - Created main_webgl.ts for WebGL rendering setup and scene management. - Introduced WGSL shaders for Perlin noise generation and ocean rendering. - Implemented vertex and fragment shaders for ocean surface displacement and lighting effects. - Enhanced camera controls and rendering logic for improved user experience.
5.9 KiB
5.9 KiB
WebGPU Migration Complete
Overview
Successfully migrated the WebOcean project from WebGL2 to WebGPU to enable future tessellation support for the ocean grid system.
What Changed
Files Converted to WebGPU:
-
Grid.ts
- Replaced WebGL VAO/VBO with GPUBuffer
- Updated
initVAO()→initBuffers(gpuContext: WebGPUContext) - Changed
draw(gl: WebGL2RenderingContext)→draw(renderPass: GPURenderPassEncoder) - Uses
mappedAtCreationpattern for buffer initialization
-
Skybox.ts
- Same conversion pattern as Grid
- Replaced WebGL buffers with GPUBuffer
- Updated draw method signature for WebGPU
-
main.ts (renamed from main_webgpu.ts)
- Replaced
initGL()with asyncinitWebGPU() - Created three render pipelines:
- Noise generation pipeline (renders Perlin noise to texture)
- Ocean rendering pipeline (vertex displacement from noise texture)
- Skybox pipeline (gradient sky with sun)
- Converted FBO to GPUTexture for render-to-texture
- Updated all shader bindings to use WebGPU bind groups
- Maintains all existing features:
- Dual camera system (Orbital + FPS)
- Animation controls (P pause, 0-5 speed)
- Wireframe toggle (F key)
- Camera switching (C key)
- Full WASD + mouse controls
- Replaced
New Files Created:
-
WebGPUContext.ts
- Centralized GPU device/adapter/context management
- Provides helper methods for creating buffers, textures, pipelines
- Handles WebGPU initialization and configuration
-
shaders.wgsl.ts
- All GLSL shaders converted to WGSL format
- Exports 6 shader strings:
noiseVertexShader- fullscreen quad for noise generationnoiseFragmentShader- 5-octave Perlin noiseoceanVertexShader- vertex displacement from textureoceanFragmentShader- normal calculation, Fresnel, SSS, glitterskyboxVertexShader- skybox cube renderingskyboxFragmentShader- gradient sky with sun
Preserved Files:
- main_webgl.ts (backup)
- Original WebGL2 implementation preserved for reference
- Excluded from TypeScript compilation
Configuration Updates:
-
tsconfig.json
- Added
"types": ["@webgpu/types"]for WebGPU type definitions - Excluded
main_webgl.tsfrom compilation
- Added
-
package.json
- Added
@webgpu/typesdev dependency
- Added
-
index.html
- Added frame time display (
<div id="frame-time">) - Kept GLSL shader script tags (not used, can be removed later)
- Added frame time display (
WebGPU vs WebGL2 Architecture
Key Differences:
| Aspect | WebGL2 | WebGPU |
|---|---|---|
| Buffers | VAO/VBO with gl.createVertexArray() | GPUBuffer with device.createBuffer() |
| Shaders | GLSL with gl.createProgram() | WGSL with device.createShaderModule() |
| Rendering | Direct gl.drawArrays() calls | Command encoder → render pass → submit |
| Textures | gl.createTexture() + gl.texImage2D() | device.createTexture() |
| State | Implicit state machine (gl.enable/disable) | Explicit pipeline state in descriptors |
| Uniforms | gl.uniformMatrix4fv() per draw | Uniform buffers + bind groups |
Rendering Pipeline:
Pass 1: Noise Generation
1. Write time uniform to buffer
2. Create command encoder
3. Begin render pass with noiseTexture as target
4. Set noise pipeline
5. Set noise bind group (contains time uniform)
6. Draw fullscreen quad (6 vertices)
7. End pass and submit commands
Pass 2: Scene Rendering
1. Update camera uniforms (view, model, projection, eyePos)
2. Update skybox uniforms (view, projection, sunDir)
3. Create command encoder
4. Begin render pass with canvas + depth texture
5. Draw skybox:
- Set skybox pipeline (no depth write, no culling)
- Set skybox bind group
- Draw skybox geometry
6. Draw ocean:
- Set ocean pipeline (depth write, back-face culling)
- Set ocean bind group (contains uniforms + noise texture + sampler)
- Draw ocean grid (wireframe or solid)
7. End pass and submit commands
Browser Compatibility
- Requires: Chrome/Edge 113+, Firefox 130+ (with flag)
- Not supported: Safari (as of December 2024)
- Shows error alert if WebGPU not available
Testing Checklist
✅ Build succeeds without TypeScript errors ✅ Dev server starts successfully ✅ WebGPU initialization completes ✅ Dual camera system functional ✅ Animation controls work (pause/play/speed) ✅ Wireframe toggle functional ✅ Mouse camera controls responsive ✅ Keyboard FPS camera controls work
Next Steps - Tessellation
Now that WebGPU migration is complete, tessellation can be implemented:
- Hull Shader - Define tessellation factors based on camera distance
- Domain Shader - Interpolate tessellated vertices
- Dynamic LOD - Increase subdivision near camera, reduce far away
- Adaptive Tessellation - More detail in areas with high wave displacement
This will provide:
- Smoother ocean surface at all zoom levels
- Better performance (fewer vertices far from camera)
- More geometric detail for displacement mapping
- Hardware-accelerated mesh subdivision
Files Modified Summary
- ✅ Grid.ts - WebGPU buffer conversion
- ✅ Skybox.ts - WebGPU buffer conversion
- ✅ main.ts - Complete WebGPU rendering pipeline
- ✅ WebGPUContext.ts - New GPU management class
- ✅ shaders.wgsl.ts - New WGSL shader definitions
- ✅ tsconfig.json - Added WebGPU types
- ✅ index.html - Added frame time display
- 📦 main_webgl.ts - Backup (excluded from build)
Performance Notes
- FPS display shows frame rate
- Frame time display shows milliseconds per frame
- Animation speed control (1x-5x)
- Pause/play functionality preserved
- WebGPU generally faster than WebGL2 for complex scenes