WebGPU入门初识

什么是 WebGPU?

WebGPU 是一种现代图形 API,旨在取代 WebGL,提供更高性能和更灵活的 GPU 加速能力。它基于 Vulkan、Metal 和 Direct3D 12,为 Web 开发者带来了类似于原生图形 API 的性能和控制力。

与 WebGL 不同,WebGPU 提供了对计算着色器和低级 GPU 操作的直接支持,使开发者能够充分利用 GPU的潜力来处理图形渲染和并行计算任务。


WebGPU 基本概念详解

在 WebGPU 开发中,理解其核心概念至关重要。以下是 WebGPU 的基本概念及相应的实例代码,帮助初学者直观理解。


1. GPU 适配器(GPUAdapter)和设备(GPUDevice)

概念

  • GPUAdapter:表示浏览器访问到的可用 GPU,类似于桥梁,连接 Web 应用与底层硬件。
  • GPUDevice:表示具体的 GPU 设备,用于执行渲染或计算任务。

示例

const adapter = await navigator.gpu.requestAdapter(); // 获取适配器
const device = await adapter.requestDevice();        // 请求设备
console.log("Adapter:", adapter);
console.log("Device:", device);

2. 管线(Pipeline)

概念

  • 渲染管线(Render Pipeline):定义顶点着色器和片元着色器的工作流程。
  • 计算管线(Compute Pipeline):专用于非图形任务的 GPU 计算。

渲染管线示例

