From 5379761507eaf00fddd5aa6a28eb314bd97c2ea5 Mon Sep 17 00:00:00 2001 From: Muhammad Mobeen Movania Date: Sun, 5 Jan 2025 22:39:34 +0500 Subject: [PATCH 1/3] Added some feature capabilities output and chap5_rotatesquare example --- Ch02_ObjectCreation/ch02_objectcreation.js | 25 ++++ Ch05_RotateSquare/ch05_rotatesquare.js | 162 +++++++++++++++++++++ Ch05_RotateSquare/index.html | 13 ++ 3 files changed, 200 insertions(+) create mode 100644 Ch05_RotateSquare/ch05_rotatesquare.js create mode 100644 Ch05_RotateSquare/index.html diff --git a/Ch02_ObjectCreation/ch02_objectcreation.js b/Ch02_ObjectCreation/ch02_objectcreation.js index 9de976d..194dc83 100755 --- a/Ch02_ObjectCreation/ch02_objectcreation.js +++ b/Ch02_ObjectCreation/ch02_objectcreation.js @@ -18,6 +18,31 @@ if (!adapter) { msg_array.push("GPUAdapter found"); } +console.log(adapter); + +// Access information about the GPU adapter +/*const info = await adapter.requestAdapterInfo(); +if(info) { + console.log("Vendor: " + info.vendor); + console.log("Architecture: " + info.architecture); + console.log("Device: " + info.device); + console.log("Description: " + info.description); +}*/ + + // Display all of the supported features + console.log("Supported feature: "); + adapter.features.forEach((value) => { + console.log("\t", value); + }); + + console.log("Limits: "); + for (const key in adapter.limits) + { + const value = adapter.limits[key]; + console.log(`\t${key}: ${value}`); + } + + // Access the GPU const device = await adapter.requestDevice(); if (!device) { diff --git a/Ch05_RotateSquare/ch05_rotatesquare.js b/Ch05_RotateSquare/ch05_rotatesquare.js new file mode 100644 index 0000000..55162bd --- /dev/null +++ b/Ch05_RotateSquare/ch05_rotatesquare.js @@ -0,0 +1,162 @@ +const shaderCode = ` +@group(0) @binding(0) var rotMat: mat4x4f; +@vertex +fn vertexMain(@location(0) coords: vec2f) -> @ +builtin(position) vec4f { + return rotMat * vec4f(coords, 0.0, 1.0); +} +@fragment +fn fragmentMain() -> @location(0) vec4f { + return vec4f(0.2, 0.2, 1.0, 1.0); +} +`; + +// Create top-level asynchronous function +async function runExample() { + +// Check if WebGPU is supported +if (!navigator.gpu) { + throw new Error("WebGPU not supported"); +} + +// Access the GPUAdapter +const adapter = await navigator.gpu.requestAdapter(); +if (!adapter) { + throw new Error("No GPUAdapter found"); +} + +// Access the client"s GPU +const device = await adapter.requestDevice(); +if (!device) { + throw new Error("Failed to create a GPUDevice"); +} + +// Access the canvas +const canvas = document.getElementById("canvas_example"); +if (!canvas) { + throw new Error("Could not access canvas in page"); +} + +// Obtain a WebGPU context for the canvas +const context = canvas.getContext("webgpu"); +if (!context) { + throw new Error("Could not obtain WebGPU context for canvas"); +} + +// Configure the context with the device and format +const canvasFormat = navigator.gpu.getPreferredCanvasFormat(); +context.configure({ + device: device, + format: canvasFormat, +}); + +// Create the command encoder +const encoder = device.createCommandEncoder(); +if (!encoder) { + throw new Error("Failed to create a GPUCommandEncoder"); +} + +// Create the render pass encoder +const renderPass = encoder.beginRenderPass({ + colorAttachments: [{ + view: context.getCurrentTexture().createView(), + loadOp: "clear", + clearValue: { r: 0.9, g: 0.9, b: 0.9, a: 1.0 }, + storeOp: "store" + }] +}); + +// Define vertex data (coordinates and colors) +const vertexData = new Float32Array([ + -0.5, -0.5, // First vertex + 0.5, -0.5, // Second vertex + -0.5, 0.5, // Third vertex + 0.5, 0.5, // Fourth vertex + ]); + +// Create vertex buffer +const vertexBuffer = device.createBuffer({ + label: "Vertex Buffer 0", + size: vertexData.byteLength, + usage: + GPUBufferUsage.VERTEX | + GPUBufferUsage.COPY_DST +}); + +// Write data to buffer +device.queue.writeBuffer(vertexBuffer, 0, vertexData); +renderPass.setVertexBuffer(0, vertexBuffer); + +// Define layout of buffer data +const bufferLayout = { + arrayStride: 8, + attributes: [ + { format: "float32x2", offset: 0, shaderLocation: 0 } + ], +}; + +// Define uniform data +const uniformData = new Float32Array([ + 0.866, 0.5, 0.0, 0.0, // First column of matrix + -0.5, 0.866, 0.0, 0.0, // Second column of matrix + 0.0, 0.0, 1.0, 0.0, // Third column of matrix + 0.0, 0.0, 0.0, 1.0, // Fourth column of matrix + ]); + +// Create uniform buffer +const uniformBuffer = device.createBuffer({ + label: "Uniform Buffer 0", + size: uniformData.byteLength, + usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST}); +device.queue.writeBuffer(uniformBuffer, 0, uniformData); + +// Create the shader module +const shaderModule = device.createShaderModule({ + label: "Shader module 0", + code: shaderCode +}); + +// Define the rendering procedure +const renderPipeline = device.createRenderPipeline({ + layout: "auto", + vertex: { + module: shaderModule, + entryPoint: "vertexMain", + buffers: [bufferLayout] + }, + fragment: { + module: shaderModule, + entryPoint: "fragmentMain", + targets: [{ + format: canvasFormat + }] + }, + primitive: { + topology: "triangle-strip" + } +}); +renderPass.setPipeline(renderPipeline); + + // Access the bind group layout + const bindGroupLayout = renderPipeline.getBindGroupLayout(0); + // Create the bind group + let bindGroup = device.createBindGroup({ + layout: bindGroupLayout, + entries: [{ + binding: 0, + resource: { buffer: uniformBuffer } + }] + }); + // Associate bind group with render pass encoder + renderPass.setBindGroup(0, bindGroup); + +// Draw vertices and complete rendering +renderPass.draw(4); +renderPass.end(); + +// Submit the render commands to the GPU +device.queue.submit([encoder.finish()]); +} + +// Run example function +runExample(); \ No newline at end of file diff --git a/Ch05_RotateSquare/index.html b/Ch05_RotateSquare/index.html new file mode 100644 index 0000000..380793c --- /dev/null +++ b/Ch05_RotateSquare/index.html @@ -0,0 +1,13 @@ + + + +

