{"id":235,"date":"2021-08-22T22:02:51","date_gmt":"2021-08-22T14:02:51","guid":{"rendered":"https:\/\/blog.indeex.club\/?p=235"},"modified":"2021-10-13T10:03:34","modified_gmt":"2021-10-13T02:03:34","slug":"webgpu%e8%8d%89%e6%a1%88","status":"publish","type":"post","link":"https:\/\/blog.indeex.club\/index.php\/2021\/08\/22\/webgpu%e8%8d%89%e6%a1%88\/","title":{"rendered":"Webgpu\u8349\u6848"},"content":{"rendered":"<hr \/>\n<p><a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/zh.wikipedia.org\/wiki\/WebGPU\">WebGPU<\/a>\u662f\u9488\u5bf9\u4e07\u7ef4\u7f51\u7684\u65b0\u5f00\u653e\u6e90\u4ee3\u7801\u56fe\u5f62API\u6807\u51c6\u7684\u8349\u6848\u63d0\u6848\u3002\u82f9\u679c\u7684WebKit\u56e2\u961f\u4e8e2017\u5e742\u67087\u65e5\u5ba3\u5e03\u4e86\u8be5\u9879\u76ee\u3002\u76ee\u524d\u4e3a\u6b62\uff0c\u82f9\u679c\u6b63\u5728\u5411W3C\u63d0\u51fa\u8fd9\u4e2a\u65b0\u6807\u51c6\uff0c\u8bd5\u56fe\u5728\u6d4f\u89c8\u5668\u4e2d\u5f00\u53d1\u4e0b\u4e00\u4ee3\u56fe\u5f62\u6280\u672f\u3002<\/p>\n<p>\u76f8\u5173Api\u90fd\u662f\u5b9e\u9a8c\u6027\u7684\uff0c\u968f\u65f6\u4f1a\u6539\uff0c\u4e0eWebGL\u7684\u533a\u522b\u3001\u6587\u6863\u7b49\u8be6\u89c1<a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/gpuweb.github.io\/gpuweb\/\">\u5b98\u7f51<\/a>\u3002<\/p>\n<p>\u76ee\u524d\uff0c\u7740\u8272\u5668\u6709\u4e24\u79cd\uff1aGLSL \u548c WGSL\u3002<\/p>\n<p>\u4e2a\u4eba\u63a8\u8350WGSL\uff0c\u672a\u6765\u6280\u672f\u5e94\u8be5\u4e5f\u4f1a\u662f\u8fd9\u4e2a\u3002<\/p>\n<p>\u4ee5\u4e0b\u662f\u6d4b\u8bd5\u4ee3\u7801\uff0c\u7528\u4e8e\u7ed8\u5236\u4e00\u4e2a\u591a\u8fb9\u5f62\uff1a<\/p>\n<pre><code class=\"language-javascript line-numbers\">&lt;canvas id=\"c\" width=\"512\" height=\"512\"&gt;&lt;\/canvas&gt;\n\n&lt;script id=\"vs\" type=\"x-shader\/x-vertex\"&gt;\n[[location(0)]] var&lt;in&gt; position : vec3&lt;f32&gt;;\n[[builtin(position)]] var&lt;out&gt; Position : vec4&lt;f32&gt;;\n\n[[stage(vertex)]]\nfn main() -&gt; void {\n    Position = vec4&lt;f32&gt;(position, 1.0);\n    return;\n}\n&lt;\/script&gt;\n\n&lt;script id=\"fs\" type=\"x-shader\/x-fragment\"&gt;\n[[location(0)]] var&lt;out&gt; outColor : vec4&lt;f32&gt;;\n\n[[stage(fragment)]]\nfn main() -&gt; void {\n    outColor = vec4&lt;f32&gt;(0.0, 0.0, 1.0, 1.0);\n    return;\n}\n&lt;\/script&gt;\n<\/code><\/pre>\n<pre><code class=\"language-javascript line-numbers\">const vs = document.getElementById(\"vs\").textContent;\nconst fs = document.getElementById(\"fs\").textContent;\ninit();\n\nasync function init() {\n    const adapter = await navigator.gpu.requestAdapter();\n    const device = await adapter.requestDevice();\n    const c = document.getElementById('c');\n    const ctx = c.getContext('gpupresent');\n    const swapChainFormat = \"bgra8unorm\";\n    const swapChain = ctx.configureSwapChain({device, format: swapChainFormat});\n    const pipeline = device.createRenderPipeline({\n        layout: device.createPipelineLayout({bindGroupLayouts: []}),\n        vertexStage: {\n            module: device.createShaderModule({\n                code: vs\n            }),\n            entryPoint: 'main'\n        },\n        fragmentStage: {\n            module: device.createShaderModule({\n                code:  fs\n            }),\n            entryPoint: 'main'\n        },\n        vertexState: {\n            vertexBuffers: [{\n                arrayStride: 12, \/\/ 3 * 4bytes\n                attributes: [{\n                    shaderLocation: 0,\n                    offset: 0,\n                    format: \"float3\"\n                }]\n            }]\n        },\n        colorStates: [{\n            format: swapChainFormat,\n            alphaBlend: {\n                srcFactor: \"src-alpha\",\n                dstFactor: \"one-minus-src-alpha\",\n                operation: \"add\"\n            }\n        }],\n        primitiveTopology: 'triangle-list',\n    });\n\n    const positions = [ \n         0.0, 0.5, 0.0, \/\/ v0\n        -0.5,-0.5, 0.0, \/\/ v1\n         0.5,-0.5, 0.0  \/\/ v2\n    ];\n    const data = new Float32Array(positions);\n    const vertexBuffer = device.createBuffer({\n        size: data.byteLength,\n        usage: GPUBufferUsage.VERTEX,\n        mappedAtCreation: true,\n    });\n    new Float32Array(vertexBuffer.getMappedRange()).set(data);\n    vertexBuffer.unmap();\n\n    const render =  function () {\n        const commandEncoder = device.createCommandEncoder();\n        const textureView = swapChain.getCurrentTexture().createView();\n        const renderPassDescriptor = {\n            colorAttachments: [{\n                attachment: textureView,\n                loadValue: {r: 1.0, g: 1.0, b: 1.0, a: 1.0},\n            }]\n        };\n        const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);\n        passEncoder.setVertexBuffer(0, vertexBuffer);\n        passEncoder.setPipeline(pipeline);\n        passEncoder.draw(3, 1, 0, 0);\n        passEncoder.endPass();\n        device.defaultQueue.submit([commandEncoder.finish()]);\n    }\n    requestAnimationFrame(render);\n}\n<\/code><\/pre>\n<p>\u8349\u68482017\u5e74\u5c31\u5df2\u7ecf\u6709\u4e86\uff0c\u4e00\u76f4\u5728\u63a8\u8fdb\u3002<\/p>\n<p>Api\u53d8\u5316\u8f83\u5feb\uff0c\u4e14\u6d4f\u89c8\u5668\u652f\u6301\u4e0d\u4e00\uff0c\u8be6\u89c1<a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/github.com\/gpuweb\/gpuweb\/wiki\/Implementation-Status\">\u6267\u884c\u72b6\u6001<\/a><\/p>\n<p>\u76f8\u4fe1\u5f88\u5feb\u5c31\u80fd\u53d1\u5e03\u6b63\u5f0f\u7248\u3002<\/p>\n<p>code enjoy! \ud83d\udc3e\ud83d\udc3e\ud83d\udc3e\ud83d\udc3e\ud83d\udc3e\ud83d\udc3e\ud83d\udc3e\ud83d\udc3e\ud83d\udc0c\ud83d\udc1d<\/p>\n<p>\u4f5c\u8005\uff1aindeex<\/p>\n<p>\u94fe\u63a5\uff1a<a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/indeex.club\/\">https:\/\/indeex.club<\/a><\/p>\n<p>\u8457\u4f5c\u6743\u5f52\u4f5c\u8005\u6240\u6709\u3002\u5546\u4e1a\u8f6c\u8f7d\u8bf7\u8054\u7cfb\u4f5c\u8005\u83b7\u5f97\u6388\u6743\uff0c\u975e\u5546\u4e1a\u8f6c\u8f7d\u8bf7\u6ce8\u660e\u51fa\u5904\u3002<\/p>\n<hr \/>\n","protected":false},"excerpt":{"rendered":"<p>WebGPU\u662f\u9488\u5bf9\u4e07\u7ef4\u7f51\u7684\u65b0\u5f00\u653e\u6e90\u4ee3\u7801\u56fe\u5f62API\u6807\u51c6\u7684\u8349\u6848\u63d0\u6848\u3002\u82f9\u679c\u7684WebKit\u56e2\u961f\u4e8e2017\u5e742<a href=\"https:\/\/blog.indeex.club\/index.php\/2021\/08\/22\/webgpu%e8%8d%89%e6%a1%88\/\" class=\"read-more\">Read More<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[10],"tags":[],"_links":{"self":[{"href":"https:\/\/blog.indeex.club\/index.php\/wp-json\/wp\/v2\/posts\/235"}],"collection":[{"href":"https:\/\/blog.indeex.club\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.indeex.club\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.indeex.club\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.indeex.club\/index.php\/wp-json\/wp\/v2\/comments?post=235"}],"version-history":[{"count":1,"href":"https:\/\/blog.indeex.club\/index.php\/wp-json\/wp\/v2\/posts\/235\/revisions"}],"predecessor-version":[{"id":236,"href":"https:\/\/blog.indeex.club\/index.php\/wp-json\/wp\/v2\/posts\/235\/revisions\/236"}],"wp:attachment":[{"href":"https:\/\/blog.indeex.club\/index.php\/wp-json\/wp\/v2\/media?parent=235"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.indeex.club\/index.php\/wp-json\/wp\/v2\/categories?post=235"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.indeex.club\/index.php\/wp-json\/wp\/v2\/tags?post=235"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}