在Nextjs使用WebGPU

本文详细介绍了如何在Next.js项目中集成WebGPU,包括安装依赖、配置环境、编写并使用WGSLshader,以及创建和绘制三角形的过程。作者还分享了使用Uniform和Storagebuffer的不同方法以及它们的性能差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在博客搭建起来之前,暂用CSDN记录一下WebGPU的学习过程

Mark的一些有用的资源

WebGPU

  1. W3C官方文档
  2. 中文翻译

WGSL语言

  1. WGSL官方文档
  2. WGSL中文翻译
  3. Google的WGSL tour

Demo

  1. 官方Demo

Tutorial

  1. webgpufundamentals

使用Nextjs以及配置基础环境

  1. 首先安装nextjs脚手架,注意需要使用typescript,CSS按需是否使用TailWind
    新建nextjs项目

  2. 安装WebGPU需要用到的依赖npm install @webgpu/types

  3. 配置项目,因为webgpu需要用到WGSL去写shader,因此需要将wgsl文件转换为纯文本引入,这里使用ts-shader-loader,需要安装 npm install ts-shader-loader

  4. 之后在next.config.(m)js中进行配置

    /** @type {import('next').NextConfig} */
    const nextConfig = {
         
        reactStrictMode: false,
        webpack: (config) => {
         
    
            // shaders loader
            config.module.rules.push({
         
                test: /\.(wgsl|glsl|vs|fs)$/,
                loader: 'ts-shader-loader'
            })
    
            return config
        },
    }
    export default nextConfig;
    
  5. 在src目录先创建wgsl.d.ts文件,增加对于.wgsl文件类型的描述,将其全部转换为string类型导入

    declare module '*.wgsl'
    {
         
    	const value: string;
    	export default value;
    }
    
  6. 在src目录下创建webgpu.d.ts文件,告诉TypeScript编译器需要包含一个额外的类型定义文件(笔者对于nextjs基本一窍不通,所以不知道为什么再tsconfig里面typeRoot引入vscode还是会找不到类型,因此就这么搞了)

    /// <reference types="@webgpu/types" />
    
  7. 到这里环境就配置好了,之后就可以画三角形了

绘制三角形

  1. 首先初始化GPU,这里对代码就不解释了

    async function initWebGPU(canvas: HTMLCanvasElement) {
         
        const adapter = await navigator.gpu.requestAdapter(
            {
         
                powerPreference: "high-performance"
            }
    	);
        const device = await adapter?.requestDevice() as GPUDevice;
        const context = canvas.getContext("webgpu") as GPUCanvasContext;
        const format = navigator.gpu.getPreferredCanvasFormat();
        const width = canvas.clientWidth;
        const height = canvas.clientHeight;
        canvas.width = Math.max(1, Math.min(width, device.limits.maxTextureDimension2D));
        canvas.height = Math.max(1, Math.min(height, device.limits.maxTextureDimension2D));
        console.log(canvas.width, canvas.height)
        const size = {
          width: canvas.width, height: canvas.height }
        context.configure({
         
            device: device!,
            format: format,
            alphaMode: "opaque"
        });
        return {
          device, context, format, size };
    }
    
  2. 创建写一个shader去定义vertex以及fragment,有种rust的美感,记得引入该shader,import shader from "./shaders.wgsl"

    struct Fragment {
         
        @builtin(position) Position : vec4<f32>,
        @location(0) Color : vec4<f32>
    };
    @vertex
    fn vs_main(@builtin(vertex_index) v_id: u32) -> Fragment {
         
        var positions = array<vec2<f32>, 3> (
            vec2<f32>( 0.0,  0.5),
            vec2<
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值