const pipeline = device.createRenderPipeline({vertex: {module: shaderModule,entryPoint: "vertex_main",},fragment: {module: shaderModule,entryPoint: "fragment_main",targets: [{ format: "bgra8unorm" }],},primitive: {topology: "triangle-list", // 图元类型},
});
console.log("Pipeline Created:", pipeline);

3. 着色器(Shader)

概念

  • 着色器是运行在 GPU 上的程序,用于处理图形数据。WebGPU 使用 WGSL 编写。
  • 常见的着色器类型:
    • 顶点着色器:处理每个顶点的位置。
    • 片元着色器:计算像素的颜色。

示例

const shaderCode = `@vertexfn vertex_main(@location(0) position: vec4<f32>) -> @builtin(position) vec4<f32> {return position; // 顶点位置传递给片元着色器}@fragmentfn fragment_main() -> @location(0) vec4<f32> {return vec4(1.0, 0.0, 0.0, 1.0); // 输出红色}
`;
const shaderModule = device.createShaderModule({ code: shaderCode });
console.log("Shader Module Created:", shaderModule);

4. 命令编码器(Command Encoder)

概念

  • 用于生成命令缓冲区,将渲染或计算任务发送到 GPU 执行。

示例

const commandEncoder = device.createCommandEncoder();
const passEncoder = commandEncoder.beginRenderPass({colorAttachments: [{view: context.getCurrentTexture().createView(),loadOp: "clear", // 清除屏幕clearValue: { r: 0.1, g: 0.2, b: 0.3, a: 1.0 }, // 背景色storeOp: "store",}],
});passEncoder.setPipeline(pipeline);
passEncoder.draw(3, 1, 0, 0); // 绘制三角形
passEncoder.end();
device.queue.submit([commandEncoder.finish()]);

5. 缓冲区(Buffer)

概念

  • GPU 缓冲区存储顶点数据、索引数据、常量等。
  • 数据以二进制格式存储,传递给着色器。

示例

const vertices = new Float32Array([0.0,  0.5, // 顶点 1-0.5, -0.5, // 顶点 20.5, -0.5, // 顶点 3
]);const vertexBuffer = device.createBuffer({size: vertices.byteLength,usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
});
device.queue.writeBuffer(vertexBuffer, 0, vertices);
console.log("Vertex Buffer Created:", vertexBuffer);

6. 纹理(Texture)

概念

  • 纹理用于存储图像或多维数据,常用于渲染图片或生成复杂效果。

示例

const texture = device.createTexture({size: [256, 256, 1],format: "rgba8unorm",usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
});
console.log("Texture Created:", texture);

WebGPU 基本示例

以下是一个简单的 WebGPU 应用示例,绘制一个彩色的三角形。

HTML 模板
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>WebGPU 三角形</title>
</head>
<body><canvas id="gpuCanvas"></canvas><script src="app.js"></script>
</body>
</html>
JavaScript 实现(app.js
(async () => {// 初始化 GPUconst adapter = await navigator.gpu.requestAdapter();const device = await adapter.requestDevice();const canvas = document.getElementById("gpuCanvas");const context = canvas.getContext("webgpu");context.configure({device: device,format: "bgra8unorm",});// 顶点数据const vertices = new Float32Array([0.0,  0.5, 1.0, 0.0, 0.0, // 顶点 1:红色-0.5, -0.5, 0.0, 1.0, 0.0, // 顶点 2:绿色0.5, -0.5, 0.0, 0.0, 1.0, // 顶点 3:蓝色]);const vertexBuffer = device.createBuffer({size: vertices.byteLength,usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,});device.queue.writeBuffer(vertexBuffer, 0, vertices);// 着色器代码const shaderCode = `@vertexfn vertex_main(@location(0) position: vec2<f32>, @location(1) color: vec3<f32>) -> @builtin(position) vec4<f32> {return vec4(position, 0.0, 1.0);}@fragmentfn fragment_main(@location(1) color: vec3<f32>) -> @location(0) vec4<f32> {return vec4(color, 1.0);}`;const shaderModule = device.createShaderModule({ code: shaderCode });// 渲染管线const pipeline = device.createRenderPipeline({vertex: {module: shaderModule,entryPoint: "vertex_main",buffers: [{arrayStride: 5 * 4, // 每个顶点占 5 个 floatattributes: [{ shaderLocation: 0, offset: 0, format: "float32x2" }, // 位置{ shaderLocation: 1, offset: 2 * 4, format: "float32x3" }, // 颜色],},],},fragment: {module: shaderModule,entryPoint: "fragment_main",targets: [{ format: "bgra8unorm" }],},primitive: { topology: "triangle-list" },});// 渲染const commandEncoder = device.createCommandEncoder();const passEncoder = commandEncoder.beginRenderPass({colorAttachments: [{view: context.getCurrentTexture().createView(),loadOp: "clear",clearValue: { r: 0.1, g: 0.1, b: 0.1, a: 1.0 },storeOp: "store",}],});passEncoder.setPipeline(pipeline);passEncoder.setVertexBuffer(0, vertexBuffer);passEncoder.draw(3, 1, 0, 0); // 绘制三角形passEncoder.end();device.queue.submit([commandEncoder.finish()]);
})();

代码解析

  1. GPU 初始化

    • navigator.gpu.requestAdapter() 请求 GPU 适配器。
    • adapter.requestDevice() 获取 GPU 设备。
  2. Canvas 配置
    使用 getPreferredCanvasFormat() 确保兼容性。

  3. 顶点数据

    • 包含位置和颜色信息。
    • 使用 Float32Array 存储。
  4. 着色器编写

    • 顶点着色器处理每个顶点的位置。
    • 片元着色器确定像素的颜色。
  5. 渲染管线
    定义顶点缓冲区格式和着色器入口。

  6. 渲染流程

    • 配置 RenderPass
    • 通过命令编码器将绘图命令提交到 GPU。

输出结果

运行代码后,您将在 Canvas 中看到一个红、绿、蓝三色的三角形。这是 WebGPU 基础应用的一个完整流程。


进一步学习方向

  1. 深入了解 WGSL
    学习 WebGPU 的着色器语言,优化渲染效果。

  2. 纹理处理
    实现纹理映射,加载外部图片。

  3. 计算着色器
    探索 WebGPU 的非图形计算能力。

  4. 性能优化
    掌握高效的资源管理和渲染技术。

欢迎各位随时交流~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/65246.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ffmpeg: stream_loop报错 Error while filtering: Operation not permitted

问题描述 执行ffmpeg命令的时候&#xff0c;报错&#xff1a;Error while filtering: Operation not permitted 我得命令如下 ffmpeg -framerate 25 -y -i /data/workerspace/mtk/work_home/mtk_202406111543-l9CSU91H1f1b3/tmp/%08d.png -stream_loop -1 -i /data/workerspa…

【微信小程序】1|底部图标 | 我的咖啡店-综合实训

底部图标 引言 在微信小程序开发中&#xff0c;底部导航栏&#xff08;tabBar&#xff09;是用户界面的重要组成部分&#xff0c;它为用户提供了快速切换不同页面的功能。今天&#xff0c;我们将通过一个实际案例——“我的咖啡店”小程序&#xff0c;来详细解析如何配置底部图…

docker mysql5.7安装

一.更改 /etc/docker/daemon.json sudo mkdir -p /etc/dockersudo tee /etc/docker/daemon.json <<-EOF {"registry-mirrors": ["https://do.nark.eu.org","https://dc.j8.work","https://docker.m.daocloud.io","https:/…

使用Wikitext2数据集对Llama-7B和Llama3-8B模型进行50%权重剪枝的一般步骤和可能的实现方式

以下是使用Wikitext2数据集对Llama-7B和Llama3-8B模型进行50%权重剪枝的一般步骤和可能的实现方式&#xff08;请注意&#xff0c;实际操作可能需要根据具体模型架构和工具进行调整&#xff09;&#xff1a; 1. 环境准备 确保你已经安装了必要的深度学习框架&#xff08;如Py…

【实验记录】动手实现一个简单的神经网络实验(一)

最近上了“神经网络与深度学习”这门课&#xff0c;有一个自己动手实现调整神经网络模型的实验感觉还挺有记录意义&#xff0c;可以帮我巩固之前学习到的理论知识&#xff0c;所以就打算记录一下。 实验大概是使用LeNet&#xff08;卷积神经网络&#xff09;对MINIST数据集做图…

c++编译过程初识

编译过程 预处理&#xff1a;主要是执行一些预处理指令&#xff0c;主要是#开头的代码&#xff0c;如#include 的头文件、#define 定义的宏常量、#ifdef #ifndef #endif等条件编译的代码&#xff0c;具体包括查找头文件、进行宏替换、根据条件编译等操作。 g -E example.cpp -…

Springboot高并发乐观锁

Spring Boot分布式锁的主要缺点包括但不限于以下几点&#xff1a; 性能开销&#xff1a;使用分布式锁通常涉及到网络通信&#xff0c;这会引入额外的延迟和性能开销。例如&#xff0c;当使用Redis或Zookeeper实现分布式锁时&#xff0c;每次获取或释放锁都需要与这些服务进行交…

揭秘 Fluss 架构组件

这是 Fluss 系列的第四篇文章了&#xff0c;我们先回顾一下前面三篇文章主要说了哪些内容。 Fluss 部署&#xff0c;带领大家部署Fluss 环境&#xff0c;体验一下 Fluss 的功能Fluss 整合数据湖的操作&#xff0c;体验Fluss 与数据湖的结合讲解了 Fluss、Kafka、Paimon 之间的…

leetcode82:删除链表中的重复元素II

原题地址&#xff1a;82. 删除排序链表中的重复元素 II - 力扣&#xff08;LeetCode&#xff09; 题目描述 给定一个已排序的链表的头 head &#xff0c; 删除原始链表中所有重复数字的节点&#xff0c;只留下不同的数字 。返回 已排序的链表 。 示例 1&#xff1a; 输入&…

【面试经典】多数元素

链接&#xff1a;169. 多数元素 - 力扣&#xff08;LeetCode&#xff09; 解题思路&#xff1a; 在本文中&#xff0c;“数组中出现次数超过一半的数字” 被称为 “众数” 。 需要注意的是&#xff0c;数学中众数的定义为 “数组中出现次数最多的数字” &#xff0c;与本文定…

AT24C02学习笔记

看手册&#xff1a; AT24Cxx xx代表能写入xxK bit(xx K)/8 byte 内部写周期很关键&#xff0c;代表每一次页写或字节写结束后时间要大于5ms&#xff08;延时5ms确保完成写周期&#xff09;&#xff0c;否则时序会出错。 页写&#xff1a;型不同号每一页可能写入不同大小的…

蓝牙BLE开发——解决iOS设备获取MAC方式

解决iOS设备获取MAC方式 uniapp 解决 iOS 获取 MAC地址&#xff0c;在Android、iOS不同端中互通&#xff0c;根据MAC 地址处理相关的业务场景&#xff1b; 文章目录 解决iOS设备获取MAC方式监听寻找到新设备的事件BLE工具效果图APP监听设备返回数据解决方式ArrayBuffer转16进制…

01 Oracle 基本操作

Oracle 基本操作 初使用步骤 1.创建表空间 2.创建用户、设置密码、指定表空间 3.给用户授权 4.切换用户登录 5.创建表 注意点&#xff1a;oracle中管理表的基本单位是用户 文章目录 了解Oracle体系结构 1.创建表空间**2.删除表空间**3.创建用户4.给用户授权5.切换用户登录6.表操…

【Linux命令】ps -a 和 ps -ef 的区别

ps -a 和 ps -ef 是 ps&#xff08;process status&#xff09;命令的不同选项&#xff0c;它们用于显示不同的进程信息。以下是这两个选项的主要区别&#xff1a; ps -a -a 选项表示显示所有拥有终端的进程&#xff0c;但不包括守护进程&#xff08;daemon processes&#x…

独一无二,万字详谈——Linux之文件管理

Linux文件部分的学习&#xff0c;有这一篇的博客足矣! 目录 一、文件的命名规则 1、可以使用哪些字符&#xff1f; 2、文件名的长度 3、Linux文件名的大小写 4、Linux文件扩展名 二、文件管理命令 1、目录的创建/删除 &#xff08;1&#xff09;、目录的创建 ① mkdir…

rust windwos 两个edit框

use winapi::shared::minwindef::LOWORD; use windows::{core::*,Win32::{Foundation::*,Graphics::Gdi::{BeginPaint, EndPaint, PAINTSTRUCT},System::LibraryLoader::GetModuleHandleA,UI::WindowsAndMessaging::*,}, };// 两个全局静态变量&#xff0c;用于保存 Edit 控件的…

解锁成长密码:探寻刻意练习之道

刻意练习&#xff0c;真有那么神&#xff1f; 在生活中&#xff0c;你是否有过这样的困惑&#xff1a;每天苦练英语口语&#xff0c;可一到交流时还是支支吾吾&#xff1b;埋头苦学吉他&#xff0c;却总是卡在几个和弦转换上&#xff1b;工作多年&#xff0c;业务能力却似乎陷入…

WPS中如何为指定区域的表格添加行或者列,同时不影响其它表格?

大家好&#xff0c;我是小鱼。 日常工作中会遇到这种情况&#xff1a;在一个Excel工作表中有多个表格&#xff0c;因为后期数据量增加就需要为指定区域的表格添加行或者列&#xff0c;但是不能影响其它表格。这种情况下我们应该怎么操作呢&#xff1f; 为指定区域的表格添加行…

Gitlab17.7+Jenkins2.4.91实现Fastapi项目持续发布版本详细操作(亲测可用)

一、gitlab设置&#xff1a; 1、进入gitlab选择主页在左侧菜单的下面点击管理员按钮。 2、选择左侧菜单的设置&#xff0c;选择网络&#xff0c;在右侧选择出站请求后选择允许来自webhooks和集成对本地网络的请求 3、webhook设置 进入你自己的项目选择左侧菜单的设置&#xff…

模型工作流:自动化的模型内部三角面剔除

1. 关于自动减面 1.1 自动减面的重要性及现状 三维模型是游戏、三维家居设计、数字孪生、VR/AR等几乎所有三维软件的核心资产&#xff0c;模型的质量和性能从根本上决定了三维软件的画面效果和渲染性能。其中&#xff0c;模型减面工作是同时关乎质量和性能这两个要素的重要工…