WgpuSharp 0.3.0-alpha

This is a prerelease version of WgpuSharp.
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package WgpuSharp --version 0.3.0-alpha
                    
NuGet\Install-Package WgpuSharp -Version 0.3.0-alpha
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="WgpuSharp" Version="0.3.0-alpha" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="WgpuSharp" Version="0.3.0-alpha" />
                    
Directory.Packages.props
<PackageReference Include="WgpuSharp" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add WgpuSharp --version 0.3.0-alpha
                    
#r "nuget: WgpuSharp, 0.3.0-alpha"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package WgpuSharp@0.3.0-alpha
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=WgpuSharp&version=0.3.0-alpha&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=WgpuSharp&version=0.3.0-alpha&prerelease
                    
Install as a Cake Tool

WgpuSharp

A clean, idiomatic C# binding layer for the browser WebGPU API via Blazor WebAssembly.

Status: Alpha (0.1.0-alpha) — API surface may change.

What it does

WgpuSharp gives you typed GPU access from C# in the browser. No raw JavaScript, no verbose interop — just async C# that mirrors the WebGPU spec.

var adapter = await Gpu.RequestAdapterAsync(JS);
var device  = await adapter.RequestDeviceAsync();
var canvas  = await GpuCanvas.ConfigureAsync(device, "my-canvas");

var shader = await device.CreateShaderModuleAsync(wgslCode);
var pipeline = await device.CreateRenderPipelineAsync(descriptor);

Features

  • Rendering — vertex/index buffers, render pipelines, depth, textures, materials, PBR shading
  • Compute shaders — storage buffers, dispatch workgroups, GPU read-back
  • Mesh loading — OBJ, GLB (glTF 2.0), STL with automatic material extraction
  • Materials — PBR properties, base color textures, MTL file parsing, auto UV generation
  • Input — keyboard, mouse, pointer lock, scroll wheel
  • Instanced rendering — instance buffers with per-instance transforms
  • Batched commands — entire frame in a single JS interop call for performance
  • Game looprequestAnimationFrame-based with delta time and FPS tracking
  • Type safety — all WebGPU values use C# enums, zero magic strings
  • Resource managementIAsyncDisposable on all GPU types, automatic per-frame handle cleanup
  • Shader playground — interactive WGSL editor with 28 templates and live preview

Running the demos

git clone <repo-url>
cd WgpuSharp
dotnet run --project src/WgpuSharp.Demo

Then open http://localhost:5212 in Chrome or Edge.

On Linux, you may need to enable WebGPU: chrome://flags/#enable-unsafe-webgpu

Demo pages

Page What it shows
/triangle Hello world — vertex buffer, render pipeline, single draw call
/cube Index buffers, uniform MVP matrix, depth buffer, batched game loop
/reaction-diffusion GPU compute shaders, storage buffers, ping-pong simulation
/mesh-viewer Load .obj/.glb/.stl files with PBR materials and textures
/fly WASD + mouse look camera, 1,728 instanced cubes, pointer lock
/shader-playground Interactive WGSL editor with 28 templates, snippets, save/load

Quick start

  1. Add the NuGet package to your Blazor WASM project:

    dotnet add package WgpuSharp
    
  2. Add the JS bridge to your index.html (before the Blazor script):

    <script src="_content/WgpuSharp/WgpuSharp.js"></script>
    
  3. Add a canvas and render from a Razor component:

    @using WgpuSharp.Core
    @using WgpuSharp.Commands
    @using WgpuSharp.Pipeline
    @using WgpuSharp.Resources
    @inject IJSRuntime JS
    
    <canvas id="gpu-canvas" width="800" height="600"></canvas>
    
    @code {
        protected override async Task OnAfterRenderAsync(bool firstRender)
        {
            if (!firstRender) return;
    
            var adapter = await Gpu.RequestAdapterAsync(JS);
            var device = await adapter.RequestDeviceAsync();
            var canvas = await GpuCanvas.ConfigureAsync(device, "gpu-canvas");
    
            // Create shaders, buffers, pipelines, and render...
        }
    }
    

The batched API collects an entire frame's GPU commands and executes them in a single JS interop call, eliminating per-command async overhead:

var batch = new RenderBatch(device);
batch.WriteBuffer(uniformBuffer, mvpBytes);

var colorView = batch.GetCurrentTextureView(canvas);
var pass = batch.BeginRenderPass(colorView, clearColor, depthView);
pass.SetPipeline(pipeline);
pass.SetVertexBuffer(0, vertexBuffer);
pass.DrawIndexed(indexCount, instanceCount);
pass.EndAndSubmit();

await batch.FlushAsync(); // single JS interop call for the entire frame

Loading meshes

var meshes = MeshLoader.Load(fileBytes, "model.glb");
var buffers = await meshes[0].CreateBuffersAsync(device);

Supports OBJ (with .mtl), GLB (with embedded textures/materials), and STL. Meshes without normals get automatic flat normals. Meshes without UVs get automatic box-projected UVs when textures are applied.

Input handling

var input = await GpuInput.InitAsync(device, "gpu-canvas");

// In your game loop:
var state = await input.GetStateAsync();
if (state.IsKeyDown("KeyW")) MoveForward();
if (state.PointerLocked) Look(state.MouseDX, state.MouseDY);

Click the canvas to lock the pointer for FPS-style controls. Press Escape to release.

Architecture

C# (Blazor WASM)  →  JS Interop Bridge  →  Browser WebGPU API

All JS interop is centralised in a single bridge file. C# holds integer handles to GPU objects. The JS side is a thin executor with no logic. Per-frame handles (textures, views, encoders) are automatically cleaned up after each frame.

Project structure

WgpuSharp/
├── src/
│   ├── WgpuSharp/              # The library (NuGet package)
│   │   ├── Core/               # Gpu, GpuAdapter, GpuDevice, GpuCanvas, GpuLoop, Input, Enums
│   │   ├── Commands/           # GpuCommandEncoder, RenderPassEncoder, ComputePassEncoder, RenderBatch
│   │   ├── Resources/          # GpuBuffer, GpuTexture, GpuSampler, GpuShaderModule, GpuBindGroup
│   │   ├── Pipeline/           # GpuRenderPipeline, GpuComputePipeline, descriptors
│   │   ├── Mesh/               # OBJ/GLB/STL loaders, Mesh, Material, MtlLoader
│   │   ├── Interop/            # JsBridge, CommandBatch (internal)
│   │   └── wwwroot/            # WgpuSharp.js (static web asset)
│   └── WgpuSharp.Demo/         # Blazor WASM demo app
│       └── Pages/              # Triangle, Cube, ReactionDiffusion, MeshViewer, FlyCamera, ShaderPlayground
└── tests/
    └── WgpuSharp.Tests/        # 48 unit tests (loaders, enums, mesh ops, materials)

Building and testing

dotnet build           # Build everything
dotnet test            # Run all 48 tests
dotnet pack src/WgpuSharp/WgpuSharp.csproj -c Release  # Create NuGet package

Browser support

Requires a WebGPU-capable browser:

  • Chrome/Edge 113+ (stable)
  • Firefox Nightly (behind flag)
  • On Linux, you may need to enable chrome://flags/#enable-unsafe-webgpu

License

MIT

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.5.0-alpha 91 4/2/2026
0.3.0-alpha 66 3/25/2026
0.2.0-alpha 61 3/25/2026