Ch05_RotateSquare

+ + + + + + + + + From 7212909e39ccc6fbbf60851e5ebf68307530fb4c Mon Sep 17 00:00:00 2001 From: Muhammad Mobeen Movania Date: Sun, 5 Jan 2025 22:43:24 +0500 Subject: [PATCH 2/3] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a18191c..cb19dd3 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ The projects in the chapters are given as follows: - **Ch03_BlueCanvas** - Fills a WebGPU canvas with color - **Ch04_OrangeTriangle** - Uses vertex attributes for rendering - **Ch04_MultiTriangle** - Passes data from the vertex shader to the fragment shader +- **Ch05_RotateSquare** - Rotates a square using matrices stored in uniform buffers - **Ch05_Cubes** - Transforms objects using matrices stored in uniform buffers - **Ch06_ShinySphere** - Implements Blinn-Phong shading in a fragment shader - **Ch06_SimpleTexture** - Uses a texture to display an image in the scene From 4434d572cb124e03e35686c2c77f81f998d17e4d Mon Sep 17 00:00:00 2001 From: Muhammad Mobeen Movania Date: Sun, 5 Jan 2025 22:53:26 +0500 Subject: [PATCH 3/3] added chapter 5 project --- Ch05_RotateSquare/ch05_rotatesquare.js | 88 ++++++++++++-------------- Ch05_RotateSquare/index.html | 16 ----- 2 files changed, 42 insertions(+), 62 deletions(-) diff --git a/Ch05_RotateSquare/ch05_rotatesquare.js b/Ch05_RotateSquare/ch05_rotatesquare.js index ef381fd..f931464 100644 --- a/Ch05_RotateSquare/ch05_rotatesquare.js +++ b/Ch05_RotateSquare/ch05_rotatesquare.js @@ -1,14 +1,14 @@ -<<<<<<< HEAD const shaderCode = ` @group(0) @binding(0) var rotMat: mat4x4f; + @vertex -fn vertexMain(@location(0) coords: vec2f) -> @ -builtin(position) vec4f { - return rotMat * vec4f(coords, 0.0, 1.0); +fn vertexMain(@location(0) coords: vec2f) -> @builtin(position) vec4f { + return rotMat * vec4f(coords, 0.0, 1.0); } + @fragment fn fragmentMain() -> @location(0) vec4f { - return vec4f(0.2, 0.2, 1.0, 1.0); + return vec4f(0.2, 0.2, 1.0, 1.0); } `; @@ -26,7 +26,7 @@ if (!adapter) { throw new Error("No GPUAdapter found"); } -// Access the client"s GPU +// Access the GPU const device = await adapter.requestDevice(); if (!device) { throw new Error("Failed to create a GPUDevice"); @@ -67,53 +67,50 @@ const renderPass = encoder.beginRenderPass({ }] }); -// Define vertex data (coordinates and colors) +// Define vertex data const vertexData = new Float32Array([ - -0.5, -0.5, // First vertex - 0.5, -0.5, // Second vertex - -0.5, 0.5, // Third vertex - 0.5, 0.5, // Fourth vertex - ]); + -0.5, -0.5, // First vertex + 0.5, -0.5, // Second vertex + -0.5, 0.5, // Third vertex + 0.5, 0.5, // Fourth vertex +]); // Create vertex buffer const vertexBuffer = device.createBuffer({ label: "Vertex Buffer 0", size: vertexData.byteLength, - usage: - GPUBufferUsage.VERTEX | - GPUBufferUsage.COPY_DST + usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST }); - -// Write data to buffer device.queue.writeBuffer(vertexBuffer, 0, vertexData); renderPass.setVertexBuffer(0, vertexBuffer); -// Define layout of buffer data +// Define layout of vertex buffer const bufferLayout = { arrayStride: 8, attributes: [ - { format: "float32x2", offset: 0, shaderLocation: 0 } + { format: "float32x2", offset: 0, shaderLocation: 0 } ], }; // Define uniform data const uniformData = new Float32Array([ - 0.866, 0.5, 0.0, 0.0, // First column of matrix - -0.5, 0.866, 0.0, 0.0, // Second column of matrix - 0.0, 0.0, 1.0, 0.0, // Third column of matrix - 0.0, 0.0, 0.0, 1.0, // Fourth column of matrix - ]); - + 0.866, 0.5, 0.0, 0.0, // First column of matrix + -0.5, 0.866, 0.0, 0.0, // Second column of matrix + 0.0, 0.0, 1.0, 0.0, // Third column of matrix + 0.0, 0.0, 0.0, 1.0, // Fourth column of matrix +]); + // Create uniform buffer const uniformBuffer = device.createBuffer({ label: "Uniform Buffer 0", size: uniformData.byteLength, - usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST}); + usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST +}); device.queue.writeBuffer(uniformBuffer, 0, uniformData); // Create the shader module const shaderModule = device.createShaderModule({ - label: "Shader module 0", + label: "Shader module 0", code: shaderCode }); @@ -121,35 +118,37 @@ const shaderModule = device.createShaderModule({ const renderPipeline = device.createRenderPipeline({ layout: "auto", vertex: { - module: shaderModule, - entryPoint: "vertexMain", - buffers: [bufferLayout] + module: shaderModule, + entryPoint: "vertexMain", + buffers: [bufferLayout] }, fragment: { - module: shaderModule, - entryPoint: "fragmentMain", - targets: [{ - format: canvasFormat - }] + module: shaderModule, + entryPoint: "fragmentMain", + targets: [{ + format: canvasFormat + }] }, primitive: { topology: "triangle-strip" - } + } }); renderPass.setPipeline(renderPipeline); - // Access the bind group layout - const bindGroupLayout = renderPipeline.getBindGroupLayout(0); - // Create the bind group - let bindGroup = device.createBindGroup({ +// Access the bind group layout +const bindGroupLayout = renderPipeline.getBindGroupLayout(0); + +// Create the bind group +let bindGroup = device.createBindGroup({ layout: bindGroupLayout, entries: [{ binding: 0, resource: { buffer: uniformBuffer } }] - }); - // Associate bind group with render pass encoder - renderPass.setBindGroup(0, bindGroup); +}); + +// Associate bind group with render pass encoder +renderPass.setBindGroup(0, bindGroup); // Draw vertices and complete rendering renderPass.draw(4); @@ -161,6 +160,3 @@ device.queue.submit([encoder.finish()]); // Run example function runExample(); -======= -const shaderCode = ` @group(0) @binding(0) var rotMat: mat4x4f; @vertex fn vertexMain(@location(0) coords: vec2f) -> @builtin(position) vec4f { return rotMat * vec4f(coords, 0.0, 1.0); } @fragment fn fragmentMain() -> @location(0) vec4f { return vec4f(0.2, 0.2, 1.0, 1.0); } `; // Create top-level asynchronous function async function runExample() { // Check if WebGPU is supported if (!navigator.gpu) { throw new Error("WebGPU not supported"); } // Access the GPUAdapter const adapter = await navigator.gpu.requestAdapter(); if (!adapter) { throw new Error("No GPUAdapter found"); } // Access the GPU const device = await adapter.requestDevice(); if (!device) { throw new Error("Failed to create a GPUDevice"); } // Access the canvas const canvas = document.getElementById("canvas_example"); if (!canvas) { throw new Error("Could not access canvas in page"); } // Obtain a WebGPU context for the canvas const context = canvas.getContext("webgpu"); if (!context) { throw new Error("Could not obtain WebGPU context for canvas"); } // Configure the context with the device and format const canvasFormat = navigator.gpu.getPreferredCanvasFormat(); context.configure({ device: device, format: canvasFormat, }); // Create the command encoder const encoder = device.createCommandEncoder(); if (!encoder) { throw new Error("Failed to create a GPUCommandEncoder"); } // Create the render pass encoder const renderPass = encoder.beginRenderPass({ colorAttachments: [{ view: context.getCurrentTexture().createView(), loadOp: "clear", clearValue: { r: 0.9, g: 0.9, b: 0.9, a: 1.0 }, storeOp: "store" }] }); // Define vertex data const vertexData = new Float32Array([ -0.5, -0.5, // First vertex 0.5, -0.5, // Second vertex -0.5, 0.5, // Third vertex 0.5, 0.5, // Fourth vertex ]); // Create vertex buffer const vertexBuffer = device.createBuffer({ label: "Vertex Buffer 0", size: vertexData.byteLength, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST }); device.queue.writeBuffer(vertexBuffer, 0, vertexData); renderPass.setVertexBuffer(0, vertexBuffer); // Define layout of vertex buffer const bufferLayout = { arrayStride: 8, attributes: [ { format: "float32x2", offset: 0, shaderLocation: 0 } ], }; // Define uniform data const uniformData = new Float32Array([ 0.866, 0.5, 0.0, 0.0, // First column of matrix -0.5, 0.866, 0.0, 0.0, // Second column of matrix 0.0, 0.0, 1.0, 0.0, // Third column of matrix 0.0, 0.0, 0.0, 1.0, // Fourth column of matrix ]); // Create uniform buffer const uniformBuffer = device.createBuffer({ label: "Uniform Buffer 0", size: uniformData.byteLength, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST }); device.queue.writeBuffer(uniformBuffer, 0, uniformData); // Create the shader module const shaderModule = device.createShaderModule({ label: "Shader module 0", code: shaderCode }); // Define the rendering procedure const renderPipeline = device.createRenderPipeline({ layout: "auto", vertex: { module: shaderModule, entryPoint: "vertexMain", buffers: [bufferLayout] }, fragment: { module: shaderModule, entryPoint: "fragmentMain", targets: [{ format: canvasFormat }] }, primitive: { topology: "triangle-strip" } }); renderPass.setPipeline(renderPipeline); // Access the bind group layout const bindGroupLayout = renderPipeline.getBindGroupLayout(0); // Create the bind group let bindGroup = device.createBindGroup({ layout: bindGroupLayout, entries: [{ binding: 0, resource: { buffer: uniformBuffer } }] }); // Associate bind group with render pass encoder renderPass.setBindGroup(0, bindGroup); // Draw vertices and complete rendering renderPass.draw(4); renderPass.end(); // Submit the render commands to the GPU device.queue.submit([encoder.finish()]); } // Run example function runExample(); ->>>>>>> 8a057f5318848c2cff3670787e233b96e8421c87 diff --git a/Ch05_RotateSquare/index.html b/Ch05_RotateSquare/index.html index 853a5ac..380793c 100644 --- a/Ch05_RotateSquare/index.html +++ b/Ch05_RotateSquare/index.html @@ -1,4 +1,3 @@ -<<<<<<< HEAD @@ -12,18 +11,3 @@

Ch05_RotateSquare

-======= - - - -

Ch05_RotateSquare

- - - - - - - - - ->>>>>>> 8a057f5318848c2cff3670787e233b96e8421c87