Files
WebOcean/WEBGPU_MIGRATION.md
Gulum 260c6e7bc0 feat: Implement WebGPU context manager and shaders for ocean rendering
- 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.
2026-02-06 21:12:49 +01:00

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:

  1. Grid.ts

    • Replaced WebGL VAO/VBO with GPUBuffer
    • Updated initVAO()initBuffers(gpuContext: WebGPUContext)
    • Changed draw(gl: WebGL2RenderingContext)draw(renderPass: GPURenderPassEncoder)
    • Uses mappedAtCreation pattern for buffer initialization
  2. Skybox.ts

    • Same conversion pattern as Grid
    • Replaced WebGL buffers with GPUBuffer
    • Updated draw method signature for WebGPU
  3. main.ts (renamed from main_webgpu.ts)

    • Replaced initGL() with async initWebGPU()
    • 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

New Files Created:

  1. WebGPUContext.ts

    • Centralized GPU device/adapter/context management
    • Provides helper methods for creating buffers, textures, pipelines
    • Handles WebGPU initialization and configuration
  2. shaders.wgsl.ts

    • All GLSL shaders converted to WGSL format
    • Exports 6 shader strings:
      • noiseVertexShader - fullscreen quad for noise generation
      • noiseFragmentShader - 5-octave Perlin noise
      • oceanVertexShader - vertex displacement from texture
      • oceanFragmentShader - normal calculation, Fresnel, SSS, glitter
      • skyboxVertexShader - skybox cube rendering
      • skyboxFragmentShader - gradient sky with sun

Preserved Files:

  1. main_webgl.ts (backup)
    • Original WebGL2 implementation preserved for reference
    • Excluded from TypeScript compilation

Configuration Updates:

  1. tsconfig.json

    • Added "types": ["@webgpu/types"] for WebGPU type definitions
    • Excluded main_webgl.ts from compilation
  2. package.json

    • Added @webgpu/types dev dependency
  3. index.html

    • Added frame time display (<div id="frame-time">)
    • Kept GLSL shader script tags (not used, can be removed later)

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:

  1. Hull Shader - Define tessellation factors based on camera distance
  2. Domain Shader - Interpolate tessellated vertices
  3. Dynamic LOD - Increase subdivision near camera, reduce far away
  4. 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

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