Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Investigate WebGPU support #558

Open
fuzhenn opened this issue May 17, 2020 · 2 comments
Open

Investigate WebGPU support #558

fuzhenn opened this issue May 17, 2020 · 2 comments

Comments

@fuzhenn
Copy link
Contributor

fuzhenn commented May 17, 2020

WebGPU is coming, although it's still in a early stage and needs years for wide supports, for sure now is the right time to do some investigations.

IMHO, with a simple and low level design, regl has the potential to migrate to WebGPU in a smooth way with few backward compatible API changes. And that would be a great news for all the regl users.

References:

@calc12 calc12 mentioned this issue Oct 25, 2021
@fr-an-k
Copy link

fr-an-k commented Jan 22, 2023

Looks like someone already made a WebGPU version of REGL: https://github.com/stackgpu/Simple-GPU

@ruofeng618
Copy link

ruofeng618 commented Jul 31, 2023

You can pay attention to GEngine, the engine provides a Model class that can be used for basic rendering packaging, very flexible and easy to use

example:

		<script type="module">
			import { Model, Context, Texture, RenderTarget, Attachment, Sampler } from "../../dist/index.js";
			import { mat4, vec3 } from "../lib/esm/index.js";
			import { cubeVertexArray, cubeVertexCount, uvs, colors, positions } from "../asset/cude.js";
			const init = async () => {
				const context = new Context({
					canvas: null,
					container: document.getElementById("app"),
					pixelRatio: 1
				});
				const { canvas, presentationFormat } = context;
				await context.init();
				const { width, height, depth } = context.presentationSize;
				const colorAttachment = new Attachment(
					{ r: 0.0, g: 0.0, b: 0.0, a: 0 },
					{
						textureView: () => {
							return context.context.getCurrentTexture().createView();
						}
					}
				);
				const response = await fetch(new URL("../textures/Di-3d.png", import.meta.url).toString());
				const imageBitmap = await createImageBitmap(await response.blob());
				const depthTexture = new Texture({
					label: "resolveDepth",
					size: { width, height, depth },
					format: "depth24plus",
					usage: GPUTextureUsage.RENDER_ATTACHMENT
				});
				const texture = new Texture({
					size: {
						width: imageBitmap.width,
						height: imageBitmap.height,
						depth: 1
					},
					format: "rgba8unorm",
					usage:
						GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,
					data: {
						source: imageBitmap,
						width: imageBitmap.width,
						height: imageBitmap.height
					}
				});
				const sampler = new Sampler({
					magFilter: "linear",
					minFilter: "linear"
					// addressModeU: "repeat",
					// addressModeV: "repeat"
				});
				const depthAttachment = new Attachment(1.0, { texture: depthTexture });
				const canvasRenderTarget = new RenderTarget("render", [colorAttachment], depthAttachment);
				const aspect = canvas.width / canvas.height;
				const projectionMatrix = mat4.perspective([], (2 * Math.PI) / 5, aspect, 1, 100.0);
				const modelViewProjectionMatrix = mat4.create();
				const model = new Model({
					shaderId: "model",
					frag: `
              @group(0) @binding(2) var mySampler: sampler;
              @group(0) @binding(1) var myTexture: texture_2d<f32>;

              @fragment
              fn main(
                @location(0) fragUV: vec2<f32>,
                @location(1) fragPosition: vec4<f32>
              ) -> @location(0) vec4<f32> {
                   return textureSample(myTexture, mySampler, fragUV) * fragPosition;
              }
              `,
					vert: `
            struct Uniforms {
              modelViewProjectionMatrix : mat4x4<f32>,
            }
            @binding(0) @group(0) var<uniform> uniforms : Uniforms;

            struct VertexOutput {
              @builtin(position) Position : vec4<f32>,
              @location(0) fragUV : vec2<f32>,
              @location(1) fragPosition: vec4<f32>,
            }

            @vertex
            fn main(
              @location(0) position : vec4<f32>,
              @location(1) color : vec4<f32>,
              @location(2) uv : vec2<f32>
            ) -> VertexOutput {
              var output : VertexOutput;
              output.Position = uniforms.modelViewProjectionMatrix * position;
              output.fragUV = uv;
              output.fragPosition = 0.5 * (position + vec4(1.0, 1.0, 1.0, 1.0));
              return output;
            }
               `,
					vertexBuffers: [
						{
							stepMode: "vertex",
							uid: "vertAttr",
							attributes: {
								interleaved: {
									names: ["position", "color", "uv"],
									value: cubeVertexArray,
									itemSizes: [4, 4, 2]
								} //interleaved buffer
							}
						}
					],
					uniformBuffers: [
						{
							type: "uniform",
							uid: "systemMatrix",
							uniforms: {
								modelViewProjectionMatrix: {
									type: "mat4x4<f32>",
									value: () => {
										let viewMatrix = mat4.identity([]);
										mat4.translate(viewMatrix, viewMatrix, vec3.fromValues(0, 0, -4));
										const now = Date.now() / 1000;
										mat4.rotate(
											viewMatrix,
											viewMatrix,
											1,
											vec3.fromValues(Math.sin(now), Math.cos(now), 0)
										);
										mat4.multiply(modelViewProjectionMatrix, projectionMatrix, viewMatrix);
										return modelViewProjectionMatrix;
									}
								}
							}
						}
					],
					uniformTextureAndSampler: {
						myTexture: { type: "texture", value: texture },
						mySampler: { type: "sampler", value: sampler }
					},
					renderState: {
						targets: [
							{
								format: presentationFormat
							}
						],
						primitive: {
							topology: "triangle-list",
							cullMode: "back"
						},
						depthStencil: {
							depthWriteEnabled: true,
							depthCompare: "less",
							format: "depth24plus"
						}
					},
					draw: {
						count: 36,
						instanceCount: 1
					}
				});
				const model1 = new Model({
					shaderId: "model",
					frag: `
              @group(0) @binding(2) var mySampler: sampler;
              @group(0) @binding(1) var myTexture: texture_2d<f32>;

              @fragment
              fn main(
                @location(0) fragUV: vec2<f32>,
                @location(1) fragPosition: vec4<f32>
              ) -> @location(0) vec4<f32> {
                   return textureSample(myTexture, mySampler, fragUV) * fragPosition;
              }
              `,
					vert: `
            struct Uniforms {
              modelViewProjectionMatrix : mat4x4<f32>,
            }
            @binding(0) @group(0) var<uniform> uniforms : Uniforms;

            struct VertexOutput {
              @builtin(position) Position : vec4<f32>,
              @location(0) fragUV : vec2<f32>,
              @location(1) fragPosition: vec4<f32>,
            }

            @vertex
            fn main(
              @location(0) position : vec4<f32>,
              @location(1) color : vec4<f32>,
              @location(2) uv : vec2<f32>
            ) -> VertexOutput {
              var output : VertexOutput;
              output.Position = uniforms.modelViewProjectionMatrix * position;
              output.fragUV = uv;
              output.fragPosition = 0.5 * (position + vec4(1.0, 1.0, 1.0, 1.0));
              return output;
            }
               `,
					vertexBuffers: [
						{
							stepMode: "vertex",
							uid: "vertAttr",
							attributes: {
								interleaved: {
									names: ["position", "color", "uv"],
									value: cubeVertexArray,
									itemSizes: [4, 4, 2]
								} //interleaved buffer
							}
						}
					],
					uniformBuffers: [
						{
							type: "uniform",
							uid: "systemMatrix",
							uniforms: {
								modelViewProjectionMatrix: {
									type: "mat4x4<f32>",
									value: () => {
										let viewMatrix = mat4.identity([]);
										mat4.translate(viewMatrix, viewMatrix, vec3.fromValues(0, -4, -8));
										const now = Date.now() / 1000;
										mat4.rotate(
											viewMatrix,
											viewMatrix,
											1,
											vec3.fromValues(Math.sin(now), Math.cos(now), 0)
										);
										mat4.multiply(modelViewProjectionMatrix, projectionMatrix, viewMatrix);
										return modelViewProjectionMatrix;
									}
								}
							}
						}
					],
					uniformTextureAndSampler: {
						myTexture: { type: "texture", value: texture },
						mySampler: { type: "sampler", value: sampler }
					},
					renderState: {
						targets: [
							{
								format: presentationFormat
							}
						],
						primitive: {
							topology: "triangle-list",
							cullMode: "back"
						},
						depthStencil: {
							depthWriteEnabled: true,
							depthCompare: "less",
							format: "depth24plus"
						}
					},
					draw: {
						count: 36,
						instanceCount: 1
					}
				});

				function animate() {
					requestAnimationFrame(animate);
					const passEncoder = canvasRenderTarget.beginRenderPass(context.device);
					model.render({ device: context.device, passEncoder });
					model1.render({ device: context.device, passEncoder });
					canvasRenderTarget.endRenderPass();
				}
				animate();
			};
			init();
		</script>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants