Google codelab WebGPU入门教程源码<2> - 绘制几何形状(源码)

对应的教程文章: https://codelabs.developers.google.com/your-first-webgpu-app?hl=zh-cn#3

源码执行效果:

对应的教程源码:

此处源码和教程本身提供的部分代码可能存在一点差异。

class Color4 {

	r: number;
	g: number;
	b: number;
	a: number;

	constructor(pr = 1.0, pg = 1.0, pb = 1.0, pa = 1.0) {
		this.r = pr;
		this.g = pg;
		this.b = pb;
		this.a = pa;
	}
}

export class WGPURRectShape {
	private mRVertices: Float32Array = null;
	private mRPipeline: any | null = null;
	private mVtxBuffer: any | null = null;
	private mCanvasFormat: any | null = null;
	private mWGPUDevice: any | null = null;
	private mWGPUContext: any | null = null;
	constructor() {}
	initialize(): void {
		console.log("WGPURRectShape::initialize() ...");
		// const canvas = document.querySelector("canvas");

		const canvas = document.createElement("canvas");
		canvas.width = 512;
		canvas.height = 512;
		document.body.appendChild(canvas);
		console.log("ready init webgpu ...");
		this.initWebGPU(canvas).then(() => {
			console.log("webgpu initialization finish ...");

			this.clearWGPUCanvas();

		});
		document.onmousedown = (evt):void => {
			this.clearWGPUCanvas( new Color4( Math.random(), Math.random(), Math.random()) );
		}
	}
	private createRectGeometryData(device: any, pass: any): void {

		let vertices = this.mRVertices;
		let vertexBuffer = this.mVtxBuffer;
		let cellPipeline = this.mRPipeline;
		if(!cellPipeline) {

			vertices = new Float32Array([
			//   X,    Y,
				-0.8, -0.8, // Triangle 1 (Blue)
				 0.8,  -0.8,
				 0.8,   0.8,

				-0.8, -0.8, // Triangle 2 (Red)
				0.8,   0.8,
				-0.8,  0.8,
			]);

			vertexBuffer = device.createBuffer({
				label: "Cell vertices",
				size: vertices.byteLength,
				usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
			});
			device.queue.writeBuffer(vertexBuffer, /*bufferOffset=*/0, vertices);
			const vertexBufferLayout = {
				arrayStride: 8,
				attributes: [{
					format: "float32x2",
					offset: 0,
					shaderLocation: 0, // Position, see vertex shader
				}],
			};
			const shaderCodes = `
			@vertex
			fn vertexMain(@location(0) pos: vec2f) ->
				@builtin(position) vec4f {
						return vec4f(pos * 0.7, 0, 1);
			}
			@fragment
			fn fragmentMain() -> @location(0) vec4f {
				return vec4f(1, 0, 0, 1);
			}
			`;
			const cellShaderModule = device.createShaderModule({
				label: "Cell shader",
				code: shaderCodes
				});
			cellPipeline = device.createRenderPipeline({
				label: "Cell pipeline",
				layout: "auto",
				vertex: {
					module: cellShaderModule,
					entryPoint: "vertexMain",
					buffers: [vertexBufferLayout]
				},
				fragment: {
					module: cellShaderModule,
					entryPoint: "fragmentMain",
					targets: [{
						format: this.mCanvasFormat
					}]
				},

			});
			this.mRVertices = vertices;
			this.mVtxBuffer = vertexBuffer;
			this.mRPipeline = cellPipeline;
		}
		pass.setPipeline(cellPipeline);
		pass.setVertexBuffer(0, vertexBuffer);
		pass.draw(vertices.length / 2);
	}
	private clearWGPUCanvas(clearColor: Color4 = null): void {

		clearColor = clearColor ? clearColor : new Color4(0.5, 0.2, 1.0);
		const device = this.mWGPUDevice;
		const context = this.mWGPUContext;
		const rpassParam = {
			colorAttachments: [
				{
					clearValue: clearColor,
					// clearValue: [0.3,0.7,0.5,1.0], // yes
					view: context.getCurrentTexture().createView(),
					loadOp: "clear",
					storeOp: "store"
				}
			]
		};

		const encoder = device.createCommandEncoder();
		const pass = encoder.beginRenderPass( rpassParam );


		this.createRectGeometryData(device, pass);
		pass.end();
		const commandBuffer = encoder.finish();
		device.queue.submit([commandBuffer]);
	}
	private async initWebGPU(canvas: HTMLCanvasElement) {
		
		const gpu = (navigator as any).gpu;
		if (gpu) {
			console.log("WebGPU supported on this browser.");

			const adapter = await gpu.requestAdapter();
			if (adapter) {
				console.log("Appropriate GPUAdapter found.");
				const device = await adapter.requestDevice();
				if (device) {
					this.mWGPUDevice = device;
					console.log("Appropriate GPUDevice found.");
					const context = canvas.getContext("webgpu") as any;
					const canvasFormat = gpu.getPreferredCanvasFormat();
					this.mWGPUContext = context;
					this.mCanvasFormat = canvasFormat;
					console.log("canvasFormat: ", canvasFormat);
					context.configure({
						device: device,
						format: canvasFormat,
						alphaMode: "premultiplied"
					});
				} else {
					throw new Error("No appropriate GPUDevice found.");
				}
			} else {
				throw new Error("No appropriate GPUAdapter found.");
			}
		} else {
			throw new Error("WebGPU not supported on this browser.");
		}
	}
	run(): void {}
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++初阶 类和对象(下)

目录 一、拷贝构造函数 1.1 什么是拷贝构造函数? 1.2 为什么得是引用? 1.3 使用拷贝构造函数 1.4 拷贝构造函数有什么用? 二、运算符重载 2.1 什么是运算符重载? 2.2 尝试前须知 2.3 常见运算符重载 2.3.1运算符重载 …

树莓派通过网线连接电脑(校园网也能连接),实现SSH连接

前言 之前通过串口登入树莓派,太麻烦,通过网络登入树莓派,学校校园网又连接不了,想起来可以使用网线连接树莓派和电脑。 目录 树莓派通过网线连接电脑思路分析 树莓派通过网线连接电脑实现 1.硬件需求 2.打开Windows的网络 …

12.Oracle的索引

Oracle11g的索引 一、什么是索引二、索引的分类三、索引的语法四、分析索引四、索引的作用及使用场景 一、什么是索引 在Oracle数据库中,索引是一种特殊的数据结构,用于提高查询性能和加速数据检索。索引存储了表中某列的值和对应的行指针,这…

2023.11.15 关于 Spring Boot 配置文件

目录 引言 Spring Boot 配置文件 properties 配置文件说明 基本语法 读取配置文件 优点 缺点 yml 配置文件说明 基本语法 读取配置文件 yml 配置不同数据数据类型及 null 字符串 加单双引号的区别 yml 配置 列表(List) 和 映射(…

WordPress丸子小程序问题常见解决方案

WordPress丸子小程序问题常见解决方案 下载uniapp,导入项目。修改下图域名为自己的WP博客地址。(如下图) 发行微信小程序,如果显示不是项目所有者,请重新获取。 重新发行微信小程序,请打开微信开发者工具端…

MySql分区

一、什么是分区 MySQL分区是一种数据库设计和管理技术,它允许你将表分割成独立的、具有特定规则的存储单元。每个分区可以独立地进行管理,包括备份、恢复和优化。分区的主要目的是提高查询性能、简化维护以及实现数据的更有效管理。 以下是MySQL分区的…

深度解析:ERP管理系统背后的逻辑

深度解析:ERP管理系统背后的逻辑企业运营日益复杂化,一套高效且实用的ERP管理系统成为了企业成功的关键因素之一。然而,许多企业对于ERP管理系统的理解仍停留在表面,并未深入理解其背后的逻辑。本文将为您深度解析ERP管理系统背后…

腾讯云服务器价格表查询,腾讯云服务器怎么买便宜?

你是否需要搭建一个属于自己的网站,但是又不知道该如何选择和购买服务器?腾讯云服务器价格表查询,让你轻松了解各款服务器的价格及配置信息,帮助你选择最合适的服务器。同时,我们还为你提供了腾讯云服务器的优惠购买入…

main.js 中的 render函数

按照之前的单组件文件中的写法&#xff0c;我们的写法应该是这样的 import App from ./App.vuenew Vue({el: #app,templete: <App></App>,components: {App}, }) 1、定义el根节点。2、注册App组件。3、渲染 templete 模板 但是在脚手架工程中&#xff0c;他是这…

kubernetes--数据存储

目录 一、数据存储引言&#xff1a; 二、基础存储卷&#xff1a; 1. emptyDir存储卷&#xff1a; 2. hostPath存储卷&#xff1a; 3. nfs共享存储卷&#xff1a; 3.1 配置nfs: 3.2 master节点编写yaml文件&#xff1a; 4. 总结&#xff1a; 三、PVC和PV&#xff1a; 1. PV 的…

Jmeter- Beanshell语法和常用内置对象(网络整理)

在利用jmeter进行接口测试或者性能测试的时候&#xff0c;我们需要处理一些复杂的请求&#xff0c;此时就需要利用beanshell脚本了&#xff0c;BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法&#xff0c;所以它和java是可以无缝衔接的。beans…

python趣味编程-5分钟实现一个测验应用程序(含源码、步骤讲解)

Python测验是用 Python 编程语言编写的,这个关于 Python 编程的简单测验是一个简单的项目,用于测试一个人在给定主题考试中的知识能力。 Python 中的 Quiz项目仅包含用户端。用户必须先登录或注册才能开始Python 测验。 此外,还规定了解决问题的时间。用户应在时间结束前解…

VIM去掉utf-8 bom头

Windows系统的txt文件在使用utf-8编码保存时会默认在文件开头插入三个不可见的字符&#xff08;0xEF 0xBB 0xBF&#xff09;称为BOM头 BOM头文件 0.加上BOM标记&#xff1a; :set bomb 1.查询当前UTF-8编码的文件是否有BOM标记&#xff1a; :set bomb? :set bomb? 2.BOM头:文…

C语言的动态内存管理

目录 一、malloc函数 二、free函数 三、calloc函数 四、realloc函数 五、realloc函数原地扩容和异地扩容测试 六、动态内存管理的注意事项 一、malloc函数 1.头文件&#xff1a;stdlib.h&#xff08;malloc.h&#xff09; 2.函数原型&#xff1a;void * malloc(size_t siz…

STM32_SPI总线驱动OLED详细原理讲解

目录 这里写目录标题 第13章 Cortex-M4-SPI总线13.1 SPI总线概述13.1.1 SPI总线介绍13.1.2 SPI总线接口与物理拓扑结构13.1.3 SPI总线通信原理13.1.4 SPI总线数据格式 13.2 IO口模拟SPI操作OLED13.2.1 常见的显示设备13.2.2 OLED显示屏概述13.2.3 OLED特征13.2.4 显示原理13.2.…

模拟实现一个Linux中的简单版shell

exec系列接口中的环境变量 在之前我们学习了exec系类函数的功能就是将一个程序替换成另外一个程序。 然后就会出现下面的问题&#xff1a; 首先父进程对应的环境变量的信息是从bash中来的&#xff0c;因为我们自己写的父进程在运行的时候首先就要成为bash的子进程。这里我们将…

基于单片机的温度控制器系统设计

**单片机设计介绍&#xff0c; 基于单片机的温度控制器系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的温度控制器系统是一种利用单片机来检测环境温度并控制温度的系统。它通常由以下几个部分组成&#xff…

12v24v60v高校同步降压转换芯片推荐

12V/24V/60V 高校同步降压转换芯片推荐&#xff1a; 对于需要高效、稳定、低噪音的降压转换芯片&#xff0c;推荐使用WD5030E和WD5105。这两款芯片都是采用同步整流技术&#xff0c;具有高效率、低噪音、低功耗等优点&#xff0c;适用于各种电子设备。 WD5030E是一款高效率…

Web前端—小兔鲜儿电商网站底部设计及网站中间过渡部分设计

版本说明 当前版本号[20231116]。 版本修改说明20231116初版 目录 文章目录 版本说明目录底部&#xff08;footer&#xff09;服务帮助中心版权 banner侧边栏圆点 新鲜好物&#xff08;goods&#xff09;标题 底部&#xff08;footer&#xff09; 结构&#xff1a;通栏 >…

阿里云ESSD云盘、高效云盘和SSD云盘介绍和IOPS性能参数表

阿里云服务器系统盘或数据盘支持多种云盘类型&#xff0c;如高效云盘、ESSD Entry云盘、SSD云盘、ESSD云盘、ESSD PL-X云盘及ESSD AutoPL云盘等&#xff0c;阿里云服务器网aliyunfuwuqi.com详细介绍不同云盘说明及单盘容量、最大/最小IOPS、最大/最小吞吐量、单路随机写平均时延…